Setup GitLab CE using Docker

When working on new project, i am always prefer to use GitLab as git repository and CICD platform, if there is no gitlab server or we are now allowed to use Gitlab saas, it's time for me to deploy self-managed gitlab ce using docker. The architecture is like this.

In the context of this post i will deploy haproxy and gitlab using docker compose. They will share same docker network and haproxy will expose port 443 (for https) and 24 to the host machine. Haproxy also do tls terminate and forward traffic to gitlab server inside docker.

We will do these following step

  • Prepare SSL cert and key
  • Prepare gitlab.rb configuration
  • Prepare haproxy.cfg configuration
  • Prepare docker-compose.yml configuration
  • Deploy service using docker compose up command.

Prepare SSL cert and key

If you did not own any cert, go grab it after reading this post https://blog.shiftasia.com/get-a-free-tls-certificate-with-acme-sh/. Haproxy need us to merge cert and key, simply copy the content of two files into one file or executing two commands.

cat tls.crt > tls.pem
cat tls.key >> tls.pem

For me after doing this, i got tls.pem content same as

Prepare gitlab.rb configuraton

Gitlab server need config to initial server, copy the content and editing external_url to your dns. After that map your domain dns record to server public ip. For example i will set A Record for git.dongnguyen.link to 54.12.64.12 while 54.12.64.12 is public ip server. You also need to add firewall rule to access ingress to port 443 and 24 .

You also need to update  smtp config, change your gmail password and user, if you use another email server, update to yours. You also need to change  initial_root_password.

external_url  'https://git.dongnguyen.link'
nginx['listen_port'] = 8000
nginx['listen_https'] = false
gitlab_rails['monitoring_whitelist'] = ['0.0.0.0/0']
gitlab_rails['gitlab_shell_ssh_port'] = 24
registry['enable'] = false
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.gmail.com"
gitlab_rails['smtp_port'] = 587
gitlab_rails['smtp_user_name'] = "coppernguyen"
gitlab_rails['smtp_password'] = "pleasechangeyourpassword"
gitlab_rails['smtp_domain'] = "gmail.com"
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['smtp_tls'] = false
prometheus_monitoring['enable'] = false
grafana['enable'] = false
gitlab_rails['pipeline_schedule_worker_cron'] = "* * * * *"
gitlab_rails['initial_root_password'] = "b0f97a668d7119fda65e1d67d09eedbfd1fd4823"

Prepare haproxy.cfg configuration

Haproxy need config to be run, copy the content of this file and write to haproxy.cfg

global
	maxconn 8192
    ulimit-n 1000000
    log stdout format raw daemon debug

resolvers docker
    nameserver dns1 127.0.0.11:53
    hold valid 10s

defaults
	log     global
	mode    http
	option  httplog
	option  dontlognull
	option httpchk
    option forwardfor
    http-reuse aggressive
	timeout connect 2s
	timeout client 1m
	timeout server 5s

listen https
	bind *:80
	bind *:443 ssl crt /tls.pem
	redirect scheme https if !{ ssl_fc }
    stats uri /stats
	http-check send meth GET uri /-/health
	http-check expect status 200
	server gitlab gitlab:8000 resolvers docker init-addr none check inter 2s  fall 5  rise 5

listen ssh
	bind *:24
	mode tcp
	option tcplog
    mode tcp
	option tcp-check
	server gitlab gitlab:22 resolvers docker init-addr none check  observe layer4  error-limit 10  on-error mark-down

In this configuration, i define two listen, one for https port and one for ssh port.  They both forward to gitlab server port. Beside that, when we visit /stats via https port we will see our haproxy backend stats.

Prepare docker-compose.yml configuration

The content of compose's file look like this.

version: "3.9"

networks:
  default:
    name: gitlab
    driver: bridge

volumes:
  config:
  logs:
  data:


configs:
  gitlab:
    file: ./gitlab.rb
  haproxy:
    file: ./haproxy.cfg

x-service-common:
  &service-common
  restart: unless-stopped
  mem_limit: 8192m

services:
  haproxy:
    <<: *service-common
    image: haproxy:lts-alpine3.17
    ports:
      - 80:80
      - 443:443
      - 24:24
    configs:
      - source: haproxy
        target: /usr/local/etc/haproxy/haproxy.cfg
    volumes:
      - ./tls.pem:/tls.pem
  gitlab:
    <<: *service-common
    image: 'gitlab/gitlab-ce:latest'
    configs:
      - source: gitlab
        target: /etc/gitlab/gitlab.rb
    volumes:
      - config:/etc/gitlab
      - logs:/var/log/gitlab
      - data:/var/opt/gitlab

You will see that i create two service, and also two configuration mount into 2 service.Our directory tree look like this so far.

Deploy using docker compose up

Run this command to deploy all service.

docker compose up -d

Go to /stats to view stats, for me i will go to https://git.dongnguyen.link/stats because git.dongnguyen.link is my external_url i set on gitlab.rb configuration.

From image above, we see that our gitlab is up, now is time to login. Go to https://git.dongnguyen.link, login with root and initial_root_password you have set in gitlab.rb above.

That is, we deployed gitlab server. Thank for reading the post.