Replace generated archive download response with FileResponse streaming so ZIP files are not fully loaded into process memory. Move monthly archive task output to a temporary file and upload that file to storage, and write invoice attachments into ZIP archives in chunks. Add Celery memory guard settings, a memory-aware base task hook, and periodic /tmp cleanup for prefixed archive files older than one day. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
128 lines
3.0 KiB
YAML
128 lines
3.0 KiB
YAML
services:
|
|
db:
|
|
restart: unless-stopped
|
|
|
|
redis:
|
|
restart: unless-stopped
|
|
|
|
backend:
|
|
build:
|
|
context: ./backend
|
|
dockerfile: Dockerfile
|
|
container_name: 004erpbackend
|
|
restart: unless-stopped
|
|
env_file:
|
|
- .env
|
|
environment:
|
|
DJANGO_SETTINGS_MODULE: core.settings.production
|
|
command: gunicorn core.wsgi:application --bind 0.0.0.0:8000 --workers 3 --timeout 120
|
|
volumes:
|
|
- media_volume:/app/media
|
|
ports:
|
|
- "8001:8000"
|
|
depends_on:
|
|
db:
|
|
condition: service_healthy
|
|
redis:
|
|
condition: service_started
|
|
|
|
worker:
|
|
build:
|
|
context: ./backend
|
|
dockerfile: Dockerfile
|
|
container_name: 004erpworker
|
|
restart: unless-stopped
|
|
env_file:
|
|
- .env
|
|
environment:
|
|
DEBUG: "False"
|
|
DJANGO_SETTINGS_MODULE: core.settings.production
|
|
CELERY_WORKER_PREFETCH_MULTIPLIER: "1"
|
|
CELERY_WORKER_MAX_TASKS_PER_CHILD: "20"
|
|
CELERY_WORKER_MAX_MEMORY_PER_CHILD: "350000"
|
|
APP_TMP_CLEANUP_DIR: "/tmp"
|
|
APP_TMP_CLEANUP_MAX_AGE_HOURS: "24"
|
|
APP_TMP_CLEANUP_PREFIXES: "erp-fleet-archive-"
|
|
command: celery -A core worker --loglevel=info --concurrency=${CELERY_WORKER_CONCURRENCY:-2}
|
|
volumes:
|
|
- media_volume:/app/media
|
|
depends_on:
|
|
db:
|
|
condition: service_healthy
|
|
redis:
|
|
condition: service_started
|
|
|
|
beat:
|
|
build:
|
|
context: ./backend
|
|
dockerfile: Dockerfile
|
|
container_name: 004erpbeat
|
|
restart: unless-stopped
|
|
env_file:
|
|
- .env
|
|
environment:
|
|
DEBUG: "False"
|
|
DJANGO_SETTINGS_MODULE: core.settings.production
|
|
command: celery -A core beat --loglevel=info
|
|
volumes:
|
|
- media_volume:/app/media
|
|
depends_on:
|
|
redis:
|
|
condition: service_started
|
|
worker:
|
|
condition: service_started
|
|
|
|
flower:
|
|
build:
|
|
context: ./backend
|
|
dockerfile: Dockerfile
|
|
container_name: 004erpflower
|
|
restart: unless-stopped
|
|
env_file:
|
|
- .env
|
|
environment:
|
|
DEBUG: "False"
|
|
DJANGO_SETTINGS_MODULE: core.settings.production
|
|
command: celery -A core flower --port=5555
|
|
ports:
|
|
- "5555:5555"
|
|
depends_on:
|
|
redis:
|
|
condition: service_started
|
|
worker:
|
|
condition: service_started
|
|
|
|
frontend:
|
|
build:
|
|
context: ./frontend
|
|
dockerfile: Dockerfile
|
|
container_name: 004erpfrontend
|
|
restart: unless-stopped
|
|
environment:
|
|
NODE_ENV: production
|
|
PUBLIC_API_URL: ${PUBLIC_API_URL}
|
|
command: sh -c "npm run build && node ./dist/server/entry.mjs"
|
|
ports:
|
|
- "4321:4321"
|
|
depends_on:
|
|
backend:
|
|
condition: service_started
|
|
|
|
webhook:
|
|
build: /opt/erp/deploy-webhook
|
|
container_name: 004erpwebhook
|
|
restart: unless-stopped
|
|
environment:
|
|
WEBHOOK_SECRET: ${GITEA_WEBHOOK_SECRET}
|
|
ports:
|
|
- "9001:9001"
|
|
volumes:
|
|
- /opt/erp/app:/opt/erp/app
|
|
- /var/run/docker.sock:/var/run/docker.sock
|
|
|
|
volumes:
|
|
postgres_data:
|
|
redis_data:
|
|
media_volume:
|
|
external: true
|