Zum Inhalt

Gitea Installation via Docker auf einer Synology Disk Station

Gitea lässt sich mithilfe von Docker Images auf einer Synology Disk Station oder einem openmediavault (omv) installieren.

In diesem Artikel wird die Installation und Konfiguration auf einer Synology Disk Station beschrieben. Eine Adaption für ein omv lässt sich einfach ableiten.

In einem früheren Artikel habe ich bereits die Installation von Gitea auf einer Synology Disk Station beschrieben.

Jedoch verwende ich in dieser "alten" Beschreibung neben Docker Images auch Dienste der Synology. Durch diesen Mischmasch ist die Installation nur auf einer Synology Disk Station möglich. Das Übertragen auf ein anderes Host-System ist nicht einfach möglich.

In dieser neuen Anleitung werden ausschließlich Docker Container verwendet. Dadurch kann die Anleitung auch auf anderen Host-Systemen, wie einem omv, zur Installation von Gitea genutzt werden.

Für das Management der Container wird Portainer verwendet.

Die unterschiedlichen Docker Images

Für die Gitea-Installation werden mit dem docker-compose.yml insgesamt 4 verschiedene Container installiert.

  1. Gitea = Gitea Installation
  2. PostgreSQL = Datenbank für Gitea
  3. Backup for PostgreSQL = Backup für die Datenbank
  4. Adminer = grafische Webadministrationsoberfläche für die Datenbank

Die beiden Container postgres-backup-local und adminer sind optional.

Es wird für die Gitea-Installation ein neuer Stack angelegt, was der Übersichtlichkeit dient und die Administration vereinfacht.

Ordner für jeden Docker Container anlegen

Dateien in einem Docker Container sind flüchtig!

Was bedeutet flüchtig?

Das Image für einen Docker Container wird von https://hub.docker.com/ heruntergeladen und bildet den Startpunkt für unsere Gitea-Installation. Die Images lassen sich sofort ohne jede weitere Anpassung starten und es kann mit den Containern auch gearbeitet werden. Aber es gibt ein großes ABER! Wird der Container neu gestartet, wird alles auf den Startpunkt zurückgestellt. (= Standard von https://hub.docker.com/)

Alle eure Daten sind weg und es wird der Daten-Stand verwendet, wie er von https://hub.docker.com/ heruntergeladen werden kann.

Die Daten flüchten also nach jedem Neustart von eurem System.

Gib mir gerne einen Kaffee ☕ aus ❗️

Wenn dir meine Beiträge gefallen und geholfen haben, dann kannst du mir gerne einen Kaffee ☕️ ausgeben.

Donation via PayPalDonation via LiberaPay

Donation via Bitcoin
Bitcoin Address: bc1qfuz93hw2fhdvfuxf6mlxlk8zdadvnktppkzqzj

Wie lässt sich das Flüchten von Daten verhindern?

Für Produktivsysteme ist das Flüchten von Daten unerwünscht. Die Daten müssen erhalten bleiben, damit nach einem Neustart oder Update mit eurem Datenbestand weitergearbeitet werden kann.

Die Lösung ist denkbar einfach. Eure Daten werden nicht im Docker-Container belassen, sondern in eigenen Ordner auf der Festplatte des Host-Systems abgelegt.

Dem Docker Image muss bei jedem Neustart zwingend gesagt werden, wo die Daten zu finden sind. Die Mitteilung bekommt der Container über die docker-compose.yml und der env-Datei (env = Environment-Datei) mitgeteilt.

Ordner auf dem Host-System anlegen

Die Ordner werden bei einer Synology als Unterordner im Docker-Verzeichnis des Host-Systems angelegt. In diesem Beispiel ist das im Verzeichnis /volume1/docker/.

Am schnellsten lassen sich die Ordner über die CLI auf dem Host-System anlegen.

cd /volume1/docker/

sudo mkdir gitea

cd /volume1/docker/gitea/

# Ordner neu erstellen
sudo mkdir secrets
sudo mkdir giteadata
sudo mkdir giteadb
sudo mkdir giteadbbackup
sudo chown -R 999:999 giteadbbackup
ls -lah

# Ordner löschen
# ggf. sinnvoll, wenn viel getestet wird
sudo rm -r secrets
sudo rm -r giteadata
sudo rm -r giteadb
sudo rm -r giteadbbackup
ls -lah

Wie der Zugriff bei einer Synology Disk Station auf die CLI konfiguriert und abgesichert werden kann, habe ich in diesem Beitrag beschrieben:

Zu beachten ist, dass der Ordner für postgres-backup-local angepasste Rechte benötigt.

Docker Secrets

In docker-compose.yml werden die Passwörter über eigene Dateien, sogenannte Secrets, an den Docker Container übergeben.

