services: redis: image: redis:7.4.2-alpine restart: always volumes: - redis_data:/data healthcheck: test: ["CMD","redis-cli","ping"] interval: 10s timeout: 5s retries: 5 web: build: # build context is the repository root (one level up from this file) context: .. dockerfile: rad/Dockerfile.prod restart: always # Use COMPOSE_ENV to select which env file to load (defaults to 'prod'). # Example: COMPOSE_ENV=dev docker compose -f rad/docker/docker-compose.prod.yml -f rad/docker/docker-compose.dev.yml up -d env_file: - ../.env.${COMPOSE_ENV:-prod} environment: - DJANGO_SETTINGS_MODULE=rad.settings depends_on: redis: condition: service_healthy volumes: - static_volume:/usr/src/app/static - media_volume:/usr/src/app/media # Mount the server-specific local settings if present (DO NOT commit secrets). # On the server create: rad/deploy/settings_local.py and it will be mounted into the container. - ../deploy/settings_local.py:/usr/src/app/rad/settings_local.py:ro expose: - "8000" command: ["/usr/src/app/entrypoint.sh"] worker: build: context: .. dockerfile: rad/Dockerfile.prod restart: always env_file: - ../.env.${COMPOSE_ENV:-prod} environment: - DJANGO_SETTINGS_MODULE=rad.settings depends_on: redis: condition: service_healthy web: condition: service_started volumes: - ../deploy/settings_local.py:/usr/src/app/rad/settings_local.py:ro - ../logs:/var/log/rad:rw entrypoint: [ "sh", "-c", "python manage.py migrate --noinput && exec python manage.py db_worker", ] nginx: image: nginx:stable-alpine restart: always ports: - "${NGINX_HTTP_PORT:-80}:80" - "${NGINX_HTTPS_PORT:-443}:443" depends_on: - web volumes: - ../deploy/nginx/prod.conf:/etc/nginx/conf.d/default.conf:ro - ../logs:/var/log/rad:rw - static_volume:/usr/src/app/static:ro - media_volume:/usr/src/app/media:ro - ../deploy/nginx/certs:/etc/letsencrypt:ro # Host-provided front-end bundles and static folders. Populate these under rad/deploy on the server - ../deploy/www/viewer:/srv/www/viewer:ro - ../deploy/www/ohif:/srv/www/ohif:ro - ../deploy/www/rts:/srv/www/rts:ro - ../deploy/nicereporter:/srv/nicereporter:rw - ../deploy/proc-rota:/srv/proc/rota:ro - ../deploy/uploader:/srv/uploader:ro healthcheck: test: ["CMD-SHELL","nginx -t" ] interval: 30s timeout: 10s retries: 3 # Optional local observability stack (can be enabled on servers that # should run Loki/Grafana). These services use configs found under # the repository `docker/` directory so the same config works in dev. loki: image: grafana/loki:2.8.2 command: -config.file=/etc/loki/local-config.yaml ports: - "3100:3100" volumes: - ./loki-config/local-config.yaml:/etc/loki/local-config.yaml:ro - ../docker/loki-data:/loki # WAL directory: map a host folder so Loki (running as UID 10001) # can create the write-ahead log. Host folder created under # `docker/loki-wal` and owned by UID 10001. - ../docker/loki-wal:/wal restart: unless-stopped healthcheck: test: ["CMD-SHELL", "wget -qO- http://localhost:3100/ready || exit 1"] interval: 10s timeout: 5s retries: 6 promtail: image: grafana/promtail:2.8.2 volumes: # In prod you may want to point this at the host system log directory. - ../logs:/var/log/rad:ro - ./promtail-config.yml:/etc/promtail/promtail-config.yml:ro command: -config.file=/etc/promtail/promtail-config.yml depends_on: - loki restart: unless-stopped grafana: image: grafana/grafana:10.2.0 ports: - "3000:3000" environment: - GF_SECURITY_ADMIN_PASSWORD=admin volumes: - grafana-data:/var/lib/grafana depends_on: loki: condition: service_healthy restart: unless-stopped volumes: postgres_data: redis_data: static_volume: media_volume: grafana-data: networks: default: driver: bridge