osob.de Unicorn Logo
Blogpost overview

Gitea docker-Container unter Ubuntu 18.04 mit Nginx und Lets Encrypt | 01.11.2018

Nicht erst seit der GitHub-Übernahme durch Microsoft nutze ich einen privaten Server, um private Repositories und einige Kundenprojekte zu hosten. Schon länger habe ich dafür eine Gitea-Instanz im Einsatz. Wer nämlich nicht zu den großen Anbietern GitHub, Bitbucket oder GitLab möchte, hat die Möglichkeit, einen eigenen Server zu betreiben.

In diesem Blogbeitrag möchte ich eine kurze Einführung in die Thematik des Git-Hostings geben, bevor ich das Setup von Gitea in einem Docker-Container beschreibe.

Überall Anbieter: Welche Software für privates Git-Hosting?

Sehr bekannt und beliebt ist, ohne jeden Zweifel, GitLab. Fast schon eine Art Pionier in diesem Bereich, war GitLab Vorbild für einige Features der Folgeprojekte. Neben GitLab gibt es aber heute auch noch GitBucket (Server), Gogs und Gitea.

You like what you find here? A donation helps to keep this project running.

Der Unterschied zwischen Gogs und Gitea ist natürlich gering. Denn Gitea ist ein Fork von Gogs. Alle Systeme haben ihre Vor- und Nachteile. Benchmarks der verschiedenen Systeme können ein Grund sein, sich für die eine oder andere Variante zu entscheiden. Am Ende ist es aber eine Frage der Bequemlichkeit und des Budgets.

Das Budget? Ja. Denn eine GitLab- oder GitBucket-Serverinstanz, die noch ein paar mehr Features bietet als Gogs oder Gitea, ist auf einem leistungsfähigen Server sehr potent. Aber auf einem schwachen VPS wird an Gitea oder Gogs kein Weg vorbeiführen. Am Ende entscheidet also das Budget. Eine umfangreiche Diskussion zum Thema gibt es bspw. auf Reddit.

Docker-Container für Gitea: Einfaches Setup

Bisher habe ich Gitea stets als Binary auf einem Server ausgeführt. Dies heißt im Endeffekt, ich musste mich um die Go-Version kümmern, den Datenbankserver aktualisieren, den Mailserver absichern und die Systeme überwachen. Mit Docker wird dies deutlich einfacher. Ich starte den Container und Docker kümmert sich um die neueste Softwareversion, Updates und bietet mir die Möglichkeit, alle Dienste vom eigentlichen (Host-)System abzukapseln. Toll.

Setup für Gitea-Container: Was es braucht für das painless-Git-Hosting

Da ich sehr auf Ubuntu stehe, habe ich mich für das neue Gitea-Hosting auch für ein Ubuntu entschieden. Dazu kommt Docker und fertig. Als Liste sehen die Anforderungen dann so aus:

Nginx, der im hier beschriebenen Setup als Proxy zum Einsatz kommen wird, wird später wie auch Lets Encrypt installiert.

Die Compose-Datei

In der Dokumentation von Gitea wird für die Installation die docker-compose.yml abgebildet. Dies ist der Ausgangspunkt für alle weiteren Schritte.

Zum Betrieb wird ein Netzwerk namens gitea aufgesetzt. Auf dieses können dann die zwei Services server (die Gitea-Installation) und db (der Datenbankserver) zugreifen und miteinander kommunizieren. Wer sich, wie ich, für eine Datenbank entscheidet, kann die Zugangsdaten im environment im Abschnitt server der Compose-Datei angeben. Alternativ können diese Angaben später im Installer eingegeben bzw. über die app.ini geändert werden. Für den Datenbankserver db müssen aber auf jeden Fall ein Datenbankname, ein Benutzername und ein Benutzerpasswort angegeben werden. Die jeweiligen Docker-Container der Datenbanken benötigen diese Angaben, um die Dienste zu konfigurieren.

Um eine persistente Datenhaltung zu ermöglichen, müssen den Services auch volumes zugeordnet werden. Je nach Vorliebe können die im Host-System abgelegt werden. Für den Gitea-Container muss jedoch /data gewählt werden. Die Datenbank-Container stellen ebenfalls bestimmte Anforderungen. PostgreSQL beispielsweise speichert die Dateien im Ordner /var/lib/postgresql/data.

Local first: Gitea-Container nur über localhost

Grundsätzlich kann Gitea über den Port 3000 öffentlich direkt zugänglich betrieben werden. Genau dieses Verhalten wird durch die Übernahme der Config aus der Dokumentation erzielt. Auch kann der Port von Gitea selbst geändert werden und so die Go-Anwendung (Gitea ist in Go geschrieben) auf dem Port 80 laufen lassen. Ich möchte aber einen Webserver dazwischen hängen und den direkten (unkontrollierten) Zugriff auf Gitea einschränken.

Dafür binde ich den Gitea-Port (3000) an localhost. Das Port-Mapping (host:guest) sieht dann so aus: 127.0.0.1:3000:3000.

Fertiges docker-compose.yml

version: "2"

networks:
  gitea:
    external: false

services:
  server:
    image: gitea/gitea:latest
    environment:
      - USER_UID=1000
      - USER_GID=1000
      - DB_TYPE=postgres
      - DB_HOST=db:5432
      - DB_NAME=gitea
      - DB_USER=gitea_usr
      - DB_PASSWD=gitea_usr_password
    restart: always
    networks:
      - gitea
    volumes:
      - ./gitea:/data
    ports:
      - "127.0.0.1:3000:3000"
      - "2223"
    depends_on:
      - db

  db:
    image: postgres:9.6
    restart: always
    environment:
      - POSTGRES_USER=gitea_usr
      - POSTGRES_PASSWORD=gitea_usr_password
      - POSTGRES_DB=gitea
    networks:
      - gitea
    volumes:
      - ./postgres:/var/lib/postgresql/data

Nginx und Lets Encrypt

Nginx kann einfach über $ sudo apt-get install nginx installiert werden. Für Lets Encrypt Certbot gibt es diverse Möglichkeiten der Installation. Ich selber habe mich für den Weg entschieden, der bei DigitalOcean beschrieben wird:

$ sudo add-apt-repository ppa:certbot/certbot
$ sudo apt install python-certbot-nginx
$ sudo certbot --nginx -d gitea.example.com

Durch die Installation des Plugins python-certbot-nginx wird durch den letzten Aufruf die notwendige SSL-Konfiguration geschrieben. Als letztes muss natürlich der Nginx-Webserver noch die Anfragen an Gitea weiterleiten. Dazu einfach in der Konfiguration den Tag proxy_pass setzen. Die Konfiguration könnte so aussehen:

server {
  listen 80;
  listen [::]:80;
        server_name gitea.example.com;
        return 301 https://$server_name$request_uri;
}

server {
    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    server_name gitea.example.com;
    root /var/www/gitea.example.com/;
    index index.html;
    ssl_certificate /etc/letsencrypt/live/gitea.example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/gitea.example.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
    location / {
            proxy_pass http://localhost:3000/; # Note: Trailing slash
    }
}