Skip to content

Instantly share code, notes, and snippets.

@victor-abz
Forked from NagariaHussain/frappe-learning.yml
Created September 20, 2025 15:02
Show Gist options
  • Select an option

  • Save victor-abz/3e2bc65ed2384f703110da7d09a26efb to your computer and use it in GitHub Desktop.

Select an option

Save victor-abz/3e2bc65ed2384f703110da7d09a26efb to your computer and use it in GitHub Desktop.

Revisions

  1. @NagariaHussain NagariaHussain revised this gist Jan 26, 2025. No changes.
  2. @NagariaHussain NagariaHussain revised this gist Jan 26, 2025. 1 changed file with 38 additions and 87 deletions.
    125 changes: 38 additions & 87 deletions frappe-learning.yml
    Original file line number Diff line number Diff line change
    @@ -1,15 +1,33 @@
    name: learning_prod_setup_done
    # documentation: https://docs.frappe.io/learning
    # slogan: Easy to Use, 100% Open Source Learning Management System.
    # tags: lms, self-hosted, dashboard
    # logo: svgs/frappe-learning.svg
    # port: 8080

    name: frappe-learning
    version: '3.8'

    x-frappe-app-image: &frappe-app-image ghcr.io/frappe/lms:stable
    x-frappe-app-common: &frappe-app-common
    image: *frappe-app-image
    platform: linux/amd64
    pull_policy: missing
    volumes:
    - sites:/home/frappe/frappe-bench/sites
    x-depends-on-configurator:
    depends_on:
    configurator:
    condition: service_completed_successfully

    services:
    backend:
    <<: *frappe-app-common
    depends_on:
    configurator:
    condition: service_completed_successfully
    required: true
    image: 'ghcr.io/frappe/lms:stable'
    networks:
    default: null
    platform: linux/amd64
    pull_policy: missing
    healthcheck:
    test:
    - CMD
    @@ -18,12 +36,6 @@ services:
    interval: 2s
    timeout: 10s
    retries: 30
    volumes:
    -
    type: volume
    source: sites
    target: /home/frappe/frappe-bench/sites
    volume: { }
    db:
    command:
    - '--character-set-server=utf8mb4'
    @@ -84,6 +96,7 @@ services:
    target: /data
    volume: { }
    configurator:
    <<: *frappe-app-common
    restart: 'no'
    exclude_from_hc: true
    command:
    @@ -108,18 +121,10 @@ services:
    REDIS_CACHE: 'redis-cache:6379'
    REDIS_QUEUE: 'redis-queue:6379'
    SOCKETIO_PORT: '9000'
    image: 'ghcr.io/frappe/lms:stable'
    networks:
    default: null
    platform: linux/amd64
    pull_policy: missing
    volumes:
    -
    type: volume
    source: sites
    target: /home/frappe/frappe-bench/sites
    volume: { }
    scheduler:
    <<: *frappe-app-common
    healthcheck:
    test:
    - CMD
    @@ -135,23 +140,15 @@ services:
    configurator:
    condition: service_completed_successfully
    required: true
    image: 'ghcr.io/frappe/lms:stable'
    labels:
    - ofelia.enabled=true
    - 'ofelia.job-exec.datecron.command="bench --site all backup"'
    - "ofelia.job-exec.datecron.schedule='@every 6h'"
    - ofelia.job-exec.datecron.user=frappe
    networks:
    default: null
    platform: linux/amd64
    pull_policy: missing
    volumes:
    -
    type: volume
    source: sites
    target: /home/frappe/frappe-bench/sites
    volume: { }
    queue-long:
    <<: *frappe-app-common
    command:
    - bench
    - worker
    @@ -161,7 +158,6 @@ services:
    configurator:
    condition: service_completed_successfully
    required: true
    image: 'ghcr.io/frappe/lms:stable'
    healthcheck:
    test:
    - CMD
    @@ -172,15 +168,8 @@ services:
    retries: 30
    networks:
    default: null
    platform: linux/amd64
    pull_policy: missing
    volumes:
    -
    type: volume
    source: sites
    target: /home/frappe/frappe-bench/sites
    volume: { }
    queue-short:
    <<: *frappe-app-common
    command:
    - bench
    - worker
    @@ -198,18 +187,10 @@ services:
    configurator:
    condition: service_completed_successfully
    required: true
    image: 'ghcr.io/frappe/lms:stable'
    networks:
    default: null
    platform: linux/amd64
    pull_policy: missing
    volumes:
    -
    type: volume
    source: sites
    target: /home/frappe/frappe-bench/sites
    volume: { }
    websocket:
    <<: *frappe-app-common
    healthcheck:
    test:
    - CMD
    @@ -225,20 +206,12 @@ services:
    configurator:
    condition: service_completed_successfully
    required: true
    image: 'ghcr.io/frappe/lms:stable'
    networks:
    default: null
    platform: linux/amd64
    pull_policy: missing
    environment:
    - FRAPPE_SITE=frontend
    volumes:
    -
    type: volume
    source: sites
    target: /home/frappe/frappe-bench/sites
    volume: { }
    frontend:
    <<: *frappe-app-common
    command:
    - nginx-entrypoint.sh
    healthcheck:
    @@ -266,23 +239,12 @@ services:
    - UPSTREAM_REAL_IP_ADDRESS=127.0.0.1
    - UPSTREAM_REAL_IP_HEADER=X-Forwarded-For
    - 'UPSTREAM_REAL_IP_RECURSIVE="off"'
    image: 'ghcr.io/frappe/lms:stable'
    networks:
    default: null
    platform: linux/amd64
    pull_policy: missing
    volumes:
    -
    type: volume
    source: sites
    target: /home/frappe/frappe-bench/sites
    volume: { }
    - '/opt/frappe/nginx.conf.template:/templates/nginx/frappe.conf.template'
    create-site:
    <<: *frappe-app-common
    exclude_from_hc: true
    restart: 'no'
    image: 'ghcr.io/frappe/lms:stable'
    platform: linux/amd64
    environment:
    ADMIN_PASS: $SERVICE_PASSWORD_ADMINPASS
    networks:
    @@ -310,15 +272,13 @@ services:
    fi
    done; echo "sites/common_site_config.json found"; bench new-site --mariadb-user-host-login-scope='%' --admin-password=$$ADMIN_PASS --db-root-username=root --db-root-password=$SERVICE_PASSWORD_MYSQLROOT --install-app lms --set-default frontend;
    migrate-site:
    <<: *frappe-app-common
    exclude_from_hc: true
    restart: 'no'
    image: 'ghcr.io/frappe/lms:stable'
    platform: linux/amd64
    networks:
    default: null
    environment:
    SERVICE_URL: $SERVICE_URL_FRAPPESITE
    FRAPPE_HOST_NAME: '${FRAPPE_HOST_NAME:-$SERVICE_URL_FRAPPESITE}'
    - FRAPPE_HOST_NAME=${FRAPPE_HOST_NAME:-$SERVICE_URL_FRAPPESITE}
    volumes:
    - 'sites:/home/frappe/frappe-bench/sites'
    - 'logs:/home/frappe/frappe-bench/logs'
    @@ -327,19 +287,10 @@ services:
    - '-c'
    command:
    - |
    curl http://frontend:8080/api/method/ping; bench --site all set-config maintenance_mode 1; bench --site all set-config pause_scheduler 1; bench --site all migrate; bench --site all set-config maintenance_mode 0; bench --site all set-config pause_scheduler 0; bench --site frontend set-config host_name $$FRAPPE_HOST_NAME;
    x-backend-defaults:
    depends_on:
    configurator:
    condition: service_completed_successfully
    image: 'ghcr.io/frappe/lms:stable'
    pull_policy: missing
    volumes:
    - 'sites:/home/frappe/frappe-bench/sites'
    x-customizable-image:
    image: 'ghcr.io/frappe/lms:stable'
    pull_policy: missing
    x-depends-on-configurator:
    depends_on:
    configurator:
    condition: service_completed_successfully
    curl -f http://frontend:8080/api/method/ping || exit 0;
    bench --site all set-config maintenance_mode 1;
    bench --site all set-config pause_scheduler 1;
    bench --site all migrate;
    bench --site all set-config maintenance_mode 0;
    bench --site all set-config pause_scheduler 0;
    bench --site frontend set-config host_name $$FRAPPE_HOST_NAME;
  3. @NagariaHussain NagariaHussain revised this gist Jan 25, 2025. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion frappe-learning.yml
    Original file line number Diff line number Diff line change
    @@ -318,7 +318,7 @@ services:
    default: null
    environment:
    SERVICE_URL: $SERVICE_URL_FRAPPESITE
    FRAPPE_HOST_NAME: "${FRAPPE_HOST_NAME:-$$SERVICE_URL_FRAPPESITE}"
    FRAPPE_HOST_NAME: '${FRAPPE_HOST_NAME:-$SERVICE_URL_FRAPPESITE}'
    volumes:
    - 'sites:/home/frappe/frappe-bench/sites'
    - 'logs:/home/frappe/frappe-bench/logs'
  4. @NagariaHussain NagariaHussain revised this gist Jan 25, 2025. 1 changed file with 76 additions and 77 deletions.
    153 changes: 76 additions & 77 deletions frappe-learning.yml
    Original file line number Diff line number Diff line change
    @@ -1,17 +1,5 @@
    name: learning_prod_setup
    name: learning_prod_setup_done
    services:
    mailpit:
    image: axllent/mailpit
    volumes:
    - mailpit-data:/data
    ports:
    - 8025:8025
    - 1025:1025
    environment:
    MP_MAX_MESSAGES: 5000
    MP_DATA_FILE: /data/mailpit.db
    MP_SMTP_AUTH_ACCEPT_ANY: 1
    MP_SMTP_AUTH_ALLOW_INSECURE: 1
    backend:
    depends_on:
    configurator:
    @@ -23,7 +11,10 @@ services:
    platform: linux/amd64
    pull_policy: missing
    healthcheck:
    test: ["CMD", "wait-for-it", "0.0.0.0:8000"]
    test:
    - CMD
    - wait-for-it
    - '0.0.0.0:8000'
    interval: 2s
    timeout: 10s
    retries: 30
    @@ -93,7 +84,7 @@ services:
    target: /data
    volume: { }
    configurator:
    restart: no
    restart: 'no'
    exclude_from_hc: true
    command:
    - |
    @@ -130,7 +121,10 @@ services:
    volume: { }
    scheduler:
    healthcheck:
    test: ["CMD", "wait-for-it", "redis-queue:6379"]
    test:
    - CMD
    - wait-for-it
    - 'redis-queue:6379'
    interval: 2s
    timeout: 10s
    retries: 30
    @@ -141,34 +135,38 @@ services:
    configurator:
    condition: service_completed_successfully
    required: true
    image: ghcr.io/frappe/lms:stable
    image: 'ghcr.io/frappe/lms:stable'
    labels:
    - ofelia.enabled=true
    - ofelia.job-exec.datecron.command="bench --site all backup"
    - ofelia.job-exec.datecron.schedule='@every 6h'
    - 'ofelia.job-exec.datecron.command="bench --site all backup"'
    - "ofelia.job-exec.datecron.schedule='@every 6h'"
    - ofelia.job-exec.datecron.user=frappe
    networks:
    default: null
    platform: linux/amd64
    pull_policy: missing
    volumes:
    - type: volume
    -
    type: volume
    source: sites
    target: /home/frappe/frappe-bench/sites
    volume: {}
    volume: { }
    queue-long:
    command:
    - bench
    - worker
    - --queue
    - long,default,short
    - '--queue'
    - 'long,default,short'
    depends_on:
    configurator:
    condition: service_completed_successfully
    required: true
    image: ghcr.io/frappe/lms:stable
    image: 'ghcr.io/frappe/lms:stable'
    healthcheck:
    test: ["CMD", "wait-for-it", "redis-queue:6379"]
    test:
    - CMD
    - wait-for-it
    - 'redis-queue:6379'
    interval: 2s
    timeout: 10s
    retries: 30
    @@ -177,38 +175,46 @@ services:
    platform: linux/amd64
    pull_policy: missing
    volumes:
    - type: volume
    -
    type: volume
    source: sites
    target: /home/frappe/frappe-bench/sites
    volume: {}
    volume: { }
    queue-short:
    command:
    - bench
    - worker
    - --queue
    - short,default
    - '--queue'
    - 'short,default'
    healthcheck:
    test: ["CMD", "wait-for-it", "redis-queue:6379"]
    test:
    - CMD
    - wait-for-it
    - 'redis-queue:6379'
    interval: 2s
    timeout: 10s
    retries: 30
    depends_on:
    configurator:
    condition: service_completed_successfully
    required: true
    image: ghcr.io/frappe/lms:stable
    image: 'ghcr.io/frappe/lms:stable'
    networks:
    default: null
    platform: linux/amd64
    pull_policy: missing
    volumes:
    - type: volume
    -
    type: volume
    source: sites
    target: /home/frappe/frappe-bench/sites
    volume: {}
    volume: { }
    websocket:
    healthcheck:
    test: ["CMD", "wait-for-it", "0.0.0.0:9000"]
    test:
    - CMD
    - wait-for-it
    - '0.0.0.0:9000'
    interval: 2s
    timeout: 10s
    retries: 30
    @@ -219,23 +225,27 @@ services:
    configurator:
    condition: service_completed_successfully
    required: true
    image: ghcr.io/frappe/lms:stable
    image: 'ghcr.io/frappe/lms:stable'
    networks:
    default: null
    platform: linux/amd64
    pull_policy: missing
    environment:
    - FRAPPE_SITE=frontend
    volumes:
    - type: volume
    -
    type: volume
    source: sites
    target: /home/frappe/frappe-bench/sites
    volume: {}
    volume: { }
    frontend:
    command:
    - nginx-entrypoint.sh
    healthcheck:
    test: ["CMD", "wait-for-it", "0.0.0.0:8080"]
    test:
    - CMD
    - wait-for-it
    - '0.0.0.0:8080'
    interval: 2s
    timeout: 10s
    retries: 30
    @@ -246,53 +256,49 @@ services:
    websocket:
    condition: service_started
    required: true

    environment:
    - SERVICE_FQDN_FRAPPESITE_8080
    - BACKEND=backend:8000
    - 'BACKEND=backend:8000'
    - CLIENT_MAX_BODY_SIZE=50m
    - FRAPPE_SITE_NAME_HEADER=frontend
    - PROXY_READ_TIMEOUT="120"
    - SOCKETIO=websocket:9000
    - 'PROXY_READ_TIMEOUT="120"'
    - 'SOCKETIO=websocket:9000'
    - UPSTREAM_REAL_IP_ADDRESS=127.0.0.1
    - UPSTREAM_REAL_IP_HEADER=X-Forwarded-For
    - UPSTREAM_REAL_IP_RECURSIVE="off"
    image: ghcr.io/frappe/lms:stable
    - 'UPSTREAM_REAL_IP_RECURSIVE="off"'
    image: 'ghcr.io/frappe/lms:stable'
    networks:
    default: null
    platform: linux/amd64
    pull_policy: missing
    volumes:
    - type: volume
    -
    type: volume
    source: sites
    target: /home/frappe/frappe-bench/sites
    volume: {}
    - /opt/frappe/nginx.conf.template:/templates/nginx/frappe.conf.template
    volume: { }
    - '/opt/frappe/nginx.conf.template:/templates/nginx/frappe.conf.template'
    create-site:
    exclude_from_hc: true
    restart: no
    image: ghcr.io/frappe/lms:stable
    restart: 'no'
    image: 'ghcr.io/frappe/lms:stable'
    platform: linux/amd64
    environment:
    FRAPPE_HOST_NAME: $SERVICE_FQDN_FRAPPESITE
    ADMIN_PASS: $SERVICE_PASSWORD_ADMINPASS
    networks:
    default: null
    deploy:
    restart_policy:
    condition: none
    volumes:
    - sites:/home/frappe/frappe-bench/sites
    - logs:/home/frappe/frappe-bench/logs
    - 'sites:/home/frappe/frappe-bench/sites'
    - 'logs:/home/frappe/frappe-bench/logs'
    entrypoint:
    - bash
    - -c
    - '-c'
    command:
    - >
    wait-for-it -t 120 db:3306;
    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"` ]] && \
    - |
    wait-for-it -t 120 db:3306; 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
    @@ -302,33 +308,26 @@ services:
    echo "could not find sites/common_site_config.json with required keys";
    exit 1
    fi
    done;
    echo "sites/common_site_config.json found";
    bench new-site --mariadb-user-host-login-scope='%' --admin-password=$SERVICE_PASSWORD_ADMINPASS --db-root-username=root --db-root-password=$SERVICE_PASSWORD_MYSQLROOT --install-app lms --set-default frontend;
    bench --site frontend set-config host_name $SERVICE_FQDN_FRAPPESITE;
    done; echo "sites/common_site_config.json found"; bench new-site --mariadb-user-host-login-scope='%' --admin-password=$$ADMIN_PASS --db-root-username=root --db-root-password=$SERVICE_PASSWORD_MYSQLROOT --install-app lms --set-default frontend;
    migrate-site:
    exclude_from_hc: true
    restart: no
    image: ghcr.io/frappe/lms:stable
    restart: 'no'
    image: 'ghcr.io/frappe/lms:stable'
    platform: linux/amd64
    networks:
    default: null
    environment:
    SERVICE_URL: $SERVICE_URL_FRAPPESITE
    FRAPPE_HOST_NAME: "${FRAPPE_HOST_NAME:-$$SERVICE_URL_FRAPPESITE}"
    volumes:
    - sites:/home/frappe/frappe-bench/sites
    - logs:/home/frappe/frappe-bench/logs
    - 'sites:/home/frappe/frappe-bench/sites'
    - 'logs:/home/frappe/frappe-bench/logs'
    entrypoint:
    - bash
    - -c
    - '-c'
    command:
    - >
    curl http://frontend:8080/api/method/ping;
    bench --site all set-config maintenance_mode 1;
    bench --site all set-config pause_scheduler 1;
    bench --site all migrate;
    bench --site all set-config maintenance_mode 0;
    bench --site all set-config pause_scheduler 0;
    - |
    curl http://frontend:8080/api/method/ping; bench --site all set-config maintenance_mode 1; bench --site all set-config pause_scheduler 1; bench --site all migrate; bench --site all set-config maintenance_mode 0; bench --site all set-config pause_scheduler 0; bench --site frontend set-config host_name $$FRAPPE_HOST_NAME;
    x-backend-defaults:
    depends_on:
    configurator:
  5. @NagariaHussain NagariaHussain revised this gist Jan 25, 2025. 1 changed file with 14 additions and 8 deletions.
    22 changes: 14 additions & 8 deletions frappe-learning.yml
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,17 @@
    name: learning_prod_setup
    services:
    mailpit:
    image: axllent/mailpit
    volumes:
    - mailpit-data:/data
    ports:
    - 8025:8025
    - 1025:1025
    environment:
    MP_MAX_MESSAGES: 5000
    MP_DATA_FILE: /data/mailpit.db
    MP_SMTP_AUTH_ACCEPT_ANY: 1
    MP_SMTP_AUTH_ALLOW_INSECURE: 1
    backend:
    depends_on:
    configurator:
    @@ -200,11 +212,8 @@ services:
    interval: 2s
    timeout: 10s
    retries: 30
    ports:
    - 9229:9229
    command:
    - node
    - --inspect=0.0.0.0:9229
    - /home/frappe/frappe-bench/apps/frappe/socketio.js
    depends_on:
    configurator:
    @@ -217,15 +226,12 @@ services:
    pull_policy: missing
    environment:
    - FRAPPE_SITE=frontend
    - SERVICE_FQDN_SOCKET_9229
    volumes:
    - type: volume
    source: sites
    target: /home/frappe/frappe-bench/sites
    volume: {}
    frontend:
    # - "traefik.http.middlewares.testHeader.headers.customrequestheaders.X-Frappe-Site-Name=$SERVICE_FQDN_FRAPPESITE"
    # - "traefik.http.middlewares.testHeader.headers.customrequestheaders.Host=frontend"
    command:
    - nginx-entrypoint.sh
    healthcheck:
    @@ -268,8 +274,7 @@ services:
    image: ghcr.io/frappe/lms:stable
    platform: linux/amd64
    environment:
    ADMIN_PASS: $SERVICE_PASSWORD_ADMINPASS

    FRAPPE_HOST_NAME: $SERVICE_FQDN_FRAPPESITE
    networks:
    default: null
    deploy:
    @@ -300,6 +305,7 @@ services:
    done;
    echo "sites/common_site_config.json found";
    bench new-site --mariadb-user-host-login-scope='%' --admin-password=$SERVICE_PASSWORD_ADMINPASS --db-root-username=root --db-root-password=$SERVICE_PASSWORD_MYSQLROOT --install-app lms --set-default frontend;
    bench --site frontend set-config host_name $SERVICE_FQDN_FRAPPESITE;
    migrate-site:
    exclude_from_hc: true
    restart: no
  6. @NagariaHussain NagariaHussain revised this gist Jan 24, 2025. 1 changed file with 8 additions and 1 deletion.
    9 changes: 8 additions & 1 deletion frappe-learning.yml
    Original file line number Diff line number Diff line change
    @@ -200,8 +200,11 @@ services:
    interval: 2s
    timeout: 10s
    retries: 30
    ports:
    - 9229:9229
    command:
    - node
    - --inspect=0.0.0.0:9229
    - /home/frappe/frappe-bench/apps/frappe/socketio.js
    depends_on:
    configurator:
    @@ -214,12 +217,15 @@ services:
    pull_policy: missing
    environment:
    - FRAPPE_SITE=frontend
    - SERVICE_FQDN_SOCKET_9229
    volumes:
    - type: volume
    source: sites
    target: /home/frappe/frappe-bench/sites
    volume: {}
    frontend:
    # - "traefik.http.middlewares.testHeader.headers.customrequestheaders.X-Frappe-Site-Name=$SERVICE_FQDN_FRAPPESITE"
    # - "traefik.http.middlewares.testHeader.headers.customrequestheaders.Host=frontend"
    command:
    - nginx-entrypoint.sh
    healthcheck:
    @@ -236,7 +242,7 @@ services:
    required: true

    environment:
    - SERVICE_FQDN_LEARNING_8080
    - SERVICE_FQDN_FRAPPESITE_8080
    - BACKEND=backend:8000
    - CLIENT_MAX_BODY_SIZE=50m
    - FRAPPE_SITE_NAME_HEADER=frontend
    @@ -255,6 +261,7 @@ services:
    source: sites
    target: /home/frappe/frappe-bench/sites
    volume: {}
    - /opt/frappe/nginx.conf.template:/templates/nginx/frappe.conf.template
    create-site:
    exclude_from_hc: true
    restart: no
  7. @NagariaHussain NagariaHussain revised this gist Jan 22, 2025. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion frappe-learning.yml
    Original file line number Diff line number Diff line change
    @@ -236,7 +236,7 @@ services:
    required: true

    environment:
    - SERVICE_FQDN_SEARXNG_8080
    - SERVICE_FQDN_LEARNING_8080
    - BACKEND=backend:8000
    - CLIENT_MAX_BODY_SIZE=50m
    - FRAPPE_SITE_NAME_HEADER=frontend
  8. @NagariaHussain NagariaHussain created this gist Jan 22, 2025.
    333 changes: 333 additions & 0 deletions frappe-learning.yml
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,333 @@
    name: learning_prod_setup
    services:
    backend:
    depends_on:
    configurator:
    condition: service_completed_successfully
    required: true
    image: 'ghcr.io/frappe/lms:stable'
    networks:
    default: null
    platform: linux/amd64
    pull_policy: missing
    healthcheck:
    test: ["CMD", "wait-for-it", "0.0.0.0:8000"]
    interval: 2s
    timeout: 10s
    retries: 30
    volumes:
    -
    type: volume
    source: sites
    target: /home/frappe/frappe-bench/sites
    volume: { }
    db:
    command:
    - '--character-set-server=utf8mb4'
    - '--collation-server=utf8mb4_unicode_ci'
    - '--skip-character-set-client-handshake'
    - '--skip-innodb-read-only-compressed'
    environment:
    MYSQL_ROOT_PASSWORD: $SERVICE_PASSWORD_MYSQLROOT
    healthcheck:
    test:
    - CMD-SHELL
    - 'mysqladmin ping -h localhost --password=$SERVICE_PASSWORD_MYSQLROOT'
    interval: 1s
    retries: 20
    image: 'mariadb:10.6'
    networks:
    default: null
    volumes:
    -
    type: volume
    source: db-data
    target: /var/lib/mysql
    volume: { }
    redis-cache:
    image: 'redis:6.2-alpine'
    healthcheck:
    test:
    - CMD
    - redis-cli
    - ping
    interval: 5s
    timeout: 5s
    retries: 3
    networks:
    default: null
    volumes:
    -
    type: volume
    source: redis-cache-data
    target: /data
    volume: { }
    redis-queue:
    image: 'redis:6.2-alpine'
    healthcheck:
    test:
    - CMD
    - redis-cli
    - ping
    interval: 5s
    timeout: 5s
    retries: 3
    networks:
    default: null
    volumes:
    -
    type: volume
    source: redis-queue-data
    target: /data
    volume: { }
    configurator:
    restart: no
    exclude_from_hc: true
    command:
    - |
    ls -1 apps > sites/apps.txt; 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;
    depends_on:
    db:
    condition: service_healthy
    required: true
    redis-cache:
    condition: service_started
    required: true
    redis-queue:
    condition: service_started
    required: true
    entrypoint:
    - bash
    - '-c'
    environment:
    DB_HOST: db
    DB_PORT: '3306'
    REDIS_CACHE: 'redis-cache:6379'
    REDIS_QUEUE: 'redis-queue:6379'
    SOCKETIO_PORT: '9000'
    image: 'ghcr.io/frappe/lms:stable'
    networks:
    default: null
    platform: linux/amd64
    pull_policy: missing
    volumes:
    -
    type: volume
    source: sites
    target: /home/frappe/frappe-bench/sites
    volume: { }
    scheduler:
    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
    image: ghcr.io/frappe/lms:stable
    labels:
    - ofelia.enabled=true
    - ofelia.job-exec.datecron.command="bench --site all backup"
    - ofelia.job-exec.datecron.schedule='@every 6h'
    - ofelia.job-exec.datecron.user=frappe
    networks:
    default: null
    platform: linux/amd64
    pull_policy: missing
    volumes:
    - type: volume
    source: sites
    target: /home/frappe/frappe-bench/sites
    volume: {}
    queue-long:
    command:
    - bench
    - worker
    - --queue
    - long,default,short
    depends_on:
    configurator:
    condition: service_completed_successfully
    required: true
    image: ghcr.io/frappe/lms:stable
    healthcheck:
    test: ["CMD", "wait-for-it", "redis-queue:6379"]
    interval: 2s
    timeout: 10s
    retries: 30
    networks:
    default: null
    platform: linux/amd64
    pull_policy: missing
    volumes:
    - type: volume
    source: sites
    target: /home/frappe/frappe-bench/sites
    volume: {}
    queue-short:
    command:
    - bench
    - worker
    - --queue
    - short,default
    healthcheck:
    test: ["CMD", "wait-for-it", "redis-queue:6379"]
    interval: 2s
    timeout: 10s
    retries: 30
    depends_on:
    configurator:
    condition: service_completed_successfully
    required: true
    image: ghcr.io/frappe/lms:stable
    networks:
    default: null
    platform: linux/amd64
    pull_policy: missing
    volumes:
    - type: volume
    source: sites
    target: /home/frappe/frappe-bench/sites
    volume: {}
    websocket:
    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
    image: ghcr.io/frappe/lms:stable
    networks:
    default: null
    platform: linux/amd64
    pull_policy: missing
    environment:
    - FRAPPE_SITE=frontend
    volumes:
    - type: volume
    source: sites
    target: /home/frappe/frappe-bench/sites
    volume: {}
    frontend:
    command:
    - nginx-entrypoint.sh
    healthcheck:
    test: ["CMD", "wait-for-it", "0.0.0.0:8080"]
    interval: 2s
    timeout: 10s
    retries: 30
    depends_on:
    backend:
    condition: service_started
    required: true
    websocket:
    condition: service_started
    required: true

    environment:
    - SERVICE_FQDN_SEARXNG_8080
    - BACKEND=backend:8000
    - CLIENT_MAX_BODY_SIZE=50m
    - FRAPPE_SITE_NAME_HEADER=frontend
    - PROXY_READ_TIMEOUT="120"
    - SOCKETIO=websocket:9000
    - UPSTREAM_REAL_IP_ADDRESS=127.0.0.1
    - UPSTREAM_REAL_IP_HEADER=X-Forwarded-For
    - UPSTREAM_REAL_IP_RECURSIVE="off"
    image: ghcr.io/frappe/lms:stable
    networks:
    default: null
    platform: linux/amd64
    pull_policy: missing
    volumes:
    - type: volume
    source: sites
    target: /home/frappe/frappe-bench/sites
    volume: {}
    create-site:
    exclude_from_hc: true
    restart: no
    image: ghcr.io/frappe/lms:stable
    platform: linux/amd64
    environment:
    ADMIN_PASS: $SERVICE_PASSWORD_ADMINPASS

    networks:
    default: null
    deploy:
    restart_policy:
    condition: none
    volumes:
    - sites:/home/frappe/frappe-bench/sites
    - logs:/home/frappe/frappe-bench/logs
    entrypoint:
    - bash
    - -c
    command:
    - >
    wait-for-it -t 120 db:3306;
    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";
    bench new-site --mariadb-user-host-login-scope='%' --admin-password=$SERVICE_PASSWORD_ADMINPASS --db-root-username=root --db-root-password=$SERVICE_PASSWORD_MYSQLROOT --install-app lms --set-default frontend;
    migrate-site:
    exclude_from_hc: true
    restart: no
    image: ghcr.io/frappe/lms:stable
    platform: linux/amd64
    networks:
    default: null
    volumes:
    - sites:/home/frappe/frappe-bench/sites
    - logs:/home/frappe/frappe-bench/logs
    entrypoint:
    - bash
    - -c
    command:
    - >
    curl http://frontend:8080/api/method/ping;
    bench --site all set-config maintenance_mode 1;
    bench --site all set-config pause_scheduler 1;
    bench --site all migrate;
    bench --site all set-config maintenance_mode 0;
    bench --site all set-config pause_scheduler 0;
    x-backend-defaults:
    depends_on:
    configurator:
    condition: service_completed_successfully
    image: 'ghcr.io/frappe/lms:stable'
    pull_policy: missing
    volumes:
    - 'sites:/home/frappe/frappe-bench/sites'
    x-customizable-image:
    image: 'ghcr.io/frappe/lms:stable'
    pull_policy: missing
    x-depends-on-configurator:
    depends_on:
    configurator:
    condition: service_completed_successfully