Gitlab CE via Docker hinter einem Reverse Proxy unter Ubuntu betreiben

English Deutsch

Ähnlich wie mein vorheriger Artikel über die Installation von Redmine via Docker hinter einem Reverse Proxy, beschreibt dieser Artikel. Da ich eine Instanz von Redmine und eine Instanz von Gitlab auf demselben virtuellen Server betreibe, plus zig andere Services.

Während der Gitlab CE Docker-Container schön vorkonfiguriert für den Standalone-Betrieb auf einem dedizierten VPS ist, wird der Betrieb hinter einem Reverse Proxy nicht unterstützt und führt zu einer Vielzahl von Fehlermeldungen — was effektiv viel zusätzliche Arbeit erfordert, um ihn zum Laufen zu bringen.

Beachte, dass wir GitLab nicht für SSH-Zugriff einrichten werden. Dies ist mit diesem Setup möglich, macht aber normalerweise mehr Ärger als es wert ist. Siehe diesen Artikel zum Speichern von git HTTPS-Passwörtern, damit du dein Passwort nicht jedes Mal eingeben musst.

Docker & Docker-Compose installieren

install_docker_prereqs.sh
# Voraussetzungen installieren
sudo apt-get update
sudo apt-get -y install apt-transport-https ca-certificates curl software-properties-common
install_docker.sh
# Dockers Paket-Signierschlüssel hinzufügen
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# Repository hinzufügen
sudo add-apt-repository -y "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
# Neueste stabile Docker-Version installieren
sudo apt-get update
sudo apt-get -y install docker-ce
install_docker_compose.sh
# docker-compose installieren
sudo curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod a+x /usr/local/bin/docker-compose

# Aktuellen Benutzer zur docker-Gruppe hinzufügen
sudo usermod -a -G docker $USER
# Docker-Service aktivieren & starten
sudo systemctl enable docker
sudo systemctl start docker

Nach der Ausführung dieses Shell-Skripts musst du dich vom System ab- und wieder anmelden, damit die docker-Gruppe dem aktuellen Benutzer hinzugefügt wird.

Verzeichnis & docker-compose-Konfiguration erstellen

Wir installieren Gitlab in /var/lib/gitlab, welches die Datenverzeichnisse und das docker-compose-Skript hostet. Du kannst ein beliebiges Verzeichnis verwenden, solange du es konsistent in allen Konfigurationen verwendest (am wichtigsten: docker-compose.yml und der systemd-Service).

create_gitlab_dirs.sh
# Verzeichnisse erstellen
sudo mkdir /var/lib/gitlab

Als Nächstes erstellen wir /var/lib/gitlab/docker-compose.yml.

Es gibt einige Dinge, die du hier ändern musst:

docker-compose.yml
gitlab:
   image: 'gitlab/gitlab-ce:latest'
   restart: always
   hostname: 'gitlab.mydomain.de'
   environment:
     GITLAB_OMNIBUS_CONFIG: |
       external_url 'https://gitlab.mydomain.de'
       letsencrypt['enabled'] = false
       # Email
       gitlab_rails['gitlab_email_enabled'] = true
       gitlab_rails['gitlab_email_from'] = '[email protected]'
       gitlab_rails['gitlab_email_display_name'] = 'My GitLab'
       # SMTP
       gitlab_rails['smtp_enable'] = true
       gitlab_rails['smtp_address'] = "mail.mydomain.de"
       gitlab_rails['smtp_port'] = 25
       gitlab_rails['smtp_user_name'] = "[email protected]"
       gitlab_rails['smtp_password'] = "yourSMTPPassword"
       gitlab_rails['smtp_domain'] = "mydomain.de"
       gitlab_rails['smtp_authentication'] = "login"
       gitlab_rails['smtp_enable_starttls_auto'] = true
       gitlab_rails['smtp_tls'] = true
       gitlab_rails['smtp_openssl_verify_mode'] = 'none'
       # Reverse proxy nginx config
       nginx['listen_port'] = 80
       nginx['listen_https'] = false
       nginx['proxy_set_headers'] = {
         "X-Forwarded-Proto" => "https",
         "X-Forwarded-Ssl" => "on",
         "Host" => "gitlab.mydomain.de",
         "X-Real-IP" => "$$remote_addr",
         "X-Forwarded-For" => "$$proxy_add_x_forwarded_for",
         "Upgrade" => "$$http_upgrade",
         "Connection" => "$$connection_upgrade"
       }
   ports:
     - '9080:80'
   volumes:
     - './config:/etc/gitlab'
     - './logs:/var/log/gitlab'
     - './data:/var/opt/gitlab'

systemd-Service einrichten

Als Nächstes konfigurieren wir den systemd-Service in /etc/systemd/system/gitlab.service.

