Container
Übersicht
Es gibt die Möglichkeit, einen Container Server mit Docker oder mit Podman zu buchen.
Dies ist eine Managed Umgebung, also ohne Root-Rechte, wo Docker bzw. Podman rootless ausgeführt werden.
Falls vom Installationsskript einer Anwendung Root-Rechte erforderlich sind, kann entweder versucht werden, dies anzupassen, oder es kann ein Cloud Server gebucht werden, wo der Benutzer Root-Rechte hat.
Erste Schritte
Bei der Bestellung des Container Servers sollte direkt der Public SSH Key mitgegeben werden, am besten bereits nach dem Ed25519-Standard, siehe auch [1].
Der Zugriff erfolgt über den Benutzer tallyman über SSH auf den Container Server.
ssh tallyman@vm4xxx.hostsharing.net
Um einen "Hello World" Docker Container zu starten:
tallyman@vm4xxx:~$ docker run hello-world
Entsprechend sieht der Befehl für Podman aus:
tallyman@vm4xxx:~$ podman run hello-world
Hilfreiche Befehle für Docker
# in einem Ordner ausführen, wo eine Datei mit dem Namen docker-compose.yml liegt, um die Umgebung zu bauen und zu starten:
docker compose up --detach
# zeige alle laufenden Container
docker ps -a
# zeige die Logs eines Containers
docker logs mein-container
# wechsle in eine Shell im Container
docker exec -t -i mein-container /bin/sh
# Images aktualisieren
docker compose pull
# Containerumgebung stoppen und löschen
docker compose down
Hilfreiche Befehle für Podman
TODO
Integration in Hostsharing Managed Platform
Subdomain einrichten
Wir haben bereits die Hauptdomain bei Hostsharing gebucht.
Nun soll unsere Anwendung auf dem Container Server auf einer Subdomain laufen.
Wir benutzen einen Caddy Container, um Letsencrypt bereitszustellen (siehe in den Beispielen unten).
Auf der Managed Umgebung müssen wir das Zonefile anpassen, um die Subdomain per A und AAAA Eintrag auf den Container Server zu verweisen.
Mit dem Befehl dig ermitteln wir die ipv4 und ipv6 Adressen unseres Container Servers:
dig -t A +short vm4xxx.hostsharing.net
dig -t AAAA +short vm4xxx.hostsharing.net
Auf der Managed Umgebung, legen wir ein Zonefile an. Siehe auch die Anleitung im Handbuch: https://www.hostsharing.net/doc/managed-operations-platform/zonefile/
doms/meinedomain.de/etc/pri.meinedomain.de:
{DEFAULT_ZONEFILE}
meinesubdomain IN A 83.223.xx.xxx
meinesubdomain IN AAAA 2a01:xx:xxxx::xxxx:xxxx:0
Tunnel zur Managed Datenbank einrichten
Wir lassen die Anwendung auf dem Container Server laufen. Dort kann natürlich auch die Datenbank laufen, in einem eigenen Container.
Wir haben aber auch Datenbanken in der Managed Umgebung von Hostsharing, mit allen Vorteilen (regelmäßiges Backup, usw.).
Wenn wir eine managed Datenbank aus der Managed Umgebung auf dem Container Server einbinden wollen, sind folgende Schritte notwendig:
- TODO Es muss ein Tunnel eingerichtet werden, damit die Datenbank vom Container Server aus erreichbar ist.
- TODO: Anpassungen an Docker Compose. Beispiel
Docker fernsteuern
Es besteht die Möglichkeit, über SSH den Docker Socket von außen zu erreichen. Damit wird es möglich, über eine IDE wie z.B. Intellij IDEA die Docker Container zu starten und zu stoppen.
Um das auszuprobieren, können diese Befehle ausgeführt werden:
ssh -nNT -L $(pwd)/docker.sock:/var/run/docker.sock tallyman@vmxxxx.hostsharing.net
export DOCKER_HOST=unix://$(pwd)/docker.sock
docker ps -a
Nun sollten die aktuell laufenden Container gelistet werden.
Beispiel Anwendungen
Container Umgebung mit Nginx und Certbot
TODO siehe https://codeberg.org/tpokorra/hs.compose/src/branch/main/nginx-certbot
Container Umgebung mit Caddy und Python Anwendung
TODO siehe https://codeberg.org/tpokorra/hs.compose/src/branch/main/caddy-test
Nextcloud High Performance Backend mit Caddy
- Docker Compose: siehe https://codeberg.org/tpokorra/hs.compose/src/branch/main/nextcloud-high_performance_backend
- Siehe auch dort die README Datei, was für die Einrichtung erforderlich ist.
OnlyOffice Documentserver
TODO siehe https://codeberg.org/tpokorra/hs.compose/src/branch/main/onlyoffice-document_server
Backups in Volumes einpflegen
Auf Anfrage stellen wir einen read-only Snapshot bereit, der unter anderem Docker-Volumes, Container und Compose-Dateien enthält.
Da Docker nicht direkt mit den User- und Gruppen-IDs des tallyman-Users arbeitet, sondern interne Sub-User- und Sub-Group-IDs verwendet, können diese Daten nicht unmittelbar zurückkopiert werden. Für die Wiederherstellung ist daher ein kurzer Zwischenschritt erforderlich.
Hinweis: selbstverständlich helfen wir auf Anfrage auch dabei, die Dateien wieder in das laufende System zu migrieren.
Beispiel: das pgdata Verzeichnis eines PostgreSQL Containers tauschen
Wo liegt das Volume auf dem Dateisystem?
docker ps -a # wie lautet der Containername?
docker inspect --format '{{ range .Mounts }}{{ if eq .Type "volume" }}{{ .Source }}{{ "\n" }}{{ end }}{{ end }}' postgres-1
In unserem Fall sehen wir den Pfad: /home/tallyman/.local/share/docker/volumes/8c73a862eaf1fc3dee55a2f29b6f3d3dd68e3049da58a21a5f73010e7233190c/_data
Den betroffenen Container abschalten
In diesem Beispiel entscheiden wir uns dafür, die Container vollständig zu stoppen. Der Grund dafür ist, dass es je nach Image nicht immer eindeutig ist, wie der darin laufende Prozess korrekt gestoppt und wieder gestartet werden sollte.
Alternativ könnten wir das Backup also auch direkt in das Volume kopieren und im bestehenden Container eine Shell öffnen, um die Dateien an die richtige Stelle zu verschieben.
docker ps -a # wie lautet der Containername?
docker stop app-1
docker stop postgres-1
# oder über die Service-Namen aus der compose.yaml
docker compose stop app
docker compose stop postgres
In eine temporäre Subshell wechseln
Hier nutzen wir eine Abkürzung und lassen Docker einen temporären Container starten, der unseren Ordner als Volume einbindet. So erhalten wir eine Shell im passenden Userid/Gruppenid-Kontext und können direkt mit den Dateien im Volume arbeiten, ohne den eigentlichen Service-Container starten, oder als root arbeiten zu müssen.
export VOL=".local/share/docker/volumes"
docker run --rm -it -v "$VOL:/data" bash
Wir wechseln nun in das oben definierte Volume. Das Beispiel geht davon aus, dass das bereitgestellte Backupverzeichnis "pgdata2" genannt wurde.
cd data
mv pgdata pgdata.old
mv pgdata2 pgdata
Hinweis: Falls wir zusätzliche Pakete brauchen, nutzt das – auf Alpine basierte – Bash image den Paketmanager `apk`. Beispiel: ncdu installieren:
~$ apk add ncdu
(1/1) Installing ncdu (1.22-r0)
Executing busybox-1.37.0-r30.trigger
OK: 8726 KiB in 20 packages
Den Container wieder starten
Wir verlassen den Container mittels exit Enter oder über die Tastenkombination STRG+D.
docker start postgres-1
docker start app-1
# oder über die Service-Namen aus der compose.yaml
docker compose start app
docker compose start postgres
Beispiel: eine Subshell mit Hilfe eine Containerprozesses starten
Für Debugging kann es nützlich sein, direkt mit allen vorinstallierten Tools im Containerserver mit Daten der Volumes zu agieren. Hier sind zwei Wege um eine Subshell ohne extra(!) Container zu starten:
Mit Hilfe eines beliebigen laufenden Containers:
docker ps
docker inspect --format '{{.State.Pid}}' app-1
nsenter -U -t 2586740 -- bash
TODO
Funktionierende subshell (mit nötigen Berechtigungen) mittels unshare oder nsenter