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 Port 3000 des Next.js-Containers (smartkris-web) geroutet.

  • WebSocket Service: Anfragen an die Domain, die zusätzlich den Pfad /ws aufweisen (Regel: Host('…​') && PathPrefix('/ws')), werden explizit an den internen Port 3001 des 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.