Installation von Forgejo mit Podman
In diesem Artikel setzen wir die Softwareentwicklungsplattform Forgejo in einer Podman-Containerumgebung auf. Forgejo dabei ein Fork von gitea, welches wiederum eine offene Implementierung von GitHub ist. Podman ist ein Verwaltungstool für Container von RedHat (ähnlich Docker).
Warum Forgejo?
Klar, heute ist die ganze Welt auf GitHub. Ganz im Zeichen der digitalen Souveränität sind wir aber der Meinung, dass Softwareentwicklungsplattformen auch lokal und unabhängig verfügbar sein sollten. Deshalb begrüssen wir Projekte wie Forgejo, welche es ermöglichen, hier ein Stück Autonomie zu gewinnen.
Warum Podman?
Viele Software wird heute als Container-Image zur Verfügung gestellt. Dies bringt im Vergleich zur klassischen (paketbasierten) Softwareverwaltung einige Vor-, aber auch Nachteile.
Als Besonderheit kann Podman Container gänzlich im normalen Benutzerkontext ausführen (rootless), was einen Sicherheitsgewinn darstellt. So kann man theoretisch ganze Serverarchitekturen im Kontext eines unprivilegierten Benutzers betreiben. Isolationsmechnismus ist allerdings immer noch der Kernel, d.h. man sollte im Hinterkopf behalten, dass hier kein Isolationsgrad wie bei virtuellen Maschinen (VM) vorliegt.
Basisumgebung schaffen
Zuerst muss af dem Zielserver (in unserem Fall Debian Trixie) Podman installiert werden. Dies gelingt wie folgt:
apt install podman podman-compose
Im Gegensatz zu anderen Container-Umgebungen wie Docker läuft bei Podman kein Daemon, sondern man verwaltet die Container direkt mittels den von Podman zur Verfügung gestellten Tools.
Forgejo-Container aufsetzen
Instanzen von Linux-Containern haben zwar einen Zustand, welcher auch Container-Neustarts übersteht, sollten trotzdem aber als "Wegwerfobjekte" betrachtet werden, welche im Prinzip beliebig entfernt und wieder erzeugt werden können. Nicht flüchtige Nutzdaten werden werden sollten einem Container daher über sogenannte Volumes zur Verfügung gestellt werden, welche ausserhalb eines Containers definiert werden und existieren. Mit Podman lassen sich Volumes am einfachsten von einem normalen User (nicht-root) mittels podman volume create erzeugen:
podman volume create forgejo-data
podman volume create forgejo-config
Die Volumes werden dabei an folgender Stelle im Home-Verzeichnis des Benutzer angelegt:
~/.local/share/containers/storage/volumes/
Verwirrend ist, dass beim rootless Podman-Konzept sogenannte sub-uid bzw. sub-gids verwendet werden, um die User-Ids innerhalb eines Containers auf diejenige des Hostsystems zu mappen (sogenanntes UID/GID shifting). Dies sieht man beispielsweise, wenn man sich den Inhalt eines der erzeugten Volumes anzeigen lässt:
ls -l ~/.local/share/containers/storage/volumes/forgejo-data/
total 4
drwxr-xr-x 15 100999 100999 4096 Nov 23 14:43 _data
Anstelle des Benutzernamens steht hier nur "100999"; Die rootless Containers können die UIDs 0–65535 innerhalb des Containers verwenden, und diese werden auf die UIDs 100000–165535 auf dem Host gemapped (man beachte: diese UID existieren auf dem Host auch nicht in /etc/passwd).
Nun wo die Volumens innerhalb eines unprivilegierten Users eingerichtet sind können wir den Container in Betrieb nehmen. Wie bei Docker kann man (auch im Verzeichnis des Benutzers) ein Compose-File namens podman-compose.yml anlegen, welches sagt, wie der Container zusammengebaut werden soll. Dieses sieht für unsere Forgejo-Instanz wie folgt aus:
version: "3.8"
services:
forgejo:
image: codeberg.org/forgejo/forgejo:13-rootless
container_name: forgejo
restart: always
ports:
- "3000:3000" # Web UI
- "2222:2222" # SSH
volumes:
- forgejo-data:/var/lib/gitea
- forgejo-config:/etc/gitea
volumes:
forgejo-data:
external: true
forgejo-config:
external: true
Dazu bedarf es auch einiger Erläuterungen:
- Der Containername wird hier als `forgejo festgelegt
- Das
Imagespezifiziert das eigentliche Container-Image und seine Quelle - Die `ports' spezifizieren das Mapping der Netzwerkports (links Host, rechts Container). In unserem Falle sind diese alle identisch und hohe Ports (>1024), da rootless.
- Die
volumes(im Bereichservices) definieren die Volumennamen, und wo diese im Container gemounted werden - Die
volumesauf der Hauptebene defineren, wie die Volumen erstellt werden sollen bzw. woher sie geladen werden sollen. Mitexternal: truewird definiert, dass sie schon vorhanden sind (d.h. nicht erzeugt werden sollen) und an vorgängig aufgezeigtem Ort existieren.
Nun kann der Container gebaut und gestartet werden:
podman-compose up -d
Dies dauert einen Moment, anschliessend sollte man die Forgejo-Applikation via http://localhost:3000 erreichen können. Auch ssh -p 2222 git@127.0.0.1 müsste nun funktionieren (kein Shell-Access, nur eine erfolgreiche Verbindungsmeldung).
Als Systemdienst einrichten
Mit folgenden Instruktionen sollte der Container auch als Systemd-Dienst mit Autostart eingerichtet werden können (dies haben wir noch nicht getestet):
podman generate systemd --name forgejo --files --new
mkdir -p ~/.config/systemd/user
mv container-forgejo.service ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user enable --now container-forgejo
loginctl enable-linger $USER
Hinweis: Für "loginctl enable-linger" war hier noch die installation des Pakets polkitd (apt install polkitd) notwendig.
Man beachte, dass dies alles im Rahmen eines unprivilegierten Benutzers erfolgt!
Podman Maintenance
Im folgenden einige nützliche Befehle für die Podman-Containerverwaltung:
- podman ps -all listet alle Container mit Id, Name und Status auf
- podman start
startet einen Container - podman stop
stoppt einen Container - podman rm
entfernt einen Container. Externe Volumes bleiben erhalten! - podman logs forgejo zeigt das Syslog des Containers mit Namen forgejo an.
Sehr wichtig ist ausserdem dieser Befehl, mit welchem sich eine Shell im Container öffnen lässt:
podman exec -it forgejo sh
Erste Schritte mit Forgejo
Die Anwendung läuft erstaunlich problemlos, hat einen tollen Leistungsumfang und lässt sich über das Webinterface (http://localhost:3000) bequem konfigurieren.
Erwähnenswerte SSH-Integration
Sie behaltet einen SSH-Server, welcher über Port 2222 erreichbar ist. Dieser ist direkt in die Anwendung integriert und ermöglicht, dass in Forgejo eingerichtete Applikationsbenutzer direkt via SSH authentifiziert werden können, wenn sie via Git Daten auf ein Forgejo-Repository pushen möchten.
Dazu muss lediglich im Benutzerprofil der SSH Public-Key eines Users hinterlegt werden. Die eigentliche SSH Verbindung erfolgt für alle User mittels dem User git, und Anhand des Public-Keys wird der dazu passende Forgejo-User aufgelöst und authentisiert. Dies ermöglicht einfach teilbare Verbindungsstrings wie ssh://git@127.0.0.1:2222/MyTestorg/OurTestApplication.git, welche auch im Forgejo-Webinterfache direkt ersichtlich sind.