commit d47361e7f2b052f013326d5637a68fa4e5d89534 Author: till Date: Tue Jun 30 10:58:22 2026 +0000 AppFlowy Cloud schlanke Self-Host-Compose (Coolify/Traefik, ohne ai+search, Mem-Limits, Secrets via Env) diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..09e5649 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SECRETS.txt diff --git a/README.md b/README.md new file mode 100644 index 0000000..7dac0d2 --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ +# appflowy-selfhost (Heidrich Digital) + +Schlanke Self-Host-Variante von AppFlowy Cloud fuer Coolify/Traefik auf dem CX33. +- Ohne `ai` + `appflowy_search` (Ressourcen sparen). Mem-Limits ~2.3 GB. +- nginx laeuft hinter Coolify-Traefik (keine Host-Ports), im `coolify`-Netz. +- FQDN: appflowy.46.224.49.66.sslip.io +- Login-Mails: AUTOCONFIRM=true (kein Pflicht-SMTP fuer den Test; Registrierung mit E-Mail+Passwort direkt moeglich). + +Bei Bedarf spaeter: `ai`/`search` ergaenzen, eigener Server, echtes SMTP, OIDC via Forgejo. diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..95a235c --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,171 @@ +# AppFlowy Cloud — schlanke Self-Host-Variante fuer Heidrich Digital (Coolify/Traefik) +# Abgespeckt: ohne 'ai' und 'appflowy_search'. Mem-Limits als Leitplanke (~2.3 GB). +# Hinter Traefik: nginx ohne Host-Ports, im coolify-Netz. +services: + postgres: + image: pgvector/pgvector:pg16 + restart: on-failure + mem_limit: 512m + environment: + - POSTGRES_USER=postgres + - POSTGRES_DB=postgres + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + healthcheck: + test: ["CMD","pg_isready","-U","postgres","-d","postgres"] + interval: 5s + timeout: 5s + retries: 12 + volumes: + - postgres_data:/var/lib/postgresql/data + + redis: + image: redis + restart: on-failure + mem_limit: 128m + + minio: + image: minio/minio + restart: on-failure + mem_limit: 256m + environment: + - MINIO_BROWSER_REDIRECT_URL=https://appflowy.46.224.49.66.sslip.io/minio + - MINIO_ROOT_USER=${MINIO_KEY} + - MINIO_ROOT_PASSWORD=${MINIO_SECRET} + command: server /data --console-address ":9001" + volumes: + - minio_data:/data + + gotrue: + image: appflowyinc/gotrue:latest + restart: on-failure + mem_limit: 192m + depends_on: + postgres: + condition: service_healthy + environment: + - GOTRUE_ADMIN_EMAIL=mail@heidrich-digital.de + - GOTRUE_ADMIN_PASSWORD=${GOTRUE_ADMIN_PASSWORD} + - GOTRUE_DISABLE_SIGNUP=false + - GOTRUE_SITE_URL=appflowy-flutter:// + - GOTRUE_URI_ALLOW_LIST=** + - GOTRUE_JWT_SECRET=${GOTRUE_JWT_SECRET} + - GOTRUE_JWT_EXP=604800 + - GOTRUE_JWT_ADMIN_GROUP_NAME=supabase_admin + - GOTRUE_DB_DRIVER=postgres + - API_EXTERNAL_URL=https://appflowy.46.224.49.66.sslip.io/gotrue + - DATABASE_URL=postgres://postgres:${POSTGRES_PASSWORD}@postgres:5432/postgres?search_path=auth + - PORT=9999 + - GOTRUE_MAILER_URLPATHS_CONFIRMATION=/gotrue/verify + - GOTRUE_MAILER_URLPATHS_INVITE=/gotrue/verify + - GOTRUE_MAILER_URLPATHS_RECOVERY=/gotrue/verify + - GOTRUE_MAILER_URLPATHS_EMAIL_CHANGE=/gotrue/verify + - GOTRUE_MAILER_AUTOCONFIRM=true + - GOTRUE_SMTP_MAX_FREQUENCY=1ns + - GOTRUE_RATE_LIMIT_EMAIL_SENT=100 + healthcheck: + test: "curl --fail http://127.0.0.1:9999/health || exit 1" + interval: 5s + timeout: 5s + retries: 12 + start_period: 40s + + appflowy_cloud: + image: appflowyinc/appflowy_cloud:latest + restart: on-failure + mem_limit: 640m + depends_on: + gotrue: + condition: service_healthy + environment: + - RUST_LOG=info + - APPFLOWY_ENVIRONMENT=production + - APPFLOWY_DATABASE_URL=postgres://postgres:${POSTGRES_PASSWORD}@postgres:5432/postgres + - APPFLOWY_REDIS_URI=redis://redis:6379 + - APPFLOWY_GOTRUE_JWT_SECRET=${GOTRUE_JWT_SECRET} + - APPFLOWY_GOTRUE_BASE_URL=http://gotrue:9999 + - APPFLOWY_S3_CREATE_BUCKET=true + - APPFLOWY_S3_USE_MINIO=true + - APPFLOWY_S3_MINIO_URL=http://minio:9000 + - APPFLOWY_S3_ACCESS_KEY=${MINIO_KEY} + - APPFLOWY_S3_SECRET_KEY=${MINIO_SECRET} + - APPFLOWY_S3_BUCKET=appflowy + - APPFLOWY_S3_PRESIGNED_URL_ENDPOINT=https://appflowy.46.224.49.66.sslip.io/minio-api + - APPFLOWY_ACCESS_CONTROL=true + - APPFLOWY_DATABASE_MAX_CONNECTIONS=20 + - APPFLOWY_WEB_URL=https://appflowy.46.224.49.66.sslip.io + - APPFLOWY_BASE_URL=https://appflowy.46.224.49.66.sslip.io + - AI_ENABLED=false + - APPFLOWY_SEARCH_SERVICE_URL= + healthcheck: + test: "curl --fail http://127.0.0.1:8000/api/health || exit 1" + interval: 5s + timeout: 5s + retries: 12 + + appflowy_worker: + image: appflowyinc/appflowy_worker:latest + restart: on-failure + mem_limit: 256m + depends_on: + appflowy_cloud: + condition: service_healthy + environment: + - RUST_LOG=info + - APPFLOWY_ENVIRONMENT=production + - APPFLOWY_WORKER_REDIS_URL=redis://redis:6379 + - APPFLOWY_WORKER_ENVIRONMENT=production + - APPFLOWY_WORKER_DATABASE_URL=postgres://postgres:${POSTGRES_PASSWORD}@postgres:5432/postgres + - APPFLOWY_WORKER_DATABASE_NAME=postgres + - APPFLOWY_WORKER_IMPORT_TICK_INTERVAL=30 + - APPFLOWY_S3_USE_MINIO=true + - APPFLOWY_S3_MINIO_URL=http://minio:9000 + - APPFLOWY_S3_ACCESS_KEY=${MINIO_KEY} + - APPFLOWY_S3_SECRET_KEY=${MINIO_SECRET} + - APPFLOWY_S3_BUCKET=appflowy + + admin_frontend: + image: appflowyinc/admin_frontend:latest + restart: on-failure + mem_limit: 96m + depends_on: + appflowy_cloud: + condition: service_healthy + environment: + - APPFLOWY_GOTRUE_BASE_URL=http://gotrue:9999 + - APPFLOWY_BASE_URL=http://appflowy_cloud:8000 + + appflowy_web: + image: appflowyinc/appflowy_web:latest + restart: on-failure + mem_limit: 256m + depends_on: + appflowy_cloud: + condition: service_healthy + environment: + - APPFLOWY_BASE_URL=https://appflowy.46.224.49.66.sslip.io + - APPFLOWY_GOTRUE_BASE_URL=https://appflowy.46.224.49.66.sslip.io/gotrue + - APPFLOWY_WS_BASE_URL=wss://appflowy.46.224.49.66.sslip.io/ws/v2 + + nginx: + image: nginx + restart: on-failure + mem_limit: 96m + depends_on: + - appflowy_cloud + - appflowy_web + - gotrue + volumes: + - ./nginx/nginx.conf:/etc/nginx/nginx.conf + - ./nginx/ssl/certificate.crt:/etc/nginx/ssl/certificate.crt + - ./nginx/ssl/private_key.key:/etc/nginx/ssl/private_key.key + networks: + - default + - coolify + +networks: + coolify: + external: true + +volumes: + postgres_data: + minio_data: diff --git a/nginx/nginx.conf b/nginx/nginx.conf new file mode 100644 index 0000000..ecd1d37 --- /dev/null +++ b/nginx/nginx.conf @@ -0,0 +1,227 @@ +# Minimal nginx configuration for AppFlowy-Cloud +# Self Hosted AppFlowy Cloud user should alter this file to suit their needs, +# or use the appflowy.site.conf in external_proxy_config/nginx if they are using +# an external proxy. + +events { + worker_connections 1024; +} + +http { + # docker dns resolver + resolver 127.0.0.11 valid=10s; + #error_log /var/log/nginx/error.log debug; + + map $http_upgrade $connection_upgrade { + default upgrade; + '' close; + } + + map $http_origin $cors_origin { + default $http_origin; + } + + server { + listen 8080; + + # https://github.com/nginxinc/nginx-prometheus-exporter + location = /stub_status { + stub_status; + } + } + + + server { + ssl_certificate /etc/nginx/ssl/certificate.crt; + ssl_certificate_key /etc/nginx/ssl/private_key.key; + + listen 80; + listen 443 ssl; + client_max_body_size 10M; + + underscores_in_headers on; + set $appflowy_cloud_backend "http://appflowy_cloud:8000"; + set $gotrue_backend "http://gotrue:9999"; + set $admin_frontend_backend "http://admin_frontend:3000"; + set $appflowy_web_backend "http://appflowy_web:80"; + set $minio_backend "http://minio:9001"; + set $minio_api_backend "http://minio:9000"; + # Host name for minio, used internally within docker compose + set $minio_internal_host "minio:9000"; + set $pgadmin_backend "http://pgadmin:80"; + + # GoTrue + location /gotrue/ { + proxy_pass $gotrue_backend; + + rewrite ^/gotrue(/.*)$ $1 break; + + # Allow headers like redirect_to to be handed over to the gotrue + # for correct redirecting + proxy_set_header Host $http_host; + proxy_pass_request_headers on; + } + + # WebSocket + location /ws { + # Existing proxy configuration + proxy_pass $appflowy_cloud_backend; + + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_read_timeout 86400s; + } + + location /api { + proxy_pass $appflowy_cloud_backend; + proxy_set_header X-Request-Id $request_id; + proxy_set_header Host $http_host; + + location ~* ^/api/workspace/([a-zA-Z0-9_-]+)/publish$ { + proxy_pass $appflowy_cloud_backend; + proxy_request_buffering off; + client_max_body_size 256M; + } + + # AppFlowy-Cloud + location /api/chat { + proxy_pass $appflowy_cloud_backend; + + proxy_http_version 1.1; + proxy_set_header Connection ""; + chunked_transfer_encoding on; + proxy_buffering off; + proxy_cache off; + + proxy_read_timeout 600s; + proxy_connect_timeout 600s; + proxy_send_timeout 600s; + } + + location /api/import { + proxy_pass $appflowy_cloud_backend; + + # Set headers + proxy_set_header X-Request-Id $request_id; + proxy_set_header Host $http_host; + + # Timeouts + proxy_read_timeout 600s; + proxy_connect_timeout 600s; + proxy_send_timeout 600s; + + # Disable buffering for large file uploads + proxy_request_buffering off; + proxy_buffering off; + proxy_cache off; + client_max_body_size 2G; + } + } + + # Minio Web UI + # Derive from: https://min.io/docs/minio/linux/integrations/setup-nginx-proxy-with-minio.html + # Optional Module, comment this section if you did not deploy minio in docker-compose.yml + # This endpoint is meant to be used for the MinIO Web UI, accessible via the admin portal + location /minio/ { + proxy_pass $minio_backend; + + rewrite ^/minio/(.*) /$1 break; + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-NginX-Proxy true; + + ## This is necessary to pass the correct IP to be hashed + real_ip_header X-Real-IP; + + proxy_connect_timeout 300s; + + ## To support websockets in MinIO versions released after January 2023 + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + # Some environments may encounter CORS errors (Kubernetes + Nginx Ingress) + # Uncomment the following line to set the Origin request to an empty string + # proxy_set_header Origin ''; + + chunked_transfer_encoding off; + } + + # Optional Module, comment this section if you did not deploy minio in docker-compose.yml + # This is used for presigned url, which is needs to be exposed to the AppFlowy client application. + location /minio-api/ { + proxy_pass $minio_api_backend; + + # Set the host to internal host because the presigned url was signed against the internal host + proxy_set_header Host $minio_internal_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + rewrite ^/minio-api/(.*) /$1 break; + + proxy_connect_timeout 300s; + proxy_read_timeout 600s; + proxy_send_timeout 600s; + proxy_request_buffering off; + # Default is HTTP/1, keepalive is only enabled in HTTP/1.1 + proxy_http_version 1.1; + proxy_set_header Connection ""; + chunked_transfer_encoding off; + client_max_body_size 0; + } + + # PgAdmin + # Optional Module, comment this section if you did not deploy pgadmin in docker-compose.yml + location /pgadmin/ { + set $pgadmin pgadmin; + proxy_pass $pgadmin_backend; + + proxy_set_header X-Script-Name /pgadmin; + proxy_set_header X-Scheme $scheme; + proxy_set_header Host $host; + proxy_redirect off; + } + + # AI + location /ai/ { + proxy_pass $appflowy_cloud_backend; + proxy_set_header X-Request-Id $request_id; + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + # Admin Frontend + location /console { + proxy_pass $admin_frontend_backend; + + proxy_set_header X-Forwarded-Host $http_host; + proxy_set_header Host $http_host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Scheme $scheme; + + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + proxy_cache_bypass $http_upgrade; + } + + # AppFlowy Web + location / { + proxy_pass $appflowy_web_backend; + proxy_set_header X-Scheme $scheme; + proxy_set_header Host $host; + } + } + +} diff --git a/nginx/ssl/certificate.crt b/nginx/ssl/certificate.crt new file mode 100755 index 0000000..10514d9 --- /dev/null +++ b/nginx/ssl/certificate.crt @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFRDCCAywCCQDXwkFioxoJ2TANBgkqhkiG9w0BAQsFADBkMQswCQYDVQQGEwJV +UzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJU3Vubnl2YWxlMRYwFAYD +VQQKDA1BcHBGbG93eSxJbmMuMRQwEgYDVQQDDAthcHBmbG93eS5pbzAeFw0yMzAz +MTUwMDUxNDVaFw0yNDAzMTQwMDUxNDVaMGQxCzAJBgNVBAYTAlVTMRMwEQYDVQQI +DApDYWxpZm9ybmlhMRIwEAYDVQQHDAlTdW5ueXZhbGUxFjAUBgNVBAoMDUFwcEZs +b3d5LEluYy4xFDASBgNVBAMMC2FwcGZsb3d5LmlvMIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEA09v/ouq4r7+oLOWqVscYpW5QRLR5O6OYZprocIARAtWA +qBkywhPku/SZq27dtPD7Pi3soSPkMhYDFALai4idgELCFxxkTuHWNm3J+Y8PcMq2 +RX325/pQVpOMTkChqaUzh93ynYqv89x3lT9z4saknBde/WO2yOJ6sfED9w+ezYgm +34LV5Z0cofQTDEiTX58KV3MmG5hRMdBwCaDg1jUb3jKr5lBrF4+EHbAN5PWH282V +JdyOTvZp/CF5TcnAMONkYENjURpnSXJes34ufYHkmr0eDa+2pfc3TI5wlB3tPQyN +p+B5TsDCDofv0Zme5Ur42TWcwsG0WRvtDw2KZ98wBtGaIv8UEQjXipNQVzeCv5Yv +zeykjdDhOJ/OZFzsm2vtl55t52M43xYMo3QPmjHMiVYz9KVvPqrVo+O5PI7B7uwY +JxWQIJosUa6AeKfkCAQd8mlNqYylqV8Utqs8b4zee8Vf7hzaCYNKxyDvqsd3yDwE +umh5zVuxJitLchDFT4mv1v3yLHocusV2lwjfEk66R/o5BBDdviycxeAM5Q1lyi7M +RywHAt/eVQNaBq0HSa2vbIm5yTZNQYwuhnNgv035hf8vpu+tFOGepTqgy/CrYpPm +VnsClJVrmxd4LfUZ0aZODiKCVx6psfeBvTXu1r7/SjsmbvYE4ubfM66optyFc3cC +AwEAATANBgkqhkiG9w0BAQsFAAOCAgEAfhSUTP91rBP+8zvsoxomKdeClVFURczr +HO/VuXVmBoKLASFqFcT84usRhb5T6XB7o2GcCYSo0VFJw99UM6nLsZ7c0MKaAjT6 +/9VeyLtDfhCDkffGGxpeYhme+0PY8TXIU5aO0ZhQwzXUOiC7t3Ac3AzHTPGrGqOK +aAGhMo7V2bQXcNR6NFhsUlJOtVE59MxL1K5Ug1oMn/H+NUF6/st+KzohruQJSSWG +GcbqVor0zZbFJSvRJ5P3ngw2cg2SIj9w6RwUWMp+a5kOx10fOYrQEHGyTHFlVDy0 +yOCU4eVO3EVTm7Se1XVwmG3kNKQaLFJf1voMuYD2sFbZ0nhGJDSZOcGUrchUXPQB +C9MwU52OeNm5VwE/41wLoFvOkJ/I/Ak7vccl1YJXpefa6qjNOFm5X0jA7D4egDfC +IVs5m30qa6Birx0xS6RUuuvxLJyNzgLSzsC1eFwjR2uwIUrGpYo3YI4+bMxp2Wnk +6qtm5G8D1giWg6z0RLw+GSj4QfcJEBP+zyiH/MdB5te9kXVYLKyS+DGgTTatLi1l +MBBK5b7dvfwo08J/sksK+mPHHBsV9TPAkqMp9vuZw25pRAEnvjEOUPfi3X9EZDw7 +A3LElN9KDks3IioioAOm0vPvHrlfziSljt5IMkuZLT3lUe6B3cs69caLO0S/ZDTz +yqGwLIqHYos= +-----END CERTIFICATE----- diff --git a/nginx/ssl/private_key.key b/nginx/ssl/private_key.key new file mode 100755 index 0000000..d403fc7 --- /dev/null +++ b/nginx/ssl/private_key.key @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +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 +Oi+igzFlcelWDZ/eQ8CpDkSpAqtwwx97 +-----END PRIVATE KEY-----