Go CI/CD

Today, I want to write an article about my configuration CI/CD for the Go project in my company. Let’s start.

I. What is CI/CD?

Continuous integration (CI) is automating the integration of code changes from multiple developers or contributors into a single software project. The team members will integration work with each other. While integrating, the project will build and run tests to find problems. It allows us to develop high quality with lower time.

Continuous Delivery (CI) is a process that helps us build into a product and deliver to QA Teams or Users. While delivering, the project will build and deliver the project into the repository. It reduces the time team members deploy products to environments and prepare the product ready to deploy.

So, CI/CD is a modern process applied in many companies to reduce development time and improve product quality.

II. How CI/CD works

In this article, I’m going to use the Github action platform. Other CI/CD services will be the same.

When developers push code into the repository, the Github will trigger change into Github Actions. It will check configuration and run pipelines like we config. In the demo, I will config it to test, build the image and send the docker image to the docker hub.

Github Actions flow

III. Config CI/CD

We are going to config Ci/CD use the Github Actions. Otherwise, you can use other platforms are Gitlab, Travis CI, Circle CI, or Jenkins.

Github Actions have 2 types of runner: Github-hosted runners and self-hosted runners. Github-hosted runners are computers to run CI/CD that are provided and operated by Github. self-hosted runners are our computers but supported by Github to run CI/CD runners. In this article, we will use self-hosted runners.

Github Actions pricing

1. Setup environment.

Before setup, you must open Terminal and run the below commands

2.1 Update apt source

sudo apt-get update

2.1 Install docker

sudo apt-get install docker.io docker-compose up
sudo systemctl enable docker

2.2 Install Go

sudo add-apt-repository ppa:longsleep/golang-backports
sudo apt update
sudo apt install golang-go

2.3 Add user to docker group

sudo usermod -a -G docker $(whoami)

2. Config Github Actions self-hosted runners

2.1 Add self-hosted runners

First, we need access to the Actions setting of the Github repo.

Select add runner. Github will guide us very detail from download app, configuration, and how to run. This step only needs to be run one time. When you restart the computer, you only need to run ./run.sh to start runner or you can install runner as a service to start runner each time you restart the computer. Learn more here

After complete these steps, you can back to the previous page and see the result.

our self-hosted runners is ready to use.

2.2 Add environment variables

To push the docker image into the docker hub, we need to log in for docker. So, we need to add more environment variables for the account and password of the docker hub.

We are going to the Secrets section in the repo setting.

Add secret by click New Secret button

We need to add 2 variables are DOCKER_USERNAME and DOCKER_PASSWORD

IV. Config CI/CD for Go project

1. Write Dockerfile

We will use docker to build this Go project. Dockerfile is a configuration file to guide docker on how to build this project into an image. Place Dockerfile at the root directory of the project.

FROM golang:alpine as BUILDER
WORKDIR /go/src/app
COPY . .
RUN go mod vendor
RUN GOOS=linux go build -o main
FROM alpine
EXPOSE 80
WORKDIR /app
COPY --from=BUILDER /go/src/app/main /app
CMD /app/main

2. Config Github Actions

Create a folder named .github at the root of the project.

In the .github folder, we create a workflows folder.

In workflows, we need to create a configuration file for Github Actions. The config file is written in YAML syntax.

We will create file main.yml in the workflows folder.

name: CI
on:
  push:
    branches: [ master, develop ]
  pull_request:
    branches: [ master, develop ]
jobs:
  test:
    runs-on: [self-hosted, Linux]
    steps:
      - uses: actions/checkout@v2
      - name: Install dependency
        run: go mod download
      - name: Unit test
        run: make test
        continue-on-error: false
  build:
    runs-on: [self-hosted, Linux]
    needs: [test]
    steps:
      - name: Login docker registry
        run: sudo docker login -u ${DOCKER_USERNAME} -p ${DOCKER_PASSWORD}
        env:
          DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
          DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
      - name: Change script permission
        run: chmod +x build_image.sh
      - name: Build
        run: sudo ./build_image.sh

After commit and push it into Github, Github Actions will run. Let’s check the result.

Github Actions is running
After run success, a green tick is appear

We will go to the Docker Hub site to check

Our project was built and pushed into Docker Hub. Now, we can deploy this image to a server.

V. Use docker to deploy

To deploy into a server, we need access to the server over ssh protocol.

First, You need to log in to the Docker hub if not yet.

sudo docker login

Next, you will create a docker-compose.yml file to deploy.

version: '3'
services:
  api:
    image: thanhdev2703/demogocicd
    restart: always
    ports:
      - 80:80
    volumes:
      - /data/log:/app/log
      - ./.env:/app/.env
    network_mode: "host"

After creating the docker-compose file, run the below command to deploy for the first time.

sudo docker-compose up -d

To deploy new image, run the below commands.

sudo docker-compose pull
sudo docker-compose down
sudo docker-compose up -d

VI. Summary

So, we completed to config Ci/CD for a Go project. That simple

Demo project in this article: https://github.com/ThanhDev2703/DemoGo-CICD

Learn more:
https://github.com/features/actions
https://github.com/actions/setup-go
https://docs.github.com/en/actions/building-and-testing-code-with-continuous-integration/about-continuous-integration

Leave a Reply