Developing Next.js applications with Kubernetes (K8s) allows for seamless scalability and high availability.
To set up Next.js with K8s, you'll need to create a Dockerfile that packages your application.
This Dockerfile can be as simple as copying your application code into a new container, making it easy to deploy.
Next, you'll need to create a Kubernetes deployment YAML file to define the structure of your application.
This YAML file will outline the resources required to run your application, such as the number of replicas and the container image.
Once you have your Dockerfile and YAML file set up, you can use a tool like helm to package and deploy your application to K8s.
This streamlined process makes it easy to deploy and manage your Next.js application with K8s.
Prerequisites
Before we dive into building our Next.js Kubernetes (k8s) project, let's make sure we have all the necessary prerequisites in place.
To get started, you'll need an external MySQL Database.
You'll also need to deploy a Vultr Kubernetes Cluster with at least 3 nodes.
Next, configure kubectl and git on your machine.
Installing Docker on your machine is also a must.
Finally, register a Docker Hub account to store your Docker Image.
Docker and Containerization
To containerize your NextJS app, follow the instructions from the NextJS team. This will create a container of your web application that you can upload to a container registry like Dockerhub.
You'll need to have Docker installed on your machine, as well as a Docker Hub account to store the Docker Image. This is a crucial step in deploying your application.
Here's a quick rundown of the prerequisites for containerization:
- Docker installed on your machine
- A Docker Hub account
By following these steps, you'll be able to containerize your NextJS app and push it to your Dockerhub registry.
Prerequisites
To get started with Docker and containerization, you'll need to have a few things in place. First, you'll need to have an external MySQL Database.
You'll also need to deploy a Vultr Kubernetes Cluster with at least 3 nodes. This will give you a solid foundation for running containers.
Make sure you've configured kubectl and git on your machine, as these tools are essential for working with containers.
Additionally, install Docker on your machine, as it's the software that will allow you to create and run containers.
Lastly, register a Docker Hub account to store your Docker Image, which will make it easy to share and manage your containerized applications.
Here's a quick rundown of the prerequisites:
- External MySQL Database
- Vultr Kubernetes Cluster with at least 3 nodes
- kubectl and git configured on your machine
- Docker installed on your machine
- Docker Hub account registered
Containerize Your App
To containerize your app, you'll need to create a Dockerfile. This is a text file that contains instructions for Docker to build your application. You can create a development Dockerfile that mounts your frontend into the container for hot-reload, or a production Dockerfile that statically builds the entire application and Next.js in a container.
The development Dockerfile is straightforward, executing npm i and then npm run dev. When mounted to the host, the ./node_modules directory will also be present on the host.
A multi-stage Dockerfile is recommended for building your application. This type of Dockerfile has three stages: deps, builder, and runner. The deps stage installs dependencies only when needed, while the builder stage rebuilds the source code only when needed. The runner stage is used for production.
Here are the common configurations specified to the next-short-urls application:
- In the builder stage, RUN npx prisma generate to generate the types from the Prisma schema.
- In the runner stage, make a folder /app/.next/cache/images and prepare the folder permission for the Automatic Image Optimization feature in Next.js.
To build the Docker Image, use the command $ docker build . -t next-short-urls. This will create an image with the specified tag.
Helm and Kubernetes
Kusk Gateway is a fully open-source API Gateway for Kubernetes that provides an amazing developer experience and simplicity of use with the power of OpenAPI.
It helps frontend developers deploy their applications easily in Kubernetes, making it a great tool for deploying NextJS applications.
To deploy your NextJS application in Kubernetes, you can use Kusk Gateway, which is a straightforward process that applies to any web application written in any language.
What is Kubernetes?
Kubernetes is a popular container orchestration tool that automates deployment, scaling, and management of containerized applications. It runs over containers created on any Container Engine, such as Docker, Podman, or CRI-O.
Kubernetes provides a range of edge functions, including Loadbalancer, Service discovery, and Roled Based Access Control (RBAC). This allows for secure and efficient management of containerized applications.
Kubernetes supports horizontal scaling, auto scaling, and service discovery. It also provides automated rollbacks and rollouts, health checks, and self-healing capabilities.
Some of the key features of Kubernetes include:
- Horizontal Scaling
- Auto Scaling
- Service Discovery
- Automated rollbacks & rollouts
- Health check & Self-healing
- Load Balancer
- Canary Deployment
Creating a Helm Chart
Creating a Helm Chart is a crucial step in effectively managing deployments and services in Kubernetes. To create a simple Helm chart, you'll need the following components: Frontend Deployment, Registry Image Pull Secrets, Frontend Service, and Ingress.
A Helm chart can be easily adapted, installed, and updated, making it a convenient choice for managing your Kubernetes deployments. We can define a flag .Values.registryAuth.use to check if registry authentication is required.
Our Helm chart will also need to define the registry that should be used, which can be done using the .Values.registryAuth.use flag. This flag is used to inject the imageURL and the registry pull secret if required.
To expose the port 3000 to the cluster, we create a simple service. We also need to create a secret that injects some general environment variables listed in values.yaml: frontend.env.*.
Here are the key components of a Helm chart:
- Frontend Deployment
- Registry Image Pull Secrets
- Frontend Service
- Ingress
We also set up an ingress, introducing flags to set up TLS if required and some annotations to facilitate WebSocket forwards.
Local Development
Local Development is key to a smooth deployment process. To set up local development, you can use a simple local microk8s installation.
We can leverage our existing template .env to push and pull the image from localhost:32000/frontend:registry. This means we can install our newly created chart locally.
Since we set up $ROOT_URL="http://localhost", the ingress will be configured to route to http://localhost.
Introduction
Developing a Next.js application locally can be a game-changer for your development workflow.
You can deploy your Next.js application to a serverless platform, but there are scenarios where you might want more control over your infrastructure.
Deploying to a controlled server and scaling it in your infrastructure can be achieved with Vultr Kubernetes Engine.
This approach has several advantages, including deploying your application close to the database, avoiding the cold-starts problem, and predictable pricing.
Here are some benefits of this approach:
- Deploy the Next.js application as close as possible to the database.
- Avoid the cold-starts problem in the serverless approach.
- Predictable pricing of cloud servers and bandwidth compared to serverless platforms.
Testing on Local
You can deploy the entire infrastructure locally using a simple local microk8s installation. This setup allows you to test your infrastructure without relying on external services.
To start, ensure you have a local microk8s installation. You can install it using the instructions provided.
Using microk8s, you can test your infrastructure by pushing and pulling images from localhost:32000/frontend:registry. This is possible because you set up the template .env earlier, which is already configured for this purpose.
Now, install your newly created chart using microk8s.
Kubernetes Deployment
To deploy your Next.js application, you'll need to create a secret with your Docker Hub credentials. This can be done by running the command `kubectl create secret docker-registry regcred --docker-username=YOUR_DOCKER_HUB_USERNAME --docker-password=YOUR_DOCKER_HUB_PASSWORD --docker-email=YOUR_DOCKER_HUB_EMAIL`.
You'll also need to create a Secret manifest file secrets.yaml with the data as the previously created .env. This file should have the following content: `apiVersion: v1 kind: Secret metadata: name: next-short-urls-secrets namespace: default type: Opaque stringData: DATABASE_URL: "DATABASE_URL_HERE" SECRET_COOKIE_PASSWORD: "SOME_SECRET_PASSWORD_WITH_MIN_LENGTH_32" AWAIT_HISTORY_UPDATE: "0"`.
To create the secret, run the command `kubectl apply -f secrets.yaml`. This will create a secret in your Kubernetes cluster that can be used to authenticate with Docker Hub.
Private Cluster Deployment
To deploy to a private cluster, you'll need a package registry available.
You can quickly get a cheap registry by checking out a blog post on deploying Gitea in a private k8s cluster.
A package registry is essential for private cluster deployment.
Deploy to Cluster
To deploy your application to a cluster, you'll need a package registry available. A cheap registry option is deploying Gitea in a private k8s cluster.
First, create a secret that contains your Docker Hub credentials. This involves running a command like `kubectl create secret docker-registry regcred --docker-username=YOUR_DOCKER_HUB_USERNAME --docker-password=YOUR_DOCKER_HUB_PASSWORD --docker-email=YOUR_DOCKER_HUB_EMAIL`.
Next, create a Secret manifest file with the data from your .env file. This file should contain sensitive information like database URLs and secret passwords.
You'll also need to create a Deployment file that specifies the number of replicas you want. For example, to scale your application to 10 replicas, you can run the command `kubectl scale --replicas=10 deployment/next-short-urls-deploy`.
To access your application, you can perform port-forwarding using the command `kubectl port-forward services/next-short-urls-service 8080:80`. This will allow you to access your application at `http://localhost:8080`.
Sources
- https://blog.t1m.me/blog/nextjs-on-kubernetes
- https://djaytechdiary.com/deploying-nextjs-on-kubernetes
- https://docs.vultr.com/how-to-deploy-a-next-js-application-with-vultr-kubernetes-engine-and-vultr-load-balancer
- https://willschenk.com/howto/2021/next_js_with_prisma/
- https://kubeshop.hashnode.dev/deploy-nextjs-app-in-kubernetes
Featured Images: pexels.com