Setze User=... auf deinen bevorzugten Benutzer im [Service]-Abschnitt. Dieser Benutzer muss Mitglied der docker-Gruppe sein. Prüfe auch, ob das WorkingDirectory=... korrekt ist.

gitlab.service
[Unit]
Description=Gitlab
Requires=docker.service
After=docker.service

[Service]
Restart=always
User=root
Group=docker
WorkingDirectory=/var/lib/gitlab
# Container herunterfahren (falls laufend) wenn Unit gestoppt wird
ExecStartPre=/usr/local/bin/docker-compose -f docker-compose.yml down -v
; Container starten wenn Unit gestartet wird
ExecStart=/usr/local/bin/docker-compose -f /docker-compose.yml up
; Container stoppen wenn Unit gestoppt wird
ExecStop=/usr/local/bin/docker-compose -f docker-compose.yml down -v

[Install]
WantedBy=multi-user.target

Nach dem Erstellen der Datei können wir den gitlab-Service aktivieren und starten:

enable_start_gitlab.sh
sudo systemctl enable gitlab
sudo systemctl start gitlab

Die Ausgabe von sudo systemctl start gitlab sollte leer sein. Falls sie es nicht ist:

gitlab_start_error.txt
Job for gitlab.service failed because the control process exited with error code.
See "systemctl status gitlab.service" and "journalctl -xe" for details.

kannst du das Problem mit journalctl -xe und journalctl -e debuggen

Der erste Start dauert normalerweise etwa 10 Minuten, also hol dir mindestens eine Tasse Kaffee. Du kannst den Fortschritt mit journalctl -xefu gitlab verfolgen. Sobald du Zeilen wie

gitlab_startup_log.txt
Dec 17 17:28:04 instance-1 docker-compose[4087]: gitlab_1  | {"method":"GET","path":"/-/metrics","format":"html","controller":"MetricsController","action":"index","status":200,"duration":28.82,"view":22.82,"db":0.97,"time":"2018-12-17T17:28:03.252Z","params":[],"remote_ip":null,"user_id":null,"username":null,"ua":null}

ist der Start abgeschlossen.

Nun kannst du prüfen, ob GitLab läuft mit

check_gitlab_wget.sh
wget -O- http://localhost:9080/

(falls du die Port-Konfiguration zuvor geändert hast, musst du deinen Custom-Port in der URL verwenden).

Wenn es funktioniert hat, wird eine Debug-Meldung ausgegeben. Da Gitlab dich automatisch auf deine Domain weiterleitet (gitlab.mydomain.de in diesem Beispiel), solltest du etwas sehen wie

gitlab_wget_output.txt
--2018-12-17 17:28:32--  http://localhost:9080/
Resolving localhost (localhost)... 127.0.0.1
Connecting to localhost (localhost)|127.0.0.1|:9080... connected.
HTTP request sent, awaiting response... 302 Found
Location: https://gitlab.gridbox.de/users/sign_in [following]
--2018-12-17 17:28:32--  https://gitlab.mydomain.de/users/sign_in
Resolving gitlab.gridbox.de (gitlab.mydomain.de)... 35.198.165.121
Connecting to gitlab.gridbox.de (gitlab.mydomain.de)|35.198.165.121|:443... failed: Connection refused.

Da wir nginx noch nicht als Reverse Proxy eingerichtet haben, ist es völlig in Ordnung, dass „Connection refused“ gemeldet wird. Die Weiterleitung hat funktioniert, wenn du die oben aufgeführte Ausgabe siehst.

nginx-Reverse-Proxy einrichten (optional aber empfohlen)

Wir verwenden nginx, um die Anfragen von einer bestimmten Domain weiterzuleiten (Apache zu verwenden ist, falls du es bereits nutzt, auch möglich, aber es würde den Rahmen dieses Tutorials sprengen, dies zu beschreiben). Installiere es mit

install_nginx_gitlab.sh
sudo apt -y install nginx

Zuerst benötigst du einen Domainnamen mit konfiguriertem DNS. Für dieses Beispiel nehmen wir an, dass dein Domainname gitlab.mydomain.de ist! Du musst ihn durch deinen Domainnamen ersetzen!

Zuerst erstellen wir die Konfigurationsdatei in /etc/nginx/sites-enabled/gitlab.conf. Ersetze gitlab.mydomain.de durch deinen Domainnamen! Wenn du einen anderen Port als 9080 verwendest, ersetze diesen ebenfalls.

gitlab.nginx.conf
map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}

server {
    server_name gitlab.mydomain.de;

    access_log /var/log/nginx/gitlab.access_log;
    error_log /var/log/nginx/gitlab.error_log info;

    location / {
        proxy_pass http://127.0.0.1:9080; # Docker-Container hört hier
        proxy_read_timeout 3600s;
        proxy_http_version 1.1;
        # Websocket-Verbindung
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
    }

    listen 80;
}

Führe nun sudo nginx -t aus, um zu testen, ob Fehler in der Konfigurationsdatei vorhanden sind. Wenn alles in Ordnung ist, siehst du

nginx_test_output.txt
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Sobald du alle Fehler behoben hast, falls vorhanden, führe sudo service nginx reload aus, um die Konfiguration anzuwenden.

Wir müssen ein Let’s Encrypt SSL-Zertifikat einrichten, bevor wir prüfen können, ob Gitlab funktioniert:

Den nginx-Reverse-Proxy mit Let’s Encrypt absichern

Zuerst müssen wir certbot und das certbot nginx-Plugin installieren, um das Zertifikat in nginx zu erstellen & zu installieren:

install_certbot_gitlab.sh
sudo apt -y install python3-certbot python3-certbot-nginx

Glücklicherweise automatisiert certbot den Großteil des Prozesses der Installation & Konfiguration von SSL und dem Zertifikat. Führe aus

certbot_nginx_gitlab.sh
sudo certbot --nginx

Es wird dich bitten, deine E-Mail-Adresse einzugeben und den Nutzungsbedingungen zuzustimmen sowie ob du den EFF-Newsletter erhalten möchtest.

Danach wird certbot dich bitten, den korrekten Domainnamen auszuwählen:

certbot_select_names_gitlab.txt
Which names would you like to activate HTTPS for?
-------------------------------------------------------------------------------
1: gitlab.mydomain.de
-------------------------------------------------------------------------------
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel):

In diesem Fall gibt es nur einen Domainnamen (es wird mehr geben, wenn du mehr Domains in nginx aktiv hast!).

Gib daher 1 ein und drücke Enter. certbot wird nun das Zertifikat generieren. Bei Erfolg siehst du eine Ausgabe inklusive einer Zeile wie

certbot_deploy_gitlab.txt
Deploying Certificate to VirtualHost /etc/nginx/sites-enabled/gitlab.mydomain.de.conf

Nun wird dich gefragt, ob alle Anfragen automatisch auf HTTPS umgeleitet werden sollen:

certbot_redirect_gitlab.txt
Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
-------------------------------------------------------------------------------
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
-------------------------------------------------------------------------------
Select the appropriate number [1-2] then [enter] (press 'c' to cancel):

Wähle hier Redirect: Gib 2 ein und drücke Enter. Nun kannst du dich bei GitLab einloggen und die Installation abschließen.

Du musst das Zertifikat alle 3 Monate erneuern, damit es gültig bleibt, und danach sudo service nginx reload ausführen, um das neue Zertifikat zu verwenden. Wenn du dies versäumst, sehen Benutzer Fehlermeldungen über abgelaufene Zertifikate und können nicht leicht auf Gitlab zugreifen! Siehe diesen Beitrag für Details, wie man diesen Prozess größtenteils automatisiert!

Gitlab einrichten

Nun kannst du einen Browser öffnen und einen ersten Blick auf deine neue GitLab-Installation werfen:

GitLab-Anmeldebildschirm im Browser

Setze das neue Passwort und melde dich dann mit dem Benutzernamen root und deinem neu gesetzten Passwort an.

Öffne danach den Admin-Bereich oben, indem du auf das Schraubenschlüssel-Symbol in der violetten Navigationsleiste oben klickst.

GitLab-Admin-Bereich-Oberfläche

Klicke in der Navigationsleiste links auf Settings (es ist ganz unten — du musst nach unten scrollen) und dann auf General.

Klicke auf die Expand-Schaltfläche rechts neben Visibility and access controls. Scrolle nach unten, bis du Enabled Git access protocols siehst, und wähle Only HTTP(S) im Kombinationsfeld.

Klicke dann auf die grüne Save changes-Schaltfläche.

Da wir nun den SSH-Zugriff deaktiviert haben (den wir ohnehin nicht eingerichtet hatten), kannst du GitLab nun verwenden. Ein guter Anfang ist, ein neues Projekt zu erstellen und zu versuchen, es auszuchecken. Siehe diesen Artikel zum Speichern von git HTTPS-Passwörtern, damit du dein git-Passwort nicht jedes Mal eingeben musst.

Hinweis: Wenn GitLab keine E-Mails sendet, prüfe config/gitlab.rb, suche nach smtp und korrigiere falls nötig die SMTP-Einstellungen dort. Führe danach sudo systemctl stop gitlab && sudo systemctl start gitlab aus


Check out similar posts by category: Container, Docker, Git, Nginx, Version Management