Gitlab CI/CD on Docker



Gitlab CI/CD on Docker

Pre-read: Gitlab on Docker

Gitlab with CI/CD is a little bit different from gitlab. For CI/CD, gitlab makes use of a separate service called gitlab-runner. And this service spawns worker nodes out of any mentioned docker image.

So we have 3 moving parts (3 docker containers)
  1. gitlab 
  2. gitlab-runner : it is like CI / CD manager for gitlab
  3. worker nodes : created by gitlab-runner to run "jobs" in pipeline

Setup

Create Network

Since we now need to work with 3 docker containers, we need a network. So lets begin with a network.
docker network create network-gitlab

Setup gitlab

With our network ready, we can now create gitlab running in this network.
Note: Create local folders (to mount as volume) before running command

docker run --detach \
  --hostname localhost:8180 \
  --publish 8143:443 --publish 8180:8180 --publish 8122:22 \
  --name gitlab \
  --restart always \
  --volume /Users/hsingh/docker/data/gitlab/config:/etc/gitlab \
  --volume /Users/hsingh/docker/data/gitlab/logs:/var/log/gitlab \
  --volume /Users/hsingh/docker/data/gitlab/data:/var/opt/gitlab \
  --net network-gitlab \
  gitlab/gitlab-ce:latest

Setup gitlab-runner

docker run --detach \
  --name gitlab-runner \
  --restart always \
  --volume /Users/hsingh/docker/data/gitlab-runner/config:/etc/gitlab-runner \
  --volume /var/run/docker.sock:/var/run/docker.sock \
  --net network-gitlab \
  gitlab/gitlab-runner:latest

Setup up CI-CD pipeline

Create project

A pipeline is specific to a project. So first create a project in gitlab. You can follow below steps
  1. Open your gitlab using http://localhost:8180
  2. Click on "Projects" on top menubar
  3. Select "Your Projects"
  4. Click on "New Project" button on top right
Or if your gitlab has no projects, and you are on homepage, you have a button to directly create a new project.

Find info to connect gitlab-runner

Now we shall setup CI/CD for this project. For this, we need to assign gitlab-runner to this project. Follow below steps
  1. Navigate to project
  2. On left navigation menu, click "Settings"
  3. Then select "CI / CD"
  4. Click on "Expand" button in "Runners" section
  5. We shall setup a runner manually. So let us stop at this page.

Configure gitlab-runner

We use gitlab-runner docker image to add config into runner, and then delete the container - because we do not need it. Hence --rm flag.

docker run --rm -it \
  --volume /Users/hsingh/docker/data/gitlab-runner/config:/etc/gitlab-runner \
  gitlab/gitlab-runner register

This is interactive and asks questions. Below are the questions and answers I set.

Questions are in RED. Answers in BLUE.

Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):
http://docker.for.mac.localhost:8180/
Make sure you set this as I set.

Please enter the gitlab-ci token for this runner:
nijG8qsxFx2i7-UcnEsT
This is the code I got from gitlab's CI/CD setting's Runner section. You will know it when you see it.

Please enter the gitlab-ci description for this runner:
[015fe0b9f66f]: test runner 01
You can give any name you want

Please enter the gitlab-ci tags for this runner (comma separated):

I left it blank. Otherwise you can give it tags. This tags will control which jobs can be run on which runner. These tags will be matched with .gitlab-ci.yml job's tags. We shall talk about it a bit later.

Please enter the executor: shell, custom, docker-ssh, parallels, ssh, virtualbox, docker+machine, docker-ssh+machine, kubernetes, docker:
docker

Please enter the default Docker image (e.g. ruby:2.6):
alpine:latest
This is the default image we shall use for any job run by this runner. It can again be overridden in .gitlab-ci.yml

Continue to configure gitlab-runner manually edit config.toml

The questions and answers in previous step add configuration to a file called config.toml. This file is kept in the "config" volume we mounted for gitlab-runner. 

What gitlab runner does is create a docker node and runs CI/CD job on it. And config.toml is a configuration for this docker node creation.

We need to add two things to this config
  1. URL to gitlab repo - so that node can checkout codebase
  2. Add docker node to network so that it can access gitlab and gitlab-runner

Add URL to gitlab repo

In config.toml, [[runners]] section, add
clone_url = "http://gitlab:8180"
"gitlab" is name of gitlab container. Everyone inside "network-gitlab" can access it with this name.

Add network name

in config.toml, [runners.docker] section of our runner, add
network_mode = "network-gitlab"

Pull images from local repo

By default gitlab-runner will pull images from dockerhub. But if you create an image locally, you would want that to be picked up - without having to go to dockerhub. For this add below line in config.toml under [[runners]]
pull_policy = "if-not-present"

Setup CI / CD pipeline

This is the final piece. Creating a .gitlab-ci.yml file for project. And put it in project root.
Put these contents

stages:
  - build
  - test
build:
  stage: build
  image: ubuntu:latest  
  script:
    - echo "This is my build stage"
test:
  stage: test
  script:
    - echo "This is my test stage"

This will trigger a pipeline. And you can see that pipeline has 2 stages: "build" and "test". And you can also see that "build" stage runs on ubuntu image, and "test" stage runs on alpine (set in config.toml).

Comments