vcard4reseller/docker-compose.yml
Thomas Peterson 67e4353c8d Skalierbarkeit: Druck-Assets in S3-Object-Storage (Flysystem)
Macht die App-Nodes zustandslos (horizontal skalierbar): Hintergrund-PDFs
und Schriften liegen nicht mehr lokal, sondern im S3-kompatiblen Object
Storage (Flysystem + async-aws). In der DB stehen Storage-Keys.

- flysystem-bundle + async-aws (Storage "card_assets"), env-getrieben
  (S3_ENDPOINT/REGION/BUCKET/KEY/SECRET/PATH_STYLE) → lokal MinIO, prod Hetzner OS
- CardAssetUploadController: Upload/Read/Delete über Storage; GET streamt PDF
- CardPdfRenderer: liest Hintergrund (FPDI StreamReader) & Schriften (Temp-Datei) aus S3
- docker-compose: minio + minio-init (Bucket) + zweiter App-Node php2 (Profil scale-test)
- app:render-card Command für den Cross-Node-Nachweis

Verifiziert: Upload über Node 1 → identisches PDF-Render (51897 B, mit
Hintergrund) auf Node 2, der nur DB + Object Storage liest.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 20:56:51 +02:00

95 lines
2.2 KiB
YAML

services:
php:
build:
context: ./docker/php
args:
UID: ${UID:-1000}
GID: ${GID:-1000}
volumes:
- ./backend:/app
depends_on:
mariadb:
condition: service_healthy
environment:
DATABASE_URL: "mysql://app:app@mariadb:3306/vcard4reseller?serverVersion=11.4.0-MariaDB&charset=utf8mb4"
# Zweiter, identischer App-Node — zum Beweis, dass Assets/Auth nodeübergreifend laufen
php2:
build:
context: ./docker/php
args:
UID: ${UID:-1000}
GID: ${GID:-1000}
volumes:
- ./backend:/app
depends_on:
mariadb:
condition: service_healthy
environment:
DATABASE_URL: "mysql://app:app@mariadb:3306/vcard4reseller?serverVersion=11.4.0-MariaDB&charset=utf8mb4"
profiles: ["scale-test"]
nginx:
image: nginx:1.27-alpine
ports:
- "8080:80"
volumes:
- ./backend:/app:ro
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
- php
minio:
image: minio/minio:latest
command: server /data --console-address ":9001"
environment:
MINIO_ROOT_USER: minioadmin
MINIO_ROOT_PASSWORD: minioadmin
ports:
- "9000:9000"
- "9001:9001"
volumes:
- minio_data:/data
# Legt den Bucket einmalig an
minio-init:
image: minio/mc
depends_on:
- minio
entrypoint: >
/bin/sh -c "
until mc alias set local http://minio:9000 minioadmin minioadmin; do sleep 1; done;
mc mb -p local/card-assets || true;
"
mariadb:
image: mariadb:11.4
ports:
- "3306:3306"
environment:
MARIADB_ROOT_PASSWORD: root
MARIADB_DATABASE: vcard4reseller
MARIADB_USER: app
MARIADB_PASSWORD: app
volumes:
- mariadb_data:/var/lib/mysql
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
interval: 5s
timeout: 5s
retries: 10
node:
image: node:25-alpine
working_dir: /app
volumes:
- ./frontend:/app
ports:
- "5173:5173"
command: sh -c "npm install && npm run dev -- --host 0.0.0.0"
profiles: ["frontend"]
volumes:
mariadb_data:
minio_data: