3 min read

GitLab CE in Docker Container hinter Nginx Reverse Proxy

In diesem Artikel beschreibe ich, wie ich eine GitLab CE Instanz ans Laufen gebracht habe. Ich betreibe diese in einem Docker Container hinter einem Nginx Reverse Proxy, dessen Zertifikate mit Certbot erstellt und erneuert werden.

Docker

Zunächst habe ich die folgenden Zeilen in meiner docker-compose.yml hinzugefügt:

  gitlab:
    image: 'gitlab/gitlab-ce:latest'
    restart: always
    hostname: 'localhost'
    container_name: gitlab-ce
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url 'https://<DOMAIN>'
        letsencrypt['enabled'] = false
        nginx['listen_port'] = 80
        nginx['listen_https'] = false
        nginx['proxy_set_headers'] = {
          "X-Forwarded-Proto" => "https",
          "X-Forwarded-Ssl" => "on",
          "Host" => "<DOMAIN>",
          "X-Real-IP" => "$$remote_addr",
          "X-Forwarded-For" => "$$proxy_add_x_forwarded_for",
          "Upgrade" => "$$http_upgrade",
          "Connection" => "$$connection_upgrade"
        }
    volumes:
      - '<GITLAB-CONFIG-PATH>/config:/etc/gitlab'
      - '<GITLAB-CONFIG-PATH>/logs:/var/log/gitlab'
      - '<GITLAB-CONFIG-PATH>/data:/var/opt/gitlab'
    ports:
      - '8888:80'
      - '<HOST-PORT>:22'
    networks:
      <NETWORK-NAME>:
        ipv4_address: <INTERNAL-IP>
Extract of docker-compose.yml

Wie man sieht, ist diese Config verglichen mit anderen Diensten recht komplex. Zunächst habe ich mit nginx['listen_https'] = false https ausgeschaltet, da der Reverse Proxy zum Container natürlich keine zusätzliche https Verbindung mehr aufbauen braucht. Mit nginx['listen_port'] = 80 lasse ich den Container die http Seite dann auf Port 80 anzeigen. Auf Port 80 lasse ich dann vom Port 8888 allen Traffic an Port 80 des Containers weiterleiten:

ports:
  - '8888:80'
Extract of docker-compose.yml

Dies kann dann mit dem Befehl curl http://127.0.0.1:8888 überprüft werden.

Ebenso lasse ich mit:

ports:
  - '<HOST-PORT>:22'
Extract of docker-compose.yml

Den Traffic vom <HOST-PORT> an den Container weiterleiten, damit über den <HOST-PORT> von außen GitLab per SSH erreicht werden kann. In der SSH Config sorgt dann der folgende Eintrag dafür, das ein git clone über SSH funktioniert.

Host <DOMAIN>
    Port <HOST-PORT>
~/.ssh/config 

Dieser Port muss dann noch in der Firewall eingehend für TCP Verbindungen freigeschaltet werden. Dann kann mit ssh -T git@<DOMAIN> überprüft werden, ob das ganze SSH Thema funktioniert. Wenn erfolgreich, sollte GitLab eine solche Zeile mit dem entsprechenden Nutzernamen, bei dem die Public Keys hinterlegt sind ausspucken:
Welcome to GitLab, @<USERNAME>!

So, das war es erstmal zu GitLab CE unter Docker betreiben und http Port und SSH Port freizugeben. Kommen wir zum Reverse Proxy Teil :)

Nginx

Zuerst erstelle ich
/etc/nginx/sites-available/<DOMAIN>
und verlinke sie mit
ln -s /etc/nginx/sites-available/<DOMAIN> /etc/nginx/sites-enabled/
nach /etc/nginx/sites-enabled/. Diese Datei ist bei mir mit dem folgenden Inhalt gefüllt:

server {
    if ($host = <DOMAIN>) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

listen 80;
server_name <DOMAIN>;
return 301 https://$host$request_uri;

}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name <DOMAIN>;
ssl on;
	ssl_certificate /etc/letsencrypt/live/<DOMAIN>/fullchain.pem; # managed by Certbot
	ssl_certificate_key /etc/letsencrypt/live/<DOMAIN>/privkey.pem; # managed by Certbot
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
        proxy_pass http://127.0.0.1:8888;
        proxy_redirect off;
        proxy_set_header Host $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;
        }
}
/etc/nginx/sites-available/<DOMAIN>

Ich gehe kurz auf die relevanten Zeilen ein:
ssl_certificate /etc/letsencrypt/live/<DOMAIN/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/<DOMAIN>/privkey.pem; # managed by Certbot
diese beiden Zeilen verweisen auf die von Certbot erstellten Zertifikatsdateien.

Mit proxy_pass http://127.0.0.1:8888; wird der Traffic an den Host Port 8888 weitergeleitet, der auf den Container Port 80 weiterleitet.

Root Login

docker exec -it gitlab-ce grep 'Password:' /etc/gitlab/initial_root_password

Mit dieser Zeile lässt sich das Passwort des root Nutzers auslesen, mit dem man dann seinen eigenen User anlegen kann. Die Funktion "Impersonate User" lässt einen dann sein eigenes Passwort setzten. Sonst würde das Passwort nur per Mail an einen vorher konfigurierten SMTP Server versendet werden.

Quellen

Gefunden habe ich die ganzen Informationen dazu aus zwei Artikeln:

https://www.czerniga.it/2021/11/14/how-to-install-gitlab-using-docker-compose/

https://techoverflow.net/2018/12/17/running-gitlab-ce-via-docker-behind-a-reverse-proxy-on-ubuntu/

Dort findet man auch noch ein Beispiel wie die Konfiguration mit SMTP geht.

Autor: peterge