What is GitLab CI?
Gitlab ci is the most useful feature of Gitlab. This feature can be used to authenticate the deployment process of any application. This can be integrated with docker, sonarqube, and the EKS service of AWS.
In this blog, we will discuss a pipeline that will use docker for running multiple jobs, and deploy to an AWS server.
Many other CI/CD tools serve the same purpose as gitlab ci, for example, jenkins, circle ci, Azure Pipelines, etc.
How do I get started?
Let’s say we have a simple Node.js application that has a Dockerfile. We will build the image with that dockerfile and push it to one of the docker registries, like dockerhub or ECR repositories.
Then we will pull the image to the server where we want to deploy the application, run the Docker container with the help of the image, and expose it on host port 80.
Before we do this procedure, we should understand the following concepts:
- Docker
- Dockerfile
- Container port and host port
- Knowledge about AWS
This article assumes that you have an idea about the above concepts.
Assume you have one project on GitLab. The project contains a Dockerfile in its root directory. Now go to the GitLab repository and make a file named “.gitlab-ci.yml” in the project root directory. We will discuss snippets of pipeline code one by one, and you can see the complete pipeline code at the end.
To deploy the project in a docker container, the first step is to build the docker image with dockerfile, push it to the container registry, and then deploy it on the required server.
Here we will use two jobs to complete the process. The first job will be “build for qa”.
- build for qa: In this job, we will build the docker image and push it to the container registry.
- Deploy for qa: In this job, we will deploy the application by pulling the image and running it with the docker command.
To run the above jobs, we need a platform where they can run. In gitlab-ci it is called ‘runner’.
Runner
In GitLab CI, a runner is a lightweight agent that runs jobs and sends the results back to the GitLab server. Runners are typically installed on a separate machine or virtual environment that is dedicated to running CI/CD pipelines.
When a GitLab CI/CD pipeline is triggered, GitLab sends the pipeline job to an available runner for execution. The runner then executes the job by cloning the repository, running the scripts defined in the pipeline configuration file, and reporting the results back to GitLab. Multiple runners can be connected to a single GitLab instance, and runners can be configured to run on different platforms and operating systems, making it possible to build and test projects in a wide range of environments.
In this article, we will be using only one runner. To configure the runner, follow the below steps:
1. Install gitlab-runner on the server with the below commands.
For installing gitlab-runner use the below commands—
#curl -L “https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh” | sudo bash
#sudo apt install gitlab-runner
2. To create runner ‘YourprojectName-ui-qa’ follow the below procedure on the terminal.
#sudo gitlab-runner register
Once the command is entered, it will ask for the GitLab URL and authentication token. to get those
Go to YourprojectName-ui(gitlab project)->settings->cicd->expand the runner section. There you will find the URL and authentication token.
After that, it will also ask for details like descriptions, executors, images, and optional notes.
The executor is the docker
Image is Ubuntu: Latest
Tags, descriptions, and optional notes should be given based on the requirement.
Let’s consider that you have given ‘runner-qa’ tag to Runner.
image: “docker:19.03.15”
services:
– docker:19.03.15-dind
.only-qa:
only:
– qa
‘image:’ This portion of the pipeline is to mention the name of the image that is going to be utilized in executing the jobs. ‘services:’ is a keyword that enables you to specify additional Docker images to be run during the build process. In this particular example, the docker:19.03.15-dind image is used to run a Docker daemon inside a Docker container. This is useful for building and testing Docker images within the CI/CD pipeline. The docker:19.03.15 image is also used, likely for running the build and test commands in the pipeline. The .only-qa: section specifies that this configuration applies only to the qa environment.
stages:
– build
– deploys1
– deploys2
In GitLab CI, ‘stages:’ is a top-level keyword that defines the different stages of a pipeline, which are executed sequentially. A stage represents a phase or step in your pipeline, such as build, test, deploy, or any custom step that you define.
build for qa:
extends: .only-qa
stage: build
timeout: 3 hours
tags:
– runner-qa
script:
– docker system prune -a –volumes -f
– docker login “$CI_REGISTRY_URL” -u “$CI_REGISTRY_USER” -p “$CI_REGISTRY_PASSWORD”
– docker build –pull -t “my-node-app”
– docker tag “my-node-app” “$CI_REGISTRY_URL/${CONTAINER_IMAGE}-v2-qa:latest”
– docker push “$CI_REGISTRY_URL/${CONTAINER_IMAGE}-v2-qa:latest”
Above is the GitLab CI/CD pipeline configuration file that defines a job called “build for qa” with the following properties:
- The extends: .only-qa will ensure that the job will be run only if changes are pushed to the qa branch.
- It runs in the “build” stage of the pipeline
- It has a timeout of 3 hours.
- It requires a runner with the “runner-qa” tag to execute the job.
- It contains a script that performs several Docker commands:
docker system prune -a –volumes -f —– this command removes unused Docker data, such as images and volumes.
docker login “$CI_REGISTRY_URL” -u “$CI_REGISTRY_USER” -p “$CI_REGISTRY_PASSWORD” – this command logs in to the Docker registry specified in the CI/CD variables using the provided credentialsdocker build –pull -t “my-node-app” – this command builds a Docker image using the Dockerfile in the current directory and tags it as “my-node-app”
docker tag “my-node-app” “$CI_REGISTRY_URL/${CONTAINER_IMAGE}-v2-qa:latest” – this command creates a new tag for the Docker image with the name and version specified in the CI/CD variables.
docker push “$CI_REGISTRY_URL/${CONTAINER_IMAGE}-v2-qa:latest” – this command pushes the Docker image with the specified tag to the Docker registry.
deploys for qa:
variables:
ENV_TYPE: qa
extends: .only-qa
stage: deploys2
tags:
– YourprojectName-ui-qa
script:
– chmod +x ./ui.sh
– ./ui.sh &
– docker login “$CI_REGISTRY_URL” -u “$CI_REGISTRY_USER” -p “$CI_REGISTRY_PASSWORD”
– docker pull “$CI_REGISTRY_URL/${CONTAINER_IMAGE}-v2-${ENV_TYPE}:latest”
– docker run -p 9000:80 -d “$CI_REGISTRY_URL/${CONTAINER_IMAGE}-v2-${ENV_TYPE}:latest”
This is a GitLab CI/CD configuration file for deploying an application to a QA environment. Here’s a breakdown of what each section does:
variables: This section defines environment variables that will be used in the job. In this case, ENV_TYPE is set to qa.
Stage and tags is same as explained in the previous code.
Script: This section contains the commands that will be run in the job. In this case, the script does the following:
chmod +x ./ui.sh ——– Sets the executable permission for the ui.sh script.
./ui.sh & ——————-Runs the ui.sh script in the background.
docker login “$CI_REGISTRY_URL” -u “$CI_REGISTRY_USER” -p “$CI_REGISTRY_PASSWORD” — Logs in to Docker registry using the credentials specified in environment variables.
docker pull “$CI_REGISTRY_URL/${CONTAINER_IMAGE}-v2-${ENV_TYPE}:latest” – Pulls the latest version of the container image for the specified environment (qa in this case).
docker run -p 9000:80 -d “$CI_REGISTRY_URL/${CONTAINER_IMAGE}-v2-${ENV_TYPE}:latest” — this command will map container port 9000 to host port 80 and run the container in detached mode.The complete .gitlab-ci.yml will look like below:
image: “docker:19.03.15”
services:
– docker:19.03.15-dind
.only-qa:
only:
– qa
stages:
– build
– deploys1
– deploys2
build for qa:
extends: .only-qa
stage: build
timeout: 3 hours
tags:
– runner-qa
script:
– docker system prune -a –volumes -f
– docker login “$CI_REGISTRY_URL” -u “$CI_REGISTRY_USER” -p “$CI_REGISTRY_PASSWORD”
– docker build –pull -t “my-node-app”
– docker tag “my-node-app” “$CI_REGISTRY_URL/${CONTAINER_IMAGE}-v2-qa:latest”
– docker push “$CI_REGISTRY_URL/${CONTAINER_IMAGE}-v2-qa:latest”
deploys for qa:
variables:
ENV_TYPE: qa
extends: .only-qa
stage: deploys2
tags:
– YourprojectName-ui-qa
script:
– chmod +x ./ui.sh
– ./ui.sh &
– docker login “$CI_REGISTRY_URL” -u “$CI_REGISTRY_USER” -p “$CI_REGISTRY_PASSWORD”
– docker pull “$CI_REGISTRY_URL/${CONTAINER_IMAGE}-v2-${ENV_TYPE}:latest”
– docker run -p 9000:80 -d “$CI_REGISTRY_URL/${CONTAINER_IMAGE}-v2-${ENV_TYPE}:latest”
In the above pipeline code, variables used are :
- CI_REGISTRY_URL
- CI_REGISTRY_USER
- CI_REGISTRY_PASSWORD
- CONTAINER_IMAGE
- ENV_TYPE
From the above list of variables, only ENV_TYPE is declared in the pipeline code. The rest are declared as follows:
- open the GitLab project, In the bottom left you will find ‘settings’ -> ci/cd -> variables.
- There you can declare variables that you want to call in the pipeline.
Conclusion
GitLab CI is a powerful continuous integration and delivery tool that enables teams to automate the building, testing, and deployment of software applications. By using GitLab CI, teams can reduce the time and effort required to deploy code changes, minimize errors and bugs, and ensure that their applications are always running smoothly. Overall, GitLab CI is an essential tool for any modern software development team looking to streamline their processes and improve their overall productivity and efficiency.