🔗 Setting up GitHub Actions
1.) Create a GitHub repository
Alright, first things first—let’s create a GitHub repository to house your Next.js app. In my case, I named mine "netflix-next." 😉 Feel free to call yours whatever you want, but I highly recommend a name that inspires fear and respect in your fellow developers.
2.) Create a GitHub repository named infrastructure
3.) Inside it, create the following directories and files
For reference, check my repositories: https://github.com/kaizerpwn/netflix-next
and https://github.com/kaizerpwn/infrastructure
):
k8s
-- netflix-next
---- deployment.yml
---- service.yml
---- ingress.yml
Here’s what each file does:
- deployment.yml: Defines the configuration for deploying your app’s Docker container, including the number of replicas and the image to use.
- service.yml: Sets up the networking layer for your app, ensuring that traffic is directed to the correct pods.
- ingress.yml: Manages external access to the services, routing HTTP/S traffic to the correct service endpoints.
The contents of these files are as follows:
deployment.yml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: netflix-next-deployment
spec:
replicas: 3
selector:
matchLabels:
app: netflix-next
template:
metadata:
labels:
app: netflix-next
spec:
containers:
- name: netflix-next-container
image: ghcr.io/<YOUR_GITHUB_USERNAME>/<YOUR_DOCKER_IMAGE_NAME>:e19d20e9df6de3f64f622c46c4f6315ce37b3097
ports:
- containerPort: 3000
imagePullSecrets:
- name: regcred
ingress.yml:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
cert-manager.io/cluster-issuer: letsencrypt-staging
name: netflix-next-ingress
namespace: default
spec:
ingressClassName: public
rules:
- host: netflix.kaizer.live
http:
paths:
- path: /.well-known/acme-challenge/
pathType: Prefix
backend:
service:
name: cm-acme-http-solver-service
port:
number: 80
- path: /
pathType: Prefix
backend:
service:
name: netflix-next-service
port:
number: 80
tls:
- hosts:
- netflix.kaizer.live
secretName: netflix-next-tls
service.yml:
apiVersion: v1
kind: Service
metadata:
name: netflix-next-service
spec:
type: LoadBalancer
selector:
app: netflix-next
ports:
- protocol: TCP
port: 80
targetPort: 3000
4.) Create a GitHub personal access token (shown in the video).
To allow GitHub Actions to interact with your repositories, create a GitHub personal access token. This token will be used to authenticate the workflow when it pushes updates or checks out code.
5.) Add the codespace secret to the infrastructure
repository (shown in the video).
Add your personal access token as a secret to the infrastructure repository. This allows the GitHub Actions workflow to use it securely without exposing your credentials.
6.) Add the actions secrets to the netflix-next
repository (shown in the video).
Similarly, add necessary secrets to the netflix-next repository. These might include Docker registry credentials, API keys, or any other sensitive information your workflow needs.
7.) Once this is done, create a workflow file pipeline.yml
(shown in the video):
Now, create a pipeline.yml file in the .github/workflows directory of your netflix-next repository. This file will define the CI/CD pipeline for your Next.js app:
pipeline.yml:
name: CI/CD Pipeline for Next.js
on:
push:
branches: [ "main" ]
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout Source Code
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: '18.x'
- name: Install Dependencies
run: npm ci
- name: Build Next.js App
run: npm run build
- name: Docker Login
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.PAT_TOKEN }}
- name: Docker Build and Push
id: build-push
uses: docker/build-push-action@v3
with:
context: .
file: ./Dockerfile
push: true
tags: |
ghcr.io/<YOUR_USERNAME>/<YOUR_DOCKER_IMAGE_NAME>:${{ github.sha }}
ghcr.io/<YOUR_USERNAME>/<YOUR_DOCKER_IMAGE_NAME>:latest
- name: Get Docker Image Digest
id: digest
run: |
IMAGE_DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' ghcr.io/<YOUR_USERNAME>/<YOUR_DOCKER_IMAGE_NAME>:${{ github.sha }})
echo "IMAGE_DIGEST=$IMAGE_DIGEST" >> $GITHUB_ENV
- name: Checkout Infra Repository
uses: actions/checkout@v4
with:
repository: <YOUR_USERNAME>/infrastructure
ref: 'main'
token: ${{ secrets.INFRASTRUCTURE_TOKEN }}
path: infrastructure
- name: Verify File Presence
run: |
echo "Checking file presence:"
ls -la infrastructure/k8s/<YOUR_REPOSITORY>/
cat infrastructure/k8s/<YOUR_REPOSITORY>/deployment.yml
- name: Update Deployment Manifest
run: |
echo "Updating deployment manifest:"
# Print the file content before changes
echo "Before update:"
cat infrastructure/k8s/<YOUR_REPOSITORY>/deployment.yml
# Update the image tag in the deployment manifest with the digest
sed -i "s|image: ghcr.io/<YOUR_USERNAME>/<YOUR_DOCKER_IMAGE_NAME>:.*|image: ghcr.io/<YOUR_USERNAME>/<YOUR_DOCKER_IMAGE_NAME>:${{ github.sha }}|g" infrastructure/k8s/<YOUR_REPOSITORY>/deployment.yml
# Print the file content after changes
echo "After update:"
cat infrastructure/k8s/<YOUR_REPOSITORY>/deployment.yml
- name: Stage and Commit Changes
run: |
cd infrastructure
git config user.name "GitHub Actions Bot"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add k8s/<YOUR_REPOSITORY>/deployment.yml
# Verify the staging
git status
# Commit and push changes if there are modifications
if git diff --cached --quiet; then
echo "No changes to commit"
else
git commit -m "Update image to version ${{ github.sha }}"
git push origin main
fi
8.) After committing this file, the first build will start. Click on the Actions tab and wait for it to run.
If everything is correct, the build will be green 🌿, and in the infrastructure
repository, the GitHub Actions bot will automatically update the image tag in the deployment.yml, so you can check that. After these steps, we have completed everything related to GitHub.
We can now move on to the server part. Also, if you wish, you can add more pipelines, e.g., one for staging environment and another for production, etc.
⚙ MicroK8s Installation and Configuration Guide
Now I will provide a step-by-step guide to installing MicroK8s, enabling essential services, and setting up Argo CD on your Kubernetes cluster.
1.) Install MicroK8s
To get started, you need to install MicroK8s using snapd. Run the following commands in your terminal:
sudo apt install snapd
sudo snap install microk8s --classic
2.) Enable Required Services
After installing MicroK8s, you need to enable several essential services to ensure your cluster is fully functional. The following commands will enable DNS, storage, registry, MetalLB (Load Balancer), hostpath storage, Ingress, Dashboard, Cert Manager, and MinIO:
microk8s enable dns
microk8s enable storage # (optional)
microk8s enable registry
microk8s enable metallb # Load balancer
microk8s enable hostpath-storage # (optional)
microk8s enable cert-manager # Certificate manager
microk8s enable dashboard # Kubernetes dashboard (optional)
microk8s enable ingress # Routing rules manager
microk8s enable minio # Object storage S3 service - like Amazon S3 (optional)
3.) Install Argo CD
To deploy Argo CD as a service, follow these steps. Ensure you check for the latest version of Argo CD before applying the command:
microk8s.kubectl create namespace argocd
microk8s.kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/v2.12.3/manifests/install.yaml
4.) Expose Argo CD on an External Port
To expose Argo CD on an external port, you have two options. You can either change the Service type to NodePort or LoadBalancer.
Method 1: Using NodePort
microk8s.kubectl edit svc argocd-server -n argocd
Change the spec.type from ClusterIP to NodePort:
spec:
type: NodePort
ports:
- name: http
port: 80
targetPort: 8080
nodePort: 32080 # Choose any port within the valid NodePort range (30000-32767)
- name: https
port: 443
targetPort: 8443
nodePort: 32443 # Choose any port within the valid NodePort range (30000-32767)
Method 2: Using LoadBalancer
Alternatively, change the spec.type to LoadBalancer if you have MetalLB or other LoadBalancer service:
spec:
type: LoadBalancer
5.) Retrieve the Initial Argo CD Admin Password
To obtain the initial password for logging into the Argo CD dashboard (the username is admin), run the following command:
microk8s.kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
Copy the output and use it to log in to the Argo CD dashboard.
6.) Create a Docker Registry Secret
To create a Docker registry secret for accessing private Docker images (e.g., from GitHub Container Registry), use the following command. Replace GITHUB_USERNAME, GITHUB_PERSONAL_ACCESS_TOKEN, and GITHUB_EMAIL with your GitHub credentials:
microk8s.kubectl create secret docker-registry regcred \
--docker-server=ghcr.io \
--docker-username="GITHUB_USERNAME" \
--docker-password="GITHUB_PERSONAL_ACCESS_TOKEN" \
--docker-email="GITHUB_EMAIL" \
-n default
By following these steps, you will have a fully configured MicroK8s cluster with essential services and Argo CD ready for use. Make sure to replace placeholders with your actual information when creating secrets or applying configuration changes.
7.) Access the ArgoCD on the web
To check the port on which ArgoCD is running, use the following command:
microk8s kubectl get svc -n argocd
You will get output like this:
argocd-applicationset-controller ClusterIP 10.152.183.42 <none> 7000/TCP,8080/TCP 5d19h
argocd-dex-server ClusterIP 10.152.183.120 <none> 5556/TCP,5557/TCP,5558/TCP 5d19h
argocd-metrics ClusterIP 10.152.183.249 <none> 8082/TCP 5d19h
argocd-notifications-controller-metrics ClusterIP 10.152.183.122 <none> 9001/TCP 5d19h
argocd-redis ClusterIP 10.152.183.218 <none> 6379/TCP 5d19h
argocd-repo-server ClusterIP 10.152.183.25 <none> 8081/TCP,8084/TCP 5d19h
argocd-server LoadBalancer 10.152.183.26 10.64.140.43 80:32092/TCP,443:31217/TCP 5d19h
argocd-server-metrics ClusterIP 10.152.183.202 <none> 8083/TCP 5d19h
You can now access ArgoCD in your web browser using https://YOUR_SERVER_IP:31217/ or the port that was displayed in the output specific to your setup.
Username: admin
Password: The password is provided in the output of step 5.
8.) Connect repository with ArgoCD
To connect your repository with ArgoCD follow steps shown in the video:
9.) Create and deploy new application
Finally, create and deploy your app using ArgoCD. Follow the steps in the video, and watch as your app springs to life like a phoenix from the ashes—or, you know, like an app from the cloud.
By the end of this adventure, you'll have a fully configured MicroK8s cluster, with all the bells and whistles, ready to handle whatever you throw at it.
Happy coding, and may your builds be ever green! 🌿
Top comments (0)