services: db: image: postgres:16-alpine environment: POSTGRES_DB: stiftung_dev POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres_dev volumes: - dbdata_dev:/var/lib/postgresql/data - ./scripts/init-paperless-db.sh:/docker-entrypoint-initdb.d/init-paperless-db.sh ports: - "5433:5432" healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres -d stiftung_dev"] interval: 10s timeout: 5s retries: 5 redis: image: redis:7-alpine ports: - "6380:6379" web: build: ./app depends_on: db: condition: service_healthy redis: condition: service_started environment: - POSTGRES_DB=stiftung_dev - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres_dev - DB_HOST=db - DB_PORT=5432 - DJANGO_SECRET_KEY=dev-secret-key-not-for-production - DJANGO_DEBUG=1 - DJANGO_ALLOWED_HOSTS=localhost,127.0.0.1,100.81.230.53 - LANGUAGE_CODE=de - TIME_ZONE=Europe/Berlin - REDIS_URL=redis://redis:6379/0 - CELERY_REDIS_URL=redis://redis:6379/2 - PAPERLESS_API_URL=http://paperless:8000 - PAPERLESS_API_TOKEN=1972509e25810d9ae7497c1c79ecfea9e942f18d - PAPERLESS_REQUIRED_TAG=Stiftung_Destinatäre - PAPERLESS_LAND_TAG=Stiftung_Land_und_Pächter - PAPERLESS_ADMIN_TAG=Stiftung_Administration - PAPERLESS_DESTINATAERE_TAG_ID=1 - PAPERLESS_LAND_TAG_ID=3 - PAPERLESS_ADMIN_TAG_ID=2 - GRAMPS_URL=http://grampsweb:5000 - GRAMPS_USERNAME=admin@localhost - GRAMPS_PASSWORD=gramps_dev_password ports: - "18081:8000" volumes: - ./app:/app command: ["python", "manage.py", "runserver", "0.0.0.0:8000"] worker: build: ./app depends_on: db: condition: service_healthy redis: condition: service_started environment: - POSTGRES_DB=stiftung_dev - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres_dev - DB_HOST=db - DB_PORT=5432 - DJANGO_SECRET_KEY=dev-secret-key-not-for-production - DJANGO_DEBUG=1 - CELERY_REDIS_URL=redis://redis:6379/2 volumes: - ./app:/app command: ["celery", "-A", "core", "worker", "-l", "info"] beat: build: ./app depends_on: - redis - db environment: - POSTGRES_DB=stiftung_dev - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres_dev - DB_HOST=db - DB_PORT=5432 - DJANGO_SECRET_KEY=dev-secret-key-not-for-production - DJANGO_DEBUG=1 - CELERY_REDIS_URL=redis://redis:6379/2 volumes: - ./app:/app command: ["celery", "-A", "core", "beat", "-l", "info"] paperless: image: ghcr.io/paperless-ngx/paperless-ngx:latest ports: - "8082:8000" environment: - PAPERLESS_REDIS=redis://redis:6379 - PAPERLESS_DBHOST=db - PAPERLESS_DBPORT=5432 - PAPERLESS_DBNAME=paperless_dev - PAPERLESS_DBUSER=postgres - PAPERLESS_DBPASS=postgres_dev - PAPERLESS_SECRET_KEY=dev-paperless-secret-key - PAPERLESS_URL=http://localhost:8082 - PAPERLESS_ALLOWED_HOSTS=localhost,127.0.0.1,paperless - PAPERLESS_CORS_ALLOWED_HOSTS=http://localhost:8082,http://localhost:8081 - PAPERLESS_ADMIN_USER=admin - PAPERLESS_ADMIN_PASSWORD=admin123 - PAPERLESS_ADMIN_MAIL=admin@localhost volumes: - paperless_data_dev:/usr/src/paperless/data - paperless_media_dev:/usr/src/paperless/media - paperless_export_dev:/usr/src/paperless/export - paperless_consume_dev:/usr/src/paperless/consume depends_on: - db - redis mcp: build: ./app depends_on: db: condition: service_healthy environment: - POSTGRES_DB=stiftung_dev - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres_dev - DB_HOST=db - DB_PORT=5432 - DJANGO_SECRET_KEY=dev-secret-key-not-for-production - DJANGO_DEBUG=1 - DJANGO_ALLOWED_HOSTS=localhost,127.0.0.1 - LANGUAGE_CODE=de - TIME_ZONE=Europe/Berlin - MCP_TOKEN_READONLY=${MCP_TOKEN_READONLY:-dev-readonly-token} - MCP_TOKEN_EDITOR=${MCP_TOKEN_EDITOR:-dev-editor-token} - MCP_TOKEN_ADMIN=${MCP_TOKEN_ADMIN:-dev-admin-token} # Kein Port-Mapping – nur internes Netz # Start via: docker compose -f compose.dev.yml run --rm -e MCP_AUTH_TOKEN=dev-readonly-token mcp stdin_open: true volumes: - ./app:/app command: ["python", "-m", "mcp_server"] ollama: image: ollama/ollama:latest # Kein externes Port-Mapping — nur über internes Docker-Netzwerk erreichbar # Django-App: http://ollama:11434 environment: - OLLAMA_MAX_LOADED_MODELS=1 - OLLAMA_NUM_PARALLEL=1 - OLLAMA_DEFAULT_MODEL=${OLLAMA_DEFAULT_MODEL:-qwen2.5:3b} volumes: - ollama_data_dev:/root/.ollama restart: unless-stopped healthcheck: test: ["CMD-SHELL", "curl -sf http://localhost:11434/api/tags || exit 1"] interval: 30s timeout: 10s retries: 5 start_period: 60s # Beim ersten Start: Ollama starten, dann Modell laden (falls nicht vorhanden) entrypoint: > sh -c " ollama serve & OLLAMA_PID=$$! echo '[ollama] Warte auf API...' RETRIES=0 until curl -sf http://localhost:11434/api/tags > /dev/null 2>&1; do RETRIES=$$((RETRIES + 1)) [ $$RETRIES -ge 60 ] && echo '[ollama] FEHLER: API nicht bereit.' && exit 1 sleep 1 done MODEL=$${OLLAMA_DEFAULT_MODEL:-qwen2.5:3b} if ollama list | grep -q \"$$MODEL\"; then echo \"[ollama] Modell '$$MODEL' bereits vorhanden.\" else echo \"[ollama] Lade Modell '$$MODEL'...\" ollama pull \"$$MODEL\" fi wait $$OLLAMA_PID " grampsweb: image: ghcr.io/gramps-project/grampsweb:latest ports: - "18090:5000" environment: - GRAMPSWEB_SECRET_KEY=dev-grampsweb-secret-key-not-for-production - GRAMPSWEB_ADMIN_EMAIL=admin@localhost - GRAMPSWEB_ADMIN_PASSWORD=gramps_dev_password - GRAMPSWEB_TREE=Stiftung - GRAMPSWEB_BASE_URL=/ - GRAMPSWEB_CELERY_CONFIG__broker_url=redis://redis:6379/0 - GRAMPSWEB_CELERY_CONFIG__result_backend=redis://redis:6379/0 - GRAMPSWEB_RATELIMIT_STORAGE_URI=redis://redis:6379/1 - GRAMPSWEB_NEW_DB_BACKEND=sqlite volumes: - gramps_data_dev:/app/data depends_on: - redis volumes: dbdata_dev: gramps_data_dev: paperless_data_dev: paperless_media_dev: paperless_export_dev: paperless_consume_dev: gramps_data_dev: ollama_data_dev: