x-custom-image: &custom_image image: ${IMAGE_NAME:-docker.io/frappe/erpnext}:${VERSION:-version-15} pull_policy: ${PULL_POLICY:-always} deploy: restart_policy: condition: always services: backend: <<: *custom_image volumes: - sites:/home/frappe/frappe-bench/sites networks: - bench-network healthcheck: test: - CMD - wait-for-it - '0.0.0.0:8000' interval: 2s timeout: 10s retries: 30 frontend: <<: *custom_image command: - nginx-entrypoint.sh depends_on: backend: condition: service_started required: true websocket: condition: service_started required: true environment: BACKEND: backend:8000 FRAPPE_SITE_NAME_HEADER: ${FRAPPE_SITE_NAME_HEADER:-$$host} SOCKETIO: websocket:9000 UPSTREAM_REAL_IP_ADDRESS: 127.0.0.1 UPSTREAM_REAL_IP_HEADER: X-Forwarded-For UPSTREAM_REAL_IP_RECURSIVE: "off" volumes: - sites:/home/frappe/frappe-bench/sites networks: - bench-network healthcheck: test: - CMD - wait-for-it - '0.0.0.0:8080' interval: 2s timeout: 30s retries: 30 queue-default: <<: *custom_image command: - bench - worker - --queue - default volumes: - sites:/home/frappe/frappe-bench/sites networks: - bench-network healthcheck: test: - CMD - wait-for-it - 'redis-queue:6379' interval: 2s timeout: 10s retries: 30 depends_on: configurator: condition: service_completed_successfully required: true queue-long: <<: *custom_image command: - bench - worker - --queue - long volumes: - sites:/home/frappe/frappe-bench/sites networks: - bench-network healthcheck: test: - CMD - wait-for-it - 'redis-queue:6379' interval: 2s timeout: 10s retries: 30 depends_on: configurator: condition: service_completed_successfully required: true queue-short: <<: *custom_image command: - bench - worker - --queue - short volumes: - sites:/home/frappe/frappe-bench/sites networks: - bench-network healthcheck: test: - CMD - wait-for-it - 'redis-queue:6379' interval: 2s timeout: 10s retries: 30 depends_on: configurator: condition: service_completed_successfully required: true scheduler: <<: *custom_image healthcheck: test: - CMD - wait-for-it - 'redis-queue:6379' interval: 2s timeout: 10s retries: 30 command: - bench - schedule depends_on: configurator: condition: service_completed_successfully required: true volumes: - sites:/home/frappe/frappe-bench/sites networks: - bench-network websocket: <<: *custom_image healthcheck: test: - CMD - wait-for-it - '0.0.0.0:9000' interval: 2s timeout: 10s retries: 30 command: - node - /home/frappe/frappe-bench/apps/frappe/socketio.js depends_on: configurator: condition: service_completed_successfully required: true volumes: - sites:/home/frappe/frappe-bench/sites networks: - bench-network configurator: <<: *custom_image deploy: mode: replicated replicas: ${CONFIGURE:-0} restart_policy: condition: none entrypoint: ["bash", "-c"] command: - > [[ $${REGENERATE_APPS_TXT} == "1" ]] && ls -1 apps > sites/apps.txt; [[ -n `grep -hs ^ sites/common_site_config.json | jq -r ".db_host // empty"` ]] && exit 0; bench set-config -g db_host $$DB_HOST; bench set-config -gp db_port $$DB_PORT; bench set-config -g redis_cache "redis://$$REDIS_CACHE"; bench set-config -g redis_queue "redis://$$REDIS_QUEUE"; bench set-config -g redis_socketio "redis://$$REDIS_QUEUE"; bench set-config -gp socketio_port $$SOCKETIO_PORT; environment: DB_HOST: "${DB_HOST:-db}" DB_PORT: "3306" REDIS_CACHE: redis-cache:6379 REDIS_QUEUE: redis-queue:6379 SOCKETIO_PORT: "9000" REGENERATE_APPS_TXT: "${REGENERATE_APPS_TXT:-0}" volumes: - sites:/home/frappe/frappe-bench/sites networks: - bench-network create-site: <<: *custom_image deploy: mode: replicated replicas: ${CREATE_SITE:-0} restart_policy: condition: none entrypoint: ["bash", "-c"] command: - > wait-for-it -t 120 $$DB_HOST:$$DB_PORT; wait-for-it -t 120 redis-cache:6379; wait-for-it -t 120 redis-queue:6379; export start=`date +%s`; until [[ -n `grep -hs ^ sites/common_site_config.json | jq -r ".db_host // empty"` ]] && \ [[ -n `grep -hs ^ sites/common_site_config.json | jq -r ".redis_cache // empty"` ]] && \ [[ -n `grep -hs ^ sites/common_site_config.json | jq -r ".redis_queue // empty"` ]]; do echo "Waiting for sites/common_site_config.json to be created"; sleep 5; if (( `date +%s`-start > 120 )); then echo "could not find sites/common_site_config.json with required keys"; exit 1 fi done; echo "sites/common_site_config.json found"; [[ -d "sites/${SITE_NAME}" ]] && echo "${SITE_NAME} already exists" && exit 0; bench new-site --mariadb-user-host-login-scope='%' --admin-password=$${ADMIN_PASSWORD} --db-root-username=root --db-root-password=$${DB_ROOT_PASSWORD} $${INSTALL_APP_ARGS} $${SITE_NAME}; volumes: - sites:/home/frappe/frappe-bench/sites environment: SITE_NAME: ${SITE_NAME} ADMIN_PASSWORD: ${ADMIN_PASSWORD} DB_HOST: ${DB_HOST:-db} DB_PORT: "${DB_PORT:-3306}" DB_ROOT_PASSWORD: ${DB_ROOT_PASSWORD} INSTALL_APP_ARGS: ${INSTALL_APP_ARGS} networks: - bench-network migration: <<: *custom_image deploy: mode: replicated replicas: ${MIGRATE:-0} restart_policy: condition: none entrypoint: ["bash", "-c"] command: - > curl -f http://${SITE_NAME}:8080/api/method/ping || echo "Site busy" && exit 0; bench --site all set-config -p maintenance_mode 1; bench --site all set-config -p pause_scheduler 1; bench --site all migrate; bench --site all set-config -p maintenance_mode 0; bench --site all set-config -p pause_scheduler 0; volumes: - sites:/home/frappe/frappe-bench/sites networks: - bench-network db: image: mariadb:10.6 deploy: mode: replicated replicas: ${ENABLE_DB:-0} restart_policy: condition: always healthcheck: test: mysqladmin ping -h localhost --password=${DB_ROOT_PASSWORD} interval: 1s retries: 20 command: - --character-set-server=utf8mb4 - --collation-server=utf8mb4_unicode_ci - --skip-character-set-client-handshake - --skip-innodb-read-only-compressed environment: - MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD} - MARIADB_ROOT_PASSWORD=${DB_ROOT_PASSWORD} volumes: - db-data:/var/lib/mysql networks: - bench-network redis-cache: deploy: restart_policy: condition: always image: redis:6.2-alpine volumes: - redis-cache-data:/data networks: - bench-network healthcheck: test: - CMD - redis-cli - ping interval: 5s timeout: 5s retries: 3 redis-queue: deploy: restart_policy: condition: always image: redis:6.2-alpine volumes: - redis-queue-data:/data networks: - bench-network healthcheck: test: - CMD - redis-cli - ping interval: 5s timeout: 5s retries: 3 redis-socketio: deploy: restart_policy: condition: always image: redis:6.2-alpine volumes: - redis-socketio-data:/data networks: - bench-network healthcheck: test: - CMD - redis-cli - ping interval: 5s timeout: 5s retries: 3 volumes: db-data: redis-cache-data: redis-queue-data: redis-socketio-data: sites: driver_opts: type: "${SITE_VOLUME_TYPE}" o: "${SITE_VOLUME_OPTS}" device: "${SITE_VOLUME_DEV}" networks: bench-network: