140 lines
5.9 KiB
YAML
140 lines
5.9 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_API_URL: ${SMS0098_API_URL:-http://www.0098sms.com/sendsmslink.aspx}
|
|
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:-}
|
|
BALE_GROUP_CHAT_ID: ${BALE_GROUP_CHAT_ID:-}
|
|
INTEGRATION_HTTP_TIMEOUT_SECONDS: ${INTEGRATION_HTTP_TIMEOUT_SECONDS:-10}
|
|
MAX_NOTIFICATION_ATTEMPTS: ${MAX_NOTIFICATION_ATTEMPTS:-5}
|
|
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:
|
|
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:
|
|
- ./docker/nginx.conf:/etc/nginx/templates/default.conf.template:ro
|
|
- 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
|