From 477fd63860830ba5eaa1828ca9f394cc0252f83d Mon Sep 17 00:00:00 2001 From: Amirhossein Khalili Date: Sun, 21 Jun 2026 01:39:57 +0330 Subject: [PATCH] chore(deploy): add compose runtime stack --- .env.sample | 12 +++++++ docker-compose.yml | 84 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 .env.sample create mode 100644 docker-compose.yml diff --git a/.env.sample b/.env.sample new file mode 100644 index 0000000..76024d2 --- /dev/null +++ b/.env.sample @@ -0,0 +1,12 @@ +POSTGRES_DB=job_queue +POSTGRES_USER=postgres +POSTGRES_PASSWORD=postgres +POSTGRES_PORT=5432 +JOB_WORKER_THREADS=4 +JOB_WORKER_POLL_INTERVAL_MS=500 +JOB_WORKER_LEASE_SECONDS=30 +JOB_WORKER_CLEANUP_INTERVAL_SECONDS=5 +JOB_WORKER_CLEANUP_BATCH_SIZE=100 +JOB_WORKER_BACKOFF_BASE_SECONDS=5 +JOB_WORKER_BACKOFF_MAX_SECONDS=300 +JOB_WORKER_MAX_ATTEMPTS_DEFAULT=3 diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..7ad0a56 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,84 @@ +services: + postgres: + image: postgres:17-alpine + environment: + POSTGRES_DB: ${POSTGRES_DB:-job_queue} + POSTGRES_USER: ${POSTGRES_USER:-postgres} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres} + ports: + - "${POSTGRES_PORT:-5432}:5432" + volumes: + - postgres_data:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-postgres} -d ${POSTGRES_DB:-job_queue}"] + interval: 5s + timeout: 5s + retries: 10 + + backend: + image: minimal-job-queue-backend:latest + build: + context: ./backend + command: sh -c "python manage.py migrate && python manage.py runserver 0.0.0.0:8000" + environment: + DEBUG: "true" + DJANGO_ALLOWED_HOSTS: localhost,127.0.0.1,0.0.0.0 + DJANGO_CORS_ALLOWED_ORIGINS: http://localhost:5173,http://127.0.0.1:5173 + POSTGRES_DB: ${POSTGRES_DB:-job_queue} + POSTGRES_USER: ${POSTGRES_USER:-postgres} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres} + POSTGRES_HOST: postgres + POSTGRES_PORT: 5432 + JOB_WORKER_MAX_ATTEMPTS_DEFAULT: ${JOB_WORKER_MAX_ATTEMPTS_DEFAULT:-3} + JOB_WORKER_LEASE_SECONDS: ${JOB_WORKER_LEASE_SECONDS:-30} + JOB_WORKER_BACKOFF_BASE_SECONDS: ${JOB_WORKER_BACKOFF_BASE_SECONDS:-5} + JOB_WORKER_BACKOFF_MAX_SECONDS: ${JOB_WORKER_BACKOFF_MAX_SECONDS:-300} + ports: + - "8000:8000" + depends_on: + postgres: + condition: service_healthy + healthcheck: + test: + [ + "CMD-SHELL", + "python -c \"import urllib.request; urllib.request.urlopen('http://localhost:8000/api/health/', timeout=2)\"", + ] + interval: 5s + timeout: 5s + retries: 20 + + worker: + image: minimal-job-queue-backend:latest + pull_policy: never + command: python manage.py run_job_workers + environment: + DEBUG: "false" + POSTGRES_DB: ${POSTGRES_DB:-job_queue} + POSTGRES_USER: ${POSTGRES_USER:-postgres} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres} + POSTGRES_HOST: postgres + POSTGRES_PORT: 5432 + JOB_WORKER_THREADS: ${JOB_WORKER_THREADS:-4} + JOB_WORKER_POLL_INTERVAL_MS: ${JOB_WORKER_POLL_INTERVAL_MS:-500} + JOB_WORKER_LEASE_SECONDS: ${JOB_WORKER_LEASE_SECONDS:-30} + JOB_WORKER_CLEANUP_INTERVAL_SECONDS: ${JOB_WORKER_CLEANUP_INTERVAL_SECONDS:-5} + JOB_WORKER_CLEANUP_BATCH_SIZE: ${JOB_WORKER_CLEANUP_BATCH_SIZE:-100} + JOB_WORKER_BACKOFF_BASE_SECONDS: ${JOB_WORKER_BACKOFF_BASE_SECONDS:-5} + JOB_WORKER_BACKOFF_MAX_SECONDS: ${JOB_WORKER_BACKOFF_MAX_SECONDS:-300} + JOB_WORKER_MAX_ATTEMPTS_DEFAULT: ${JOB_WORKER_MAX_ATTEMPTS_DEFAULT:-3} + depends_on: + backend: + condition: service_healthy + + frontend: + build: + context: ./frontend + ports: + - "5173:80" + depends_on: + backend: + condition: service_healthy + +volumes: + postgres_data: