diff --git a/public/svgs/appflowy.svg b/public/svgs/appflowy.svg new file mode 100644 index 000000000..7853ed36e --- /dev/null +++ b/public/svgs/appflowy.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/templates/compose/appflowy.yaml b/templates/compose/appflowy.yaml new file mode 100644 index 000000000..805134b71 --- /dev/null +++ b/templates/compose/appflowy.yaml @@ -0,0 +1,217 @@ +# documentation: https://docs.appflowy.io/docs/documentation/appflowy-cloud +# slogan: AppFlowy is the AI collaborative workspace where you achieve more without losing control of your data. +# tags: appflowy,notion,open-source,productivity,notes,ai,self-hosted +# logo: svgs/appflowy.svg +# category: productivity +# port: 80 + +services: + appflowy_web: + environment: + - SERVICE_FQDN_APPFLOWYWEB_80 + - APPFLOWY_BASE_URL=${SERVICE_FQDN_APPFLOWYCLOUD_8000} + - APPFLOWY_GOTRUE_BASE_URL=${SERVICE_FQDN_GOTRUE_9999} + - APPFLOWY_WS_BASE_URL=${SERVICE_FQDN_APPFLOWYCLOUD_8000}/ws/v2 + image: appflowyinc/appflowy_web:latest + depends_on: + - appflowy_cloud + + appflowy_cloud: + image: appflowyinc/appflowy_cloud:latest + labels: + - "traefik.http.middlewares.appflowy-cors.headers.customRequestHeaders.X-Request-Id={{.RequestID}}" + - "traefik.http.middlewares.appflowy-cors.headers.accessControlAllowMethods=GET,POST,PUT,DELETE,PATCH,OPTIONS" + - "traefik.http.middlewares.appflowy-cors.headers.accessControlAllowHeaders=Content-Type,Authorization,Accept,Client-Version,Device-Id" + - "traefik.http.middlewares.appflowy-cors.headers.accessControlMaxAge=3600" + - "traefik.http.middlewares.appflowy-cors.headers.accessControlAllowOriginList=*" + - "traefik.http.middlewares.appflowy-cors.headers.addvaryheader=true" + environment: + - SERVICE_FQDN_APPFLOWYCLOUD_8000 + - RUST_LOG=${RUST_LOG:-info} + - APPFLOWY_ENVIRONMENT=production + - APPFLOWY_DATABASE_URL=postgres://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@postgres:5432/${POSTGRES_DB:-appflowy} + - APPFLOWY_REDIS_URI=redis://redis:6379 + - APPFLOWY_GOTRUE_JWT_SECRET=${SERVICE_PASSWORD_JWT} + - APPFLOWY_GOTRUE_JWT_EXP=${GOTRUE_JWT_EXP:-7200} + - APPFLOWY_GOTRUE_BASE_URL=http://gotrue:9999 + - APPFLOWY_S3_CREATE_BUCKET=${APPFLOWY_S3_CREATE_BUCKET:-true} + - APPFLOWY_S3_USE_MINIO=true + - APPFLOWY_S3_MINIO_URL=http://minio:9000 + - APPFLOWY_S3_ACCESS_KEY=${SERVICE_USER_MINIO} + - APPFLOWY_S3_SECRET_KEY=${SERVICE_PASSWORD_MINIO} + - APPFLOWY_S3_BUCKET=${APPFLOWY_S3_BUCKET:-appflowy} + - APPFLOWY_S3_REGION=${APPFLOWY_S3_REGION:-us-east-1} + - APPFLOWY_MAILER_SMTP_HOST=${APPFLOWY_MAILER_SMTP_HOST:-smtp.gmail.com} + - APPFLOWY_MAILER_SMTP_PORT=${APPFLOWY_MAILER_SMTP_PORT:-587} + - APPFLOWY_MAILER_SMTP_USERNAME=${APPFLOWY_MAILER_SMTP_USERNAME:-notify@appflowy.io} + - APPFLOWY_MAILER_SMTP_EMAIL=${APPFLOWY_MAILER_SMTP_EMAIL:-notify@appflowy.io} + - APPFLOWY_MAILER_SMTP_PASSWORD=${APPFLOWY_MAILER_SMTP_PASSWORD:-email_sender_password} + - APPFLOWY_MAILER_SMTP_TLS_KIND=${APPFLOWY_MAILER_SMTP_TLS_KIND:-none} + - APPFLOWY_ACCESS_CONTROL=true + - APPFLOWY_DATABASE_MAX_CONNECTIONS=40 + - AI_SERVER_HOST=ai + - AI_SERVER_PORT=5001 + - AI_OPENAI_API_KEY=${AI_OPENAI_API_KEY:-} + - APPFLOWY_WEB_URL=${SERVICE_FQDN_APPFLOWYWEB_80} + depends_on: + gotrue: + condition: service_healthy + postgres: + condition: service_healthy + redis: + condition: service_started + + gotrue: + image: appflowyinc/gotrue:latest + environment: + - SERVICE_FQDN_GOTRUE_9999 + - GOTRUE_API_HOST=0.0.0.0 + - GOTRUE_API_PORT=9999 + - PORT=9999 + - GOTRUE_ADMIN_EMAIL=${GOTRUE_ADMIN_EMAIL:-admin@example.com} + - GOTRUE_ADMIN_PASSWORD=${SERVICE_PASSWORD_ADMIN} + - GOTRUE_DISABLE_SIGNUP=false + - GOTRUE_SITE_URL=appflowy-flutter:// + - GOTRUE_URI_ALLOW_LIST=** + - GOTRUE_JWT_SECRET=${SERVICE_PASSWORD_JWT} + - GOTRUE_JWT_EXP=${GOTRUE_JWT_EXP:-7200} + - GOTRUE_JWT_ADMIN_GROUP_NAME=supabase_admin + - GOTRUE_DB_DRIVER=postgres + - API_EXTERNAL_URL=${SERVICE_FQDN_GOTRUE_9999} + - DATABASE_URL=postgres://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@postgres:5432/${POSTGRES_DB:-appflowy}?search_path=auth + - GOTRUE_SMTP_HOST=${GOTRUE_SMTP_HOST} + - GOTRUE_SMTP_PORT=${GOTRUE_SMTP_PORT:-587} + - GOTRUE_SMTP_USER=${GOTRUE_SMTP_USER} + - GOTRUE_SMTP_PASS=${GOTRUE_SMTP_PASS} + - GOTRUE_MAILER_URLPATHS_CONFIRMATION=/verify + - GOTRUE_MAILER_URLPATHS_INVITE=/verify + - GOTRUE_MAILER_URLPATHS_RECOVERY=/verify + - GOTRUE_MAILER_URLPATHS_EMAIL_CHANGE=/verify + - GOTRUE_SMTP_ADMIN_EMAIL=${GOTRUE_SMTP_ADMIN_EMAIL} + - GOTRUE_SMTP_MAX_FREQUENCY=1ns + - GOTRUE_RATE_LIMIT_EMAIL_SENT=100 + - GOTRUE_MAILER_AUTOCONFIRM=true + depends_on: + postgres: + condition: service_healthy + healthcheck: + test: "curl --fail http://127.0.0.1:9999/health || exit 1" + interval: 5s + timeout: 5s + retries: 12 + + admin_frontend: + image: appflowyinc/admin_frontend:latest + environment: + - SERVICE_FQDN_ADMINFRONTEND_3000 + - RUST_LOG=info + - ADMIN_FRONTEND_REDIS_URL=redis://redis:6379 + - ADMIN_FRONTEND_GOTRUE_URL=http://gotrue:9999 + - ADMIN_FRONTEND_APPFLOWY_CLOUD_URL=http://appflowy_cloud:8000 + - ADMIN_FRONTEND_PATH_PREFIX=/console + - ADMIN_FRONTEND_HOST=0.0.0.0 + - ADMIN_FRONTEND_PORT=3000 + - ADMIN_FRONTEND_OAUTH_CLIENT_ID=appflowy_cloud + - ADMIN_FRONTEND_OAUTH_CLIENT_SECRET=${SERVICE_PASSWORD_ADMINOAUTH} + - ADMIN_FRONTEND_OAUTH_ALLOWABLE_REDIRECT_URIS=${SERVICE_FQDN_ADMINFRONTEND_3000} + depends_on: + gotrue: + condition: service_healthy + appflowy_cloud: + condition: service_started + + ai: + image: appflowyinc/appflowy_ai:latest + environment: + - OPENAI_API_KEY=${AI_OPENAI_API_KEY:-} + - AI_SERVER_PORT=5001 + - DEFAULT_AI_MODEL=gpt-4.1-mini # Make sure the model is available in your OpenAI account + - DEFAULT_AI_COMPLETION_MODEL=gpt-4.1-mini # Make sure the model is available in your OpenAI account + - AI_APPFLOWY_HOST=${SERVICE_FQDN_APPFLOWYWEB_80} + - APPFLOWY_GOTRUE_JWT_SECRET=${SERVICE_PASSWORD_JWT} + + - AZURE_OPENAI_API_KEY=${AZURE_OPENAI_API_KEY} + - AZURE_OPENAI_ENDPOINT=${AZURE_OPENAI_ENDPOINT} + - AZURE_OPENAI_API_VERSION=${AZURE_OPENAI_API_VERSION} + - APPFLOWY_S3_ACCESS_KEY=${SERVICE_USER_MINIO} + - APPFLOWY_S3_SECRET_KEY=${SERVICE_PASSWORD_MINIO} + - APPFLOWY_S3_BUCKET=${APPFLOWY_S3_BUCKET:-appflowy} + - APPFLOWY_S3_REGION=${APPFLOWY_S3_REGION:-us-east-1} + - AI_DATABASE_URL=postgres://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@postgres:5432/${POSTGRES_DB:-appflowy} + - AI_REDIS_URL=redis://redis:6379 + - AI_USE_MINIO=true + - AI_MINIO_URL=http://minio:9000 + depends_on: + postgres: + condition: service_healthy + + appflowy_worker: + image: appflowyinc/appflowy_worker:latest + environment: + - RUST_LOG=info + - APPFLOWY_ENVIRONMENT=production + - APPFLOWY_WORKER_ENVIRONMENT=production + - APPFLOWY_WORKER_REDIS_URL=redis://redis:6379 + - APPFLOWY_WORKER_DATABASE_URL=postgres://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@postgres:5432/${POSTGRES_DB:-appflowy} + - APPFLOWY_WORKER_DATABASE_NAME=${POSTGRES_DB:-appflowy} + - APPFLOWY_WORKER_IMPORT_TICK_INTERVAL=30 + - APPFLOWY_S3_USE_MINIO=true + - APPFLOWY_S3_MINIO_URL=http://minio:9000 + - APPFLOWY_S3_ACCESS_KEY=${SERVICE_USER_MINIO} + - APPFLOWY_S3_SECRET_KEY=${SERVICE_PASSWORD_MINIO} + - APPFLOWY_S3_BUCKET=${APPFLOWY_S3_BUCKET:-appflowy} + - APPFLOWY_S3_REGION=${APPFLOWY_S3_REGION:-us-east-1} + - APPFLOWY_MAILER_SMTP_HOST=${APPFLOWY_MAILER_SMTP_HOST:-smtp.gmail.com} + - APPFLOWY_MAILER_SMTP_PORT=${APPFLOWY_MAILER_SMTP_PORT:-587} + - APPFLOWY_MAILER_SMTP_USERNAME=${APPFLOWY_MAILER_SMTP_USERNAME:-notify@appflowy.io} + - APPFLOWY_MAILER_SMTP_EMAIL=${APPFLOWY_MAILER_SMTP_EMAIL:-notify@appflowy.io} + - APPFLOWY_MAILER_SMTP_PASSWORD=${APPFLOWY_MAILER_SMTP_PASSWORD:-email_sender_password} + - APPFLOWY_MAILER_SMTP_TLS_KIND=${APPFLOWY_MAILER_SMTP_TLS_KIND:-none} + depends_on: + postgres: + condition: service_healthy + redis: + condition: service_started + + minio: + image: minio/minio + environment: + - MINIO_ROOT_USER=${SERVICE_USER_MINIO} + - MINIO_ROOT_PASSWORD=${SERVICE_PASSWORD_MINIO} + command: server /data --console-address ":9001" + healthcheck: + test: ["CMD", "mc", "ready", "local"] + interval: 5s + timeout: 20s + retries: 10 + volumes: + # Coolify will manage this named volume for persistent object storage. + - minio_data:/data + + postgres: + image: pgvector/pgvector:pg16 + environment: + - POSTGRES_USER=${SERVICE_USER_POSTGRES} + - POSTGRES_DB=${POSTGRES_DB:-appflowy} + - POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES} + - POSTGRES_HOST=postgres + volumes: + # Coolify will manage this named volume for persistent database storage. + - postgres_data:/var/lib/postgresql/data + healthcheck: + test: [ "CMD", "pg_isready", "-U", "${SERVICE_USER_POSTGRES}", "-d", "${POSTGRES_DB:-appflowy}" ] + interval: 5s + timeout: 5s + retries: 12 + + redis: + image: redis + volumes: + - "redis_data:/data" + healthcheck: + test: + - CMD-SHELL + - "redis-cli -h localhost -p 6379 ping" + interval: 5s + timeout: 5s + retries: 3