Infrastruktur: Docker, Netzwerke & Traefik
Auf den Zielservern (Pre-Staging, Staging, Produktion) werden die SMARTKRIS-Komponenten als Docker-Container orchestriert. Die Architektur legt hierbei höchsten Wert auf Netzwerk-Isolation und Routing-Sicherheit.
1. Docker-Netzwerke & Isolation
Das System nutzt zwei logisch getrennte Docker-Netzwerke, um die Angriffsfläche zu minimieren. Das Backend und die Datenbanken sind von außen nicht direkt erreichbar.
Das öffentliche Netzwerk (devparse_default)
Dieses externe Netzwerk wird von Traefik verwaltet. Ausschließlich die beiden Node.js-Services, die Traffic von außen annehmen müssen, sind mit diesem Netzwerk verbunden:
* smartkris-web (Next.js Dashboard / BFF)
* smartkris-ws-service (WebSocket Service)
Das interne Netzwerk (shared-network-{{CI_ENVIRONMENT_SLUG}})
Dieses interne Netzwerk wird pro Umgebung von Ansible dynamisch angelegt. Alle Komponenten des Systems kommunizieren ausschließlich über dieses Netzwerk miteinander.
Verbundene Container:
* smartkris-web
* smartkris-ws-service
* spring-service (Spring Boot Backend)
* postgres-db (PostgreSQL Datenbank)
* rabbitmq (Message Broker)
Wichtig: Der spring-service mappt keine Ports (wie z.B. 8080) auf den Host. Er ist nur für Container erreichbar, die sich im selben shared-network befinden.
2. Traefik Reverse Proxy & Routing
Traefik fungiert als zentraler Reverse Proxy für eingehende HTTPS-Anfragen. Er kümmert sich automatisch um die Terminierung von SSL/TLS-Zertifikaten über Let’s Encrypt (certresolver=LE).
Das Routing zu den beiden öffentlich erreichbaren Containern wird über Docker-Labels in der generierten docker-compose.traefik.yml gesteuert:
-
Dashboard & API-Gateway: Alle Standard-Anfragen an die konfgiurierte Domain (Regel:
Host('{{ APPLICATION_BASE_URL }}')) werden an den internen Port3000des Next.js-Containers (smartkris-web) geroutet. -
WebSocket Service: Anfragen an die Domain, die zusätzlich den Pfad
/wsaufweisen (Regel:Host('…') && PathPrefix('/ws')), werden explizit an den internen Port3001des Node.js-WebSocket-Containers (smartkris-ws-service) geroutet.
3. Datenpersistenz & Volumes
Um Daten über Container-Neustarts hinweg zu erhalten, werden benannte Docker Volumes (volumes) verwendet, die den Umgebungs-Slug im Namen tragen (z.B. postgres-data-staging):
-
Datenbank:
/var/lib/postgresql/data(postgres-db) -
Message Broker:
/var/lib/rabbitmq(rabbitmq) -
Datei-Uploads:
/app/uploads(spring-service)
Das chmod-uploads Init-Pattern
Da der Spring Boot Container aus Sicherheitsgründen nicht als root, sondern mit einem eingeschränkten Benutzer (user: "1002:1000") läuft, kann es bei neu angelegten Docker Volumes zu Berechtigungsproblemen kommen.
Um dies zu lösen, definiert die Backend-Infrastruktur einen Init-Container namens chmod-uploads. Dieser nutzt ein winziges busybox-Image, mounted das uploads-Volume, ändert per Shell-Befehl die Besitzer (chown -R 1002:1000) und beendet sich sofort wieder. Der spring-service wartet per depends_on, bis dieser Fix durchgelaufen ist, bevor er startet.