Run GitLab in Docker Containers using Docker Compose

ComputingPost
10 min readOct 12, 2022

--

GitLab is a web-based platform used to host Git repositories. This tool supports software development using the Continuous Delivery(CD) and Continuous Integration(CI) processes. The GitLab Enterprise Edition builds on top of Git with extra features such as LDAP group sync, multiple roles, and audit logs. It also includes authorization integration with deeper authentication.

The amazing features associated with GitLab are:

  • Easy integration with Jenkins, Docker, Slack, Kubernetes, JIRA, LDAP e.t.c
  • Code Quality (Code Climate)
  • On-premise or cloud-based installations
  • Development Analytics
  • Performance monitoring
  • Rich API
  • Integration with IDEs like Eclipse, Visual Studio, Koding, and IntelliJ
  • Issue management, bug tracking, and boards
  • Repository mirroring and high availability (HA)
  • Hosting static websites (GitLab Pages)
  • ChatOp tool (Mattermost)
  • Code Review functionality and Review Apps tool
  • Service Desk (ticketing system)

The GitLab system is made up of several distinct components and dependencies. When installing GitLab directly on your system, these components are installed as well. They include Redis, Gitaly, PostgreSQL, and the GitLab application itself. To avoid these components from being populated into your environment, using Docker containers is the preferred installation method. This ensures that all the components live within a single container away from the filesystem of the host.

In this guide, we will walk through how to run GitLab in Docker Containers using Docker Compose.

Setup Pre-requisites

For this guide you need the following:

  • 1GB or more of available RAM on the host
  • Docker and Docker-compose
  • A fully Qualified Domain name(For SSL certificates)

But before you begin, update your system and install the required tools:

## On Debian/Ubuntu

sudo apt update && sudo apt upgrade

sudo apt install curl vim git



## On RHEL/CentOS/RockyLinux 8

sudo yum -y update

sudo yum -y install curl vim git



## On Fedora

sudo dnf update

sudo dnf -y install curl vim git

#1. Install Docker and Docker Compose on Linux

Begin by installing the Docker engine on your system. Below is a dedicated guide to help you install docker on your system

Once docker has been installed, start and enable the service.

sudo systemctl start docker && sudo systemctl enable docker

Add your system user to the docker group.

sudo usermod -aG docker $USER

newgrp docker

Now proceed and install Docker compose with aid of the below guide.

Another easy way of installing Docker Dev release is with the docker.sh script below:

sudo apt update && sudo apt install curl uidmap -y

curl -fsSL get.docker.com -o get-docker.sh

sudo sh get-docker.sh

dockerd-rootless-setuptool.sh install

#2. Provisioning the GitLab Container

We will begin by pulling the docker-compose.yml file for the deployment.

wget https://raw.githubusercontent.com/sameersbn/docker-gitlab/master/docker-compose.yml

You need to generate 3 random strings at least 64 characters long to be used for:

  • GITLAB_SECRETS_OTP_KEY_BASE: this is used to encrypt 2FA secrets in the database
  • GITLAB_SECRETS_DB_KEY_BASE: used for CI secret variables encryption and importing variables into the database.
  • GITLAB_SECRETS_SECRET_KEY_BASE: it is used for password reset links as well as other ‘standard’ auth features.

These strings can be generated using pwgen installed as with the commands:

##On Debian/Ubuntu

sudo apt install -y pwgen



##On RHEL/CentOS/RockyLinux 8

sudo yum install epel-release -y

sudo yum install pwgen -y



## On Fedora

sudo dnf install -y pwgen

Generate random strings with the command:

pwgen -Bsv1 64

Edit the file and add the strings appropriately, the deployment file has 3 containers i.e Redis, PostgreSQL, and GitLab. Open the file for editing.

vim docker-compose.yml

Make the below changes as desired.

  • PostgreSQL container

Configure your database as preferred. You need to set the database password.

......

postgresql:

restart: always

volumes:

- postgresql-data:/var/lib/postgresql:Z

environment:

- DB_USER=gitlab

- DB_PASS=StrongDBPassword

- DB_NAME=gitlab_production

- DB_EXTENSION=pg_trgm,btree_gist

......
  • GitLab Container

Proceed and provide database details, and set the health check appropriately in the GitLab container.

gitlab:

restart: always

image: sameersbn/gitlab:14.10.2

depends_on:

- redis

- postgresql

ports:

