DEV Community

boiledsteak
boiledsteak

Posted on

How to set up on-prem Gitlab VCS, Gitlab CI/CD, Gitlab Runner, with Docker

Introduction

Hello! I haven't posted to Dev.to in a while. I have been learning more about Devops, Devsecops, and how I want to navigate my cybersecurity career.

I did some hands-on CI/CD by setting up my own pipeline in my local hosted Virtual Machines. This is sort of my documentation of what I did, a tutorial for others, but more importantly to guide my future self should I want to build something like this again.

To preface, I am a cybersecurity student from Singapore. Apart from school projects, internships, and a couple of side hustles, I do not have true web development/ system adminstration experience in a real-world, large scale production environment. My information may not be 100% accurate; I may be deviating from best practices. Nevertheless, I know that it works. I couldn't find information on this specific permutation of Gitlab and Docker so I hope my sharing would be useful for others who want to build something similar. Let me know if there's anything I could have done better!

Infrastructure

Image description

The infrastructure is actually very simple. It's just 2 docker containers running inside an ubuntu VM. You could even run the 2 docker containers inside Windows. Just need to configure slightly differently. The containers are even pulled from Dockerhub. What made this difficult for me was the configuration files. There's small details that I had to dig from several sources to get my pipeline working.

Prerequisites

If running in a VM, you might want to allocate more resources. My Gitlab was quite laggy. I suspect its hardware ... If your Gitlab starts becoming unresponsive, just restart the machine. Avoid pausing the VM too.
Image description

Apart from that, you just need Docker.

It's very simple with apt on Ubuntu. Steps here

You could also use Docker Desktop for a GUI process however most guides and documentation online give steps through CLI so I used CLI too.

After installing Docker, you might realise that most Docker commands require sudo. If you do not want to keep typing in sudo:

sudo usermod -aG docker $USER
Enter fullscreen mode Exit fullscreen mode

HOWEVER this opens up a privilege escalation security vulneraibility. This entire write up is for home testing and learning. This is NOT for production.

That's all! On to the actual installation of Gitlab!

Installation

Gitlab has a CE and EE version (community and enterprise). Both are free to download. I used the EE version. Download the Gitlab EE image from Dockerhub

docker pull gitlab/gitlab-ee
Enter fullscreen mode Exit fullscreen mode

In a Gitlab CI/CD pipeline, there are jobs. Different machines can run the jobs in whatever permutation needed for load balancing and scaling. I'm not very clear on this feature of Gitlab CI/CD but I know that to run a job you need a runner. As quoted in Runner documentation,

For security and performance reasons, you should install GitLab Runner on a machine that is separate to the machine that hosts your GitLab instance

I'm not too sure about the specifics, but I just wanted a single runner to run a simple pipeline. Based on this thread, it seems okay for my use case to run both the Gitlab container and the Runner container on the same machine.

So that's what I did.

docker pull gitlab/gitlab-runner
Enter fullscreen mode Exit fullscreen mode

Configuration

Now this is the part where I couldn't find a single source of answers.

From Gitlab documentation, first create a directory for the Gitlab files:

export GITLAB_HOME=/srv/gitlab
Enter fullscreen mode Exit fullscreen mode

Then create a file named docker-compose.yml (actually you can name it anything you want but this step makes some processes more convenient). Docker compose files allow you to write whatever configuration you want before running the container. Multiple containers can be run with one single compose file too. But I'm not too sure about the best practices of this. I believe IAC tools such as Ansible can be used too but for my testing I just used one compose file for one container.

Gitlab container's docker-compose.yml

version: '3.6'
services:
    docker:
        volumes:
            - '/var/run/docker.sock:/var/run/docker.sock'
        tty: true
        stdin_open: true
        image: docker
    web:
        image: 'gitlab/gitlab-ee:latest'
        restart: always
        environment:
            GITLAB_OMNIBUS_CONFIG: |

        ports:
            - '80:80'
            - '443:443'
            - '22:22'
            - '8093:8093'
        volumes:
            - '$GITLAB_HOME/config:/etc/gitlab'
            - '$GITLAB_HOME/logs:/var/log/gitlab'
            - '$GITLAB_HOME/data:/var/opt/gitlab'
        shm_size: '256m'
Enter fullscreen mode Exit fullscreen mode

I don't remember exactly what each config is for but I can roughly explain a few key ones:
volumes this is to make storage persistent
restart I think this is to run the container on boot
ports apart from the common ports, I believe port 8093 is for session_server.
shm_size the Gitlab app is very resource heavy so apparently this increases RAM allocation... I think

Next, in a separate directory, create another docker-compose.yml

version: '3.6'
services:
     gitlab-runner:
          container_name: gitlab-runner
          restart: always
          stdin_open: true
          tty: true
          command: register
          volumes:
                - '/srv/gitlab-runner/config:/etc/gitlab-runner'
                - '/var/run/docker.sock:/var/run/docker.sock'
          image: 'gitlab/gitlab-runner:latest'
          ports:
                - '81:80'
                - '8094:8093'
Enter fullscreen mode Exit fullscreen mode

Then in the Gitlab container directory and the Runner directory:

docker compose up -d
Enter fullscreen mode Exit fullscreen mode

Gitlab takes some time to start. To see the status of the containers:

docker ps
Enter fullscreen mode Exit fullscreen mode

Next, you need to access the Gitlab app's config files. You could try open an editor within the container or do what I did lol. Install the docker extention in VS code.

Image description
Navigate to etc/gitlab/gitlb.rb and look for the external_url. For home testing/learning you can use your own IP address. hostname -I. Read here

If everything goes well, open your web browser and enter your IP address. You should see the Gitlab login. The default username should be root while the password can be found in etc/gitlab/initial_root_password. You can change the password through the web GUI afterwards. Once logged in, click click click ~ create your project.

Then there's 2 things you'd want to look at. First, the pipeline editor:
Image description
This is where you configure your CI/CD pipeline with whatever building and testing you want.

Second, you'd want to link your runner to your project.
Image description

The Gitlab app guides you on the runner registration. Just click new runner registration and follow the steps. Allow the runner to run untagged jobs. This is just for convenience. Next screen shows you the steps to continue.

To run commands in the Runner app:

docker exec -it gitlab-runner bash
Enter fullscreen mode Exit fullscreen mode

With that, you can start testing your CI/CD pipeline script! Perhaps try some devsecops tools. Snyk? Synopsys?

Thank you for reading my post :) I am still learning so please let me know if I can do this better! I might just be spreading misinformation lol

Top comments (0)