services: db: image: docker.io/postgres:16-alpine environment: POSTGRES_DB: ${POSTGRES_DB:-access_core} POSTGRES_USER: ${POSTGRES_USER:-access_user} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-dev_password_synthetic_only} ports: - "${POSTGRES_PORT:-5432}:5432" volumes: - pgdata:/var/lib/postgresql/data - ./scripts/init_db.sh:/docker-entrypoint-initdb.d/init_db.sh healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-access_user} -d ${POSTGRES_DB:-access_core}"] interval: 5s timeout: 3s retries: 5 networks: - access_net django: build: context: . dockerfile: Dockerfile command: > sh -c "python manage.py migrate --noinput && python manage.py loaddata sample_data/fixtures/*.json || true && python manage.py runserver 0.0.0.0:8000" environment: DJANGO_SETTINGS_MODULE: access_core.settings.dev DJANGO_SECRET_KEY: ${DJANGO_SECRET_KEY:-dev-secret-key-DO-NOT-USE-IN-PRODUCTION} DJANGO_DEBUG: "true" ALLOWED_HOSTS: "*" # Container-side DB host is always the `db` service; .env POSTGRES_HOST # applies to host-side processes only. POSTGRES_DB: ${POSTGRES_DB:-access_core} POSTGRES_USER: ${POSTGRES_USER:-access_user} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-dev_password_synthetic_only} POSTGRES_HOST: db HEALTHIE_API_BASE_URL: ${HEALTHIE_API_BASE_URL:-https://api.gethealthie.com/graphql} HEALTHIE_API_KEY: ${HEALTHIE_API_KEY:-} HEALTHIE_INTAKE_FORM_ID: ${HEALTHIE_INTAKE_FORM_ID:-2360739} HEALTHIE_WEBHOOK_SECRET: ${HEALTHIE_WEBHOOK_SECRET:-dev-webhook-secret} HEALTHIE_WEBHOOK_VERIFY_SIGNATURE: ${HEALTHIE_WEBHOOK_VERIFY_SIGNATURE:-true} CMS_API_BASE_URL: ${CMS_API_BASE_URL:-https://sandbox.bcda.cms.gov} CMS_API_CLIENT_ID: ${CMS_API_CLIENT_ID:-dev-client-id} CMS_API_CLIENT_SECRET: ${CMS_API_CLIENT_SECRET:-dev-client-secret} CMS_FHIR_VERSION_PATH: ${CMS_FHIR_VERSION_PATH:-R4} # URL path templates; empty = built-in defaults (manual's shapes). When pointing # at the mock server, set the query-param status form: # /fhir/Patient/$submission-status?submissionID={submission_id} CMS_API_POST_PATH: ${CMS_API_POST_PATH:-} CMS_API_SUBMISSION_STATUS_PATH: ${CMS_API_SUBMISSION_STATUS_PATH:-} ports: - "8000:8000" volumes: - ./access_core:/app/access_core - ./sample_data/fixtures:/app/sample_data/fixtures depends_on: db: condition: service_healthy networks: - access_net # Single consumer for all CMS ACCESS API $submission-status polling. Dev ECS # runs with enable_worker=false, so local compose provides it here with a fast # poll cadence (override via .env to slow down). cms-worker: build: context: . dockerfile: Dockerfile command: > sh -c "python manage.py migrate --noinput && python manage.py cms_polling_worker" environment: DJANGO_SETTINGS_MODULE: access_core.settings.dev DJANGO_SECRET_KEY: ${DJANGO_SECRET_KEY:-dev-secret-key-DO-NOT-USE-IN-PRODUCTION} DJANGO_DEBUG: "true" ALLOWED_HOSTS: "*" POSTGRES_DB: ${POSTGRES_DB:-access_core} POSTGRES_USER: ${POSTGRES_USER:-access_user} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-dev_password_synthetic_only} POSTGRES_HOST: db CMS_API_BASE_URL: ${CMS_API_BASE_URL:-https://sandbox.bcda.cms.gov} CMS_API_CLIENT_ID: ${CMS_API_CLIENT_ID:-dev-client-id} CMS_API_CLIENT_SECRET: ${CMS_API_CLIENT_SECRET:-dev-client-secret} CMS_FHIR_VERSION_PATH: ${CMS_FHIR_VERSION_PATH:-R4} CMS_API_POST_PATH: ${CMS_API_POST_PATH:-} CMS_API_SUBMISSION_STATUS_PATH: ${CMS_API_SUBMISSION_STATUS_PATH:-} CMS_POLL_INTERVAL_SECONDS: ${CMS_POLL_INTERVAL_SECONDS:-1} CMS_POLL_LOOP_SECONDS: ${CMS_POLL_LOOP_SECONDS:-2} volumes: - ./access_core:/app/access_core depends_on: db: condition: service_healthy networks: - access_net # Mirrors .github/workflows/ci.yml: same settings module (base) and the same # Postgres-backed flow, so local results match CI. tests: build: context: . dockerfile: Dockerfile command: sh -c "python manage.py test access_core/ --verbosity 1" environment: DJANGO_SETTINGS_MODULE: access_core.settings.base DJANGO_SECRET_KEY: ${DJANGO_SECRET_KEY:-dev-secret-key-DO-NOT-USE-IN-PRODUCTION} DJANGO_DEBUG: "true" POSTGRES_DB: access_core_test POSTGRES_USER: ${POSTGRES_USER:-access_user} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-dev_password_synthetic_only} POSTGRES_HOST: db # Deterministic test-only key (same value as access_core/settings/test.py). PHI_LOCAL_ENCRYPTION_KEY: VcTbV55bLdCaKgpV1ihnVkTQkP4hj4I2nY/bfEexS0g= volumes: - ./access_core:/app/access_core - ./sample_data/fixtures:/app/sample_data/fixtures depends_on: db: condition: service_healthy cms-mock: build: context: ./access_fhir_sandbox dockerfile: Dockerfile environment: MOCK_PORT: ${CMS_MOCK_PORT:-3001} LOCK_IN_DAYS: ${CMS_LOCK_IN_DAYS:-90} BASELINE_WINDOW_DAYS: ${CMS_BASELINE_WINDOW_DAYS:-60} ASYNC_DELAY_MS: ${CMS_ASYNC_DELAY_MS:-500} # Host side is pinned to 3001 (the port the rest of the stack expects); # the container-side port follows CMS_MOCK_PORT. ports: - "3001:${CMS_MOCK_PORT:-3001}" healthcheck: test: ["CMD-SHELL", "wget -qO- http://localhost:${CMS_MOCK_PORT:-3001}/fhir/metadata"] interval: 5s timeout: 3s retries: 10 start_period: 10s networks: - access_net volumes: pgdata: networks: access_net: driver: bridge