Files
templates/blueprints/appwrite/template.toml
Chirag Aggarwal 5523024b95 feat(appwrite): update template to 1.9.5 (#970)
* feat(appwrite): update template to 1.9.5

Move default datastore to MongoDB (DocumentsDB), add worker-screenshots,
worker-executions and task-interval, bump all images to 1.9.5, expand v5
function runtimes, and provide mongo bootstrap files via config.mounts.
MariaDB kept as a supported alternative. PostgreSQL/embedding (VectorsDB)
and bundled Traefik intentionally excluded.

* fix(appwrite): re-add compose version header and add mongodb tag

Address review: restore "version: 3.8" header (repo convention across
blueprints) and add the mongodb tag to meta.json to reflect the new
default datastore.

* (fix): add container_name to appwrite executor so it can find itself

The openruntimes executor v0.25 discovers its own container by listing
containers whose name matches its hostname (exc1). Without
container_name, compose names the container <project>-openruntimes-executor-1,
the lookup fails with 'Own container not found' and the executor
crash-loops, breaking all function/site builds and executions with
'Could not resolve host: exc1'. Matches upstream appwrite 1.9.5 compose.

Verified end-to-end on a fresh Dokploy v0.29.8 server: executor healthy,
function build + execution succeed.

* (fix): route wildcard sites/functions subdomains to appwrite

Dokploy domains only support exact hosts, so Appwrite-generated preview
and execution URLs (<id>.sites.<domain>, <id>.functions.<domain>) hit
Dokploy traefik with no matching router: 404 over HTTP and the traefik
default self-signed certificate over HTTPS ('site is insecure').

Add HostRegexp routers on the appwrite service for *.sites and
*.functions domains on both web and websecure entrypoints. HTTPS for
these subdomains still requires the user to provide a wildcard
certificate (DNS-01 resolver or uploaded wildcard/Origin CA cert);
with tls=true routers in place traefik picks it up via SNI once added.

Verified on a live Dokploy v0.29.8 deployment: site subdomains route
correctly over HTTP and HTTPS after adding the labels.

* (chore): remove wildcard routing comment

* (fix): drop container_name, use service-name hostname for executor self-discovery

container_name is disallowed by repo conventions and fails CI validation.
The executor discovers its own container by matching gethostname()
against Docker container names (substring filter), so hostname
openruntimes-executor matches <project>-openruntimes-executor-1 and
_APP_EXECUTOR_HOST can use the DNS-resolvable service name.

Also read the MongoDB healthcheck password from the container env
(MONGO_INITDB_ROOT_PASSWORD) instead of interpolating _APP_DB_ROOT_PASS
at render time, so shell-special characters in generated passwords
cannot break authentication.

Both verified on a live Dokploy v0.29.8 deployment: executor healthy,
function execution succeeds, mongodb healthcheck passes.

---------

Co-authored-by: ChiragAgg5k <chirag@appwrite.io>
2026-07-07 15:43:53 -06:00

231 lines
7.1 KiB
TOML

[variables]
main_domain = "${domain}"
functions_domain = "functions.${main_domain}"
sites_domain = "sites.${main_domain}"
openssl_key = "${password:32}"
db_root_pw = "${password:32}"
db_user_pw = "${password:32}"
executor_secret = "${password:32}"
[config]
env = [
"_APP_ENV=production",
"_APP_EDITION=self-hosted",
"_APP_LOCALE=en",
"_APP_POOL_ADAPTER=stack",
"_APP_WORKER_PER_CORE=6",
"_APP_OPTIONS_ABUSE=enabled",
"_APP_OPTIONS_FORCE_HTTPS=disabled",
"_APP_OPTIONS_ROUTER_FORCE_HTTPS=disabled",
"_APP_OPTIONS_ROUTER_PROTECTION=disabled",
"_APP_OPENSSL_KEY_V1=${openssl_key}",
"_APP_DOMAIN=${main_domain}",
"_APP_CONSOLE_DOMAIN=${main_domain}",
"_APP_CONSOLE_TRUSTED_PROJECTS=",
"_APP_CUSTOM_DOMAIN_DENY_LIST=example.com,test.com,app.example.com",
"_APP_DOMAIN_FUNCTIONS=${functions_domain}",
"_APP_DOMAIN_SITES=${sites_domain}",
"_APP_DOMAIN_TARGET_CNAME=localhost",
"_APP_DOMAIN_TARGET_AAAA=::1",
"_APP_DOMAIN_TARGET_A=127.0.0.1",
"_APP_DOMAIN_TARGET_CAA=",
"_APP_DNS=8.8.8.8",
"_APP_TRUSTED_HEADERS=x-forwarded-for",
"_APP_CONSOLE_WHITELIST_ROOT=enabled",
"_APP_CONSOLE_WHITELIST_EMAILS=",
"_APP_CONSOLE_WHITELIST_IPS=",
"_APP_CONSOLE_HOSTNAMES=",
"_APP_CONSOLE_SCHEMA=appwriteio",
"_APP_CONSOLE_SESSION_ALERTS=disabled",
"_APP_CONSOLE_COUNTRIES_DENYLIST=",
"_APP_SYSTEM_EMAIL_NAME=Appwrite",
"_APP_SYSTEM_EMAIL_ADDRESS=noreply@appwrite.io",
"_APP_SYSTEM_TEAM_EMAIL=team@appwrite.io",
"_APP_SYSTEM_RESPONSE_FORMAT=",
"_APP_EMAIL_SECURITY=",
"_APP_EMAIL_CERTIFICATES=",
"_APP_COMPRESSION_ENABLED=enabled",
"_APP_COMPRESSION_MIN_SIZE_BYTES=1024",
"_APP_USAGE_STATS=enabled",
"_APP_USAGE_AGGREGATION_INTERVAL=30",
"_APP_STATS_RESOURCES_INTERVAL=30",
"_APP_LOGGING_PROVIDER=",
"_APP_LOGGING_CONFIG=",
"_APP_LOGGING_CONFIG_REALTIME=",
"_APP_EXPERIMENT_LOGGING_PROVIDER=",
"_APP_EXPERIMENT_LOGGING_CONFIG=",
"_APP_REDIS_HOST=redis",
"_APP_REDIS_PORT=6379",
"_APP_REDIS_USER=",
"_APP_REDIS_PASS=",
"_APP_DB_ADAPTER=mongodb",
"_APP_DB_HOST=mongodb",
"_APP_DB_PORT=27017",
"_APP_DB_SCHEMA=appwrite",
"_APP_DB_USER=user",
"_APP_DB_PASS=${db_user_pw}",
"_APP_DB_ROOT_PASS=${db_root_pw}",
"_APP_DATABASE_SHARED_TABLES=",
"_APP_DATABASE_SHARED_NAMESPACE=",
"_APP_DB_ADAPTER_VECTORSDB=",
"_APP_DB_HOST_VECTORSDB=",
"_APP_DB_PORT_VECTORSDB=",
"_APP_DB_SCHEMA_VECTORSDB=",
"_APP_DB_USER_VECTORSDB=",
"_APP_DB_PASS_VECTORSDB=",
"_APP_SMTP_HOST=",
"_APP_SMTP_PORT=",
"_APP_SMTP_SECURE=",
"_APP_SMTP_USERNAME=",
"_APP_SMTP_PASSWORD=",
"_APP_SMS_PROVIDER=",
"_APP_SMS_FROM=",
"_APP_SMS_PROJECTS_DENY_LIST=",
"_APP_STORAGE_LIMIT=30000000",
"_APP_STORAGE_PREVIEW_LIMIT=20000000",
"_APP_STORAGE_ANTIVIRUS=disabled",
"_APP_STORAGE_ANTIVIRUS_HOST=clamav",
"_APP_STORAGE_ANTIVIRUS_PORT=3310",
"_APP_STORAGE_DEVICE=local",
"_APP_STORAGE_S3_ACCESS_KEY=",
"_APP_STORAGE_S3_SECRET=",
"_APP_STORAGE_S3_REGION=us-east-1",
"_APP_STORAGE_S3_BUCKET=",
"_APP_STORAGE_S3_ENDPOINT=",
"_APP_STORAGE_DO_SPACES_ACCESS_KEY=",
"_APP_STORAGE_DO_SPACES_SECRET=",
"_APP_STORAGE_DO_SPACES_REGION=us-east-1",
"_APP_STORAGE_DO_SPACES_BUCKET=",
"_APP_STORAGE_BACKBLAZE_ACCESS_KEY=",
"_APP_STORAGE_BACKBLAZE_SECRET=",
"_APP_STORAGE_BACKBLAZE_REGION=us-west-004",
"_APP_STORAGE_BACKBLAZE_BUCKET=",
"_APP_STORAGE_LINODE_ACCESS_KEY=",
"_APP_STORAGE_LINODE_SECRET=",
"_APP_STORAGE_LINODE_REGION=eu-central-1",
"_APP_STORAGE_LINODE_BUCKET=",
"_APP_STORAGE_WASABI_ACCESS_KEY=",
"_APP_STORAGE_WASABI_SECRET=",
"_APP_STORAGE_WASABI_REGION=eu-central-1",
"_APP_STORAGE_WASABI_BUCKET=",
"_APP_COMPUTE_SIZE_LIMIT=30000000",
"_APP_COMPUTE_BUILD_TIMEOUT=900",
"_APP_COMPUTE_CPUS=0",
"_APP_COMPUTE_MEMORY=0",
"_APP_COMPUTE_INACTIVE_THRESHOLD=60",
"_APP_COMPUTE_MAINTENANCE_INTERVAL=3600",
"_APP_COMPUTE_RUNTIMES_NETWORK=dokploy-network",
"_APP_FUNCTIONS_TIMEOUT=900",
"_APP_FUNCTIONS_CREATION_ABUSE_LIMIT=5000",
"_APP_FUNCTIONS_RUNTIMES=node-22,python-3.12,php-8.3,ruby-3.3,dart-3.5,go-1.23,rust-1.83,bun-1.1,deno-1.46,java-21.0,dotnet-8.0",
"_APP_SITES_TIMEOUT=900",
"_APP_SITES_RUNTIMES=static-1,node-22",
"_APP_EXECUTOR_SECRET=${executor_secret}",
"_APP_EXECUTOR_HOST=http://openruntimes-executor/v1",
"_APP_EXECUTOR_IMAGES=openruntimes/node:v5-22,openruntimes/python:v5-3.12,openruntimes/php:v5-8.3,openruntimes/static:v5-1",
"_APP_OPEN_RUNTIMES_NFT=enabled",
"_APP_BROWSER_HOST=http://appwrite-browser:3000/v1",
"_APP_WORKER_SCREENSHOTS_ROUTER=http://appwrite",
"_APP_DOCKER_HUB_USERNAME=",
"_APP_DOCKER_HUB_PASSWORD=",
"_APP_MAINTENANCE_INTERVAL=86400",
"_APP_MAINTENANCE_START_TIME=00:00",
"_APP_MAINTENANCE_RETENTION_CACHE=2592000",
"_APP_MAINTENANCE_RETENTION_EXECUTION=1209600",
"_APP_MAINTENANCE_RETENTION_AUDIT=1209600",
"_APP_MAINTENANCE_RETENTION_AUDIT_CONSOLE=15778800",
"_APP_MAINTENANCE_RETENTION_ABUSE=86400",
"_APP_MAINTENANCE_RETENTION_USAGE_HOURLY=8640000",
"_APP_MAINTENANCE_RETENTION_SCHEDULES=86400",
"_APP_INTERVAL_DOMAIN_VERIFICATION=120",
"_APP_INTERVAL_CLEANUP_STALE_EXECUTIONS=300",
"_APP_GRAPHQL_INTROSPECTION=enabled",
"_APP_GRAPHQL_MAX_BATCH_SIZE=10",
"_APP_GRAPHQL_MAX_COMPLEXITY=250",
"_APP_GRAPHQL_MAX_DEPTH=4",
"_APP_WEBHOOK_MAX_FAILED_ATTEMPTS=10",
"_APP_VCS_GITHUB_APP_NAME=",
"_APP_VCS_GITHUB_PRIVATE_KEY=",
"_APP_VCS_GITHUB_APP_ID=",
"_APP_VCS_GITHUB_CLIENT_ID=",
"_APP_VCS_GITHUB_CLIENT_SECRET=",
"_APP_VCS_GITHUB_WEBHOOK_SECRET=",
"_APP_MIGRATION_HOST=appwrite",
"_APP_MIGRATIONS_FIREBASE_CLIENT_ID=",
"_APP_MIGRATIONS_FIREBASE_CLIENT_SECRET=",
"_APP_ASSISTANT_OPENAI_API_KEY=",
]
[[config.mounts]]
filePath = "mongo-init.js"
content = """// mongo-init.js
// Switch to the admin database
const adminDb = db.getSiblingDB('admin');
// Get username and password from environment variables
const username = process.env.MONGO_INITDB_USERNAME;
const password = process.env.MONGO_INITDB_PASSWORD;
const database = process.env.MONGO_INITDB_DATABASE;
// Create the user
adminDb.createUser({
user: username,
pwd: password,
roles: [
{ role: 'readWrite', db: database }
]
});
"""
[[config.mounts]]
filePath = "mongo-entrypoint.sh"
content = """#!/bin/bash
set -e
# Fix keyfile permissions if mounted from volume
KEYFILE_PATH="/data/keyfile/mongo-keyfile"
if [ ! -f "$KEYFILE_PATH" ]; then
echo "Generating random MongoDB keyfile..."
mkdir -p /data/keyfile
openssl rand -base64 756 > "$KEYFILE_PATH"
fi
chmod 400 "$KEYFILE_PATH"
chown mongodb:mongodb "$KEYFILE_PATH" 2>/dev/null || chown 999:999 "$KEYFILE_PATH"
# Use MongoDB's standard entrypoint with our command
exec docker-entrypoint.sh mongod --replSet rs0 --bind_ip_all --auth --keyFile "$KEYFILE_PATH"
"""
[[config.domains]]
serviceName = "appwrite"
port = 80
host = "${main_domain}"
path = "/"
[[config.domains]]
serviceName = "appwrite"
port = 80
host = "${sites_domain}"
path = "/"
[[config.domains]]
serviceName = "appwrite"
port = 80
host = "${functions_domain}"
path = "/"
[[config.domains]]
serviceName = "appwrite-console"
port = 80
host = "${main_domain}"
path = "/console"
[[config.domains]]
serviceName = "appwrite-realtime"
port = 80
host = "${main_domain}"
path = "/v1/realtime"