Home Backend Development Golang Devops pipeline on a Golang Web App with Gitops and Kubernetes

Devops pipeline on a Golang Web App with Gitops and Kubernetes

Oct 24, 2024 am 02:44 AM

In this blog post I'll walk you through the journey of automating the deployment of a web app in golang with CI/CD pipelines and using Gitops approach.

We'll go through containerizing our app to deploying it on kubernetes to using ArgoCD for deployment.

Requirements

  1. A kubernetes cluster You can use any of the managed services from cloud providers for kubernetes or if your system has enough resources to provision a kubernetes cluster you can setup a local kubernetes cluster using Minikube/kind
  2. A github account A free account is sufficient enough as we will be using Github Actions for Continuous Integration (CI)
  3. A dockerhub account We'll be using dockerhub to pull container images
  4. Eagerness to learn
  5. Not giving up This is the important one you'll face problems and you should be able to troubleshoot them and resolve them. I had to troubleshoot a lot of times before I can complete this project.

Lets start

Containerizing the app with Multi-stage docker builds

For the web app to be available on all machines we have to containerize it and when containerization is the word what's best than docker.
I created a Dockerfile to run the app but I have used multi-stage format

Why multi-stage builds ?

The reason is simple if I create an image in a single stage it would consume more space on the machine whereas by using multi-stage builds we optimize the final size of the image by seperating build and runtime environments and also reduce the attack surface of our image for better security

Here's how you can do it

  1. Create a dockerfile
  2. Compile the application in the build stage
  3. Copy the compiled binary to a minimal base image
  4. Build the image and push it to dockerhub so the image can be used by Github Actions in CI
# Start with a base image
FROM golang:1.22 as base
WORKDIR /app
COPY go.mod ./
RUN go mod download
COPY . .
RUN go build -o main .

#######################################################
# Reduce the image size using multi-stage builds
# We will use a distroless image to run the application
FROM gcr.io/distroless/base

# Copy the binary from the previous stage
COPY --from=base /app/main .

# Copy the static files from the previous stage
COPY --from=base /app/static ./static

# Expose the port on which the application will run
EXPOSE 8080

# Command to run the application
CMD ["./main"]
Copy after login
Copy after login
Copy after login

Now that we have the dockerfile let's build it and deploy it to dockerhub

docker build -t pankaj892/webapp:v1 .

We try to check whether app works as expected on local machine
docker run -p 8080:8080 pankaj892-webapp:v1

Lets push it to dockerhub
docker push pankaj892/webapp:v1 .

Kubernetes cluster creation

You can create a cluster locally using mininkube/kind or use any one of the managed solutions on cloud. I'll be using Elastic Kubernetes Service(EKS) from AWS.

You can launch a cluster in EKS using console or from commandline. I'll be using the commandline

eksctl create cluster--instance-selector-vcpus=2 --instance-selector-memory=4 --name <name-of-cluster> --region <region-code> 
Copy after login
Copy after login

This will choose only those machine types for node groups which have 2 vCPUs and memory of 4gb

Helm chart creation and configuration

We can deploy all the resources one by one but it would be difficult to manage them as they scale this is where Helm comes in it acts as a package manager to manage all of our resources with the use of charts

Create a helm chart

# Start with a base image
FROM golang:1.22 as base
WORKDIR /app
COPY go.mod ./
RUN go mod download
COPY . .
RUN go build -o main .

#######################################################
# Reduce the image size using multi-stage builds
# We will use a distroless image to run the application
FROM gcr.io/distroless/base

# Copy the binary from the previous stage
COPY --from=base /app/main .

# Copy the static files from the previous stage
COPY --from=base /app/static ./static

# Expose the port on which the application will run
EXPOSE 8080

# Command to run the application
CMD ["./main"]
Copy after login
Copy after login
Copy after login

Helm will create files for our use but we don't need most of them for our project.

Create the following files and add them in the helm directory

Deployment

eksctl create cluster--instance-selector-vcpus=2 --instance-selector-memory=4 --name <name-of-cluster> --region <region-code> 
Copy after login
Copy after login

Service

helm create web-app
Copy after login

Ingress

# This is a sample deployment manifest file for a simple web application.
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
  labels:
    app: web-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: web-app
  template:
    metadata:
      labels:
        app: web-app
    spec:
      containers:
      - name: web-app
        image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
        ports:
        - containerPort: 8080
Copy after login

Update the values file to this

# Service for the application
apiVersion: v1
kind: Service
metadata:
  name: web-app
  labels:
    app: web-app
spec:
  ports:
  - port: 80
    targetPort: 8080
    protocol: TCP
  selector:
    app: web-app
  type: ClusterIP
Copy after login

Helm part is done now let's move on to deploying our CI

Continuous Integration (CI) with Github Actions

Github Actions allow us to automate the build process of our app based on some events in our repo like push,pull.

Let's create our pipeline file
Workflow file is stored in (.github/workflows/cicd.yml)

# Ingress resource for the application
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web-app
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
  - host: web-app.local
    http:
      paths: 
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-app
            port:
              number: 80
Copy after login

This workflow file first builds our image from dockerfile then pushes it to dockerhub and then updates the tag of the image in our charts.yaml file in helm.

Setting up ArgoCD for Continuous Delivery

We will use argocd for our Cd pipeline since argocd will be able to pick up changes from our git repo and update them in the app.

Lets install argocd on our cluster

kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

To access the argocd server we need to change the service to loadbalancer type

kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'

For windows this would be
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'

If it doesn't work just edit service through kubectl and change the type to LoadBalancer it should work

Now get the ip of the service

kubectl get svc argocd-server -n argocd

We got the ip but we need the password to login to argocd

kubectl get secret argocd-initial-admin-secret -n argocd -o jsonpath="{.data.password}" | base64 --decode

This command would get the password and decode the password since the password is encoded in base64 format

After logging in click on New Project > Add the name for your project > Add the repo so that argocd can sync the repo argocd will automatically look for values file and pick that up after that click on submit

Devops pipeline on a Golang Web App with Gitops and Kubernetes

Ingress and DNS Mapping

We built our pipeline but how do we access our app you can't put in the cluster url from EKS everytime to access it we need to use an ingress for this

I am using Nginx Ingress from AWS so that I can access the app

Deploy the ingress on our cluster

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.11.1/deploy/static/provider/aws/deploy.yaml

Now ingress is deployed and we need to add the ip of our cluster from EKS in our local hosts file for linux its /etc/hosts for windows it is in C:WindowsSystem32etchosts

# Start with a base image
FROM golang:1.22 as base
WORKDIR /app
COPY go.mod ./
RUN go mod download
COPY . .
RUN go build -o main .

#######################################################
# Reduce the image size using multi-stage builds
# We will use a distroless image to run the application
FROM gcr.io/distroless/base

# Copy the binary from the previous stage
COPY --from=base /app/main .

# Copy the static files from the previous stage
COPY --from=base /app/static ./static

# Expose the port on which the application will run
EXPOSE 8080

# Command to run the application
CMD ["./main"]
Copy after login
Copy after login
Copy after login

Now we can access our app on web-app.local

We have done all the steps lets test our app

Devops pipeline on a Golang Web App with Gitops and Kubernetes

As you can see the url at the top is what we defined in our hosts file

Devops pipeline on a Golang Web App with Gitops and Kubernetes

We have the app running lets add something and commit to our repo so argocd can pick up that change and deploy to app

I made a change to me repo and this should trigger the pipeline

Devops pipeline on a Golang Web App with Gitops and Kubernetes

Pipeline has started and after its completion lets see whether argocd picks up that change

Devops pipeline on a Golang Web App with Gitops and Kubernetes

Yes we see changes in our app argocd did pick up changes and synced our app with the latest changes

If you made it this far then congrats!!!

This project has been a great learning experience for me right from deploying kubernetes on AWS to creating my pipelines and deployments and troubleshooting them. This project helped me create an end-to-end devops pipeline for a go app and it can be scalable based on needs. I plan to explore more like maybe deploying the eks clutser using terraform or cloudformation stacks and refine more.

If you get stuck somewhere you can reference this repo

Let me know in the comments how was your experience building this pipeline.

The above is the detailed content of Devops pipeline on a Golang Web App with Gitops and Kubernetes. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Roblox: Bubble Gum Simulator Infinity - How To Get And Use Royal Keys
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Mandragora: Whispers Of The Witch Tree - How To Unlock The Grappling Hook
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Nordhold: Fusion System, Explained
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Hot Topics

Java Tutorial
1668
14
PHP Tutorial
1273
29
C# Tutorial
1256
24
Golang vs. Python: Performance and Scalability Golang vs. Python: Performance and Scalability Apr 19, 2025 am 12:18 AM

Golang is better than Python in terms of performance and scalability. 1) Golang's compilation-type characteristics and efficient concurrency model make it perform well in high concurrency scenarios. 2) Python, as an interpreted language, executes slowly, but can optimize performance through tools such as Cython.

Golang and C  : Concurrency vs. Raw Speed Golang and C : Concurrency vs. Raw Speed Apr 21, 2025 am 12:16 AM

Golang is better than C in concurrency, while C is better than Golang in raw speed. 1) Golang achieves efficient concurrency through goroutine and channel, which is suitable for handling a large number of concurrent tasks. 2)C Through compiler optimization and standard library, it provides high performance close to hardware, suitable for applications that require extreme optimization.

Getting Started with Go: A Beginner's Guide Getting Started with Go: A Beginner's Guide Apr 26, 2025 am 12:21 AM

Goisidealforbeginnersandsuitableforcloudandnetworkservicesduetoitssimplicity,efficiency,andconcurrencyfeatures.1)InstallGofromtheofficialwebsiteandverifywith'goversion'.2)Createandrunyourfirstprogramwith'gorunhello.go'.3)Exploreconcurrencyusinggorout

Golang vs. C  : Performance and Speed Comparison Golang vs. C : Performance and Speed Comparison Apr 21, 2025 am 12:13 AM

Golang is suitable for rapid development and concurrent scenarios, and C is suitable for scenarios where extreme performance and low-level control are required. 1) Golang improves performance through garbage collection and concurrency mechanisms, and is suitable for high-concurrency Web service development. 2) C achieves the ultimate performance through manual memory management and compiler optimization, and is suitable for embedded system development.

Golang's Impact: Speed, Efficiency, and Simplicity Golang's Impact: Speed, Efficiency, and Simplicity Apr 14, 2025 am 12:11 AM

Goimpactsdevelopmentpositivelythroughspeed,efficiency,andsimplicity.1)Speed:Gocompilesquicklyandrunsefficiently,idealforlargeprojects.2)Efficiency:Itscomprehensivestandardlibraryreducesexternaldependencies,enhancingdevelopmentefficiency.3)Simplicity:

C   and Golang: When Performance is Crucial C and Golang: When Performance is Crucial Apr 13, 2025 am 12:11 AM

C is more suitable for scenarios where direct control of hardware resources and high performance optimization is required, while Golang is more suitable for scenarios where rapid development and high concurrency processing are required. 1.C's advantage lies in its close to hardware characteristics and high optimization capabilities, which are suitable for high-performance needs such as game development. 2.Golang's advantage lies in its concise syntax and natural concurrency support, which is suitable for high concurrency service development.

Golang vs. Python: Key Differences and Similarities Golang vs. Python: Key Differences and Similarities Apr 17, 2025 am 12:15 AM

Golang and Python each have their own advantages: Golang is suitable for high performance and concurrent programming, while Python is suitable for data science and web development. Golang is known for its concurrency model and efficient performance, while Python is known for its concise syntax and rich library ecosystem.

Golang and C  : The Trade-offs in Performance Golang and C : The Trade-offs in Performance Apr 17, 2025 am 12:18 AM

The performance differences between Golang and C are mainly reflected in memory management, compilation optimization and runtime efficiency. 1) Golang's garbage collection mechanism is convenient but may affect performance, 2) C's manual memory management and compiler optimization are more efficient in recursive computing.

See all articles