name: ${COMPOSE_PROJECT_NAME:-recruitment-hc} services: app: build: &app-build context: . dockerfile: Dockerfile restart: unless-stopped init: true ports: - "${APP_BIND_IP:-127.0.0.1}:${APP_PORT:-8086}:80" environment: &app-environment MYSQL_HOST: db MYSQL_PORT: "3306" MYSQL_DATABASE: ${MYSQL_DATABASE:-recruitment} MYSQL_USER: ${MYSQL_USER:-recruitment} MYSQL_PASSWORD: ${MYSQL_PASSWORD:?Set MYSQL_PASSWORD} REC_PASS_SCORE: ${REC_PASS_SCORE:-300} TZ: Asia/Jakarta depends_on: migrate: condition: service_completed_successfully volumes: - php_sessions:/var/lib/php/sessions healthcheck: test: ["CMD", "php", "/usr/local/bin/recruitment-healthcheck.php"] interval: 30s timeout: 5s start_period: 30s retries: 3 logging: driver: json-file options: max-size: "10m" max-file: "3" db: image: mysql:8.4 restart: unless-stopped environment: MYSQL_DATABASE: ${MYSQL_DATABASE:-recruitment} MYSQL_USER: ${MYSQL_USER:-recruitment} MYSQL_PASSWORD: ${MYSQL_PASSWORD:?Set MYSQL_PASSWORD} MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:?Set MYSQL_ROOT_PASSWORD} TZ: Asia/Jakarta volumes: - mysql_data:/var/lib/mysql healthcheck: test: - CMD-SHELL - >- MYSQL_PWD="$${MYSQL_ROOT_PASSWORD}" mysql --protocol=TCP -h 127.0.0.1 -u root -Nse "SELECT 1" >/dev/null 2>&1 interval: 10s timeout: 5s start_period: 60s retries: 12 logging: driver: json-file options: max-size: "10m" max-file: "3" # One-shot services: never run the destructive dump as an app entrypoint. db-init: image: mysql:8.4 restart: "no" entrypoint: ["sh", "/bootstrap/init-db.sh"] environment: *app-environment depends_on: db: condition: service_healthy volumes: - type: bind source: ./docker/init-db.sh target: /bootstrap/init-db.sh read_only: true bind: create_host_path: false - type: bind source: ${DB_INIT_SQL_PATH:-./DB/recruitment_local_2026-10-14.sql} target: /bootstrap/initial.sql read_only: true bind: create_host_path: false migrate: build: *app-build restart: "no" command: ["php", "/usr/local/share/recruitment/migrate.php"] environment: *app-environment depends_on: db-init: condition: service_completed_successfully # This service exits after migration; it is not an Apache server. healthcheck: disable: true phpmyadmin: image: phpmyadmin:5.2-apache restart: unless-stopped ports: - "${PHPMYADMIN_BIND_IP:-127.0.0.1}:${PHPMYADMIN_PORT:-8087}:80" environment: PMA_HOST: db PMA_PORT: "3306" PMA_ABSOLUTE_URI: ${PMA_ABSOLUTE_URI:-} UPLOAD_LIMIT: ${PHPMYADMIN_UPLOAD_LIMIT:-64M} HIDE_PHP_VERSION: "true" TZ: Asia/Jakarta depends_on: db: condition: service_healthy volumes: - phpmyadmin_sessions:/sessions healthcheck: test: - CMD-SHELL - curl --fail --silent --max-time 3 http://127.0.0.1/ > /dev/null interval: 30s timeout: 5s start_period: 30s retries: 3 logging: driver: json-file options: max-size: "10m" max-file: "3" volumes: mysql_data: php_sessions: phpmyadmin_sessions: