We show you how we deployed our self hosted gitlab instance on a virtual machine, added gitlab runners to execute out build pipelines and added a container registry all behind a traefik reverse proxy.
We’re using docker swarm do deploy and scale our services.
version: '3.8'
services:
app:
image: traefik:v2.9.6
environment:
- TZ=Europe/Zurich
ports:
- target: 80
published: 80
mode: host
- target: 443
published: 443
mode: host
- target: 5000
published: 5000
mode: host
volumes:
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./etc/traefik:/etc/traefik:ro
- traefik__acme:/letsencrypt
volumes:
traefik__acme:
name: stack__traefik__acme
docker-compose.yml
General configuration for your docker instance. The following file etc/traefik/traefik.yml
is injected to /etc/traefik/traefik.yml
within your container.
global:
checkNewVersion: true
sendAnonymousUsage: false
api:
dashboard: true
log:
level: INFO
format: json
accessLog:
format: json
entryPoints:
web:
address: ':80'
http:
redirections:
entryPoint:
to: websecure
websecure:
address: ':443'
providers:
docker:
endpoint: 'unix:///var/run/docker.sock'
exposedByDefault: false
swarmMode: true
file:
directory: /etc/traefik
watch: true
traefik:
docker:
network: web
certificatesresolvers:
letsencrypt:
acme:
email: info@example.com
storage: /letsencrypt/acme.json
httpChallenge:
entryPoint: web
etc/traefik/traefik.yml
The file etc/traefik/domains/me_squibble_cluster01_git.yml
handles the http router and services for our two domains git.intern.squibble.me and registry.git.intern.squibble.me.
http:
routers:
me_squibble__cluster01__git:
entryPoints:
- websecure
rule: 'Host(`git.intern.squibble.me`)'
service: me_squibble__cluster01__git@file
tls:
certResolver: letsencrypt
me_squibble__cluster01__git_registry:
entryPoints:
- websecure
rule: 'Host(`registry.git.intern.squibble.me`)'
service: me_squibble__cluster01__git_registry@file
tls:
certResolver: letsencrypt
services:
me_squibble__cluster01__git:
loadBalancer:
servers:
- url: http://<GITLAB SERVER IP>
me_squibble__cluster01__git_registry:
loadBalancer:
servers:
- url: http://<GITLAB SERVER IP>:5000
etc/traefik/domains/me_squibble_cluster01_git.yml
We used a ubuntu 22.04 server installation with currently 4 cpu cores and 8 GB RAM. On this vm we’ll install gitlab and gitlab-runner.
We do export the port 9022 to this vm to the public internet so we’re able to use this port for regular git commands.
To be able to use docker as a gitlab runner executor we have to install docker on our virtual machine.
sudo apt update
sudo apt install tzdata curl ca-certificates openssh-server
gpg_key_url="https://packages.gitlab.com/gitlab/gitlab-ce/gpgkey"
curl -fsSL $gpg_key_url| sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/gitlab.gpg
sudo tee /etc/apt/sources.list.d/gitlab_gitlab-ce.list<<EOF
deb https://packages.gitlab.com/gitlab/gitlab-ce/ubuntu/ focal main
deb-src https://packages.gitlab.com/gitlab/gitlab-ce/ubuntu/ focal main
EOF
sudo apt update
sudo apt install gitlab-ce
# General Configuration
#
external_url 'https://git.intern.squibble.me'
gitlab_rails['gitlab_shell_ssh_port'] = 9022
# Mail Server Configuration
#
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "<MAIL_SERVER__HOST>"
gitlab_rails['smtp_port'] = <MAIL_SERVER__PORT>
gitlab_rails['smtp_user_name'] = "<MAIL_SERVER__USERNAME>"
gitlab_rails['smtp_password'] = "<MAIL_SERVER__PASSWORD>"
gitlab_rails['smtp_domain'] = "<MAIL_SERVER__DOMAIN>"
# The following configuration are optional and maybe not required for
# your mailserver setup.
#
gitlab_rails['smtp_authentication'] = "plain"
gitlab_rails['smtp_enable_starttls_auto'] = false
gitlab_rails['smtp_openssl_verify_mode'] = 'none'
gitlab_rails['gitlab_email_from'] = 'git@squibble.me'
gitlab_rails['gitlab_email_display_name'] = 'Squibble Gitlab'
# Registry Configuration
#
registry_external_url 'https://registry.git.intern.squibble.me'
gitlab_rails['registry_enabled'] = true
registry['enable'] = true
# Enable registry listening on all ip addresses on port 5000
# so we're able to connect traefik to this server and port.
#
registry['registry_http_addr'] = "0.0.0.0:5000"
# nginx Configuration
#
nginx['listen_port'] = 80
# SSL is handled via traefik and letsencrypt
#
nginx['listen_https'] = false
nginx['proxy_set_headers'] = {
"Host" => "$http_host_with_default",
"X-Real-IP" => "$remote_addr",
"X-Forwarded-For" => "$proxy_add_x_forwarded_for",
"X-Forwarded-Proto" => "https",
"X-Forwarded-Ssl" => "on"
}
nginx['http2_enabled'] = false
# Disable the nginx server for container registry
#
registry_nginx['enable'] = false
/etc/gitlab/gitlab.rb
After applying all those settings execute gitlab-ctl reconfigure
to enable the new settings. gitlab-ce is now correct configured so we should be able to access it via traefik.
We followed the installation instructions on the official documentation and successfully installed version 15.9.2.
After successfully installing the gitlab-runner cli tool we have to register our runners to the gitlab instance.
Therefore we have to access /admin/runners on our gitlab instance and click on “Register an instance runner” to open a dropdown and copy the required registration token.
Replace the GITLAB_INSTANCE_HOST and REGISTRATION_TOKEN placeholder in the following commands with your registration token. You can specify the available resources to your needs.
sudo gitlab-runner register \
--url https://<GITLAB_INSTANCE_HOST> \
--registration-token <REGISTRATION_TOKEN> \
--name cluster01/cirunner01--mem4g \
--limit 6 \
--executor "docker" \
--tag-list "docker,cluster01,mem4G" \
--docker-image ubuntu:jammy \
--docker-cpus "4" \
--docker-memory-swap "5G" \
--docker-memory "4G" \
--docker-memory-reservation "512m"
After execution this command you should see a new entry with your runner and state online.
Congratulations: You successfully deployed your self hosted gitlab instance with custom gitlab runners and a self hosted docker registry.