Deploying a NuxtJS application to a Kubernetes Cluster in Cloud
type
Article
date
May 12, 2021
description
This article showcases one of the possible ways to deploy your NuxtJS or any similar application on the Google Kubernetes platform
If you have been following my series on creating a Personal Website, you might think this is insane! We haven't even written a single line of code for our website, and we are already deploying it to internet!! Hold your horses!
I know this is uncommon. But believe me, this will help you to develop a more reliable and stable codebase. In addition, this article will help you deploy a web application(whether it's a full-fledged Portfolio website or just a shabby page with Grandma quotes) to a Kubernetes Cluster in Cloud(In this case, GCP).
Also, in case you haven't setup a starter project, you can check out this article here.
Some of the advantages of deploying a barebone base application to the internet:
- Cross-Device Compatibility checking: Even after using containerization of application, you might still face issues where the web app works perfectly in Dev environment but has issues in prod. These issues might accumulate over numerous commits. Detecting them early makes our life easier.
- Easier to ask for Reviews: It's impossible to share your code with your peers for review. But they can always suggest improvements by visiting your deployed website. I have received reviews and incorporated them to improve the user experience.
- Gives an Agile spirit to your Project: Large Enterprises don't deploy a 100% developed product to production. They deploy the most miniature usable product and then build upon it. You can follow the same. Use versioning to track changes to your website. You can even create a
Changelog
.
- Source of Motivation: A visible product will motivate you to work than a codebase running on Sandbox in your development machine. It feels nice to open your website now and then. ?
What is Kubernetes Platform?
I won't go into many details here, but Kubernetes is a container orchestration framework. According to an official quote
Kubernetes is a portable, extensible, open-source platform for managing containerized workloads and services that facilitates both declarative configuration and automation. It has a large, rapidly growing ecosystem. Kubernetes services, support, and tools are widely available.
If you want to learn more, visit these links:
Setting up a Cluster
Here we'll use the native Google Kubernetes Engine (GKE) Provided by Google Cloud Platform (GCP) to deploy our nuxt application.
Visit this link for steps on how to setup GKE on GCP.
You can create a
standard
cluster with the following configuration:- Name: Give any to your liking
- Location Type: Depends on your requirements and budget. If you are low on budget, select zone instead of the region. You are trading redundancy for cost.
- The number of nodes: Two should be more than enough for our use case.
- Machine configuration: You can choose E2-Medium (2 vCPU, 4 GB Ram). This gives you a total of 4vCPU and 8 GB Ram.
- Leave the rest as default.
Setting up Persistent Volumes
Containers, by definition, are stateless and ephemeral. Hence, to store persistent data, you need persistent storage, which the containers can then connect to store data. You can create a standard PV(persistent volume). But here, I'll create a better, solid-state drive for improved performance.
1. First, you need to create a Volume class
# ssd-storageclass.yaml apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: solid-state provisioner: kubernetes.io/gce-pd parameters: type: pd-ssd
2. Then, you can create a PV Claim.
# PersistentVolumeClaim.yml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: limosyn-com-pv-claim spec: storageClassName: solid-state accessModes: - ReadWriteOnce resources: requests: storage: 10Gi
Great! We need to setup Github Actions to directly build and deploy our application from the Repository(CI/CD).
Setting up GitHub Actions
If you are using
GitHub
as your version control, you can use GitHub actions to setup a CI/CD workflow that will directly deploy your application to production. GitHub Actions has good integration with the GKE platform.Some Prerequisites
Make sure you have a GCP account and have already setup a cluster following the steps in the previous section.
- Get a service account with proper access to GKE. Visit this link to create one.
- Keep your cluster, Information Handy.
Adding required files
Now you need to add four important files. You can add them manually, but I suggest using GitHub itself to add them. These files are:
.github/workflows/google.yml
: Main configuration used by GitHub to access your Kubernetes cluster and deploy. It also publishes the generated Image to google's Container Registry.
.github/deployment.yml
: Has deployment information such as the number of replicas, deployment strategy, to name a few.
.github/service.yml
: Has information required to expose your deployed service to the internet or within your cluster.
kustomization.yml
: Keeps a record of all the deployment and yml files.
Dockerfile
: For creating your application container image
First of all, let's setup a
Dockerfile
which will be used by GA to generate the application image. This image would then be pushed to Google Container Registry.#Dockerfile FROM node:latest as build-stage RUN apt update -y && apt upgrade -y WORKDIR /app COPY package.json yarn.lock ./ RUN yarn install COPY ./ . EXPOSE 3000 ENV HOST=0.0.0.0 ENV PORT=3000 RUN yarn build CMD ["yarn", "start"]
To setup GA, visit the actions tab on your application Repository:
Scrolling down, you can find a
Build and Deploy to GKE
workflow among many others. You'll get something similar to this:Make changes to the
google.yml
file, such as:PROJECT_ID
: The GCP Project ID.
GKE_CLUSTER
: Name of the GKE Cluster
GKE_ZONE
: Zone where the cluster exists
DEPLOYMENT_NAME
: Give any to your liking.
For adding Secrets, go to
Repository Settings > Secrets > New Repository Secret
GKE_SA_KEY
is the content of your service account credentials.json
file.Now add
deployment.yml
, kustomization.yml
and service.yml
files. For reference, they can be:# deployment.yml apiVersion: apps/v1 kind: Deployment metadata: name: nuxt-frontend namespace: "default" spec: replicas: 2 strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 0 selector: matchLabels: app: nuxt-frontend template: metadata: labels: app: nuxt-frontend spec: containers: - name: app image: gcr.io/PROJECT_ID/IMAGE:TAG imagePullPolicy: Always ports: - containerPort: 3000 livenessProbe: tcpSocket: port: 3000 initialDelaySeconds: 10 timeoutSeconds: 5 periodSeconds: 30 readinessProbe: tcpSocket: port: 3000 initialDelaySeconds: 30 timeoutSeconds: 5 periodSeconds: 30
# service.yml apiVersion: v1 kind: Service metadata: name: nuxt-frontend namespace: default labels: app: nuxt-frontend tier: frontend spec: ports: - protocol: TCP port: 80 targetPort: 3000 selector: app: nuxt-frontend type: LoadBalancer
# kustomization.yml apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - .github/service.yaml - .github/deployment.yaml
Once added, commit your changes!! ??
Provided you did everything right, the next time you push changes to your repository, GitHub actions will deploy your application to your Kubernetes Cluster.
Also, your application should be accessible via the Load balancer IP address.
Summing it up...
Following this article, you:
- Created a GCP account with a free trial.
- Set up a GKE cluster to deploy your application.
- Created files critical to GitHub Actions integration.
- Created a GitHub actions workflow.
This guide can be used to deploy all types of basic applications. Of course, there will be adaptations, but the soul would remain the same.✌?