- "10080:80"

- "10022:22"

volumes:

- gitlab-data:/home/git/data:Z

healthcheck:

test: curl http://localhost/-/health || exit 1

interval: 1m

timeout: 10s

retries: 3

start_period: 1m


environment:

- DEBUG=false



- DB_ADAPTER=postgresql

- DB_HOST=postgresql

- DB_PORT=5432

- DB_USER=gitlab

- DB_PASS=StrongDBPassword

- DB_NAME=gitlab_production

......

Also update Timezone variables

- TZ=Africa/Nairobi

- GITLAB_TIMEZONE=Nairobi

Under the GitLab container, you can add HTTPS support by making the below settings. If you do not have an FQDN, enable self-signed certificates as well.

- GITLAB_HTTPS=true

....

If you are using self-signed certificates, you need to enable this as well.

- SSL_SELF_SIGNED=true

Proceed and provide the random strings. Remember to set the GITLAB_HOST and remove the GITLAB_PORT. This is done because we will configure reverse proxy later.

- GITLAB_HOST=gitlab.computingpost.com

- GITLAB_PORT=

- GITLAB_SSH_PORT=10022

- GITLAB_RELATIVE_URL_ROOT=

- GITLAB_SECRETS_DB_KEY_BASE=long-and-random-alphanumeric-string

- GITLAB_SECRETS_SECRET_KEY_BASE=long-and-random-alphanumeric-string

- GITLAB_SECRETS_OTP_KEY_BASE=long-and-random-alphanumeric-string

Set the GitLab user email and password.

- GITLAB_ROOT_PASSWORD=StrongPassw0rd

- GITLAB_ROOT_EMAIL=myemail@example.com

You can also enable SMTP support by making the desired settings.

- SMTP_ENABLED=true

- SMTP_DOMAIN=www.example.com

- SMTP_HOST=smtp.gmail.com

- SMTP_PORT=587

- SMTP_USER=mailer@example.com

- SMTP_PASS=password

- SMTP_STARTTLS=true

- SMTP_AUTHENTICATION=login

There are many other configurations you can make to this container. These settings include the Timezone, OAUTH, IMAP e.t.c

#3. Configure Persistent Volumes

For data persistent, we have to map the volumes appropriately. The docker-compose.yml file has 3 volumes. Here, we will use a secondary disk mounted on our system for data persistence.

Identify the disk.

$ lsblk

NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT

sda 8:0 0 40G 0 disk

├─sda1 8:1 0 1G 0 part /boot

└─sda2 8:2 0 39G 0 part

├─rl-root 253:0 0 35G 0 lvm /

└─rl-swap 253:1 0 4G 0 lvm [SWAP]

sdb 8:16 0 10G 0 disk

└─sdb1 8:17 0 10G 0 part

Ensure the disk is formatted before you proceed to mount it as shown.

sudo mkdir /mnt/data

sudo mount /dev/sdb1 /mnt/data

Confirm if the disk has been mounted on the desired path.

$ sudo mount | grep /dev/sdb1

/dev/sdb1 on /mnt/data type xfs (rw,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota)

Create the 3 volumes in the disk.

sudo mkdir -p /mnt/data/redis

sudo mkdir -p /mnt/data/postgresql

sudo mkdir -p /mnt/data/gitlab

Set the appropriate file permissions.

sudo chmod 775 -R /mnt/data

sudo chown -R $USER:docker /mnt/data

On Rhel-based systems, you need to configure SELinux as below for the paths to be accessible.

sudo setenforce 0

sudo sed -i 's/^SELINUX=.*/SELINUX=permissive/g' /etc/selinux/config

Now create the docker volumes for the containers.

  • Redis
docker volume create --driver local \

--opt type=none \

--opt device=/mnt/data/redis \

--opt o=bind redis-data
  • PostgreSQL
docker volume create --driver local \

--opt type=none \

--opt device=/mnt/data/postgresql \

--opt o=bind postgresql-data
  • GitLab
docker volume create --driver local \

--opt type=none \

--opt device=/mnt/data/gitlab \

--opt o=bind gitlab-data

Once created, list the volumes with the command:

$ docker volume list

DRIVER VOLUME NAME

local gitlab-data

local postgresql-data

local redis-data

Now in the YAML file, add these lines at the bottom.

$ vim docker-compose.yml 

.......

volumes:

redis-data:

external: true

postgresql-data:

external: true

gitlab-data:

external: true

#4. Bringing up GitLab.

After the desired configurations have been made, bring up the containers with the command:

docker-compose up -d

Sample execution output:

[+] Running 23/28

⠇ gitlab Pulling 33.9s

⠿ d5fd17ec1767 Pull complete 8.0s

⠿ 2cbc1a21dc95 Pull complete 9.3s

⠿ e3cf021c7259 Pull complete 25.0s

⠿ c55daad7c782 Pull complete 25.2s

.....

⠿ redis Pulled 24.4s

⠿ 1fe172e4850f Pull complete 17.6s

⠿ 6fbcd347bf99 Pull complete 18.1s

⠿ 993114c67627 Pull complete 18.9s

⠿ 2a560260ca39 Pull complete 20.5s

⠿ b7179886a292 Pull complete 20.8s

....

⠿ postgresql Pulled 21.4s

⠿ 23884877105a Pull complete 2.6s

⠿ bc38caa0f5b9 Pull complete 2.8s

⠿ 2910811b6c42 Pull complete 3.1s

⠿ 36505266dcc6 Pull complete 3.5s

........

Verify if the containers are running:

$ docker ps

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

f5e238c85afb sameersbn/gitlab:14.10.2 "/sbin/entrypoint.sh…" 2 minutes ago Up 2 minutes (healthy) 443/tcp, 0.0.0.0:10022->22/tcp, :::10022->22/tcp, 0.0.0.0:10080->80/tcp, :::10080->80/tcp ubuntu-gitlab-1

c4113ccccc8a sameersbn/postgresql:12-20200524 "/sbin/entrypoint.sh" 2 minutes ago Up 2 minutes 5432/tcp ubuntu-postgresql-1

a352f63cdea5 redis:6.2.6 "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 6379/tcp ubuntu-redis-1

#5. Secure GitLab with SSL Certificates.

We need to secure the site with SSL so as to prevent unauthorized access to your data. With the GITLAB_HTTPS option enabled, you can generate certificates for your domain name. Normally, the container looks for the certificates in the volume that belongs to the GitLab container.

However, in this guide, we will configure the Nginx reverse proxy for HTTPS. First, install Nginx on your system.

##On RHEL/CentOS/Rocky Linux 8

sudo yum install nginx



##On Debian/Ubuntu

sudo apt install nginx

Create a virtual host file as shown.

sudo vim /etc/nginx/conf.d/gitlab.conf

Add the below lines to the file.

server 

listen 80;

server_name gitlab.computinforgeeks.com;

client_max_body_size 0;

chunked_transfer_encoding on;



location /

proxy_pass http://localhost:10080/;

proxy_set_header Host $http_host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;



proxy_set_header X-Forwarded-Proto $scheme;

proxy_set_header X-Forwarded-Ssl on;



proxy_buffering off;

proxy_request_buffering off;

Save the file, restart and enable Nginx.

sudo systemctl restart nginx

sudo systemctl enable nginx

Option1 — Using Self Signed Certificate

The certificate pair is generated using openSSL. Begin by generating the private key.

openssl genrsa -out gitlab.key 2048

Create a certificate signing request(CSR).

openssl req -new -key gitlab.key -out gitlab.csr

Sign the certificate using the CSR and private key.

openssl x509 -req -days 3650 -in gitlab.csr -signkey gitlab.key -out gitlab.crt

After this, you will have a self-signed certificate generated. For more security, you need to create more robust DHE parameters.

openssl dhparam -out dhparam.pem 2048

Now you will have 3 files, gitlab.key, gitlab.crt and dhparam.pem. Copy these files to the certificates directory.

sudo cp gitlab.crt /etc/ssl/certs/gitlab.crt

sudo mkdir -p /etc/ssl/private/

sudo cp gitlab.key /etc/ssl/private/gitlab.key

sudo cp dhparam.pem /etc/ssl/certs/dhparam.pem

Now edit your Nginx config to accommodate the certificates.

server 

server_name gitlab.computingpost.com;

client_max_body_size 0;

chunked_transfer_encoding on;



location /

proxy_pass http://localhost:10080/;

proxy_set_header Host $http_host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;



proxy_set_header X-Forwarded-Proto $scheme;

proxy_set_header X-Forwarded-Ssl on;



proxy_buffering off;

proxy_request_buffering off;







listen 443 ssl;

