Files
customerTicket/docker-compose.yml
2026-09-16 14:16:05 +03:30

148 lines
6.3 KiB
YAML

x-django-service: &django-service
build:
context: .
dockerfile: Dockerfile
restart: unless-stopped
init: true
networks:
- coolify
environment: &django-environment
DJANGO_SETTINGS_MODULE: config.settings.prod
DJANGO_SECRET_KEY: ${DJANGO_SECRET_KEY:?Set DJANGO_SECRET_KEY in Coolify}
DJANGO_ALLOWED_HOSTS: ${DJANGO_ALLOWED_HOSTS:?Set DJANGO_ALLOWED_HOSTS in Coolify}
CSRF_TRUSTED_ORIGINS: ${CSRF_TRUSTED_ORIGINS:?Set CSRF_TRUSTED_ORIGINS in Coolify}
PUBLIC_BASE_URL: ${PUBLIC_BASE_URL:?Set PUBLIC_BASE_URL in Coolify}
WEBOTP_HOST: ${WEBOTP_HOST:-}
TIME_ZONE: ${TIME_ZONE:-Asia/Tehran}
DATABASE_URL: ${DATABASE_URL:-}
POSTGRES_DB: ${POSTGRES_DB:-customerTicket}
POSTGRES_USER: ${POSTGRES_USER:-postgres}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-}
POSTGRES_HOST: ${POSTGRES_HOST:-}
POSTGRES_PORT: ${POSTGRES_PORT:-5432}
DB_CONN_MAX_AGE: ${DB_CONN_MAX_AGE:-60}
DB_CONNECT_TIMEOUT: ${DB_CONNECT_TIMEOUT:-10}
DB_SSLMODE: ${DB_SSLMODE:-prefer}
DATABASE_WAIT_TIMEOUT: ${DATABASE_WAIT_TIMEOUT:-60}
PRODUCTION_SEED_DIR: /app/production-seed
REQUIRE_PRODUCTION_SEED: ${REQUIRE_PRODUCTION_SEED:-1}
MEDIA_ROOT: /app/media
MEDIA_SIGNING_SECRET: ${MEDIA_SIGNING_SECRET:?}
USE_NGINX_MEDIA: "true"
SMS_PROVIDER_CLASS: ${SMS_PROVIDER_CLASS:-apps.integrations.sms.sms0098.ZeroZeroNinetyEightSMSProvider}
SMS0098_USERNAME: ${SMS0098_USERNAME:-}
SMS0098_PASSWORD: ${SMS0098_PASSWORD:-}
SMS0098_FROM: ${SMS0098_FROM:-}
SMS0098_WSDL_URL: ${SMS0098_WSDL_URL:-https://webservice.0098sms.com/service.asmx?WSDL}
BEHIN_SMS_USERNAME: ${BEHIN_SMS_USERNAME:-}
BEHIN_SMS_PASSWORD: ${BEHIN_SMS_PASSWORD:-}
BEHIN_SMS_SPECIAL_NUMBER: ${BEHIN_SMS_SPECIAL_NUMBER:-}
BEHIN_SMS_WSDL_URL: ${BEHIN_SMS_WSDL_URL:-http://panel.behinsms.com/SMSWS/SOAP.asmx?wsdl}
SMS_API_URL: ${SMS_API_URL:-}
SMS_API_TOKEN: ${SMS_API_TOKEN:-}
SMS_SENDER: ${SMS_SENDER:-}
BALE_API_BASE: ${BALE_API_BASE:-https://tapi.bale.ai}
BALE_BOT_TOKEN: ${BALE_BOT_TOKEN:-}
INTEGRATION_HTTP_TIMEOUT_SECONDS: ${INTEGRATION_HTTP_TIMEOUT_SECONDS:-10}
MAX_NOTIFICATION_ATTEMPTS: ${MAX_NOTIFICATION_ATTEMPTS:-5}
SMS_MAX_RETRIES: ${SMS_MAX_RETRIES:-3}
SMS_RETRY_DELAY_SECONDS: ${SMS_RETRY_DELAY_SECONDS:-180}
SMS_DELIVERY_CHECK_DELAY_SECONDS: ${SMS_DELIVERY_CHECK_DELAY_SECONDS:-180}
SMS_DELIVERY_MAX_CHECKS: ${SMS_DELIVERY_MAX_CHECKS:-15}
SMS_DEFINITIVE_DELIVERY_RETRY_AFTER_SECONDS: ${SMS_DEFINITIVE_DELIVERY_RETRY_AFTER_SECONDS:-2700}
SMS_HISTORICAL_DELIVERY_RETRY_STAGGER_SECONDS: ${SMS_HISTORICAL_DELIVERY_RETRY_STAGGER_SECONDS:-30}
SECURE_SSL_REDIRECT: ${SECURE_SSL_REDIRECT:-true}
SECURE_HSTS_SECONDS: ${SECURE_HSTS_SECONDS:-31536000}
SECURE_HSTS_INCLUDE_SUBDOMAINS: ${SECURE_HSTS_INCLUDE_SUBDOMAINS:-true}
SECURE_HSTS_PRELOAD: ${SECURE_HSTS_PRELOAD:-false}
services:
web:
<<: *django-service
environment:
<<: *django-environment
RUN_STARTUP_TASKS: "1"
expose:
- "8000"
volumes:
- static_data:/app/staticfiles
- media_data:/app/media
- seed_data:/app/production-seed:ro
healthcheck:
test: ["CMD", "python", "-c", "import http.client,os; c=http.client.HTTPConnection('127.0.0.1',8000,timeout=5); c.request('GET','/healthz/',headers={'Host':os.getenv('HEALTHCHECK_HOST','localhost'),'X-Forwarded-Proto':'https'}); r=c.getresponse(); raise SystemExit(0 if r.status==200 else 1)"]
interval: 15s
timeout: 7s
retries: 8
start_period: 45s
stop_grace_period: 35s
notification-worker:
<<: *django-service
command: ["python", "manage.py", "process_notifications"]
depends_on:
web:
condition: service_healthy
volumes:
- media_data:/app/media
stop_grace_period: 20s
nginx:
build:
context: .
dockerfile: Dockerfile.nginx
args:
NGINX_IMAGE: ${NGINX_IMAGE:-nginx:1.27-alpine}
restart: unless-stopped
networks:
- coolify
labels:
# Coolify generates the Host/PathPrefix/TLS rules from the three nginx
# Domains entries. Pin those generated routers to this container and give
# them precedence over web's catch-all PathPrefix(`/`) router.
- "traefik.enable=true"
- "traefik.docker.network=${COOLIFY_RESOURCE_UUID:?}"
- "traefik.http.services.customer-ticket-assets-${COOLIFY_RESOURCE_UUID:?}.loadbalancer.server.port=80"
- "traefik.http.routers.http-0-${COOLIFY_RESOURCE_UUID:?}-nginx.priority=10000"
- "traefik.http.routers.http-0-${COOLIFY_RESOURCE_UUID:?}-nginx.service=customer-ticket-assets-${COOLIFY_RESOURCE_UUID:?}"
- "traefik.http.routers.http-1-${COOLIFY_RESOURCE_UUID:?}-nginx.priority=10000"
- "traefik.http.routers.http-1-${COOLIFY_RESOURCE_UUID:?}-nginx.service=customer-ticket-assets-${COOLIFY_RESOURCE_UUID:?}"
- "traefik.http.routers.http-2-${COOLIFY_RESOURCE_UUID:?}-nginx.priority=10000"
- "traefik.http.routers.http-2-${COOLIFY_RESOURCE_UUID:?}-nginx.service=customer-ticket-assets-${COOLIFY_RESOURCE_UUID:?}"
- "traefik.http.routers.https-0-${COOLIFY_RESOURCE_UUID:?}-nginx.priority=10000"
- "traefik.http.routers.https-0-${COOLIFY_RESOURCE_UUID:?}-nginx.service=customer-ticket-assets-${COOLIFY_RESOURCE_UUID:?}"
- "traefik.http.routers.https-1-${COOLIFY_RESOURCE_UUID:?}-nginx.priority=10000"
- "traefik.http.routers.https-1-${COOLIFY_RESOURCE_UUID:?}-nginx.service=customer-ticket-assets-${COOLIFY_RESOURCE_UUID:?}"
- "traefik.http.routers.https-2-${COOLIFY_RESOURCE_UUID:?}-nginx.priority=10000"
- "traefik.http.routers.https-2-${COOLIFY_RESOURCE_UUID:?}-nginx.service=customer-ticket-assets-${COOLIFY_RESOURCE_UUID:?}"
expose:
- "80"
depends_on:
web:
condition: service_healthy
volumes:
- static_data:/app/staticfiles:ro
- media_data:/app/media:ro
environment:
MEDIA_SIGNING_SECRET: ${MEDIA_SIGNING_SECRET:?}
healthcheck:
test: ["CMD-SHELL", "wget -q -O /dev/null http://127.0.0.1/healthz/ || exit 1"]
interval: 15s
timeout: 7s
retries: 5
start_period: 10s
volumes:
static_data:
external: true
name: ${STATIC_VOLUME_NAME:-customer_ticket_static}
media_data:
external: true
name: ${MEDIA_VOLUME_NAME:-customer_ticket_media}
seed_data:
external: true
name: ${SEED_VOLUME_NAME:-customer_ticket_seed}
networks:
coolify:
external: true