GitLab ist eine OpenSource Softwareentwicklungsplattform mit integrierter Versionskontrolle, Fehlerverfolgung, Codeüberprüfung, CI/CD und vielem mehr. In dieser Anleitung zeige ich euch, wie ihr die Community Version von GitLab in wenigen Minuten mittels Docker und Traefik installiert.
1. Vorraussetzung
- Docker mit Docker Compose installiert (Anleitung für Ubuntu / Debian)
- Traefik v2 installiert (nach der Anleitung von Jonathan)
2. Verzeichnisse / Dateien anlegen
Als erstes legen wir uns ein Verzeichnis für Gitlab an und wechsel in das Verzeichnis:
mkdir -p /opt/containers/gitlab cd /opt/containers/gitlab
Anschließend erzeugen wir uns noch Ordner, welche wir noch benötigen:
mkdir -p /opt/containers/gitlab/{data,registry} mkdir -p /opt/containers/gitlab/data/{config,logs,data,database} mkdir -p /opt/containers/gitlab/registry/{data,certs}
3. Anlegen der docker-compose.yml
nano /opt/containers/gitlab/docker-compose.yml
version: '3.9' services: gitlab-ce: image: 'gitlab/gitlab-ce:latest' container_name: gitlab restart: unless-stopped hostname: 'git.meinedomain.de' environment: GITLAB_OMNIBUS_CONFIG: | external_url 'https://git.meinedomain.de' nginx['listen_port'] = 80 nginx['listen_https'] = false nginx['proxy_set_headers'] = { "X-Forwarded-Proto" => "https", "X-Forwarded-Ssl" => "on" } gitlab_rails['db_adapter'] = "postgresql" gitlab_rails['db_database'] = "gitlab" gitlab_rails['db_username'] = "postgres" gitlab_rails['db_password'] = "PostgreSQLPasswort" gitlab_rails['db_host'] = "gitlab-db" registry['enable'] = false gitlab_rails['registry_enabled'] = true gitlab_rails['registry_host'] = "registry.git.meinedomain.de" gitlab_rails['registry_api_url'] = "https://registry.git.meinedomain.de" gitlab_rails['registry_issuer'] = "gitlab-issuer" gitlab_rails['backup_archive_permissions'] = 0644 gitlab_rails['backup_keep_time'] = 1468800 gitlab_rails['smtp_enable'] = true gitlab_rails['smtp_address'] = "mail.meinedomain.de" gitlab_rails['smtp_port'] = 465 gitlab_rails['smtp_user_name'] = "noreply@meinedomain.de" gitlab_rails['smtp_password'] = "emailpassword" gitlab_rails['smtp_domain'] = "mail.meinedomain.de" gitlab_rails['smtp_authentication'] = "login" gitlab_rails['smtp_enable_starttls_auto'] = true gitlab_rails['smtp_tls'] = false gitlab_rails['smtp_ssl'] = true gitlab_rails['smtp_force_ssl'] = true gitlab_rails['gitlab_email_from'] = 'noreply@meinedomain.de' volumes: - ./data/config:/etc/gitlab - ./data/logs:/var/log/gitlab - ./data/data:/var/opt/gitlab labels: - "traefik.enable=true" - "traefik.http.routers.gitlab.entrypoints=https" - "traefik.http.routers.gitlab.rule=Host(`git.meinedomain.de`)" - "traefik.http.routers.gitlab.tls=true" - "traefik.http.routers.gitlab.tls.certresolver=letsEncrypt" - "traefik.http.routers.gitlab.service=gitlab" - "traefik.http.services.gitlab.loadbalancer.server.port=80" - "traefik.docker.network=proxy" networks: - proxy - system registry: restart: unless-stopped image: registry:latest container_name: gitlab-registry volumes: - ./registry/data:/registry - ./registry/certs:/certs labels: - "traefik.enable=true" - "traefik.http.routers.gitlab-registry.entrypoints=https" - "traefik.http.routers.gitlab-registry.rule=Host(`registry.git.meinedomain.de`)" - "traefik.http.routers.gitlab-registry.tls=true" - "traefik.http.routers.gitlab-registry.tls.certresolver=letsEncrypt" - "traefik.http.routers.gitlab-registry.service=gitlab-registry" - "traefik.http.services.gitlab-registry.loadbalancer.server.port=5000" - "traefik.docker.network=proxy" networks: - proxy - system environment: REGISTRY_LOG_LEVEL: debug REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /registry REGISTRY_AUTH_TOKEN_REALM: https://git.meinedomain.de/jwt/auth REGISTRY_AUTH_TOKEN_SERVICE: container_registry REGISTRY_AUTH_TOKEN_ISSUER: gitlab-issuer REGISTRY_AUTH_TOKEN_ROOTCERTBUNDLE: /certs/gitlab-registry.crt REGISTRY_STORAGE_DELETE_ENABLED: 'true' database: image: postgres:12-alpine container_name: gitlab-db restart: unless-stopped networks: - system environment: POSTGRES_PASSWORD: "PostgreSQLPasswort" POSTGRES_DB: gitlab volumes: - ./data/database:/var/lib/postgresql/data networks: proxy: external: true system: driver: bridge
Notwendige Anpassungen:
Es gibt einige Stellen, die mit eigenen Informationen befüllt werden müssen.
- Zeile 7, 10, 48, 79:
git.meinedomain.de
– Eigene Domain für GitLab definieren - Zeile 20, 91:
PostgreSQLPasswort
– Eigenes Passwort für PostgreSQL - Zeile 24, 25, 67:
registry.git.meinedomain.de
– Eigene Domain für GitLab Registry definieren - Zeile 29-40:
SMTP Mail Zugangsdaten
– Damit GitLab E-Mails versenden kann muss ein SMTP Server und Postfach angegeben werden. Hier kann neben einem eigenen Mail-Server auf Gmail oder ein anderer Anbieter verwendet werden.
4. GitLab starten und Zertifikat generieren
Jetzt können wir GitLab starten
docker compose -f /opt/containers/gitlab/docker-compose.yml up -d
GitLab ist sehr komplex, daher ist es auch nicht verwunderlich, dass der Start schon mal einige Minuten in Anspruch nehmen kann.
Zum Abschluss müssen wir noch einen Schritt machen, dass GitLab und die GitLab Registry miteinander kommunizieren können:
cd /opt/containers/gitlab/registry/certs/ docker cp gitlab:/var/opt/gitlab/gitlab-rails/etc/gitlab-registry.key . openssl req -key gitlab-registry.key -new -subj "/CN=gitlab-issuer" -x509 -days 365 -out gitlab-registry.crt
Nun haben wir unser eigenes GitLab mit Registry für Container.
5. SSH aktivieren
Um unser GitLab auch mit SSH nutzen zu können benötigen wir ein paar anpassungen. Wir möchte an dieser Stelle den Port 22 nicht einfach freigeben sondern auch diesen durch Traefik verwalten lassen.
5.1. Konfiguration von Traefik anpassen
5.1.1. Traefik.yml anpassen
Als erstes erweitern wir die traefik.yml um den Port 22:
nano /opt/containers/traefik/data/traefik.yml
entryPoints: http: address: ":80" http: redirections: entryPoint: to: "https" scheme: "https" https: address: ":443" http: middlewares: - default@file - gzip@file - crowdsec-bouncer@file # Dieser Zeil wird hinzugefügt git-ssh: address: ":22" http: middlewares: - crowdsec-bouncer@file
5.1.2 docker-compose.yml anpassen
Nun noch die docker-compose.yml von Traefik um den Port 22 erweitern:
nano /opt/containers/traefik/docker-compose.yml
version: '3.9' services: traefik: ports: - "22:22" - "80:80" - "443:443"
5.2. GitLab anpassen
Jetzt benötigen wir nur noch eine kleine Änderung an der docker-compose.yml von GitLab. Wir müssen die Traefik Labels um SSH erweitern:
nano /opt/containers/gitlab/docker-compose.yml
version: '3.9' services: gitlab-ce: labels: - "traefik.enable=true" - "traefik.http.routers.gitlab.entrypoints=https" - "traefik.http.routers.gitlab.rule=Host(`git.meinedomain.de`)" - "traefik.http.routers.gitlab.tls=true" - "traefik.http.routers.gitlab.tls.certresolver=letsEncrypt" - "traefik.http.routers.gitlab.service=gitlab" - "traefik.http.services.gitlab.loadbalancer.server.port=80" - "traefik.docker.network=proxy" # Dieser Teil wird ergänzt - "traefik.tcp.routers.gitlab-ssh.entrypoints=git-ssh" # Dieser Teil ist notwendig um alle eingehenden Port 22 Verbindungen zu Catchen - "traefik.tcp.routers.gitlab-ssh.rule=HostSNI(`*`)" - "traefik.tcp.routers.gitlab-ssh.service=gitlab-ssh" - "traefik.tcp.services.gitlab-ssh.loadbalancer.server.port=22"
5.3. Container neustarten
Damit Traefik sowie auch GitLab die neuen Konfigurationen laden können müssen wir diese noch neustarten:
docker compose -f /opt/containers/traefik/docker-compose.yml up -d --force-recreate docker compose -f /opt/containers/gitlab/docker-compose.yml up -d --force-recreate
7. Root-Passwort setzten
Um Zugriff auf unser erstelltes GitLab zu erhalten müssen wir dem Root noch ein neues Passwort zuweisen. Dazu müssen wir einmal in den Container:
docker compose exec gitlab-ce /bin/bash > gitlab-rake "gitlab:password:reset" > Enter username: root
Damit haben wir nun auch Zugriff auf unser GitLab!
8. Logs für CrowdSec bereitstellen
Auch GitLab lässt sich wunderbar mit CrowdSec überwachen.
8.1. docker-compose.yml anpassen
Dafür müssen wir die docker-compose.yml
von CrowdSec um die Collection timokoessler/gitlab
erweitern:
nano /opt/containers/crowdsec/docker-compose.yml
version: "3.9" services: crowdsec: environment: COLLECTIONS: "crowdsecurity/traefik crowdsecurity/http-cve crowdsecurity/whitelist-good-actors timokoessler/gitlab"
8.2. acquis.yaml anpassen
Kurz noch die acquis.yaml
um die Log-Dateien erweitert bzw. den Zugriff auf den richtigen Docker Container definieren:
sudo nano /opt/containers/crowdsec/config/acquis.yaml
filenames: - /var/log/auth.log - /var/log/syslog labels: type: syslog --- filenames: - /var/log/crowdsec/traefik/*.log labels: type: traefik --- source: docker container_name: - gitlab labels: type: gitlab
8.3. CrowdSec neustarten
Jetzt starten wir CrowdSec neu, damit die Konfigurationen auch geladen werden können:
docker compose -f /opt/containers/crowdsec/docker-compose.yml up -d --force-recreate
9. Quellen
- https://janl1.de/gitlab-ce-mit-registry-und-traefik-2-0-reverse-proxy/
- https://gist.github.com/FaKeller/2d3fb1a3dcf5a87fce7fe3fb04554443
- https://hub.crowdsec.net/author/timokoessler/collections/gitlab
- https://www.fabian-keller.de/blog/migrating-a-gitlab-omnibus-deployment-to-docker/
Servus miteinander,
ich habe GitLab-CE in 2024 zum Laufen bekommen und noch ein bisschen erweitert. Ich weiß nicht, ob ich jetzt irgendwelche sicherheitsbedenklichen Löcher implementiert habe, aber vielleicht kann der ein oder andere auch was dazu sagen. Auch bin ich mir nicht sicher, ob ich irgendwelche “unnötigen” Settings in der
GITLAB_OMNIBUS_CONFIG:
vorgenommen habe, aber noch läuft es jetzt seit etwa 2 Wochen.SSH Entrypoint hinzufügen in traefik.yml
In der Datei traefik.yml legen wir einen neuen Entrypoint an, damit Anfragen über SSH an GitLab von Traefik akzeptiert und an GitLab weitergeleitet werden, etwa bei
git clone *
ssh:
address: ‘:2222’
http:
middlewares:
– traefik-crowdsec-bouncer@file
Dementsprechend die
docker-compose.yml
von Traefik anpassen.ports:
– mode: host
target: 80
published: “80”
protocol: tcp
– mode: host
target: 443
published: “443”
protocol: tcp
– mode: host
target: 2222
published: “2222”
protocol: tcp
Gitlab Collection in crowdsec.env hinzufügen
Wie oben in Kapitel 8 beschrieben
Traefik übernimmt den SSH Traffic von Gitlab
traefik.tcp.routers.gitlab-ssh.rule=HostSNI('*')
ermölgicht es Traefik SSH-Anfragen anzunehmen und mittraefik.tcp.routers.gitlab-ssh.entrypoints=ssh
an GitLab auf Porttraefik.tcp.services.gitlab-ssh.loadbalancer.server.port=22
weiterzuleiten.docker network create gitlab-network
docker-compose.yml
networks:
gitlab-network:
proxy:
external: true
services:
postgres:
image: ${GITLAB_POSTGRES_IMAGE_TAG}
volumes:
– ./data/postgres:/var/lib/postgresql/data
environment:
POSTGRES_DB: ${GITLAB_DB_NAME}
POSTGRES_USER: ${GITLAB_DB_USER}
POSTGRES_PASSWORD: ${GITLAB_DB_PASSWORD}
networks:
– gitlab-network
healthcheck:
test: [ “CMD”, “pg_isready”, “-q”, “-d”, “${GITLAB_DB_NAME}”, “-U”, “${GITLAB_DB_USER}” ]
interval: 10s
timeout: 5s
retries: 3
start_period: 60s
restart: unless-stopped
gitlab:
image: ${GITLAB_IMAGE_TAG}
volumes:
– ./data/data:/var/opt/gitlab
– ./data/config:/etc/gitlab
– ./data/log:/var/log/gitlab
shm_size: “256m”
environment:
GITLAB_OMNIBUS_CONFIG: |
external_url ‘${GITLAB_URL}’
gitlab_rails[‘gitlab_shell_ssh_port’] = ${GITLAB_SHELL_SSH_PORT}
nginx[‘enable’] = true
nginx[‘listen_port’] = 80
nginx[‘listen_https’] = false
nginx[‘proxy_set_headers’] = {
‘X-Forwarded-Proto’ => ‘https’,
‘X-Forwarded-Ssl’ => ‘on’
}
gitlab_rails[‘db_adapter’] = “${GITLAB_DB_TYPE}”
gitlab_rails[‘db_encoding’] = “unicode”
gitlab_rails[‘db_host’] = “postgres”
gitlab_rails[‘db_database’] = “${GITLAB_DB_NAME}”
gitlab_rails[‘db_username’] = “${GITLAB_DB_USER}”
gitlab_rails[‘db_password’] = “${GITLAB_DB_PASSWORD}”
gitlab_rails[‘smtp_enable’] = true
gitlab_rails[‘smtp_address’] = “${GITLAB_SMTP_ADDRESS}”
gitlab_rails[‘smtp_port’] = 587
gitlab_rails[‘smtp_user_name’] = “${GITLAB_SMTP_USER_NAME}”
gitlab_rails[‘smtp_password’] = “${GITLAB_SMTP_PASSWORD}”
gitlab_rails[‘smtp_domain’] = “${GITLAB_SMTP_ADDRESS}”
gitlab_rails[‘smtp_authentication’] = “login”
gitlab_rails[‘smtp_enable_starttls_auto’] = true
gitlab_rails[‘smtp_tls’] = false
gitlab_rails[‘gitlab_email_from’] = “${GITLAB_EMAIL_FROM}”
gitlab_rails[‘gitlab_email_reply_to’] = “${GITLAB_EMAIL_REPLY_TO}”
postgresql[‘enable’] = false
# registry
registry_external_url ‘https://${REGISTRY_HOSTNAME}’
gitlab_rails[‘registry_enabled’] = true
gitlab_rails[‘registry_api_url’] = ‘https://${REGISTRY_HOSTNAME}’
registry[‘enable’] = true
registry_nginx[‘enable’] = false
registry[‘registry_http_addr’] = “0.0.0.0:5000”
# pages
pages_external_url ‘http://${PAGES_HOSTNAME}’
gitlab_pages[‘enable’] = true
gitlab_pages[‘external_http’] = []
gitlab_pages[‘listen_proxy’] = “0.0.0.0:5201”
gitlab_pages[‘inplace_chroot’] = true
pages_nginx[‘enable’] = true
pages_nginx[‘listen_https’] = false
pages_nginx[‘redirect_http_to_https’] = false
# Prometheus
prometheus_monitoring[‘enable’] = false
sidekiq[‘metrics_enabled’] = false
# Logrotate
logging[‘logrotate_frequency’] = “daily”
networks:
– gitlab-network
– proxy
healthcheck:
test: [“CMD”, “curl”, “-f”, “http://localhost:80/”]
interval: 10s
timeout: 5s
retries: 3
start_period: 240s
labels:
– “traefik.enable=true”
– “traefik.http.routers.gitlab.rule=Host(
${GITLAB_HOSTNAME}
)”– “traefik.http.routers.gitlab.service=gitlab”
– “traefik.http.routers.gitlab.entrypoints=websecure”
– “traefik.http.services.gitlab.loadbalancer.server.port=80”
– “traefik.http.routers.gitlab.tls=true”
– “traefik.http.routers.gitlab.tls.certresolver=http_resolver”
– “traefik.http.services.gitlab.loadbalancer.passhostheader=true”
– “traefik.http.routers.gitlab.middlewares=default@file”
– “traefik.tcp.routers.gitlab-ssh.rule=HostSNI(
*
)”– “traefik.tcp.routers.gitlab-ssh.service=gitlab-ssh”
– “traefik.tcp.routers.gitlab-ssh.entrypoints=ssh”
– “traefik.tcp.services.gitlab-ssh.loadbalancer.server.port=22”
– “traefik.docker.network=proxy”
# Regisry
– “traefik.http.routers.gitlab-registry.rule=Host(
${REGISTRY_HOSTNAME}
)”– “traefik.http.routers.gitlab-registry.entrypoints=websecure”
– “traefik.http.routers.gitlab-registry.tls=true”
– “traefik.http.routers.gitlab-registry.tls.certresolver=http_resolver”
– “traefik.http.routers.gitlab-registry.service=gitlab-registry”
– “traefik.http.services.gitlab-registry.loadbalancer.server.port=5000”
– “traefik.http.services.gitlab-registry.loadbalancer.passhostheader=true”
– “traefik.http.routers.gitlab-registry.middlewares=default@file”
# Pages
– “traefik.http.routers.gitlab-pages.rule=Host(
${PAGES_HOSTNAME}
,dev.${PAGES_HOSTNAME}
)”– “traefik.http.routers.gitlab-pages.entrypoints=websecure”
– “traefik.http.routers.gitlab-pages.tls=true”
– “traefik.http.routers.gitlab-pages.tls.certresolver=http_resolver”
– “traefik.http.routers.gitlab-pages.service=gitlab-pages”
– “traefik.http.services.gitlab-pages.loadbalancer.server.port=5201”
– “traefik.http.routers.gitlab-pages.middlewares=default@file”
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
Anmerkung zu pages: dev.${PAGES_HOSTNAME}
“dev” ist eine Gruppe in GitLab damit folgende Anleitung bei mir funktioniert hat
https://yodamad.hashnode.dev/beautiful-pages-on-gitlab-with-mkdocs
Root Passwort
sudo docker exec -it $(sudo docker ps -aqf “name=gitlab-gitlab-1”) grep ‘Password:’ /etc/gitlab/initial_root_password
Runner
Den Runner habe ich leider nicht in der Gitlab docker-compose zum laufen bekommen.
Mit einer eigenen docker compose hat es allerdings funktioniert.
Registration Token kopieren
In der Admin-Area unter Runners den Registration Token kopieren.
.env
RUNNER_NAME=Docker-Runner-1
REGISTRATION_TOKEN=
CI_SERVER_URL=https://git.domain.de/
docker compose
services:
dind:
image: docker:20-dind
restart: always
privileged: true
environment:
DOCKER_TLS_CERTDIR: “”
command:
– –storage-driver=overlay2
runner:
restart: always
image: registry.gitlab.com/gitlab-org/gitlab-runner:alpine
depends_on:
– dind
environment:
– DOCKER_HOST=tcp://dind:2375
volumes:
– ./config:/etc/gitlab-runner:z
register-runner:
restart: ‘no’
image: registry.gitlab.com/gitlab-org/gitlab-runner:alpine
depends_on:
– dind
environment:
– CI_SERVER_URL=${CI_SERVER_URL}
– REGISTRATION_TOKEN=${REGISTRATION_TOKEN}
command:
– register
– –non-interactive
– –locked=false
– –name=${RUNNER_NAME}
– –executor=docker
– –docker-image=docker:20-dind
– –docker-volumes=/var/run/docker.sock:/var/run/docker.sock
volumes:
– ./config:/etc/gitlab-runner:z
Nach dem Start sollte in Gitlab unter Runner der Runner erscheinen
Moin Moin. Ich hab heut mal versucht das ganze auf den aktuellen . Crwodsec Stack zu Implimentieren. Es will mir aber nicht wirklich gelinken..
EntryPoints alle sind gesetzt.. Aber am ende find ich im traefik dash nur die registry.git / und nicht die git .xxx.org.
Übrigens beim versuchen auf passen. Hier sind links ganz anderster müssen alle angepasst werden.. Wer Traefik mit der aktuellen version am laufen hat .
greezly
Irgendwie will das bei mir nicht funktionieren.
Der Container “Gitlab” kommt bei mir über das “Starting” nicht hinaus.
Wie lange muss man denn in etwa warten, bis alles läuft und healthy ist?
Ich würde mich freuen, wenn diese Anleitung auf die neuste Traeefik anleitung geupdated würde
Danke erstmal für den super Artikel!
Wenn ich in der acquis.yaml den output aus dem gitlab docker container so einbaue, bekomme ich zwar eine Menge an Lines read in den Acquisition Metrics in CrowdSec, aber keine davon wird geparsed. Ich hab mal testweise die gitlab/data/logs/gitlab-rails/production_json.log über filenames in die acquis.yaml gepackt. Da bekomme ich dann weniger Zeilen rein (Denke der rest is overhead), aber ebenfalls kein parsing … Funktioniert das setup bei dir so wie in der Anleitung beschrieben wirklich?