Erfahrungsbericht zur Bereitstellung von Nextcloud in einer mit Ansible und Docker verwalteten Staging-Umgebung.
Im Rahmen der Umstrukturierung meiner Infrastruktur habe ich kürzlich eine von der Produktion getrennte Staging-Umgebung eingerichtet. Das Ziel war einfach: neue Anwendungsversionen validieren, bevor sie in Produktion gehen.
Die meisten meiner Anwendungen folgen demselben Muster:
Dieser Ansatz funktioniert einwandfrei für:
Dafür habe ich eine generische Ansible-Rolle namens erstellt:
staging_docker_app
Diese Rolle erledigt schlicht:
Für einfache Anwendungen ist dieser Ansatz effizient, wiederverwendbar und leicht zu warten.
Nextcloud zeigte jedoch rasch die Grenzen dieser Methode.
Zunächst nahm ich an, Nextcloud könne wie jede andere Anwendung bereitgestellt werden.
Die Konfiguration sah in etwa so aus:
app_name: nextcloud
app_image: ghcr.io/sepp67/ansible-role-nextcloud-stack:latest
app_container_name: nextcloud-staging
app_host_port: 18080
app_container_port: 80
Das Deployment schien zu gelingen.
Der Container startete.
Der Proxy funktionierte.
Aber die Anwendung war nicht wirklich betriebsbereit.
Anders als eine klassische Webanwendung besteht Nextcloud nicht aus einem einzigen Dienst.
Mein Deployment setzt sich zusammen aus:
Nextcloud Stack
├── Nextcloud
├── PostgreSQL
├── Redis
└── Cron
Die Docker-Compose-Datei zeigt das deutlich:
services:
db:
image: postgres
redis:
image: redis
app:
image: nextcloud
cron:
image: nextcloud
Der Hauptcontainer hängt ab von:
Nur den Nextcloud-Container zu starten führt daher zu einem unvollständigen Deployment.
Meine generische Rolle beruhte auf der Annahme:
Eine Anwendung = Ein Container
Nextcloud folgt einem anderen Modell:
Eine Anwendung = Mehrere zusammenarbeitende Dienste
Das ist ein völlig anderes Deployment-Schema.
Der Versuch, beide Modelle in derselben Rolle zu verwalten, führt schnell zu:
Die generische Rolle hört dann auf, wirklich generisch zu sein.
Statt die bestehende Rolle zu verkomplizieren, habe ich eine dedizierte Rolle erstellt:
staging_nextcloud_stack
Die Verantwortlichkeiten sind nun klar getrennt.
staging_docker_app
Verwendet für:
Verantwortlichkeiten:
staging_nextcloud_stack
Verantwortlichkeiten:
Eine weitere wichtige Lektion betrifft die Wiederverwendung.
Meine Infrastruktur verfügte bereits über eine Rolle:
docker_host
zuständig für die Installation von:
Zunächst hatte ich versucht, Docker direkt aus der Nextcloud-Rolle heraus zu installieren.
Das schuf redundante Zuständigkeiten.
Die endgültige Architektur wurde:
docker_host
│
▼
staging_nextcloud_stack
Die Docker-Rolle verwaltet Docker.
Die Nextcloud-Rolle verwaltet Nextcloud.
Die Staging-Umgebung stellt sich nun so dar:
vm-proxy-staging
│
├── lavallee.staging.local
├── facturier.staging.local
├── grav.staging.local
├── webcam.staging.local
└── nextcloud.staging.local
Die Anwendungen werden auf dedizierten virtuellen Maschinen bereitgestellt.
Die Nextcloud-VM enthält:
vm-nextcloud-staging
│
├── PostgreSQL
├── Redis
├── Nextcloud
└── Cron
Das Ganze wird automatisch mit Ansible und Docker Compose bereitgestellt.
Das Ziel der Automatisierung ist nicht, jedes Deployment identisch zu machen.
Das Ziel ist, jedes Deployment vorhersehbar, wartbar und nachvollziehbar zu machen.
Für einfache Anwendungen ist eine generische Rolle bestens geeignet.
Für aus mehreren Diensten bestehende Anwendungen wie Nextcloud liefert eine dedizierte Rolle eine sauberere, dauerhaftere Architektur.
Die Lektion ist einfach:
Generische Rollen sollten generisch bleiben. Komplexe Anwendungen verdienen ihre eigene Deployment-Logik.