From 6b781414df0f4b22af16b4fe7578772c0ef9d0d4 Mon Sep 17 00:00:00 2001 From: amass <168062547@qq.com> Date: Sun, 9 Mar 2025 01:11:43 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=83=A8=E7=BD=B2appflowy?= =?UTF-8?q?=E7=9A=84=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- resources/appflowy.conf | 235 ++++++++++++++++++++++++++++++++++++++++ resources/appflowy.env | 198 +++++++++++++++++++++++++++++++++ resources/appflowy.sh | 187 ++++++++++++++++++++++++++++++++ 3 files changed, 620 insertions(+) create mode 100644 resources/appflowy.conf create mode 100644 resources/appflowy.env create mode 100644 resources/appflowy.sh diff --git a/resources/appflowy.conf b/resources/appflowy.conf new file mode 100644 index 0000000..eab802d --- /dev/null +++ b/resources/appflowy.conf @@ -0,0 +1,235 @@ +map $http_upgrade $connection_upgrade { + default upgrade; + '' close; +} + +map $http_origin $cors_origin { + # AppFlowy Web origin + "~^http://localhost:3000$" $http_origin; + default "null"; +} + +server { + listen 8086; + client_max_body_size 10M; + + underscores_in_headers on; + set $appflowy_cloud_backend "http://192.168.3.3:8000"; + set $gotrue_backend "http://192.168.3.3:9999"; + set $admin_frontend_backend "http://192.168.3.3:3001"; + set $appflowy_web_backend "http://192.168.3.3:8090"; + set $appflowy_ai_backend "http://192.168.3.3:5001"; + set $minio_backend "http://192.168.3.3:9001"; + set $minio_api_backend "http://192.168.3.3:9000"; + # Host name for minio, used internally within docker compose + set $minio_internal_host "192.168.3.3:9000"; + set $portainer_backend "http://192.168.3.3:9000"; + set $pgadmin_backend "http://192.168.3.3:80"; + + # GoTrue + location /gotrue/ { + if ($request_method = 'OPTIONS') { + add_header 'Access-Control-Allow-Origin' $cors_origin always; + add_header 'Access-Control-Allow-Credentials' 'true' always; + add_header 'Access-Control-Allow-Headers' '*' always; + add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, PATCH, OPTIONS' always; + add_header 'Access-Control-Max-Age' 3600 always; + add_header 'Content-Type' 'text/plain charset=UTF-8' always; + add_header 'Content-Length' 0 always; + return 204; + } + + 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 { + 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_read_timeout 86400; + } + + location /api { + proxy_pass $appflowy_cloud_backend; + proxy_set_header X-Request-Id $request_id; + proxy_set_header Host $http_host; + + # Set CORS headers for other requests + if ($request_method = 'OPTIONS') { + add_header 'Access-Control-Allow-Origin' $cors_origin always; + add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, PATCH, OPTIONS' always; + add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization, Accept, Client-Version, Device-Id' always; + add_header 'Access-Control-Max-Age' 3600 always; + return 204; + } + + add_header 'Access-Control-Allow-Origin' $cors_origin always; + add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, PATCH, OPTIONS' always; + add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization, Accept, Client-Version, Device-Id' always; + add_header 'Access-Control-Max-Age' 3600 always; + + location ~* ^/api/workspace/([a-zA-Z0-9_-]+)/publish$ { + proxy_pass $appflowy_cloud_backend; + proxy_request_buffering off; + client_max_body_size 256M; + if ($request_method = 'OPTIONS') { + add_header 'Access-Control-Allow-Origin' $cors_origin always; + add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, PATCH, OPTIONS' always; + add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization, Accept, Client-Version, Device-Id' always; + add_header 'Access-Control-Max-Age' 3600 always; + return 204; + } + + add_header 'Access-Control-Allow-Origin' $cors_origin always; + add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, PATCH, OPTIONS' always; + add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization, Accept, Client-Version, Device-Id' always; + add_header 'Access-Control-Max-Age' 3600 always; + } + + # 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; + + # Handle CORS + add_header 'Access-Control-Allow-Origin' $cors_origin always; + add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, PATCH, OPTIONS' always; + add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization, Accept, Device-Id' always; + add_header 'Access-Control-Max-Age' 3600 always; + + # 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; + } + } + + + # AppFlowy AI + location /ai { + proxy_pass $appflowy_ai_backend; + proxy_set_header Host $host; + proxy_pass_request_headers on; + } + + # 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 are 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 300; + + ## 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 are 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 300; + # 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; + } + + # PgAdmin + # Optional Module, comment this section if you are 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; + } + + # Portainer + # Optional Module, comment this section if you are did not deploy portainer in docker-compose.yml + location /portainer/ { + proxy_pass $portainer_backend; + rewrite ^/portainer/(.*) /$1 break; + } + + # Admin Frontend + # Optional Module, comment this section if you are did not deploy admin_frontend in docker-compose.yml + location /console { + proxy_pass $admin_frontend_backend; + + proxy_set_header X-Scheme $scheme; + proxy_set_header Host $host; + } + + # AppFlowy Web + location / { + proxy_pass $appflowy_web_backend; + proxy_set_header X-Scheme $scheme; + proxy_set_header Host $host; + } +} + + diff --git a/resources/appflowy.env b/resources/appflowy.env new file mode 100644 index 0000000..797cb4e --- /dev/null +++ b/resources/appflowy.env @@ -0,0 +1,198 @@ +# This file is a template for docker compose deployment +# Copy this file to .env and change the values as needed + +# Fully qualified domain name for the deployment. Replace appflowy.localhost with your domain, +# such as mydomain.com. +FQDN=localhost +# Change this to https if you wish to enable TLS. +SCHEME=http +# If this has changed, AppFlowy Web might still use the old value due to Javascript cache. +# If AppFlowy Web is sending requests to the wrong URL, do a hard reload on the browser, +# and/or purge Cloudflare cache if you are using CloudFlare. +APPFLOWY_BASE_URL=${SCHEME}://${FQDN} + +# PostgreSQL Settings +POSTGRES_HOST=postgres +POSTGRES_USER=postgres +POSTGRES_PASSWORD=password +POSTGRES_PORT=5432 +POSTGRES_DB=postgres + +# Postgres credential for supabase_auth_admin +SUPABASE_PASSWORD=root + +# Redis Settings +REDIS_HOST=redis +REDIS_PORT=6379 + +# Minio Host +MINIO_HOST=minio +MINIO_PORT=9000 + +AWS_ACCESS_KEY=minioadmin +AWS_SECRET=minioadmin + +# AppFlowy Cloud +## URL that connects to the gotrue docker container +APPFLOWY_GOTRUE_BASE_URL=http://gotrue:9999 +## URL that connects to the postgres docker container. If your password contains special characters, instead of using ${POSTGRES_PASSWORD}, +## you will need to convert them into url encoded format. For example, `p@ssword` will become `p%40ssword`. +APPFLOWY_DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB} +APPFLOWY_ACCESS_CONTROL=true +APPFLOWY_WEBSOCKET_MAILBOX_SIZE=6000 +APPFLOWY_DATABASE_MAX_CONNECTIONS=40 +## URL that connects to the redis docker container +APPFLOWY_REDIS_URI=redis://${REDIS_HOST}:${REDIS_PORT} + +# admin frontend +## URL that connects to redis docker container +ADMIN_FRONTEND_REDIS_URL=redis://${REDIS_HOST}:${REDIS_PORT} +## URL that connects to gotrue docker container +ADMIN_FRONTEND_GOTRUE_URL=http://gotrue:9999 +## URL that connects to the cloud docker container +ADMIN_FRONTEND_APPFLOWY_CLOUD_URL=http://appflowy_cloud:8000 +## Base Url for the admin frontend. If you use the default Nginx conf provided here, this value should be /console. +## If you want to keep the previous behaviour where admin frontend is served at the root, don't set this env variable, +## or set it to empty string. +ADMIN_FRONTEND_PATH_PREFIX=/console + +# authentication key, change this and keep the key safe and secret +# self defined key, you can use any string +GOTRUE_JWT_SECRET=hello456 +# Expiration time in seconds for the JWT token +GOTRUE_JWT_EXP=7200 + +# User sign up will automatically be confirmed if this is set to true. +# If you have OAuth2 set up or smtp configured, you can set this to false +# to enforce email confirmation or OAuth2 login instead. +# If you set this to false, you need to either set up SMTP +GOTRUE_MAILER_AUTOCONFIRM=true +# Number of emails that can be per minute +GOTRUE_RATE_LIMIT_EMAIL_SENT=100 + +# If you intend to use mail confirmation, you need to set the SMTP configuration below +# You would then need to set GOTRUE_MAILER_AUTOCONFIRM=false +# Check for logs in gotrue service if there are any issues with email confirmation +# Note that smtps will be used for port 465, otherwise plain smtp with optional STARTTLS +GOTRUE_SMTP_HOST=smtp.gmail.com +GOTRUE_SMTP_PORT=465 +GOTRUE_SMTP_USER=email_sender@some_company.com +GOTRUE_SMTP_PASS=email_sender_password +GOTRUE_SMTP_ADMIN_EMAIL=comp_admin@some_company.com + +# This user will be created when GoTrue starts successfully +# You can use this user to login to the admin panel +GOTRUE_ADMIN_EMAIL=admin@example.com +GOTRUE_ADMIN_PASSWORD=password + +# Set this to true if users can only join by invite +GOTRUE_DISABLE_SIGNUP=false + +# External URL where the GoTrue service is exposed. +API_EXTERNAL_URL=${APPFLOWY_BASE_URL}/gotrue + +# GoTrue connect to postgres using this url. If your password contains special characters, +# replace ${SUPABASE_PASSWORD} with the url encoded version. For example, `p@ssword` will become `p%40ssword` +GOTRUE_DATABASE_URL=postgres://supabase_auth_admin:${SUPABASE_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB} + +# Refer to this for details: https://github.com/AppFlowy-IO/AppFlowy-Cloud/blob/main/doc/AUTHENTICATION.md +# Google OAuth2 +GOTRUE_EXTERNAL_GOOGLE_ENABLED=false +GOTRUE_EXTERNAL_GOOGLE_CLIENT_ID= +GOTRUE_EXTERNAL_GOOGLE_SECRET= +GOTRUE_EXTERNAL_GOOGLE_REDIRECT_URI=${API_EXTERNAL_URL}/callback +# GitHub OAuth2 +GOTRUE_EXTERNAL_GITHUB_ENABLED=false +GOTRUE_EXTERNAL_GITHUB_CLIENT_ID= +GOTRUE_EXTERNAL_GITHUB_SECRET= +GOTRUE_EXTERNAL_GITHUB_REDIRECT_URI=${API_EXTERNAL_URL}/callback +# Discord OAuth2 +GOTRUE_EXTERNAL_DISCORD_ENABLED=false +GOTRUE_EXTERNAL_DISCORD_CLIENT_ID= +GOTRUE_EXTERNAL_DISCORD_SECRET= +GOTRUE_EXTERNAL_DISCORD_REDIRECT_URI=${API_EXTERNAL_URL}/callback +# Apple OAuth2 +GOTRUE_EXTERNAL_APPLE_ENABLED=false +GOTRUE_EXTERNAL_APPLE_CLIENT_ID= +GOTRUE_EXTERNAL_APPLE_SECRET= +GOTRUE_EXTERNAL_APPLE_REDIRECT_URI=${API_EXTERNAL_URL}/callback + +# File Storage +# Create the bucket if not exists on AppFlowy Cloud start up. +# Set this to false if the bucket has been created externally. +APPFLOWY_S3_CREATE_BUCKET=true +# This is where storage like images, files, etc. will be stored. +# By default, Minio is used as the default file storage which uses host's file system. +# Keep this as true if you are using other S3 compatible storage provider other than AWS. +APPFLOWY_S3_USE_MINIO=true +APPFLOWY_S3_MINIO_URL=http://${MINIO_HOST}:${MINIO_PORT} # change this if you are using a different address for minio +APPFLOWY_S3_ACCESS_KEY=${AWS_ACCESS_KEY} +APPFLOWY_S3_SECRET_KEY=${AWS_SECRET} +APPFLOWY_S3_BUCKET=appflowy +# Uncomment this if you are using AWS S3 +# APPFLOWY_S3_REGION=us-east-1 +# Uncomment this if you are using the Minio service hosted within this docker compose file +# This is so that, the presigned URL generated by AppFlowy Cloud will use the publicly availabe minio endpoint. +# APPFLOWY_S3_PRESIGNED_URL_ENDPOINT=${APPFLOWY_BASE_URL}/minio-api + +# AppFlowy Cloud Mailer +# Note that smtps (TLS) is always required, even for ports other than 465 +APPFLOWY_MAILER_SMTP_HOST=smtp.gmail.com +APPFLOWY_MAILER_SMTP_PORT=465 +APPFLOWY_MAILER_SMTP_USERNAME=email_sender@some_company.com +APPFLOWY_MAILER_SMTP_EMAIL=email_sender@some_company.com +APPFLOWY_MAILER_SMTP_PASSWORD=email_sender_password +APPFLOWY_MAILER_SMTP_TLS_KIND=wrapper # "none" "wrapper" "required" "opportunistic" + +# Log level for the appflowy-cloud service +RUST_LOG=info + +# PgAdmin +# Optional module to manage the postgres database +# You can access the pgadmin at http://your-host/pgadmin +# Refer to the APPFLOWY_DATABASE_URL for password when connecting to the database +PGADMIN_DEFAULT_EMAIL=admin@example.com +PGADMIN_DEFAULT_PASSWORD=password + +# Portainer (username: admin) +PORTAINER_PASSWORD=password1234 + +# Cloudflare tunnel token +CLOUDFLARE_TUNNEL_TOKEN= + +# NGINX +# Optional, change this if you want to use custom ports to expose AppFlowy +NGINX_PORT=80 +NGINX_TLS_PORT=443 + +# AppFlowy AI +AI_OPENAI_API_KEY= +AI_SERVER_PORT=5001 +AI_SERVER_HOST=ai +AI_DATABASE_URL=postgresql+psycopg://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB} +AI_REDIS_URL=redis://${REDIS_HOST}:${REDIS_PORT} +LOCAL_AI_TEST_ENABLED=false +AI_APPFLOWY_BUCKET_NAME=${APPFLOWY_S3_BUCKET} +AI_APPFLOWY_HOST=${APPFLOWY_BASE_URL} +AI_MINIO_URL=http://${MINIO_HOST}:${MINIO_PORT} + +# AppFlowy Indexer +APPFLOWY_INDEXER_ENABLED=true +APPFLOWY_INDEXER_DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB} +APPFLOWY_INDEXER_REDIS_URL=redis://${REDIS_HOST}:${REDIS_PORT} +APPFLOWY_INDEXER_EMBEDDING_BUFFER_SIZE=5000 + +# AppFlowy Collaborate +APPFLOWY_COLLABORATE_MULTI_THREAD=false +APPFLOWY_COLLABORATE_REMOVE_BATCH_SIZE=100 + +# AppFlowy Worker +APPFLOWY_WORKER_REDIS_URL=redis://${REDIS_HOST}:${REDIS_PORT} +APPFLOWY_WORKER_DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB} +APPFLOWY_WORKER_DATABASE_NAME=${POSTGRES_DB} + +# AppFlowy Web +# If your AppFlowy Web is hosted on a different domain, update this variable to the correct domain +APPFLOWY_WEB_URL=${APPFLOWY_BASE_URL} +# If you are running AppFlowy Web locally for development purpose, use the following value instead +# APPFLOWY_WEB_URL=http://localhost:3000 diff --git a/resources/appflowy.sh b/resources/appflowy.sh new file mode 100644 index 0000000..c25eaf6 --- /dev/null +++ b/resources/appflowy.sh @@ -0,0 +1,187 @@ +#!/bin/bash + +if [ -f "appflowy.env" ]; then + set -a + source appflowy.env + set +a +else + echo "cannot find appflowy.env" + exit 1 +fi + +# http://192.168.3.3:8086 + +CONTAINERS=( + frpc + minio + postgres + redis + appflowy_gotrue + appflowy_cloud + appflowy_admin_frontend + appflowy_ai + appflowy_worker + appflowy_web +) + +for container in "${CONTAINERS[@]}"; do + if docker ps -a --format '{{.Names}}' | grep -q "^${container}\$"; then + echo "delete $container" + docker rm --force "$container" 2>/dev/null && echo "$container delete successed" || echo "$container delete failed" + else + echo "$container not existed" + fi +done + +docker run --restart=always --network host -d --name frpc \ + -e TZ="Asia/Shanghai" \ + -v /mnt/user/appdata/frpc/frpc.toml:/etc/frp/frpc.toml \ + -v /mnt/user/appdata/frpc:/app \ + registry.cn-shenzhen.aliyuncs.com/amass_toolset/frpc:0.61.1 + +docker run -d --name minio --restart=on-failure \ + -p 9000:9000 \ + -p 9001:9001 \ + -e MINIO_BROWSER_REDIRECT_URL="${APPFLOWY_BASE_URL}/minio" \ + -e MINIO_ROOT_USER="${APPFLOWY_S3_ACCESS_KEY}" \ + -e MINIO_ROOT_PASSWORD="${APPFLOWY_S3_SECRET_KEY}" \ + -v /mnt/user/appdata/minio:/data \ + minio/minio:latest server /data --console-address ":9001" + +docker run -d --name postgres --restart=on-failure \ + -p 5432:5432 \ + -e POSTGRES_USER=${POSTGRES_USER} \ + -e POSTGRES_DB=${POSTGRES_DB} \ + -e POSTGRES_PASSWORD=${POSTGRES_PASSWORD} \ + -e POSTGRES_HOST=${POSTGRES_HOST} \ + -e SUPABASE_PASSWORD=${SUPABASE_PASSWORD} \ + -v /mnt/user/appdata/postgres/migrations/before:/docker-entrypoint-initdb.d \ + -v /mnt/user/appdata/postgres/data:/var/lib/postgresql/data \ + pgvector/pgvector:pg16 + +docker run -d --name redis --restart=on-failure -p 6379:6379 redis + +docker run -d --name appflowy_gotrue --restart=on-failure \ + -p 9999:9999 \ + -e GOTRUE_ADMIN_EMAIL=${GOTRUE_ADMIN_EMAIL} \ + -e GOTRUE_ADMIN_PASSWORD=${GOTRUE_ADMIN_PASSWORD} \ + -e GOTRUE_DISABLE_SIGNUP=${GOTRUE_DISABLE_SIGNUP} \ + -e GOTRUE_SITE_URL='appflowy-flutter://' \ + -e GOTRUE_URI_ALLOW_LIST='**' \ + -e GOTRUE_JWT_SECRET=${GOTRUE_JWT_SECRET} \ + -e GOTRUE_JWT_EXP=${GOTRUE_JWT_EXP} \ + -e GOTRUE_JWT_ADMIN_GROUP_NAME=supabase_admin \ + -e GOTRUE_DB_DRIVER=postgres \ + -e API_EXTERNAL_URL=${API_EXTERNAL_URL} \ + -e DATABASE_URL=${GOTRUE_DATABASE_URL} \ + -e PORT=9999 \ + -e GOTRUE_SMTP_HOST=${GOTRUE_SMTP_HOST}\ + -e GOTRUE_SMTP_PORT=${GOTRUE_SMTP_PORT} \ + -e GOTRUE_SMTP_USER=${GOTRUE_SMTP_USER} \ + -e GOTRUE_SMTP_PASS=${GOTRUE_SMTP_PASS} \ + -e GOTRUE_MAILER_URLPATHS_CONFIRMATION='/gotrue/verify' \ + -e GOTRUE_MAILER_URLPATHS_INVITE='/gotrue/verify' \ + -e GOTRUE_MAILER_URLPATHS_RECOVERY='/gotrue/verify' \ + -e GOTRUE_MAILER_URLPATHS_EMAIL_CHANGE='/gotrue/verify' \ + -e GOTRUE_SMTP_ADMIN_EMAIL=${GOTRUE_SMTP_ADMIN_EMAIL} \ + -e GOTRUE_SMTP_MAX_FREQUENCY=${GOTRUE_SMTP_MAX_FREQUENCY:-1ns} \ + -e GOTRUE_RATE_LIMIT_EMAIL_SENT=${GOTRUE_RATE_LIMIT_EMAIL_SENT:-100} \ + -e GOTRUE_MAILER_AUTOCONFIRM=${GOTRUE_MAILER_AUTOCONFIRM:-false} \ + -e GOTRUE_EXTERNAL_GOOGLE_ENABLED=${GOTRUE_EXTERNAL_GOOGLE_ENABLED} \ + -e GOTRUE_EXTERNAL_GOOGLE_CLIENT_ID=${GOTRUE_EXTERNAL_GOOGLE_CLIENT_ID} \ + -e GOTRUE_EXTERNAL_GOOGLE_SECRET=${GOTRUE_EXTERNAL_GOOGLE_SECRET} \ + -e GOTRUE_EXTERNAL_GOOGLE_REDIRECT_URI=${GOTRUE_EXTERNAL_GOOGLE_REDIRECT_URI} \ + -e GOTRUE_EXTERNAL_GITHUB_ENABLED=${GOTRUE_EXTERNAL_GITHUB_ENABLED} \ + -e GOTRUE_EXTERNAL_GITHUB_CLIENT_ID=${GOTRUE_EXTERNAL_GITHUB_CLIENT_ID} \ + -e GOTRUE_EXTERNAL_GITHUB_SECRET=${GOTRUE_EXTERNAL_GITHUB_SECRET} \ + -e GOTRUE_EXTERNAL_GITHUB_REDIRECT_URI=${GOTRUE_EXTERNAL_GITHUB_REDIRECT_URI} \ + -e GOTRUE_EXTERNAL_DISCORD_ENABLED=${GOTRUE_EXTERNAL_DISCORD_ENABLED} \ + -e GOTRUE_EXTERNAL_DISCORD_CLIENT_ID=${GOTRUE_EXTERNAL_DISCORD_CLIENT_ID} \ + -e GOTRUE_EXTERNAL_DISCORD_SECRET=${GOTRUE_EXTERNAL_DISCORD_SECRET} \ + -e GOTRUE_EXTERNAL_DISCORD_REDIRECT_URI=${GOTRUE_EXTERNAL_DISCORD_REDIRECT_URI} \ + appflowyinc/gotrue:latest + + +docker run -d --name appflowy_cloud --restart=on-failure \ + -p 8000:8000 \ + -e RUST_LOG=${RUST_LOG:-info} \ + -e APPFLOWY_ENVIRONMENT=production \ + -e APPFLOWY_DATABASE_URL=${APPFLOWY_DATABASE_URL} \ + -e APPFLOWY_REDIS_URI=${APPFLOWY_REDIS_URI} \ + -e APPFLOWY_GOTRUE_JWT_SECRET=${GOTRUE_JWT_SECRET} \ + -e APPFLOWY_GOTRUE_JWT_EXP=${GOTRUE_JWT_EXP} \ + -e APPFLOWY_GOTRUE_BASE_URL=${APPFLOWY_GOTRUE_BASE_URL} \ + -e APPFLOWY_GOTRUE_EXT_URL=${API_EXTERNAL_URL} \ + -e APPFLOWY_GOTRUE_ADMIN_EMAIL=${GOTRUE_ADMIN_EMAIL} \ + -e APPFLOWY_GOTRUE_ADMIN_PASSWORD=${GOTRUE_ADMIN_PASSWORD} \ + -e APPFLOWY_S3_CREATE_BUCKET=${APPFLOWY_S3_CREATE_BUCKET} \ + -e APPFLOWY_S3_USE_MINIO=${APPFLOWY_S3_USE_MINIO} \ + -e APPFLOWY_S3_MINIO_URL=${APPFLOWY_S3_MINIO_URL} \ + -e APPFLOWY_S3_ACCESS_KEY=${APPFLOWY_S3_ACCESS_KEY} \ + -e APPFLOWY_S3_SECRET_KEY=${APPFLOWY_S3_SECRET_KEY} \ + -e APPFLOWY_S3_BUCKET=${APPFLOWY_S3_BUCKET} \ + -e APPFLOWY_S3_REGION=${APPFLOWY_S3_REGION} \ + -e APPFLOWY_S3_PRESIGNED_URL_ENDPOINT=${APPFLOWY_S3_PRESIGNED_URL_ENDPOINT} \ + -e APPFLOWY_MAILER_SMTP_HOST=${APPFLOWY_MAILER_SMTP_HOST} \ + -e APPFLOWY_MAILER_SMTP_PORT=${APPFLOWY_MAILER_SMTP_PORT} \ + -e APPFLOWY_MAILER_SMTP_USERNAME=${APPFLOWY_MAILER_SMTP_USERNAME} \ + -e APPFLOWY_MAILER_SMTP_EMAIL=${APPFLOWY_MAILER_SMTP_EMAIL} \ + -e APPFLOWY_MAILER_SMTP_PASSWORD=${APPFLOWY_MAILER_SMTP_PASSWORD} \ + -e APPFLOWY_MAILER_SMTP_TLS_KIND=${APPFLOWY_MAILER_SMTP_TLS_KIND} \ + -e APPFLOWY_ACCESS_CONTROL=${APPFLOWY_ACCESS_CONTROL} \ + -e APPFLOWY_DATABASE_MAX_CONNECTIONS=${APPFLOWY_DATABASE_MAX_CONNECTIONS} \ + -e AI_SERVER_HOST=${AI_SERVER_HOST} \ + -e AI_SERVER_PORT=${AI_SERVER_PORT} \ + -e AI_OPENAI_API_KEY=${AI_OPENAI_API_KEY} \ + -e APPFLOWY_ADMIN_FRONTEND_PATH_PREFIX=${ADMIN_FRONTEND_PATH_PREFIX} \ + -e APPFLOWY_WEB_URL=${APPFLOWY_WEB_URL} \ + appflowyinc/appflowy_cloud:latest + +docker run -d --name appflowy_admin_frontend \ + --restart on-failure \ + -p 3001:3000 \ + -e RUST_LOG=${RUST_LOG:-info} \ + -e ADMIN_FRONTEND_REDIS_URL=${ADMIN_FRONTEND_REDIS_URL} \ + -e ADMIN_FRONTEND_GOTRUE_URL=${ADMIN_FRONTEND_GOTRUE_URL} \ + -e ADMIN_FRONTEND_APPFLOWY_CLOUD_URL=${ADMIN_FRONTEND_APPFLOWY_CLOUD_URL} \ + -e ADMIN_FRONTEND_PATH_PREFIX=${ADMIN_FRONTEND_PATH_PREFIX:-} \ + appflowyinc/admin_frontend:latest + +docker run -d --name appflowy_ai \ + --restart on-failure \ + -p 5001:5001 \ + -e OPENAI_API_KEY=${AI_OPENAI_API_KEY} \ + -e APPFLOWY_AI_SERVER_PORT=${AI_SERVER_PORT} \ + -e APPFLOWY_AI_DATABASE_URL=${AI_DATABASE_URL} \ + -e APPFLOWY_AI_REDIS_URL=${AI_REDIS_URL} \ + appflowyinc/appflowy_ai:latest + +docker run -d --name appflowy_worker \ + --restart on-failure \ + -e RUST_LOG=${RUST_LOG:-info} \ + -e APPFLOWY_ENVIRONMENT=production \ + -e APPFLOWY_WORKER_REDIS_URL=${APPFLOWY_WORKER_REDIS_URL} \ + -e APPFLOWY_WORKER_ENVIRONMENT=production \ + -e APPFLOWY_WORKER_DATABASE_URL=${APPFLOWY_WORKER_DATABASE_URL} \ + -e APPFLOWY_WORKER_DATABASE_NAME=${APPFLOWY_WORKER_DATABASE_NAME} \ + -e APPFLOWY_WORKER_IMPORT_TICK_INTERVAL=30 \ + -e APPFLOWY_S3_USE_MINIO=${APPFLOWY_S3_USE_MINIO} \ + -e APPFLOWY_S3_MINIO_URL=${APPFLOWY_S3_MINIO_URL} \ + -e APPFLOWY_S3_ACCESS_KEY=${APPFLOWY_S3_ACCESS_KEY} \ + -e APPFLOWY_S3_SECRET_KEY=${APPFLOWY_S3_SECRET_KEY} \ + -e APPFLOWY_S3_BUCKET=${APPFLOWY_S3_BUCKET} \ + -e APPFLOWY_S3_REGION=${APPFLOWY_S3_REGION} \ + -e APPFLOWY_MAILER_SMTP_HOST=${APPFLOWY_MAILER_SMTP_HOST} \ + -e APPFLOWY_MAILER_SMTP_PORT=${APPFLOWY_MAILER_SMTP_PORT} \ + -e APPFLOWY_MAILER_SMTP_USERNAME=${APPFLOWY_MAILER_SMTP_USERNAME} \ + -e APPFLOWY_MAILER_SMTP_EMAIL=${APPFLOWY_MAILER_SMTP_EMAIL} \ + -e APPFLOWY_MAILER_SMTP_PASSWORD=${APPFLOWY_MAILER_SMTP_PASSWORD} \ + -e APPFLOWY_MAILER_SMTP_TLS_KIND=${APPFLOWY_MAILER_SMTP_TLS_KIND} \ + appflowyinc/appflowy_worker:latest + +docker run -d --name appflowy_web \ + --restart on-failure \ + -p 8090:80 \ + -e AF_BASE_URL="${APPFLOWY_BASE_URL}" \ + -e AF_GOTRUE_URL="${API_EXTERNAL_URL}" \ + appflowyinc/appflowy_web:latest \ No newline at end of file