Die Credentials könnten auch über die env-Datei übertragen werden, wenn keine Secrets verwendet werden sollen

Wie werden die Secrets übertragen?

Die sensiblen Informationen, wie Benutzername, Passwörter, etc., werden jeweils in einfachen txt-Dateien gespeichert.

In der env-Datei teilen wir den Docker Containern mit, wo die Secret-txt-Dateien abgespeichert sind.

SECRETS_DIRECTORY=/volume1/docker/gitea/secrets

In der docker-compose.yml wird dann jedes Secrets referenziert.

Am Beispiel für das Passwort für die PostgreSQL-Datenbank lässt sich das schön aufzeigen.

Es wird in der docker-compose.yml auf das Secret verwiesen.

GITEA__database__PASSWD_FILE=/run/secrets/gitea_db_password

gitea_db_password = Name der txt-Datei ohne Datei-Endung.

Vorteile von Secrets

Die sensiblen Informationen, wie Benutzernamen, Passwörter, etc., können geschützt abgelegt werden und der Zugriff auf die Dateien eingeschränkt werden.

Ein weiterer Vorteil ist das einfache Verwalten der Dateien, wie docker-compose.yml, env-Datei, über Git. Sensible Informationen sind in einfache txt-Dateien "ausgelagert", die nicht per Git versioniert werden. Die Dateien können z.B. über die .gitignore ausgeschlossen werden

Die Secret-Dateien werden alle im Ordner secrets auf dem Host als txt-Datei abgespeichert.

Die Rechte für den Ordner secrets lassen sich über die CLI anpassen.

cd /volume1/docker/gitea/
chmod o-rwx secrets/
chmod g-rwx secrets/

Die Zugriffsrechte für eine txt-Datei lässt sich über die CLI ändern. Am Beispiel der gitea_db_name.tx sieht das wie folgt aus.

cd /volume1/docker/gitea/secrets/

chmod o-rwx gitea_db_name.tx
chmod g-rwx gitea_db_name.tx

Für die anderen txt-Dateien ist das analog durchzuführen.

Docker Compose ausführen

Mit Hilfe von Portainer lässt sich ein neuer Stack erstellen und der Inhalt der docker-compose.yml per Strg+C und Strg+V hineinkopieren.

Portainer Stack

Die Variablen aus der env-Datei lassen sich auf diesem Weg ebenfalls einfügen.

Portainer Stack

Portainer Stack

Das Stack kann erstellt werden.

PostgreSQL Backup Konfiguration

Ein regelmäßiges Backup der PostgreSQL-Datenbank kann mit dem Container postgres-backup-local erstellt werden.

PostgreSQL Backup Folder Permissions

Die Rechte für den PostgreSQL-Ordner sind anzupassen, damit das Backup-Skript Schreibzugriff erhält.

sudo chown -R 999:999 /volume1/docker/gitea/giteadbbackup

Backup Script für PostgreSQL

Es ist eine Bash im Container pgbackups zu öffnen und der Befehl ./backup.sh im Ordner /volume1/docker/gitea/giteadbbackup (= DB_BACKUP_FOLDER).

Der Befehl ist entsprechend anzupassen.

postgres = Docker Service name of the PostgreSQL (db )

password = Datenbankpasswort (gitea_db_password.txt)

Über das Synology eigene Tool zur Verwaltung der Docker Container lässt sich auch auf die Bash des Containers zugreifen, wie in den Screenshots dargestellt.

Gitea Docker auf Synology installieren

echo db:*:*:*:passwd > /backups/.pgpass && chmod 0600 /backups/.pgpass

Das Skript ausführen ./backup.sh.

./backup.sh

Gitea Docker auf Synology installieren

Im Ordner /volume1/docker/gitea/giteadbbackup kann verfolgt werden, wie neue Dateien erscheinen.

Gitea Docker auf Synology installieren

Auch in Portainer ist der Zugriff auf die Bash des Containers möglich.

Portainer - Docker Bash

Portainer - Docker Bash

Portainer - Docker Bash

Gitea Konfiguration

Nach der Installation des Containers ist ein Eintrag in der app.ini anzupassen.

Die Konfigurationsdatei ist entweder über die grafische Weboberfläche oder über die CLI erreichbar.

Der Eintrag sollte auf den gleichen Wert wie in der env-Datei gesetzt werden.

...
ROOT_URL         = http://192.168.22.12:3005
...

...
SSH_PORT         = 3333
SSH_LISTEN_PORT  = 22
...

Die Dateien

docker-compose.yml

version: "3.8"

networks:
  gitea:
    external: false

