---
application_id: "web-app-moodle"
entity_name: "{{ application_id | entity_name }}"
swarm_stack_converge_retries: 600
MOODLE_CODE_DIR: "{{ lookup('volume', 'web-app-moodle', 'code').target }}"
MOODLE_DATA_DIR: "{{ lookup('volume', 'web-app-moodle', 'data').target }}"
MOODLE_LOCAL_CACHE_DIR: "{{ lookup('volume', application_id, 'localcache').mounts[0].target }}"
MOODLE_SOURCE_DIR: "/opt/moodle-source"
MOODLE_ENTRYPOINT_PATH: "/usr/local/bin/moodle-entrypoint.sh"
MOODLE_BOOTSTRAP_STAGE: "{{ [MOODLE_CODE_DIR, '.bootstrap.stage'] | path_join }}"
MOODLE_BOOTSTRAP_SENTINEL: "{{ [MOODLE_CODE_DIR, '.bootstrap.done'] | path_join }}"
MOODLE_RELEASE_LIB: "/usr/local/bin/moodle-release.sh"
MOODLE_TRANSIT_DIR: "/opt/moodle-transit"
MOODLE_UPGRADE_PATH: "{{ [MOODLE_TRANSIT_DIR, 'upgrade-path'] | path_join }}"
MOODLE_BUILD_DIR: "build"
MOODLE_BUILD_FILES:
entrypoint: "moodle/entrypoint.sh"
release_lib: "moodle/release.sh"
config_php: "config.php"
install_source: "install/moodle/source.sh"
install_upgrade_path: "install/moodle/upgrade-path.sh"
install_oidc: "install/auth-oidc.sh"
install_mcp: "install/webservice-mcp.sh"
install_objectfs: "install/tool-objectfs.sh"
patch_objectfs: "patch/tool-objectfs-path-style.patch"
opcache_ini: "php-conf/opcache-recommended.ini"
runtime_ini: "php-conf/moodle-runtime.ini"
fpm_pool: "php-conf/zz-moodle-pool.conf"
MOODLE_WEBROOT_SUBDIR: "public"
MOODLE_WEBROOT_DIR: "{{ [MOODLE_CODE_DIR, MOODLE_WEBROOT_SUBDIR] | path_join }}"
MOODLE_VERSION_FILE: "{{ [MOODLE_WEBROOT_SUBDIR, 'version.php'] | path_join }}"
MOODLE_AUTH_SUBDIR: "{{ [MOODLE_WEBROOT_SUBDIR, 'auth'] | path_join }}"
MOODLE_WEBSERVICE_SUBDIR: "{{ [MOODLE_WEBROOT_SUBDIR, 'webservice'] | path_join }}"
MOODLE_ADMIN_TOOL_SUBDIR: "{{ [MOODLE_WEBROOT_SUBDIR, 'admin/tool'] | path_join }}"
MOODLE_CLI_RELPATH: "admin/cli"
MOODLE_OIDC_PLUGIN_VERSION: "{{ lookup('config', application_id, 'addons.auth_oidc.version') }}"
MOODLE_OIDC_PLUGIN_UPSTREAM: "{{ lookup('config', application_id, 'addons.auth_oidc.update.upstream_id') }}"
MOODLE_OIDC_PLUGIN_ARCHIVE_URL: "https://github.com/{{ MOODLE_OIDC_PLUGIN_UPSTREAM }}/archive/refs/tags/{{ MOODLE_OIDC_PLUGIN_VERSION }}.zip"
MOODLE_OIDC_PLUGIN_URL_PATH: "auth/oidc"
MOODLE_OIDC_PLUGIN_RELPATH: "{{ [MOODLE_WEBROOT_SUBDIR, MOODLE_OIDC_PLUGIN_URL_PATH] | path_join }}"
MOODLE_OIDC_PLUGIN_SOURCE_DIR: "{{ [MOODLE_SOURCE_DIR, MOODLE_OIDC_PLUGIN_RELPATH] | path_join }}"
MOODLE_OIDC_PLUGIN_DIR: "{{ [MOODLE_CODE_DIR, MOODLE_OIDC_PLUGIN_RELPATH] | path_join }}"
MOODLE_OIDC_PLUGIN_SYNC_DIR: "{{ [MOODLE_CODE_DIR, '.auth_oidc.sync'] | path_join }}"
MOODLE_CLI_DIR: "{{ [MOODLE_CODE_DIR, MOODLE_CLI_RELPATH] | path_join }}"
MOODLE_CONFIG: "{{ [MOODLE_CODE_DIR, 'config.php'] | path_join }}"
MOODLE_PLUGIN_CONFIG_SCRIPT: "/tmp/infinito-plugin-config.php"
MOODLE_RUNTIME_USER: "www-data"
MOODLE_RUNTIME_USER_GROUP: "{{ MOODLE_RUNTIME_USER }}:{{ MOODLE_RUNTIME_USER }}"
MOODLE_ADMIN_USERNAME: "{{ lookup('users', 'platform_administrator').username }}"
MOODLE_ADMIN_PASSWORD: "{{ lookup('users', 'platform_administrator').password }}"
MOODLE_ADMIN_EMAIL: "{{ lookup('users', 'platform_administrator').email }}"
MOODLE_RELEASE: "{{ lookup('config', application_id, 'services.moodle.app_version') }}"
MOODLE_TARBALL_URL: "https://github.com/moodle/moodle/archive/refs/tags/v{{ MOODLE_RELEASE }}.tar.gz"
MOODLE_TRANSIT_RELEASE: "{{ lookup('config', application_id, 'services.moodle.transit_version') }}"
MOODLE_TRANSIT_TARBALL_URL: "https://github.com/moodle/moodle/archive/refs/tags/v{{ MOODLE_TRANSIT_RELEASE }}.tar.gz"
MOODLE_MSMTP_SRC: "{{ lookup('path_absolute', 'roles/sys-svc-mail-msmtp/templates/msmtprc.conf.j2') }}"
MOODLE_MSMTP_ABS: "{{ [ lookup('container', application_id, 'directories.config'), 'msmtprc.conf'] | path_join }}"
MOODLE_IMAGE: "{{ lookup('config', application_id, 'services.moodle.image') }}"
MOODLE_VERSION: "{{ lookup('config', application_id, 'services.moodle.version') }}"
MOODLE_CONTAINER: "{{ lookup('config', application_id, 'services.moodle.name') }}"
MOODLE_CONTAINER_ADDRESS: "{{ lookup('container_address', application_id, entity_name) }}"
MOODLE_DB_CONTAINER_ADDRESS: "{{ lookup('database', application_id, 'address') }}"
MOODLE_NGINX_CONTAINER: "{{ lookup('config', application_id, 'services.nginx.name') }}"
MOODLE_CRON_CONTAINER: "{{ lookup('config', application_id, 'services.cron.name') }}"
MOODLE_CRON_FAILURE_LIMIT: 3
MOODLE_OIDC_ENABLED: "{{ lookup('config', application_id, 'services.sso.enabled') }}"
MOODLE_LDAP_ENABLED: "{{ lookup('config', application_id, 'services.ldap.enabled') }}"
MOODLE_OIDC_ONION_ISSUER: "{{ lookup('tls', 'web-app-keycloak', 'domain').endswith('.onion') }}"
MOODLE_OIDC_SOCKS_PROXY: "{{ lookup('tor_socks_proxy') if MOODLE_OIDC_ONION_ISSUER | bool else '' }}"
MOODLE_LITELLM_ENABLED: "{{ lookup('config', application_id, 'services.litellm.enabled') | bool }}"
MOODLE_LITELLM_API_KEY: "{{ lookup('config', application_id, 'secrets.credentials.litellm_api_key') }}"
MOODLE_LITELLM_CHAT_ENDPOINT: "{{ LITELLM_OPENAI_BASE_LOCAL_URL }}/chat/completions"
MOODLE_LITELLM_IMAGE_ENDPOINT: "{{ LITELLM_OPENAI_BASE_LOCAL_URL }}/images/generations"
MOODLE_LITELLM_PROVIDER_NAME: "LiteLLM gateway"
MOODLE_LITELLM_PLACEMENTS:
- aiplacement_courseassist
- aiplacement_editor
MOODLE_EGRESS_BLOCKED_HOSTS:
- "0.0.0.0"
- "127.0.0.0/8"
- "localhost"
- "169.254.169.254"
- "0000::1"
MOODLE_EGRESS_WEB_PORTS:
- "80"
- "443"
MOODLE_EGRESS_ALLOWED_PORTS: "{{ MOODLE_EGRESS_WEB_PORTS + ([MOODLE_LITELLM_CHAT_ENDPOINT | urlsplit('port') | string] if MOODLE_LITELLM_ENABLED | bool else []) }}"
MOODLE_DEBUG_SETTINGS:
- name: debug
value: "{{ (MODE_DEBUG | bool) | ternary('32767', '0') }}"
- name: debugdisplay
value: "{{ (MODE_DEBUG | bool) | ternary('1', '0') }}"
MOODLE_PROXY_EXCLUDED_HOSTS: "{{ lookup('proxy_excluded_hosts', application_id) + [MOODLE_MCP_SERVICE_KEY] + ([MOODLE_LITELLM_CHAT_ENDPOINT | urlsplit('hostname')]
if MOODLE_LITELLM_ENABLED | bool else []) }}"
MOODLE_OBJECTFS_ENABLED: "{{ lookup('config', application_id, 'services.seaweedfs.enabled') }}"
MOODLE_OBJECTFS_PLUGIN_COMMIT: "{{ lookup('config', application_id, 'addons.tool_objectfs.version') }}"
MOODLE_OBJECTFS_PLUGIN_UPSTREAM: "{{ lookup('config', application_id, 'addons.tool_objectfs.update.upstream_id') }}"
MOODLE_OBJECTFS_PLUGIN_ARCHIVE_URL: "https://github.com/{{ MOODLE_OBJECTFS_PLUGIN_UPSTREAM }}/archive/{{ MOODLE_OBJECTFS_PLUGIN_COMMIT }}.zip"
MOODLE_OBJECTFS_PLUGIN_RELPATH: "{{ [MOODLE_ADMIN_TOOL_SUBDIR, 'objectfs'] | path_join }}"
MOODLE_OBJECTFS_PLUGIN_SOURCE_DIR: "{{ [MOODLE_SOURCE_DIR, MOODLE_OBJECTFS_PLUGIN_RELPATH] | path_join }}"
MOODLE_OBJECTFS_PLUGIN_DIR: "{{ [MOODLE_CODE_DIR, MOODLE_OBJECTFS_PLUGIN_RELPATH] | path_join }}"
MOODLE_OBJECTFS_READY_FILE: "{{ [MOODLE_CODE_DIR, '.objectfs.installed'] | path_join }}"
MOODLE_MCP_ENABLED: "{{ lookup('config', application_id, 'mcp.enabled') }}"
MOODLE_MCP_PLUGIN_VERSION: "v0.6.0"
MOODLE_MCP_PLUGIN_ARCHIVE_URL: "https://github.com/onbirdev/moodle-webservice_mcp/archive/refs/tags/{{ MOODLE_MCP_PLUGIN_VERSION }}.zip"
MOODLE_MCP_PLUGIN_RELPATH: "{{ [MOODLE_WEBSERVICE_SUBDIR, 'mcp'] | path_join }}"
MOODLE_MCP_PLUGIN_SOURCE_DIR: "{{ [MOODLE_SOURCE_DIR, MOODLE_MCP_PLUGIN_RELPATH] | path_join }}"
MOODLE_MCP_PLUGIN_DIR: "{{ [MOODLE_CODE_DIR, MOODLE_MCP_PLUGIN_RELPATH] | path_join }}"
MOODLE_MCP_SERVICE_KEY: "{{ lookup('config', application_id, 'mcp.endpoint.service_key') }}"
MOODLE_MCP_PORT: "{{ lookup('config', application_id, 'services.nginx.ports.internal.http') }}"
MOODLE_MCP_URL: "http://{{ MOODLE_MCP_SERVICE_KEY }}:{{ MOODLE_MCP_PORT }}{{ lookup('config', application_id, 'mcp.endpoint.path') }}"
MOODLE_MCP_EXTERNAL_SERVICE_NAME: "Model Context Protocol"
MOODLE_MCP_EXTERNAL_SERVICE_SHORTNAME: "infinito_mcp"
MOODLE_MCP_EXTERNAL_FUNCTIONS:
- core_webservice_get_site_info
- core_course_get_courses
- core_enrol_get_users_courses
- core_user_get_users_by_field
- core_calendar_get_calendar_events
MOODLE_MCP_ACCOUNT: "{{ lookup('users', 'mcp-web-app-moodle') }}"
MOODLE_MCP_ACCOUNT_USERNAME: "{{ MOODLE_MCP_ACCOUNT.username }}"
MOODLE_MCP_ACCOUNT_EMAIL: "{{ MOODLE_MCP_ACCOUNT.email }}"
MOODLE_MCP_ACCOUNT_PASSWORD: "{{ MOODLE_MCP_ACCOUNT.password }}"
MOODLE_MCP_ROLE_SHORTNAME: "infinito_mcp"
MOODLE_MCP_ROLE_NAME: "Infinito MCP service"
MOODLE_MCP_ROLE_CAPABILITIES:
- webservice/mcp:use
- webservice/rest:use
- moodle/course:view
- moodle/user:viewdetails
MOODLE_MCP_TOOLS_LIST_PAYLOAD:
jsonrpc: "2.0"
id: 1
method: tools/list
params: {}
MOODLE_OIDC_CUSTOM_SCOPE: "{{ lookup('config', 'web-app-keycloak', 'services.keycloak.scopes.moodle') }}"
MOODLE_OIDC_SCOPES: "openid profile email phone address {{ MOODLE_OIDC_CUSTOM_SCOPE }}"
MOODLE_SITE_TITLE: "{{ lookup('design', application_id).label }}"
MOODLE_DESIGN_ENABLED: "{{ lookup('config', application_id, 'services.design.enabled') | bool }}"
MOODLE_DESIGN_DIR: "{{ [lookup('container', application_id, 'directories.config'), 'design'] | path_join }}"
MOODLE_DESIGN_PRIMARY: "{{ lookup('design_palette', lookup('config', 'web-svc-design', 'services.design.colors.base')).light['--design-primary'] }}"
MOODLE_DESIGN_LOGO_ENABLED: "{{ MOODLE_DESIGN_ENABLED | bool and lookup('design', application_id).logo is string }}"
MOODLE_DESIGN_STAGING_PREFIX: "/tmp/design-"
MOODLE_DESIGN_LOGO_FILES:
logo: "logo.png"
logocompact: "logo-compact.png"
favicon: "favicon.png"
MOODLE_FPM_PORT: "{{ lookup('config', application_id, 'services.moodle.ports.internal.fpm') }}"
MOODLE_NGINX_PORT: "{{ lookup('config', application_id, 'services.moodle.ports.internal.http') }}"
MOODLE_PHP_MEMORY_LIMIT: "{{ lookup('service_memory_mb', application_id, 'moodle', 0.25) }}M"
MOODLE_PHP_UPLOAD_MAX_FILESIZE: "{{ lookup('config', application_id, 'services.moodle.performance.php.upload_max_filesize') }}"
MOODLE_PHP_POST_MAX_SIZE: "{{ lookup('config', application_id, 'services.moodle.performance.php.post_max_size') }}"
MOODLE_PHP_MAX_EXECUTION_TIME: "300"
MOODLE_PHP_MAX_INPUT_VARS: "5000"