From 8c120ae78d598bfcc0e0b28f9d1f8b61c67006d9 Mon Sep 17 00:00:00 2001 From: Nils Pukropp Date: Mon, 15 Jun 2026 16:43:14 +0200 Subject: [PATCH] updated docker-compose and nginx --- .gitignore | 2 + docker-compose.yml | 142 -------------------------------------------- frontend/nginx.conf | 42 ++++--------- 3 files changed, 15 insertions(+), 171 deletions(-) diff --git a/.gitignore b/.gitignore index fdfcb70..a495895 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,8 @@ ENV/ # Databases *.sqlite3 db.sqlite3 +backend/db.sqlite3-shm +backend/db.sqlite3-wal # Python cache __pycache__/ diff --git a/docker-compose.yml b/docker-compose.yml index bb19c57..a8f789d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,138 +1,4 @@ services: - # --- Redis (Celery broker + result backend) --- - redis: - image: redis:7-alpine - container_name: holy-redis - command: redis-server --appendonly yes --save 60 1 - restart: unless-stopped - sysctls: - - net.core.somaxconn=512 - - vm.overcommit_memory=1 - networks: - - holy-net - volumes: - - redis_data:/data - healthcheck: - test: ["CMD", "redis-cli", "ping"] - interval: 10s - timeout: 3s - retries: 5 - - # --- Backend Service --- - backend: - build: - context: ./backend - container_name: holy-backend - user: "app" - restart: unless-stopped - networks: - - holy-net - ports: - - 8000 - env_file: - - .env - volumes: - - ./backend:/app - - ./legacy:/app/legacy - environment: - - PYTHONUNBUFFERED=1 - - DOMAIN=${DOMAIN:-localhost} - - DJANGO_SETTINGS_MODULE=${DJANGO_SETTINGS_MODULE:-holy_backend.settings.prod} - - CELERY_BROKER_URL=${CELERY_BROKER_URL:-redis://redis:6379/0} - - CELERY_RESULT_BACKEND=${CELERY_RESULT_BACKEND:-redis://redis:6379/0} - depends_on: - redis: - condition: service_healthy - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:8000/health/"] - interval: 10s - timeout: 5s - retries: 5 - start_period: 30s - - worker: - build: - context: ./backend - container_name: holy-worker - command: celery -A holy_backend worker -l info --concurrency=2 - user: "app" - restart: unless-stopped - networks: - - holy-net - env_file: - - .env - environment: - - PYTHONUNBUFFERED=1 - - DOMAIN=${DOMAIN:-localhost} - - DJANGO_SETTINGS_MODULE=${DJANGO_SETTINGS_MODULE:-holy_backend.settings.prod} - - CELERY_BROKER_URL=${CELERY_BROKER_URL:-redis://redis:6379/0} - - CELERY_RESULT_BACKEND=${CELERY_RESULT_BACKEND:-redis://redis:6379/0} - - SKIP_INIT=true - volumes: - - ./backend:/app - - ./legacy:/app/legacy - depends_on: - redis: - condition: service_healthy - backend: - condition: service_healthy - healthcheck: - test: ["CMD-SHELL", "celery -A holy_backend inspect ping -d celery@$$HOSTNAME || exit 1"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 30s - - beat: - build: - context: ./backend - container_name: holy-beat - command: celery -A holy_backend beat -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler --pidfile /tmp/celerybeat.pid - user: "app" - restart: unless-stopped - networks: - - holy-net - env_file: - - .env - environment: - - PYTHONUNBUFFERED=1 - - DOMAIN=${DOMAIN:-localhost} - - DJANGO_SETTINGS_MODULE=${DJANGO_SETTINGS_MODULE:-holy_backend.settings.prod} - - CELERY_BROKER_URL=${CELERY_BROKER_URL:-redis://redis:6379/0} - - CELERY_RESULT_BACKEND=${CELERY_RESULT_BACKEND:-redis://redis:6379/0} - - SKIP_INIT=true - volumes: - - ./backend:/app - - ./legacy:/app/legacy - depends_on: - redis: - condition: service_healthy - backend: - condition: service_healthy - healthcheck: - test: ["CMD-SHELL", "test -f /tmp/celerybeat.pid && kill -0 $$(cat /tmp/celerybeat.pid) || exit 1"] - interval: 30s - timeout: 5s - retries: 3 - start_period: 15s - - flower: - image: mher/flower:2.0 - container_name: holy-flower - restart: unless-stopped - command: celery --broker=${CELERY_BROKER_URL:-redis://redis:6379/0} flower --port=5555 - environment: - - CELERY_BROKER_URL=${CELERY_BROKER_URL:-redis://redis:6379/0} - - CELERY_RESULT_BACKEND=${CELERY_RESULT_BACKEND:-redis://redis:6379/0} - - FLOWER_BASIC_AUTH=${FLOWER_BASIC_AUTH:-admin:change-me} - ports: - - 5555 - networks: - - holy-net - depends_on: - redis: - condition: service_healthy - # --- Rust backend (strangler) -------------------------------------------- # Runs beside Django, sharing the SAME db.sqlite3, media/, banners/ and # legacy/ via bind mounts and the SAME SECRET_KEY (so SimpleJWT tokens verify @@ -170,10 +36,6 @@ services: volumes: - ./backend:/srv/backend - ./legacy:/srv/legacy - depends_on: - # Wait for Django to apply migrations / create the schema before reading it. - backend: - condition: service_healthy healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8001/health/"] interval: 10s @@ -204,9 +66,6 @@ services: # from either backend so Django can be retired without losing media. - ./backend/media:/usr/share/nginx/media:ro depends_on: - backend: - condition: service_healthy - # nginx resolves the rust upstream at startup, so the container must exist. backend-rs: condition: service_healthy @@ -216,4 +75,3 @@ networks: volumes: db_data: - redis_data: diff --git a/frontend/nginx.conf b/frontend/nginx.conf index 1d00716..d2c1a4a 100644 --- a/frontend/nginx.conf +++ b/frontend/nginx.conf @@ -14,10 +14,6 @@ # nginx; drop Django /admin/ + /static/ if unused. # ========================================================================= -upstream django_backend { - server holy-backend:8000; -} - upstream rust_backend { server holy-rust:8001; } @@ -38,40 +34,28 @@ server { # rust_backend on its proxy_pass line. # Phase 1 — read-only (safe to move first): - location /api/categories/ { proxy_pass http://django_backend; include /etc/nginx/proxy_params.conf; } - location /api/flavors/ { proxy_pass http://django_backend; include /etc/nginx/proxy_params.conf; } - location /api/banners/ { proxy_pass http://django_backend; include /etc/nginx/proxy_params.conf; } + location /api/categories/ { proxy_pass http://rust_backend; include /etc/nginx/proxy_params.conf; } + location /api/flavors/ { proxy_pass http://rust_backend; include /etc/nginx/proxy_params.conf; } + location /api/banners/ { proxy_pass http://rust_backend; include /etc/nginx/proxy_params.conf; } # Phase 2 — auth + writes: - location /api/auth/ { proxy_pass http://django_backend; include /etc/nginx/proxy_params.conf; } - location = /api/token/ { proxy_pass http://django_backend; include /etc/nginx/proxy_params.conf; } # legacy JWT alias - location /api/ratings/ { proxy_pass http://django_backend; include /etc/nginx/proxy_params.conf; } - location /api/replies/ { proxy_pass http://django_backend; include /etc/nginx/proxy_params.conf; } - location /api/users/ { proxy_pass http://django_backend; include /etc/nginx/proxy_params.conf; } - location /api/notifications/ { proxy_pass http://django_backend; include /etc/nginx/proxy_params.conf; } - location /api/tickets/ { proxy_pass http://django_backend; include /etc/nginx/proxy_params.conf; } + location /api/auth/ { proxy_pass http://rust_backend; include /etc/nginx/proxy_params.conf; } + location = /api/token/ { proxy_pass http://rust_backend; include /etc/nginx/proxy_params.conf; } # legacy JWT alias + location /api/ratings/ { proxy_pass http://rust_backend; include /etc/nginx/proxy_params.conf; } + location /api/replies/ { proxy_pass http://rust_backend; include /etc/nginx/proxy_params.conf; } + location /api/users/ { proxy_pass http://rust_backend; include /etc/nginx/proxy_params.conf; } + location /api/notifications/ { proxy_pass http://rust_backend; include /etc/nginx/proxy_params.conf; } + location /api/tickets/ { proxy_pass http://rust_backend; include /etc/nginx/proxy_params.conf; } # Phase 3 — admin + jobs (cut over, THEN flip the scheduler ownership): - location /api/admin-custom/ { proxy_pass http://django_backend; include /etc/nginx/proxy_params.conf; } + location /api/admin-custom/ { proxy_pass http://rust_backend; include /etc/nginx/proxy_params.conf; } # OpenAPI schema / Swagger UI (both backends serve these): - location /api/schema { proxy_pass http://django_backend; include /etc/nginx/proxy_params.conf; } + location /api/schema { proxy_pass http://rust_backend; include /etc/nginx/proxy_params.conf; } # Catch-all: anything not explicitly cut over stays on Django. location /api/ { - proxy_pass http://django_backend; - include /etc/nginx/proxy_params.conf; - } - - # --- Django-only paths (retire last) --------------------------------- - # Django admin site + its static assets. The app's own admin UI uses - # /api/admin-custom/, so these are only the Django admin site + DRF UI. - location /admin/ { - proxy_pass http://django_backend; - include /etc/nginx/proxy_params.conf; - } - location /static/ { - proxy_pass http://django_backend; + proxy_pass http://rust_backend; include /etc/nginx/proxy_params.conf; }