services:
  gitea:
    image: gitea/gitea:latest
    container_name: ${CONTAINER_NAME_GITEA} # Container Name
    environment:
      - USER_UID=${USER_UID}
      - USER_GID=${USER_GID}
      - GITEA__database__DB_TYPE=${GITEA__database__DB_TYPE}
      - GITEA__database__HOST=${GITEA__database__HOST}
      - GITEA__database__NAME_FILE=/run/secrets/gitea_db_name
      - GITEA__database__USER_FILE=/run/secrets/gitea_db_user
      - GITEA__database__PASSWD_FILE=/run/secrets/gitea_db_password
    restart: always
    networks:
      - gitea
    volumes:
      - ${GITEA_DATA_FOLDER}:/data
    ports:
      - "${GITEA_PORT_TCP}:3000"
      - "${GITEA_PORT_SSH}:22"
    depends_on:
      - db
    secrets:
      - gitea_db_password
      - gitea_db_user
      - gitea_db_name

  db:
    image: postgres:latest
    container_name: ${CONTAINER_NAME_POSTGRES} # Container Name
    restart: always
    environment:
      - POSTGRES_USER_FILE=/run/secrets/gitea_db_user
      - POSTGRES_PASSWORD_FILE=/run/secrets/gitea_db_password
      - POSTGRES_DB_FILE=/run/secrets/gitea_db_name
    networks:
      - gitea
    volumes:
      - /volume1/docker/ims-gitea/giteadb:/var/lib/postgresql/data
    secrets:
      - gitea_db_password
      - gitea_db_user
      - gitea_db_name

  pgbackups:
    image: prodrigestivill/postgres-backup-local
    container_name: ${CONTAINER_NAME_PGBACKUPS} # Container Name
    restart: always
    networks:
      - gitea
    #user: ${GITEA__database__USER}:${GITEA__database__USER}
    volumes:
      - ${DB_BACKUP_FOLDER}:/backups
    depends_on:
      - db
    environment:
      - TZ=Europe/Berlin
      - POSTGRES_HOST=db # Container Name of Postgres
      - POSTGRES_DB_FILE=/run/secrets/gitea_db_name
      - POSTGRES_CLUSTER=TRUE
      - POSTGRES_USER_FILE=/run/secrets/gitea_db_user
      - POSTGRES_PASSWORD_FILE=/run/secrets/gitea_db_password
      - POSTGRES_PASSFILE_STORE=/backups/.pgpass
      - POSTGRES_EXTRA_OPTS=--clean
      - SCHEDULE=@daily
      - BACKUP_KEEP_DAYS=7
      - BACKUP_KEEP_WEEKS=4
      - BACKUP_KEEP_MONTHS=6
      - HEALTHCHECK_PORT=8080
    secrets:
      - gitea_db_password
      - gitea_db_user
      - gitea_db_name

  adminer:
    image: adminer
    container_name: ${CONTAINER_NAME_ADMINER}
    restart: always
    networks:
      - gitea
    ports:
      - ${ADMINER_PORT}:8080

volumes:
  gitea:
  db:
  pgbackups:

secrets:
  gitea_db_user:
    file: ${SECRETS_DIRECTORY}/gitea_db_user.txt
  gitea_db_password:
    file: ${SECRETS_DIRECTORY}/gitea_db_password.txt
  gitea_db_name:
    file: ${SECRETS_DIRECTORY}/gitea_db_name.txt

env Datei

CONTAINER_NAME_GITEA=gitea
CONTAINER_NAME_POSTGRES=giteadb
CONTAINER_NAME_PGBACKUPS=gitea-pgbackups
CONTAINER_NAME_ADMINER=gitea-adminer
TZ=Europe/Berlin
UID=1026
GID=100
GITEA__database__DB_TYPE=postgres
GITEA__database__HOST=db:5432
GITEA__database__USER=postgres
GITEA_DATA_FOLDER=/volume1/docker/gitea/giteadata
GITEA_PORT_TCP=3005
GITEA_PORT_SSH=3333
DB_BACKUP_FOLDER=/volume1/docker/gitea/giteadbbackup
ADMINER_PORT=8081
SECRETS_DIRECTORY=/volume1/docker/gitea/secrets

gitea_db_name.txt

gitea

gitea_db_password.txt

passwd

gitea_db_user.txt

postgres

Gib mir gerne einen Kaffee ☕ aus ❗️

Wenn dir meine Beiträge gefallen und geholfen haben, dann kannst du mir gerne einen Kaffee ☕️ ausgeben.

Donation via PayPalDonation via LiberaPay

Donation via Bitcoin
Bitcoin Address: bc1qfuz93hw2fhdvfuxf6mlxlk8zdadvnktppkzqzj

Source

Photo by Laårk Boshoff on Unsplash