Surya downloads models from HuggingFace to /root/.cache on first use. Without a volume, every container restart re-downloads ~73MB+. Added ocr_cache volume to persist the cache. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
191 lines
5.6 KiB
YAML
191 lines
5.6 KiB
YAML
services:
|
|
# --- Datenbank: PostgreSQL ---
|
|
db:
|
|
image: postgres:16-alpine
|
|
container_name: archive-db
|
|
restart: unless-stopped
|
|
environment:
|
|
POSTGRES_USER: ${POSTGRES_USER}
|
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
|
POSTGRES_DB: ${POSTGRES_DB}
|
|
volumes:
|
|
- ./data/postgres:/var/lib/postgresql/data
|
|
ports:
|
|
- "${PORT_DB}:5432"
|
|
networks:
|
|
- archive-net
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
|
|
interval: 5s
|
|
timeout: 5s
|
|
retries: 5
|
|
|
|
# --- Object Storage: MinIO (S3 kompatibel) ---
|
|
minio:
|
|
image: minio/minio:latest
|
|
container_name: archive-minio
|
|
restart: unless-stopped
|
|
command: server /data --console-address ":9001"
|
|
environment:
|
|
MINIO_ROOT_USER: ${MINIO_ROOT_USER}
|
|
MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD}
|
|
volumes:
|
|
- ./data/minio:/data
|
|
ports:
|
|
- "${PORT_MINIO_API}:9000" # API Port
|
|
- "${PORT_MINIO_CONSOLE}:9001" # Web-Oberfläche
|
|
networks:
|
|
- archive-net
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
|
|
interval: 30s
|
|
timeout: 20s
|
|
retries: 3
|
|
|
|
# --- Helper: Erstellt automatisch den Bucket ---
|
|
create-buckets:
|
|
image: minio/mc
|
|
depends_on:
|
|
minio:
|
|
condition: service_healthy
|
|
entrypoint: >
|
|
/bin/sh -c "
|
|
/usr/bin/mc alias set myminio http://minio:9000 ${MINIO_ROOT_USER} ${MINIO_ROOT_PASSWORD};
|
|
/usr/bin/mc mb myminio/${MINIO_DEFAULT_BUCKETS} --ignore-existing;
|
|
/usr/bin/mc anonymous set private myminio/${MINIO_DEFAULT_BUCKETS};
|
|
exit 0;
|
|
"
|
|
networks:
|
|
- archive-net
|
|
|
|
# --- Mail catcher: Mailpit (dev only) ---
|
|
# Catches all outgoing emails and displays them in a web UI.
|
|
# Access the inbox at http://localhost:${PORT_MAILPIT_UI} after starting the stack.
|
|
mailpit:
|
|
image: axllent/mailpit:latest
|
|
container_name: archive-mailpit
|
|
restart: unless-stopped
|
|
ports:
|
|
- "${PORT_MAILPIT_UI:-8025}:8025" # Web UI
|
|
- "${PORT_MAILPIT_SMTP:-1025}:1025" # SMTP
|
|
networks:
|
|
- archive-net
|
|
|
|
# --- OCR: Python microservice (Surya + Kraken) ---
|
|
ocr-service:
|
|
build:
|
|
context: ./ocr-service
|
|
dockerfile: Dockerfile
|
|
container_name: archive-ocr
|
|
restart: unless-stopped
|
|
mem_limit: 8g
|
|
memswap_limit: 8g
|
|
volumes:
|
|
- ocr_models:/app/models
|
|
- ocr_cache:/root/.cache
|
|
environment:
|
|
KRAKEN_MODEL_PATH: /app/models/german_kurrent.mlmodel
|
|
OCR_CONFIDENCE_THRESHOLD: "0.3"
|
|
OCR_CONFIDENCE_THRESHOLD_KURRENT: "0.5"
|
|
RECOGNITION_BATCH_SIZE: "8"
|
|
DETECTOR_BATCH_SIZE: "4"
|
|
networks:
|
|
- archive-net
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 12
|
|
start_period: 60s
|
|
|
|
# --- Backend: Spring Boot ---
|
|
backend:
|
|
build:
|
|
context: ./backend
|
|
dockerfile: Dockerfile
|
|
container_name: archive-backend
|
|
restart: unless-stopped
|
|
volumes:
|
|
- ./backend:/app
|
|
- ./import:/import
|
|
- maven_cache:/root/.m2
|
|
depends_on:
|
|
db:
|
|
condition: service_healthy
|
|
minio:
|
|
condition: service_healthy
|
|
mailpit:
|
|
condition: service_started
|
|
ocr-service:
|
|
condition: service_healthy
|
|
environment:
|
|
SPRING_DATASOURCE_URL: jdbc:postgresql://db:5432/${POSTGRES_DB}
|
|
SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER}
|
|
SPRING_DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD}
|
|
S3_ENDPOINT: http://minio:9000
|
|
S3_ACCESS_KEY: ${MINIO_ROOT_USER}
|
|
S3_SECRET_KEY: ${MINIO_ROOT_PASSWORD}
|
|
S3_BUCKET_NAME: ${MINIO_DEFAULT_BUCKETS}
|
|
S3_REGION: us-east-1
|
|
SPRING_PROFILES_ACTIVE: dev,e2e
|
|
APP_BASE_URL: ${APP_BASE_URL:-http://localhost:3000}
|
|
# Defaults to the local Mailpit catcher — override in .env for production SMTP
|
|
MAIL_HOST: ${MAIL_HOST:-mailpit}
|
|
MAIL_PORT: ${MAIL_PORT:-1025}
|
|
MAIL_USERNAME: ${MAIL_USERNAME:-}
|
|
MAIL_PASSWORD: ${MAIL_PASSWORD:-}
|
|
APP_MAIL_FROM: ${APP_MAIL_FROM:-noreply@familienarchiv.local}
|
|
# Mailpit needs no auth or STARTTLS; production SMTP overrides these via .env
|
|
SPRING_MAIL_PROPERTIES_MAIL_SMTP_AUTH: ${MAIL_SMTP_AUTH:-false}
|
|
SPRING_MAIL_PROPERTIES_MAIL_SMTP_STARTTLS_ENABLE: ${MAIL_STARTTLS_ENABLE:-false}
|
|
APP_OCR_BASE_URL: http://ocr-service:8000
|
|
APP_S3_INTERNAL_URL: http://minio:9000
|
|
ports:
|
|
- "${PORT_BACKEND}:8080"
|
|
networks:
|
|
- archive-net
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "wget -qO- http://localhost:8080/actuator/health | grep -q UP || exit 1"]
|
|
interval: 15s
|
|
timeout: 5s
|
|
retries: 10
|
|
start_period: 60s
|
|
|
|
# --- Frontend: SvelteKit (Dev Server) ---
|
|
frontend:
|
|
build:
|
|
context: ./frontend
|
|
dockerfile: Dockerfile
|
|
container_name: archive-frontend
|
|
restart: unless-stopped
|
|
depends_on:
|
|
db:
|
|
condition: service_healthy
|
|
minio:
|
|
condition: service_healthy
|
|
backend:
|
|
condition: service_healthy
|
|
volumes:
|
|
- ./frontend:/app
|
|
# Keep container's node_modules separate from host to avoid OS binary conflicts
|
|
- frontend_node_modules:/app/node_modules
|
|
environment:
|
|
# SSR calls (server-side) use the internal Docker network
|
|
API_INTERNAL_URL: http://backend:8080
|
|
# Vite dev proxy forwards /api from browser to the backend container
|
|
API_PROXY_TARGET: http://backend:8080
|
|
ports:
|
|
- "${PORT_FRONTEND}:5173"
|
|
networks:
|
|
- archive-net
|
|
|
|
networks:
|
|
archive-net:
|
|
driver: bridge
|
|
|
|
volumes:
|
|
frontend_node_modules:
|
|
maven_cache:
|
|
ocr_models:
|
|
ocr_cache:
|