Self-contained stack with 25 containers: API server, console, realtime WebSocket server, 10 workers, 3 schedulers, maintenance task, browser, OpenRuntimes executor, plus internal MariaDB 10.11 and Redis 7.4. Exposed on port 8093 via bundled Traefik. Watchtower disabled for deliberate upgrades. Also includes media.yml reformatting and Jellyfin GPU deploy block. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
671 lines
22 KiB
YAML
671 lines
22 KiB
YAML
version: '3.8'
|
|
|
|
# Appwrite - Backend-as-a-Service Platform
|
|
# Purpose: Self-hosted BaaS for development and testing (auth, database, storage, functions)
|
|
# Port: 8093 (console + API via Traefik), 8094 (HTTPS)
|
|
# GPU: No
|
|
# External: LAN only (dev/testing)
|
|
# Storage: SSD (all data), internal MariaDB + Redis
|
|
# Containers: ~20 (API, console, realtime, workers, schedulers, executor, MariaDB, Redis)
|
|
|
|
x-logging: &x-logging
|
|
logging:
|
|
driver: 'json-file'
|
|
options:
|
|
max-file: '5'
|
|
max-size: '10m'
|
|
|
|
x-appwrite-env: &appwrite-env
|
|
_APP_ENV: production
|
|
_APP_WORKER_PER_CORE: 6
|
|
_APP_LOCALE: en
|
|
_APP_DOMAIN: 192.168.86.149
|
|
_APP_DOMAIN_TARGET_CNAME: 192.168.86.149
|
|
_APP_DOMAIN_TARGET_A: 192.168.86.149
|
|
_APP_DOMAIN_FUNCTIONS: functions.localhost
|
|
_APP_DOMAIN_SITES: sites.localhost
|
|
_APP_CONSOLE_WHITELIST_ROOT: enabled
|
|
_APP_OPENSSL_KEY_V1: 2b8fd82b91b25205332c9d219a5838a752125965c6ea8ecfb0afe02e3307e163
|
|
_APP_EXECUTOR_SECRET: gbnq4JwfnXBm4J7h7kUNEWt+OhwV3agu
|
|
_APP_EXECUTOR_HOST: http://openruntimes-executor/v1
|
|
_APP_DB_ADAPTER: mariadb
|
|
_APP_DB_HOST: appwrite-mariadb
|
|
_APP_DB_PORT: '3306'
|
|
_APP_DB_SCHEMA: appwrite
|
|
_APP_DB_USER: appwrite
|
|
_APP_DB_PASS: ML8QbYgD05+7ZDHuRfmSTgDBr5VusxLi87ifyO5RlJg=
|
|
_APP_DB_ROOT_PASS: 2b8fd82b91b25205332c9d219a5838a752125965c6ea8ecfb0afe02e3307e163
|
|
_APP_REDIS_HOST: appwrite-redis
|
|
_APP_REDIS_PORT: '6379'
|
|
_APP_REDIS_USER: ''
|
|
_APP_REDIS_PASS: ''
|
|
_APP_STORAGE_LIMIT: '30000000'
|
|
_APP_STORAGE_PREVIEW_LIMIT: '20000000'
|
|
_APP_STORAGE_ANTIVIRUS: disabled
|
|
_APP_STORAGE_DEVICE: local
|
|
_APP_USAGE_STATS: enabled
|
|
_APP_OPTIONS_ABUSE: enabled
|
|
_APP_OPTIONS_FORCE_HTTPS: disabled
|
|
_APP_OPTIONS_ROUTER_PROTECTION: disabled
|
|
_APP_OPTIONS_ROUTER_FORCE_HTTPS: disabled
|
|
_APP_SYSTEM_EMAIL_NAME: Appwrite
|
|
_APP_SYSTEM_EMAIL_ADDRESS: appwrite@schweitz.net
|
|
_APP_EMAIL_SECURITY: ''
|
|
_APP_SYSTEM_RESPONSE_FORMAT: ''
|
|
_APP_GRAPHQL_INTROSPECTION: disabled
|
|
_APP_GRAPHQL_MAX_BATCH_SIZE: '10'
|
|
_APP_GRAPHQL_MAX_COMPLEXITY: '250'
|
|
_APP_GRAPHQL_MAX_DEPTH: '3'
|
|
_APP_MAINTENANCE_INTERVAL: '86400'
|
|
_APP_MAINTENANCE_RETENTION_EXECUTION: '1209600'
|
|
_APP_MAINTENANCE_RETENTION_CACHE: '2592000'
|
|
_APP_MAINTENANCE_RETENTION_ABUSE: '86400'
|
|
_APP_MAINTENANCE_RETENTION_AUDIT: '1209600'
|
|
_APP_MAINTENANCE_RETENTION_AUDIT_CONSOLE: '1209600'
|
|
_APP_MAINTENANCE_RETENTION_USAGE_HOURLY: '8640000'
|
|
_APP_MAINTENANCE_RETENTION_SCHEDULES: '86400'
|
|
_APP_FUNCTIONS_TIMEOUT: '900'
|
|
_APP_SITES_TIMEOUT: '900'
|
|
_APP_COMPUTE_BUILD_TIMEOUT: '900'
|
|
_APP_COMPUTE_CPUS: '0'
|
|
_APP_COMPUTE_MEMORY: '0'
|
|
_APP_COMPUTE_SIZE_LIMIT: '30000000'
|
|
_APP_FUNCTIONS_RUNTIMES: node-22.0,python-3.12,php-8.3,dart-3.5,bun-1.1
|
|
_APP_SITES_RUNTIMES: static-1.0
|
|
_APP_COMPUTE_RUNTIMES_NETWORK: runtimes
|
|
_APP_COMPUTE_INACTIVE_THRESHOLD: '60'
|
|
_APP_COMPUTE_MAINTENANCE_INTERVAL: '60'
|
|
_APP_LOGGING_CONFIG: ''
|
|
_APP_DNS: ''
|
|
_APP_COMPRESSION_MIN_SIZE_BYTES: '1024'
|
|
TZ: Europe/Amsterdam
|
|
|
|
services:
|
|
# ============================================
|
|
# Traefik - Internal Reverse Proxy
|
|
# Port: 8093 (HTTP), 8094 (HTTPS)
|
|
# Routes /console to console, /v1/realtime to realtime, everything else to API
|
|
# ============================================
|
|
appwrite-traefik:
|
|
image: traefik:3.6
|
|
container_name: appwrite-traefik
|
|
<<: *x-logging
|
|
restart: unless-stopped
|
|
command:
|
|
- --providers.file.directory=/storage/config
|
|
- --providers.file.watch=true
|
|
- --providers.docker=true
|
|
- --providers.docker.exposedByDefault=false
|
|
- --providers.docker.constraints=Label(`traefik.constraint-label-stack`,`appwrite`)
|
|
- --entrypoints.appwrite_web.address=:80
|
|
- --entrypoints.appwrite_websecure.address=:443
|
|
ports:
|
|
- "8093:80"
|
|
- "8094:443"
|
|
volumes:
|
|
- /var/run/docker.sock:/var/run/docker.sock
|
|
- /home/jpmschweitzer/docker-data/appwrite/config:/storage/config:ro
|
|
- /home/jpmschweitzer/docker-data/appwrite/certificates:/storage/certificates:ro
|
|
depends_on:
|
|
- appwrite
|
|
networks:
|
|
- appwrite
|
|
- docker-dataplane
|
|
|
|
# ============================================
|
|
# Appwrite API Server
|
|
# Internal only - served via Traefik
|
|
# ============================================
|
|
appwrite:
|
|
image: appwrite/appwrite:1.9.0
|
|
container_name: appwrite
|
|
<<: *x-logging
|
|
restart: unless-stopped
|
|
networks:
|
|
- appwrite
|
|
labels:
|
|
- traefik.enable=true
|
|
- traefik.constraint-label-stack=appwrite
|
|
- traefik.docker.network=appwrite
|
|
- traefik.http.services.appwrite_api.loadbalancer.server.port=80
|
|
- traefik.http.routers.appwrite_api_http.entrypoints=appwrite_web
|
|
- traefik.http.routers.appwrite_api_http.rule=PathPrefix(`/`)
|
|
- traefik.http.routers.appwrite_api_http.service=appwrite_api
|
|
- traefik.http.routers.appwrite_api_https.entrypoints=appwrite_websecure
|
|
- traefik.http.routers.appwrite_api_https.rule=PathPrefix(`/`)
|
|
- traefik.http.routers.appwrite_api_https.service=appwrite_api
|
|
- traefik.http.routers.appwrite_api_https.tls=true
|
|
- "com.centurylinklabs.watchtower.enable=false"
|
|
volumes:
|
|
- /home/jpmschweitzer/docker-data/appwrite/uploads:/storage/uploads:rw
|
|
- /home/jpmschweitzer/docker-data/appwrite/imports:/storage/imports:rw
|
|
- /home/jpmschweitzer/docker-data/appwrite/cache:/storage/cache:rw
|
|
- /home/jpmschweitzer/docker-data/appwrite/config:/storage/config:rw
|
|
- /home/jpmschweitzer/docker-data/appwrite/certificates:/storage/certificates:rw
|
|
- /home/jpmschweitzer/docker-data/appwrite/functions:/storage/functions:rw
|
|
- /home/jpmschweitzer/docker-data/appwrite/sites:/storage/sites:rw
|
|
- /home/jpmschweitzer/docker-data/appwrite/builds:/storage/builds:rw
|
|
depends_on:
|
|
appwrite-redis:
|
|
condition: service_healthy
|
|
appwrite-mariadb:
|
|
condition: service_healthy
|
|
environment:
|
|
<<: *appwrite-env
|
|
|
|
# ============================================
|
|
# Appwrite Console - Web UI
|
|
# Internal only - served via Traefik at /console
|
|
# ============================================
|
|
appwrite-console:
|
|
image: appwrite/console:7.8.26
|
|
container_name: appwrite-console
|
|
<<: *x-logging
|
|
restart: unless-stopped
|
|
networks:
|
|
- appwrite
|
|
labels:
|
|
- traefik.enable=true
|
|
- traefik.constraint-label-stack=appwrite
|
|
- traefik.docker.network=appwrite
|
|
- traefik.http.services.appwrite_console.loadbalancer.server.port=80
|
|
- traefik.http.routers.appwrite_console_http.entrypoints=appwrite_web
|
|
- traefik.http.routers.appwrite_console_http.rule=PathPrefix(`/console`)
|
|
- traefik.http.routers.appwrite_console_http.service=appwrite_console
|
|
- traefik.http.routers.appwrite_console_https.entrypoints=appwrite_websecure
|
|
- traefik.http.routers.appwrite_console_https.rule=PathPrefix(`/console`)
|
|
- traefik.http.routers.appwrite_console_https.service=appwrite_console
|
|
- traefik.http.routers.appwrite_console_https.tls=true
|
|
- "com.centurylinklabs.watchtower.enable=false"
|
|
|
|
# ============================================
|
|
# Appwrite Realtime - WebSocket Server
|
|
# Internal only - served via Traefik at /v1/realtime
|
|
# ============================================
|
|
appwrite-realtime:
|
|
image: appwrite/appwrite:1.9.0
|
|
entrypoint: realtime
|
|
container_name: appwrite-realtime
|
|
<<: *x-logging
|
|
restart: unless-stopped
|
|
networks:
|
|
- appwrite
|
|
labels:
|
|
- traefik.enable=true
|
|
- traefik.constraint-label-stack=appwrite
|
|
- traefik.docker.network=appwrite
|
|
- traefik.http.services.appwrite_realtime.loadbalancer.server.port=80
|
|
- traefik.http.routers.appwrite_realtime_ws.entrypoints=appwrite_web
|
|
- traefik.http.routers.appwrite_realtime_ws.rule=PathPrefix(`/v1/realtime`)
|
|
- traefik.http.routers.appwrite_realtime_ws.service=appwrite_realtime
|
|
- traefik.http.routers.appwrite_realtime_wss.entrypoints=appwrite_websecure
|
|
- traefik.http.routers.appwrite_realtime_wss.rule=PathPrefix(`/v1/realtime`)
|
|
- traefik.http.routers.appwrite_realtime_wss.service=appwrite_realtime
|
|
- traefik.http.routers.appwrite_realtime_wss.tls=true
|
|
depends_on:
|
|
appwrite-redis:
|
|
condition: service_healthy
|
|
appwrite-mariadb:
|
|
condition: service_healthy
|
|
environment:
|
|
<<: *appwrite-env
|
|
|
|
# ============================================
|
|
# Workers - Background Processing
|
|
# ============================================
|
|
appwrite-worker-audits:
|
|
image: appwrite/appwrite:1.9.0
|
|
entrypoint: worker-audits
|
|
container_name: appwrite-worker-audits
|
|
<<: *x-logging
|
|
restart: unless-stopped
|
|
networks:
|
|
- appwrite
|
|
depends_on:
|
|
appwrite-redis:
|
|
condition: service_healthy
|
|
appwrite-mariadb:
|
|
condition: service_healthy
|
|
environment:
|
|
<<: *appwrite-env
|
|
|
|
appwrite-worker-webhooks:
|
|
image: appwrite/appwrite:1.9.0
|
|
entrypoint: worker-webhooks
|
|
container_name: appwrite-worker-webhooks
|
|
<<: *x-logging
|
|
restart: unless-stopped
|
|
networks:
|
|
- appwrite
|
|
depends_on:
|
|
appwrite-redis:
|
|
condition: service_healthy
|
|
appwrite-mariadb:
|
|
condition: service_healthy
|
|
environment:
|
|
<<: *appwrite-env
|
|
|
|
appwrite-worker-deletes:
|
|
image: appwrite/appwrite:1.9.0
|
|
entrypoint: worker-deletes
|
|
container_name: appwrite-worker-deletes
|
|
<<: *x-logging
|
|
restart: unless-stopped
|
|
networks:
|
|
- appwrite
|
|
volumes:
|
|
- /home/jpmschweitzer/docker-data/appwrite/uploads:/storage/uploads:rw
|
|
- /home/jpmschweitzer/docker-data/appwrite/cache:/storage/cache:rw
|
|
- /home/jpmschweitzer/docker-data/appwrite/functions:/storage/functions:rw
|
|
- /home/jpmschweitzer/docker-data/appwrite/sites:/storage/sites:rw
|
|
- /home/jpmschweitzer/docker-data/appwrite/builds:/storage/builds:rw
|
|
- /home/jpmschweitzer/docker-data/appwrite/certificates:/storage/certificates:rw
|
|
depends_on:
|
|
appwrite-redis:
|
|
condition: service_healthy
|
|
appwrite-mariadb:
|
|
condition: service_healthy
|
|
environment:
|
|
<<: *appwrite-env
|
|
|
|
appwrite-worker-databases:
|
|
image: appwrite/appwrite:1.9.0
|
|
entrypoint: worker-databases
|
|
container_name: appwrite-worker-databases
|
|
<<: *x-logging
|
|
restart: unless-stopped
|
|
networks:
|
|
- appwrite
|
|
depends_on:
|
|
appwrite-redis:
|
|
condition: service_healthy
|
|
appwrite-mariadb:
|
|
condition: service_healthy
|
|
environment:
|
|
<<: *appwrite-env
|
|
|
|
appwrite-worker-builds:
|
|
image: appwrite/appwrite:1.9.0
|
|
entrypoint: worker-builds
|
|
container_name: appwrite-worker-builds
|
|
<<: *x-logging
|
|
restart: unless-stopped
|
|
networks:
|
|
- appwrite
|
|
volumes:
|
|
- /home/jpmschweitzer/docker-data/appwrite/functions:/storage/functions:rw
|
|
- /home/jpmschweitzer/docker-data/appwrite/sites:/storage/sites:rw
|
|
- /home/jpmschweitzer/docker-data/appwrite/builds:/storage/builds:rw
|
|
- /home/jpmschweitzer/docker-data/appwrite/uploads:/storage/uploads:rw
|
|
depends_on:
|
|
appwrite-redis:
|
|
condition: service_healthy
|
|
appwrite-mariadb:
|
|
condition: service_healthy
|
|
environment:
|
|
<<: *appwrite-env
|
|
|
|
appwrite-worker-certificates:
|
|
image: appwrite/appwrite:1.9.0
|
|
entrypoint: worker-certificates
|
|
container_name: appwrite-worker-certificates
|
|
<<: *x-logging
|
|
restart: unless-stopped
|
|
networks:
|
|
- appwrite
|
|
volumes:
|
|
- /home/jpmschweitzer/docker-data/appwrite/config:/storage/config:rw
|
|
- /home/jpmschweitzer/docker-data/appwrite/certificates:/storage/certificates:rw
|
|
depends_on:
|
|
appwrite-redis:
|
|
condition: service_healthy
|
|
appwrite-mariadb:
|
|
condition: service_healthy
|
|
environment:
|
|
<<: *appwrite-env
|
|
|
|
appwrite-worker-functions:
|
|
image: appwrite/appwrite:1.9.0
|
|
entrypoint: worker-functions
|
|
container_name: appwrite-worker-functions
|
|
<<: *x-logging
|
|
restart: unless-stopped
|
|
networks:
|
|
- appwrite
|
|
depends_on:
|
|
appwrite-redis:
|
|
condition: service_healthy
|
|
appwrite-mariadb:
|
|
condition: service_healthy
|
|
openruntimes-executor:
|
|
condition: service_started
|
|
environment:
|
|
<<: *appwrite-env
|
|
|
|
appwrite-worker-mails:
|
|
image: appwrite/appwrite:1.9.0
|
|
entrypoint: worker-mails
|
|
container_name: appwrite-worker-mails
|
|
<<: *x-logging
|
|
restart: unless-stopped
|
|
networks:
|
|
- appwrite
|
|
depends_on:
|
|
appwrite-redis:
|
|
condition: service_healthy
|
|
appwrite-mariadb:
|
|
condition: service_healthy
|
|
environment:
|
|
<<: *appwrite-env
|
|
|
|
appwrite-worker-messaging:
|
|
image: appwrite/appwrite:1.9.0
|
|
entrypoint: worker-messaging
|
|
container_name: appwrite-worker-messaging
|
|
<<: *x-logging
|
|
restart: unless-stopped
|
|
networks:
|
|
- appwrite
|
|
volumes:
|
|
- /home/jpmschweitzer/docker-data/appwrite/uploads:/storage/uploads:rw
|
|
depends_on:
|
|
appwrite-redis:
|
|
condition: service_healthy
|
|
appwrite-mariadb:
|
|
condition: service_healthy
|
|
environment:
|
|
<<: *appwrite-env
|
|
|
|
appwrite-worker-migrations:
|
|
image: appwrite/appwrite:1.9.0
|
|
entrypoint: worker-migrations
|
|
container_name: appwrite-worker-migrations
|
|
<<: *x-logging
|
|
restart: unless-stopped
|
|
networks:
|
|
- appwrite
|
|
volumes:
|
|
- /home/jpmschweitzer/docker-data/appwrite/imports:/storage/imports:rw
|
|
depends_on:
|
|
appwrite-redis:
|
|
condition: service_healthy
|
|
appwrite-mariadb:
|
|
condition: service_healthy
|
|
environment:
|
|
<<: *appwrite-env
|
|
|
|
# ============================================
|
|
# Stats Workers
|
|
# ============================================
|
|
appwrite-task-stats-resources:
|
|
image: appwrite/appwrite:1.9.0
|
|
entrypoint: stats-resources
|
|
container_name: appwrite-task-stats-resources
|
|
<<: *x-logging
|
|
restart: unless-stopped
|
|
networks:
|
|
- appwrite
|
|
depends_on:
|
|
appwrite-redis:
|
|
condition: service_healthy
|
|
appwrite-mariadb:
|
|
condition: service_healthy
|
|
environment:
|
|
<<: *appwrite-env
|
|
|
|
appwrite-worker-stats-resources:
|
|
image: appwrite/appwrite:1.9.0
|
|
entrypoint: worker-stats-resources
|
|
container_name: appwrite-worker-stats-resources
|
|
<<: *x-logging
|
|
restart: unless-stopped
|
|
networks:
|
|
- appwrite
|
|
depends_on:
|
|
appwrite-redis:
|
|
condition: service_healthy
|
|
appwrite-mariadb:
|
|
condition: service_healthy
|
|
environment:
|
|
<<: *appwrite-env
|
|
|
|
appwrite-worker-stats-usage:
|
|
image: appwrite/appwrite:1.9.0
|
|
entrypoint: worker-stats-usage
|
|
container_name: appwrite-worker-stats-usage
|
|
<<: *x-logging
|
|
restart: unless-stopped
|
|
networks:
|
|
- appwrite
|
|
depends_on:
|
|
appwrite-redis:
|
|
condition: service_healthy
|
|
appwrite-mariadb:
|
|
condition: service_healthy
|
|
environment:
|
|
<<: *appwrite-env
|
|
|
|
# ============================================
|
|
# Task Schedulers
|
|
# ============================================
|
|
appwrite-task-scheduler-functions:
|
|
image: appwrite/appwrite:1.9.0
|
|
entrypoint: schedule-functions
|
|
container_name: appwrite-task-scheduler-functions
|
|
<<: *x-logging
|
|
restart: unless-stopped
|
|
networks:
|
|
- appwrite
|
|
depends_on:
|
|
appwrite-redis:
|
|
condition: service_healthy
|
|
appwrite-mariadb:
|
|
condition: service_healthy
|
|
environment:
|
|
<<: *appwrite-env
|
|
|
|
appwrite-task-scheduler-executions:
|
|
image: appwrite/appwrite:1.9.0
|
|
entrypoint: schedule-executions
|
|
container_name: appwrite-task-scheduler-executions
|
|
<<: *x-logging
|
|
restart: unless-stopped
|
|
networks:
|
|
- appwrite
|
|
depends_on:
|
|
appwrite-redis:
|
|
condition: service_healthy
|
|
appwrite-mariadb:
|
|
condition: service_healthy
|
|
environment:
|
|
<<: *appwrite-env
|
|
|
|
appwrite-task-scheduler-messages:
|
|
image: appwrite/appwrite:1.9.0
|
|
entrypoint: schedule-messages
|
|
container_name: appwrite-task-scheduler-messages
|
|
<<: *x-logging
|
|
restart: unless-stopped
|
|
networks:
|
|
- appwrite
|
|
depends_on:
|
|
appwrite-redis:
|
|
condition: service_healthy
|
|
appwrite-mariadb:
|
|
condition: service_healthy
|
|
environment:
|
|
<<: *appwrite-env
|
|
|
|
# ============================================
|
|
# Maintenance Task
|
|
# ============================================
|
|
appwrite-task-maintenance:
|
|
image: appwrite/appwrite:1.9.0
|
|
entrypoint: maintenance
|
|
container_name: appwrite-task-maintenance
|
|
<<: *x-logging
|
|
restart: unless-stopped
|
|
networks:
|
|
- appwrite
|
|
depends_on:
|
|
appwrite-redis:
|
|
condition: service_healthy
|
|
appwrite-mariadb:
|
|
condition: service_healthy
|
|
environment:
|
|
<<: *appwrite-env
|
|
|
|
# ============================================
|
|
# Browser Service (SSR rendering)
|
|
# ============================================
|
|
appwrite-browser:
|
|
image: appwrite/browser:0.3.2
|
|
container_name: appwrite-browser
|
|
<<: *x-logging
|
|
restart: unless-stopped
|
|
networks:
|
|
- appwrite
|
|
|
|
# ============================================
|
|
# OpenRuntimes - Serverless Function Executor
|
|
# Requires Docker socket for spawning runtime containers
|
|
# ============================================
|
|
openruntimes-executor:
|
|
image: openruntimes/executor:0.7.22
|
|
container_name: openruntimes-executor
|
|
hostname: exc1
|
|
<<: *x-logging
|
|
restart: unless-stopped
|
|
stop_signal: SIGINT
|
|
networks:
|
|
- appwrite
|
|
- runtimes
|
|
volumes:
|
|
- /var/run/docker.sock:/var/run/docker.sock
|
|
- /home/jpmschweitzer/docker-data/appwrite/builds:/storage/builds:rw
|
|
- /home/jpmschweitzer/docker-data/appwrite/functions:/storage/functions:rw
|
|
- /home/jpmschweitzer/docker-data/appwrite/sites:/storage/sites:rw
|
|
- /tmp:/tmp:rw
|
|
environment:
|
|
- OPR_EXECUTOR_INACTIVE_TRESHOLD=${_APP_COMPUTE_INACTIVE_THRESHOLD:-60}
|
|
- OPR_EXECUTOR_MAINTENANCE_INTERVAL=${_APP_COMPUTE_MAINTENANCE_INTERVAL:-60}
|
|
- OPR_EXECUTOR_NETWORK=runtimes
|
|
- OPR_EXECUTOR_ENV=production
|
|
- OPR_EXECUTOR_RUNTIMES=node-22.0,python-3.12,php-8.3,dart-3.5,bun-1.1,static-1.0
|
|
- OPR_EXECUTOR_SECRET=gbnq4JwfnXBm4J7h7kUNEWt+OhwV3agu
|
|
- OPR_EXECUTOR_RUNTIME_VERSIONS=v5
|
|
- OPR_EXECUTOR_LOGGING_CONFIG=
|
|
- OPR_EXECUTOR_STORAGE_DEVICE=local
|
|
|
|
# ============================================
|
|
# MariaDB - Internal Database (Appwrite core component)
|
|
# NOT exposed to host - Appwrite-only
|
|
# ============================================
|
|
appwrite-mariadb:
|
|
image: mariadb:10.11
|
|
container_name: appwrite-mariadb
|
|
<<: *x-logging
|
|
restart: unless-stopped
|
|
networks:
|
|
- appwrite
|
|
volumes:
|
|
- /home/jpmschweitzer/docker-data/appwrite/mariadb:/var/lib/mysql:rw
|
|
environment:
|
|
MYSQL_ROOT_PASSWORD: 2b8fd82b91b25205332c9d219a5838a752125965c6ea8ecfb0afe02e3307e163
|
|
MYSQL_DATABASE: appwrite
|
|
MYSQL_USER: appwrite
|
|
MYSQL_PASSWORD: ML8QbYgD05+7ZDHuRfmSTgDBr5VusxLi87ifyO5RlJg=
|
|
MARIADB_AUTO_UPGRADE: '1'
|
|
TZ: Europe/Amsterdam
|
|
command: 'mysqld --innodb-flush-method=fsync'
|
|
healthcheck:
|
|
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
|
|
interval: 10s
|
|
timeout: 10s
|
|
retries: 10
|
|
start_period: 30s
|
|
|
|
|
|
# ============================================
|
|
# Redis - Internal Cache/Queue (Appwrite core component)
|
|
# NOT exposed to host - lives and dies with the stack
|
|
# ============================================
|
|
appwrite-redis:
|
|
image: redis:7.4-alpine
|
|
container_name: appwrite-redis
|
|
<<: *x-logging
|
|
restart: unless-stopped
|
|
networks:
|
|
- appwrite
|
|
command: >
|
|
redis-server
|
|
--maxmemory 512mb
|
|
--maxmemory-policy allkeys-lru
|
|
--maxmemory-samples 5
|
|
volumes:
|
|
- /home/jpmschweitzer/docker-data/appwrite/redis:/data:rw
|
|
healthcheck:
|
|
test: ["CMD", "redis-cli", "ping"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
start_period: 10s
|
|
|
|
networks:
|
|
appwrite:
|
|
name: appwrite
|
|
runtimes:
|
|
name: runtimes
|
|
docker-dataplane:
|
|
external: true
|
|
name: docker-dataplane
|
|
|
|
# =============================================================================
|
|
# DEPLOYMENT INSTRUCTIONS
|
|
# =============================================================================
|
|
#
|
|
# Phase 1: Data Directories (DONE)
|
|
# Created at ~/docker-data/appwrite/{uploads,imports,cache,config,certificates,
|
|
# functions,sites,builds,mariadb,redis}
|
|
#
|
|
# Phase 2: Deploy Stack
|
|
# Deploy via Portainer as stack "appwrite"
|
|
# All environment variables are inline - no .env file needed
|
|
#
|
|
# Phase 3: Initial Setup
|
|
# 1. Access http://192.168.86.149:8093/console
|
|
# 2. Create admin account (first user becomes admin)
|
|
# 3. Create a project for development
|
|
#
|
|
# Phase 4: (Optional) NPM Proxy Configuration
|
|
# If external access is needed later:
|
|
# 1. Create proxy host: appwrite.schweitz.net -> 192.168.86.149:8093
|
|
# 2. Enable: Block Common Exploits, Websockets Support
|
|
# 3. SSL: Let's Encrypt, Force SSL, HTTP/2
|
|
#
|
|
# =============================================================================
|
|
# CREDENTIALS
|
|
# =============================================================================
|
|
# MariaDB:
|
|
# Host: appwrite-mariadb:3306 (internal only)
|
|
# Database: appwrite
|
|
# User: appwrite
|
|
# Password: ML8QbYgD05+7ZDHuRfmSTgDBr5VusxLi87ifyO5RlJg=
|
|
# Root Password: 2b8fd82b91b25205332c9d219a5838a752125965c6ea8ecfb0afe02e3307e163
|
|
#
|
|
# Redis:
|
|
# Host: appwrite-redis:6379 (internal only, no password)
|
|
#
|
|
# OpenSSL Key: 2b8fd82b91b25205332c9d219a5838a752125965c6ea8ecfb0afe02e3307e163
|
|
# Executor Secret: gbnq4JwfnXBm4J7h7kUNEWt+OhwV3agu
|
|
#
|
|
# =============================================================================
|
|
# ARCHITECTURE NOTES
|
|
# =============================================================================
|
|
# - MariaDB and Redis are internal to the stack (not exposed to host)
|
|
# - Traefik handles routing: /console -> console, /v1/realtime -> realtime, / -> API
|
|
# - OpenRuntimes executor needs Docker socket to spawn function containers
|
|
# - The 'runtimes' network is used for executor <-> function container communication
|
|
# - Watchtower is disabled (label) - Appwrite upgrades should be deliberate
|
|
# - All 20+ containers share the same appwrite/appwrite:1.9.0 image with different entrypoints
|