ssl_certificate /etc/ssl/certs/gitlab.crt;

ssl_certificate_key /etc/ssl/private/gitlab.key;

ssl_dhparam /etc/ssl/certs/dhparam.pem;





server

if ($host = gitlab.computingpost.com)

return 301 https://$host$request_uri;







listen 80;

server_name gitlab.computingpost.com;

return 404;

To establish trust with the server, the client needs to copy the gitlab.crt to the list of trusted certificates. Normally at /usr/local/share/ca-certificates/ for Ubuntu and /etc/pki/ca-trust/source/anchors/ for CentOS. Once done, update the certificates:

##On Ubuntu/Debian

sudo update-ca-certificates



##On CentOS/Rocky Linux

sudo update-ca-trust extract

This is done to avoid the error below during git clone on the client.

$ git clone https://gitlab.computingpost.com/gitlab-instance-dbda973a/my-android-project.git

Cloning into 'my-android-project'...

fatal: unable to access 'https://gitlab.computingpost.com/gitlab-instance-dbda973a/my-android-project.git/': SSL certificate problem: self signed certificate

Option 2 — Using Let’s Encrypt

This requires one to have a Fully Qualified Domain Name(FQDN). Here, we will use a reverse proxy(Nginx) Begin by installing the required packages.

##On RHEL 8/CentOS/Rocky Linux 8/Fedora

sudo dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm

sudo dnf install certbot python3-certbot-nginx



##On Debian/Ubuntu

sudo apt install certbot python3-certbot-nginx

Generate SSL certificates for your domain name using the command:

sudo certbot --nginx

Proceed and issue certificates for the domain name.

........

Which names would you like to activate HTTPS for?

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

1: gitlab.computingpost.com

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Select the appropriate numbers separated by commas and/or spaces, or leave input

blank to select all options shown (Enter 'c' to cancel): 1



Requesting a certificate for gitlab.computingpost.com

Performing the following challenges:

http-01 challenge for bitwarden.example.com

Waiting for verification...

Cleaning up challenges

....

Restart Nginx.

sudo systemctl restart nginx

#6. Access GitLab Web UI.

Now proceed and access GitLab via HTTPS. If you have a firewall enabled, allow the port/service through it.

##For UFW

sudo ufw allow 443/tcp



##For Firewalld

sudo firewall-cmd --add-service=http --permanent

sudo firewall-cmd --add-service=https --permanent

sudo firewall-cmd --reload

Now proceed and access the page using the URL https://domain_name

Run-GitLab-in-Docker-Containers-using-Docker-Compose-6

Login using the created credentials. On successful login, you will see this dashboard.

Run-GitLab-in-Docker-Containers-using-Docker-Compose-1

Set if you want the account to be used by everyone or for personal use by setting who to register for an account. Once configured, proceed and create a new project by clicking on “New Project“.

Run-GitLab-in-Docker-Containers-using-Docker-Compose-2

Here, I will deploy a project from a template as shown.

Run-GitLab-in-Docker-Containers-using-Docker-Compose-3.png-1024x726

Once created, the project will appear as shown.

Run-GitLab-in-Docker-Containers-using-Docker-Compose-4

You can proceed and add SSH keys for easier management. To confirm if everything is set up accordingly, we will try and git clone the repository. Click on clone to obtain the desired URL. Since I do not have SSH keys, I will proceed to use HTTPS as shown.

Run-GitLab-in-Docker-Containers-using-Docker-Compose-7

Voila!

That verifies that the GitLab installation is working as preferred.

#7. Cleanup

To remove the GitLab installation and all the persistent data, use the command:

$ docker-compose down -v

[+] Running 4/4

⠿ Container admin-gitlab-1 Removed 13.5s

⠿ Container admin-redis-1 Removed 0.7s

⠿ Container admin-postgresql-1 Removed 0.5s

⠿ Network admin_default Removed 0.4s

Closing Thoughts.

We have triumphantly walked through how to run GitLab in Docker Containers using Docker Compose. Now you have a GitLab installation from which you can host Git repositories. I hope this was significant.

https://www.computingpost.com/run-gitlab-in-docker-containers-using-docker-compose/?feed_id=11914&_unique_id=63473e31aaa71

--

--

ComputingPost
ComputingPost

Written by ComputingPost

ComputingPost — Linux Howtos, Tutorials, Guides, News, Tips and Tricks.

No responses yet