[GH-ISSUE #8173] 502 - Bad gateway #3618

Closed
opened 2026-03-23 21:31:50 +00:00 by mirror · 2 comments
Owner

Originally created by @maggiv8 on GitHub (Aug 19, 2025).
Original GitHub issue: https://github.com/AppFlowy-IO/AppFlowy/issues/8173

Hi there,

I am currently facing a 'HTTP 502' issue after login into Appflowy Web.
Steps to reproduce issue:

  1. Go to Appyflow web (based on my config 'https://v4-vmhomehub.local.markert.live:4430')
  2. Login with username and password.

Current result:
I am getting an HTTP 502 - Bad Gateway after logging in:
The browser console logs:
api/user/profile:1 Failed to load resource: the server responded with a status of 502 (Bad Gateway)
The docker container log contains the followign message:

172.18.0.8 - - [19/Aug/2025:04:07:18 +0000] "GET /favicon.ico HTTP/1.0" 404 555 "https://v4-vmhomehub.local.markert.live:4430/api/user/workspace" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36"
172.18.0.8 - - [19/Aug/2025:04:14:44 +0000] "GET /app HTTP/1.0" 200 2904 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36"

I guess there is something wrong with my NGINX routing?
Any help would be appreciated.
Thank you.

P.S. My config is pasted below:

.env

# =============================================================================
# AppFlowy Cloud - Production Deployment Configuration
# =============================================================================
# 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 localhost with your domain,
# such as mydomain.com.
FQDN=v4-vmhomehub.local.markert.live

# Change this to https if you wish to enable TLS.
SCHEME=http

APPFLOWY_BASE_URL=${SCHEME}://${FQDN}

# =============================================================================
# 🗄️ DATABASE & CACHE: Core data infrastructure
# =============================================================================

# PostgreSQL Settings
POSTGRES_HOST=v4-vmdatabaseserver.local.markert.live
POSTGRES_USER=user
POSTGRES_PASSWORD=pwd
POSTGRES_PORT=5432
POSTGRES_DB=db

# Redis Settings
REDIS_HOST=redis
REDIS_PORT=6379

# =============================================================================
# 🏗️ INFRASTRUCTURE SERVICES: Object storage and networking
# =============================================================================

# MinIO Configuration: S3-compatible object storage for file uploads and attachments
# Docker service discovery: These values are used for container-to-container communication
# MINIO_HOST refers to the Docker Compose service name, not an external domain/IP
# Used by: AppFlowy Cloud, Worker services, AI service, and Admin Frontend
MINIO_HOST=minio
MINIO_PORT=9000

# MinIO/AWS Credentials: Authentication keys for object storage access
# Development: Uses MinIO's default credentials (minioadmin/minioadmin) for quick setup
# Production: MUST be changed to secure, randomly generated credentials for security
# These credentials are used across all services that access file storage
# Security note: Default credentials are well-known and should never be used in production
AWS_ACCESS_KEY=minioadmin
AWS_SECRET=minioadmin

# =============================================================================
# ☁️ APPFLOWY SERVICES: Application service configuration
# =============================================================================

# AppFlowy Cloud Service Configuration
# 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 Service Configuration
# Access Control System: Enables/disables permission-based access control
# Controls workspace access, collaboration permissions, and realtime access restrictions
APPFLOWY_ACCESS_CONTROL=true

# WebSocket Mailbox Configuration: Controls realtime server message handling capacity
# Sets the maximum number of messages that can be queued in the WebSocket actor's mailbox
# Higher values allow more concurrent WebSocket messages but use more memory
# Lower values may cause message drops under high load but reduce memory usage
APPFLOWY_WEBSOCKET_MAILBOX_SIZE=6000

# Database Connection Pool: Maximum number of concurrent PostgreSQL connections
# Controls the size of the database connection pool for the AppFlowy Cloud service
# PostgreSQL has a default limit of ~100 connections total (15 reserved for superuser)
# Higher values improve concurrency but consume more database resources
# Lower values reduce database load but may cause connection timeouts under load
APPFLOWY_DATABASE_MAX_CONNECTIONS=40

# URL that connects to the redis docker container
APPFLOWY_REDIS_URI=redis://${REDIS_HOST}:${REDIS_PORT}

# GoTrue database connection. If your password contains special characters,
# instead of using ${POSTGRES_PASSWORD}, use the url encoded version.
# For example, `p@ssword` will become `p%40ssword`
GOTRUE_DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}?search_path=auth

# =============================================================================
# 🔐 GOTRUE: Authentication service configuration
# =============================================================================

# GoTrue Admin Credentials
# 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=pwd

# JWT Configuration
# Authentication key, change this and keep the key safe and secret
GOTRUE_JWT_SECRET=1234

# Expiration time in seconds for the JWT token
GOTRUE_JWT_EXP=7200

# External URL where the GoTrue service is exposed
API_EXTERNAL_URL=${APPFLOWY_BASE_URL}/gotrue

# User Registration & Login Settings
# 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

# Set this to true if users can only join by invite
GOTRUE_DISABLE_SIGNUP=true

# Number of emails that can be sent per minute
GOTRUE_RATE_LIMIT_EMAIL_SENT=100

# Email Templates
# Optional. You can provide a public http link (eg. github) to customize your magic link template.
# Refer to https://github.com/supabase/auth?tab=readme-ov-file#configuration for details on how to create a custom email template.
GOTRUE_MAILER_TEMPLATES_MAGIC_LINK=

# =============================================================================
# 🎛️ ADMIN FRONTEND: Management interface configuration
# =============================================================================

# 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

# =============================================================================
# 📧 EMAIL CONFIGURATION: SMTP settings (optional but recommended for production)
# =============================================================================

# 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

# 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"

# =============================================================================
# 🔑 OAUTH PROVIDERS: Third-party authentication (optional)
# =============================================================================
# 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

# SAML 2.0. Refer to https://github.com/AppFlowy-IO/AppFlowy-Cloud/blob/main/doc/OKTA_SAML.md for example using Okta.
GOTRUE_SAML_ENABLED=false
GOTRUE_SAML_PRIVATE_KEY=

# =============================================================================
# 💾 FILE STORAGE: S3/MinIO configuration (required for file uploads)
# =============================================================================

# Storage Architecture Control: Determines the file storage backend for the entire system
# Affects: User uploads, document attachments, collaboration snapshots, AI embeddings, import/export files
# When true: Uses MinIO (S3-compatible) with path-style URLs and MinIO endpoint configuration
# When false: Uses AWS S3 with region-based configuration and standard S3 URLs
# Production options: Keep true for self-hosted MinIO, set false for AWS S3
APPFLOWY_S3_USE_MINIO=true

# Bucket Management: Controls automatic bucket creation during AppFlowy startup
# When true: AppFlowy automatically creates the storage bucket if it doesn't exist
# When false: Assumes bucket exists and was created externally (recommended for production)
APPFLOWY_S3_CREATE_BUCKET=true

# MinIO Endpoint Configuration: URL for MinIO API access
# Uses Docker service discovery variables for container networking
# Format combines MINIO_HOST and MINIO_PORT for internal service communication
# Change this URL if using external MinIO instance or different networking setup
APPFLOWY_S3_MINIO_URL=http://${MINIO_HOST}:${MINIO_PORT}

# Storage Authentication: Maps to the MinIO/AWS credentials defined above
# These reference the AWS_ACCESS_KEY and AWS_SECRET variables for consistency
# All AppFlowy services use these credentials to access the file storage backend
APPFLOWY_S3_ACCESS_KEY=${AWS_ACCESS_KEY}
APPFLOWY_S3_SECRET_KEY=${AWS_SECRET}

# Storage Bucket: Default bucket name for all AppFlowy file storage
# Contains: User files, document attachments, collaboration data, AI embeddings
# Must exist in both MinIO and AWS S3 configurations
APPFLOWY_S3_BUCKET=appflowy

# AWS S3 Configuration: Required only when APPFLOWY_S3_USE_MINIO=false
# Uncomment and configure these settings when using AWS S3 instead of MinIO
# APPFLOWY_S3_REGION=us-east-1

# MinIO Presigned URL Endpoint: External URL for client-side file access (optional)
# Enables direct file uploads/downloads from AppFlowy clients through presigned URLs
# Set this to your public MinIO endpoint if using nginx proxy configuration
# Format: Uses the external base URL with /minio-api path for API access
# APPFLOWY_S3_PRESIGNED_URL_ENDPOINT=${APPFLOWY_BASE_URL}/minio-api

# =============================================================================
# 🤖 AI FEATURES: Optional AI capabilities (configure only if needed)
# =============================================================================

# AppFlowy AI
# OpenAI API Authentication: Required API key for AI-powered features and semantic search
# Controls access to OpenAI's embedding models (text-embedding-3-small) for document indexing
# and ChatGPT models (gpt-4o-mini default) for search result summarization
# When configured: Enables semantic document search, AI-powered search summaries, and document embeddings
# When empty: AI features are disabled but core AppFlowy functionality remains fully operational
AI_OPENAI_API_KEY=

# If no summary model is provided, there will be no search summary when using AI search.
AI_OPENAI_API_SUMMARY_MODEL=

# Azure-hosted OpenAI API:
# If you're using a self-hosted OpenAI API via Azure, leave AI_OPENAI_API_KEY empty
# and set the following Azure-specific variables instead. If both are set, the standard OpenAI API will be used.
AI_AZURE_OPENAI_API_KEY=
AI_AZURE_OPENAI_API_BASE=
AI_AZURE_OPENAI_API_VERSION=

# AI Service Configuration (Docker container defaults)
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}
AI_APPFLOWY_BUCKET_NAME=${APPFLOWY_S3_BUCKET}
AI_APPFLOWY_HOST=${APPFLOWY_BASE_URL}
AI_MINIO_URL=http://${MINIO_HOST}:${MINIO_PORT}

# Embedding Configuration
APPFLOWY_EMBEDDING_CHUNK_SIZE=2000
APPFLOWY_EMBEDDING_CHUNK_OVERLAP=200

# =============================================================================
# ⚙️ WORKER SERVICES: Background processing (good defaults for production)
# =============================================================================

# AppFlowy Indexer (for search functionality)
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 Collaboration Service Configuration:
# Controls real-time collaboration behavior and performance
# Multi-thread: Whether collaboration service uses multiple threads (can be true for production)
# When deployed as standalone service, can be set to true for better performance
APPFLOWY_COLLABORATE_MULTI_THREAD=false

# Remove batch size: Number of inactive collaboration groups to remove in a single batch (default: 100)
# Higher values improve cleanup efficiency but may cause temporary blocking
APPFLOWY_COLLABORATE_REMOVE_BATCH_SIZE=100

# AppFlowy Worker Service
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}

# =============================================================================
# 🌐 WEB FRONTEND: AppFlowy Web interface
# =============================================================================

# 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

# =============================================================================
# 🗄️ PGADMIN: Database Management Web Interface
# =============================================================================

# PgAdmin credentials for database management web UI
# You can access pgadmin at http://your-host/pgadmin
# Use the APPFLOWY_DATABASE_URL values when connecting to the database
PGADMIN_DEFAULT_EMAIL=admin@example.com
PGADMIN_DEFAULT_PASSWORD=password

# =============================================================================
# 🌐 NGINX: Reverse proxy and web server configuration
# =============================================================================

# NGINX Configuration
# We changes this from 80/443 to our custom ports to expose AppFlowy via these custom ports
NGINX_PORT=800
NGINX_TLS_PORT=4430

# =============================================================================
# 🛠️ INFRASTRUCTURE: Networking, logging, and admin tools
# =============================================================================

# Log level for the appflowy-cloud service
RUST_LOG=info

# Cloudflare Tunnel (Advanced Networking)
# Leave empty unless you're using Cloudflare tunnel for secure connections
CLOUDFLARE_TUNNEL_TOKEN=

# Enable AI tests in production environment (usually false)
# Set to true only if you want to run AI-related tests in production
AI_TEST_ENABLED=false

docker-compse.yml

# Essential services for AppFlowy Cloud

services:
  nginx:
    restart: on-failure
    image: nginx
    ports:
      - ${NGINX_PORT:-800}:80   # Disable this if you are using TLS - the port needs to match the port configured in '.env'
      - ${NGINX_TLS_PORT:-4430}:443 # The port needs to match the port configured in '.env'
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
      #- ./nginx/ssl/certificate.crt:/etc/nginx/ssl/certificate.crt
      - ./nginx/ssl/vmhomeserver.local.markert.live.crt:/etc/nginx/ssl/certificate.crt #Local certificate
      #- ./nginx/ssl/private_key.key:/etc/nginx/ssl/private_key.key
      - ./nginx/ssl/vmhomeserver.local.markert.live.key:/etc/nginx/ssl/private_key.key #Local key for certificate

  # You do not need this if you have configured to use your own s3 file storage
  minio:
    restart: on-failure
    image: minio/minio
    environment:
      - MINIO_BROWSER_REDIRECT_URL=${APPFLOWY_BASE_URL?:err}/minio
      - MINIO_ROOT_USER=${APPFLOWY_S3_ACCESS_KEY:-minioadmin}
      - MINIO_ROOT_PASSWORD=${APPFLOWY_S3_SECRET_KEY:-minioadmin}
    command: server /data --console-address ":9001"
    volumes:
      - minio_data:/data

  postgres:
    restart: on-failure
    image: pgvector/pgvector:pg16
    environment:
      - POSTGRES_USER=${POSTGRES_USER:-postgres}
      - POSTGRES_DB=${POSTGRES_DB:-postgres}
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-password}
      - POSTGRES_HOST=${POSTGRES_HOST:-postgres}
    healthcheck:
      test: [ "CMD", "pg_isready", "-U", "${POSTGRES_USER}", "-d", "${POSTGRES_DB}" ]
      interval: 5s
      timeout: 5s
      retries: 12
    volumes:
      - postgres_data:/var/lib/postgresql/data

  redis:
    restart: on-failure
    image: redis

  gotrue:
    restart: on-failure
    build:
      context: docker/gotrue
      dockerfile: Dockerfile
    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
    image: appflowyinc/gotrue:${GOTRUE_VERSION:-latest}
    environment:
      # There are a lot of options to configure GoTrue. You can reference the example config:
      # https://github.com/supabase/auth/blob/master/example.env
      # The initial GoTrue Admin user to create, if not already exists.
      - GOTRUE_ADMIN_EMAIL=${GOTRUE_ADMIN_EMAIL}
      # The initial GoTrue Admin user password to create, if not already exists.
      # If the user already exists, the update will be skipped.
      - GOTRUE_ADMIN_PASSWORD=${GOTRUE_ADMIN_PASSWORD}
      - GOTRUE_DISABLE_SIGNUP=${GOTRUE_DISABLE_SIGNUP:-false}
      - GOTRUE_SITE_URL=appflowy-flutter://                           # redirected to AppFlowy application
      - GOTRUE_URI_ALLOW_LIST=** # adjust restrict if necessary
      - GOTRUE_JWT_SECRET=${GOTRUE_JWT_SECRET}                        # authentication secret
      - GOTRUE_JWT_EXP=${GOTRUE_JWT_EXP}
      # Without this environment variable, the createuser command will create an admin
      # with the `admin` role as opposed to `supabase_admin`
      - GOTRUE_JWT_ADMIN_GROUP_NAME=supabase_admin
      - GOTRUE_DB_DRIVER=postgres
      - API_EXTERNAL_URL=${API_EXTERNAL_URL}
      - DATABASE_URL=${GOTRUE_DATABASE_URL}
      - PORT=9999
      - GOTRUE_SMTP_HOST=${GOTRUE_SMTP_HOST}                          # e.g. smtp.gmail.com
      - GOTRUE_SMTP_PORT=${GOTRUE_SMTP_PORT}                          # e.g. 465
      - GOTRUE_SMTP_USER=${GOTRUE_SMTP_USER}                          # email sender, e.g. noreply@appflowy.io
      - GOTRUE_SMTP_PASS=${GOTRUE_SMTP_PASS}                          # email password
      - 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_TEMPLATES_MAGIC_LINK=${GOTRUE_MAILER_TEMPLATES_MAGIC_LINK}
      - GOTRUE_SMTP_ADMIN_EMAIL=${GOTRUE_SMTP_ADMIN_EMAIL}                # email with admin privileges e.g. internal@appflowy.io
      - GOTRUE_SMTP_MAX_FREQUENCY=${GOTRUE_SMTP_MAX_FREQUENCY:-1ns}       # set to 1ns for running tests
      - GOTRUE_RATE_LIMIT_EMAIL_SENT=${GOTRUE_RATE_LIMIT_EMAIL_SENT:-100} # number of email sendable per minute
      - GOTRUE_MAILER_AUTOCONFIRM=${GOTRUE_MAILER_AUTOCONFIRM:-false}     # change this to true to skip email confirmation
      # Google OAuth config
      - GOTRUE_EXTERNAL_GOOGLE_ENABLED=${GOTRUE_EXTERNAL_GOOGLE_ENABLED}
      - GOTRUE_EXTERNAL_GOOGLE_CLIENT_ID=${GOTRUE_EXTERNAL_GOOGLE_CLIENT_ID}
      - GOTRUE_EXTERNAL_GOOGLE_SECRET=${GOTRUE_EXTERNAL_GOOGLE_SECRET}
      - GOTRUE_EXTERNAL_GOOGLE_REDIRECT_URI=${GOTRUE_EXTERNAL_GOOGLE_REDIRECT_URI}
      # GITHUB OAuth config
      - GOTRUE_EXTERNAL_GITHUB_ENABLED=${GOTRUE_EXTERNAL_GITHUB_ENABLED}
      - GOTRUE_EXTERNAL_GITHUB_CLIENT_ID=${GOTRUE_EXTERNAL_GITHUB_CLIENT_ID}
      - GOTRUE_EXTERNAL_GITHUB_SECRET=${GOTRUE_EXTERNAL_GITHUB_SECRET}
      - GOTRUE_EXTERNAL_GITHUB_REDIRECT_URI=${GOTRUE_EXTERNAL_GITHUB_REDIRECT_URI}
      # Discord OAuth config
      - GOTRUE_EXTERNAL_DISCORD_ENABLED=${GOTRUE_EXTERNAL_DISCORD_ENABLED}
      - GOTRUE_EXTERNAL_DISCORD_CLIENT_ID=${GOTRUE_EXTERNAL_DISCORD_CLIENT_ID}
      - GOTRUE_EXTERNAL_DISCORD_SECRET=${GOTRUE_EXTERNAL_DISCORD_SECRET}
      - GOTRUE_EXTERNAL_DISCORD_REDIRECT_URI=${GOTRUE_EXTERNAL_DISCORD_REDIRECT_URI}
      # SAML 2.0 OAuth config
      - GOTRUE_SAML_ENABLED=${GOTRUE_SAML_ENABLED}
      - GOTRUE_SAML_PRIVATE_KEY=${GOTRUE_SAML_PRIVATE_KEY}

  appflowy_cloud:
    restart: on-failure
    environment:
      - RUST_LOG=${RUST_LOG:-info}
      - APPFLOWY_ENVIRONMENT=production
      - APPFLOWY_DATABASE_URL=${APPFLOWY_DATABASE_URL}
      - APPFLOWY_REDIS_URI=${APPFLOWY_REDIS_URI}
      - APPFLOWY_GOTRUE_JWT_SECRET=${GOTRUE_JWT_SECRET}
      - APPFLOWY_GOTRUE_JWT_EXP=${GOTRUE_JWT_EXP}
      - APPFLOWY_GOTRUE_BASE_URL=${APPFLOWY_GOTRUE_BASE_URL}
      - APPFLOWY_S3_CREATE_BUCKET=${APPFLOWY_S3_CREATE_BUCKET}
      - APPFLOWY_S3_USE_MINIO=${APPFLOWY_S3_USE_MINIO}
      - APPFLOWY_S3_MINIO_URL=${APPFLOWY_S3_MINIO_URL}
      - APPFLOWY_S3_ACCESS_KEY=${APPFLOWY_S3_ACCESS_KEY}
      - APPFLOWY_S3_SECRET_KEY=${APPFLOWY_S3_SECRET_KEY}
      - APPFLOWY_S3_BUCKET=${APPFLOWY_S3_BUCKET}
      - APPFLOWY_S3_REGION=${APPFLOWY_S3_REGION}
      - APPFLOWY_S3_PRESIGNED_URL_ENDPOINT=${APPFLOWY_S3_PRESIGNED_URL_ENDPOINT}
      - APPFLOWY_MAILER_SMTP_HOST=${APPFLOWY_MAILER_SMTP_HOST}
      - APPFLOWY_MAILER_SMTP_PORT=${APPFLOWY_MAILER_SMTP_PORT}
      - APPFLOWY_MAILER_SMTP_USERNAME=${APPFLOWY_MAILER_SMTP_USERNAME}
      - APPFLOWY_MAILER_SMTP_EMAIL=${APPFLOWY_MAILER_SMTP_EMAIL}
      - APPFLOWY_MAILER_SMTP_PASSWORD=${APPFLOWY_MAILER_SMTP_PASSWORD}
      - APPFLOWY_MAILER_SMTP_TLS_KIND=${APPFLOWY_MAILER_SMTP_TLS_KIND}
      - APPFLOWY_ACCESS_CONTROL=${APPFLOWY_ACCESS_CONTROL}
      - APPFLOWY_DATABASE_MAX_CONNECTIONS=${APPFLOWY_DATABASE_MAX_CONNECTIONS}
      - AI_SERVER_HOST=${AI_SERVER_HOST}
      - AI_SERVER_PORT=${AI_SERVER_PORT}
      - AI_OPENAI_API_KEY=${AI_OPENAI_API_KEY}
      - APPFLOWY_WEB_URL=${APPFLOWY_WEB_URL}
    build:
      context: .
      dockerfile: Dockerfile
      args:
        FEATURES: ""
    image: appflowyinc/appflowy_cloud:${APPFLOWY_CLOUD_VERSION:-latest}
    depends_on:
      gotrue:
        condition: service_healthy

  admin_frontend:
    restart: on-failure
    build:
      context: .
      dockerfile: ./admin_frontend/Dockerfile
    image: appflowyinc/admin_frontend:${APPFLOWY_ADMIN_FRONTEND_VERSION:-latest}
    environment:
      - RUST_LOG=${RUST_LOG:-info}
      - ADMIN_FRONTEND_REDIS_URL=${ADMIN_FRONTEND_REDIS_URL:-redis://redis:6379}
      - ADMIN_FRONTEND_GOTRUE_URL=${ADMIN_FRONTEND_GOTRUE_URL:-http://gotrue:9999}
      - ADMIN_FRONTEND_APPFLOWY_CLOUD_URL=${ADMIN_FRONTEND_APPFLOWY_CLOUD_URL:-http://appflowy_cloud:8000}
      - ADMIN_FRONTEND_PATH_PREFIX=${ADMIN_FRONTEND_PATH_PREFIX:-}
    depends_on:
      gotrue:
        condition: service_healthy
      appflowy_cloud:
        condition: service_started

  ai:
    restart: on-failure
    image: appflowyinc/appflowy_ai:${APPFLOWY_AI_VERSION:-latest}
    environment:
      - OPENAI_API_KEY=${AI_OPENAI_API_KEY}
      - APPFLOWY_AI_SERVER_PORT=${AI_SERVER_PORT}
      - APPFLOWY_AI_DATABASE_URL=${AI_DATABASE_URL}
      - APPFLOWY_AI_REDIS_URL=${AI_REDIS_URL}
    depends_on:
      postgres:
        condition: service_healthy

  appflowy_worker:
    restart: on-failure
    image: appflowyinc/appflowy_worker:${APPFLOWY_WORKER_VERSION:-latest}
    build:
      context: .
      dockerfile: ./services/appflowy-worker/Dockerfile
    environment:
      - RUST_LOG=${RUST_LOG:-info}
      - APPFLOWY_ENVIRONMENT=production
      - APPFLOWY_WORKER_REDIS_URL=${APPFLOWY_WORKER_REDIS_URL:-redis://redis:6379}
      - APPFLOWY_WORKER_ENVIRONMENT=production
      - APPFLOWY_WORKER_DATABASE_URL=${APPFLOWY_WORKER_DATABASE_URL}
      - APPFLOWY_WORKER_DATABASE_NAME=${APPFLOWY_WORKER_DATABASE_NAME}
      - APPFLOWY_WORKER_IMPORT_TICK_INTERVAL=30
      - APPFLOWY_S3_USE_MINIO=${APPFLOWY_S3_USE_MINIO}
      - APPFLOWY_S3_MINIO_URL=${APPFLOWY_S3_MINIO_URL}
      - APPFLOWY_S3_ACCESS_KEY=${APPFLOWY_S3_ACCESS_KEY}
      - APPFLOWY_S3_SECRET_KEY=${APPFLOWY_S3_SECRET_KEY}
      - APPFLOWY_S3_BUCKET=${APPFLOWY_S3_BUCKET}
      - APPFLOWY_S3_REGION=${APPFLOWY_S3_REGION}
      - APPFLOWY_MAILER_SMTP_HOST=${APPFLOWY_MAILER_SMTP_HOST}
      - APPFLOWY_MAILER_SMTP_PORT=${APPFLOWY_MAILER_SMTP_PORT}
      - APPFLOWY_MAILER_SMTP_USERNAME=${APPFLOWY_MAILER_SMTP_USERNAME}
      - APPFLOWY_MAILER_SMTP_EMAIL=${APPFLOWY_MAILER_SMTP_EMAIL}
      - APPFLOWY_MAILER_SMTP_PASSWORD=${APPFLOWY_MAILER_SMTP_PASSWORD}
      - APPFLOWY_MAILER_SMTP_TLS_KIND=${APPFLOWY_MAILER_SMTP_TLS_KIND}
    depends_on:
      postgres:
        condition: service_healthy

  appflowy_web:
    restart: on-failure
    image: appflowyinc/appflowy_web:${APPFLOWY_WEB_VERSION:-latest}
    depends_on:
      - appflowy_cloud
volumes:
  postgres_data:
  minio_data:
Originally created by @maggiv8 on GitHub (Aug 19, 2025). Original GitHub issue: https://github.com/AppFlowy-IO/AppFlowy/issues/8173 Hi there, I am currently facing a 'HTTP 502' issue after login into Appflowy Web. Steps to reproduce issue: 1. Go to Appyflow web (based on my config 'https://v4-vmhomehub.local.markert.live:4430') 2. Login with username and password. Current result: I am getting an HTTP 502 - Bad Gateway after logging in: The browser console logs: `api/user/profile:1 Failed to load resource: the server responded with a status of 502 (Bad Gateway)` The docker container log contains the followign message: ``` 172.18.0.8 - - [19/Aug/2025:04:07:18 +0000] "GET /favicon.ico HTTP/1.0" 404 555 "https://v4-vmhomehub.local.markert.live:4430/api/user/workspace" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36" 172.18.0.8 - - [19/Aug/2025:04:14:44 +0000] "GET /app HTTP/1.0" 200 2904 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36" ``` I guess there is something wrong with my NGINX routing? Any help would be appreciated. Thank you. P.S. My config is pasted below: .env ``` # ============================================================================= # AppFlowy Cloud - Production Deployment Configuration # ============================================================================= # 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 localhost with your domain, # such as mydomain.com. FQDN=v4-vmhomehub.local.markert.live # Change this to https if you wish to enable TLS. SCHEME=http APPFLOWY_BASE_URL=${SCHEME}://${FQDN} # ============================================================================= # 🗄️ DATABASE & CACHE: Core data infrastructure # ============================================================================= # PostgreSQL Settings POSTGRES_HOST=v4-vmdatabaseserver.local.markert.live POSTGRES_USER=user POSTGRES_PASSWORD=pwd POSTGRES_PORT=5432 POSTGRES_DB=db # Redis Settings REDIS_HOST=redis REDIS_PORT=6379 # ============================================================================= # 🏗️ INFRASTRUCTURE SERVICES: Object storage and networking # ============================================================================= # MinIO Configuration: S3-compatible object storage for file uploads and attachments # Docker service discovery: These values are used for container-to-container communication # MINIO_HOST refers to the Docker Compose service name, not an external domain/IP # Used by: AppFlowy Cloud, Worker services, AI service, and Admin Frontend MINIO_HOST=minio MINIO_PORT=9000 # MinIO/AWS Credentials: Authentication keys for object storage access # Development: Uses MinIO's default credentials (minioadmin/minioadmin) for quick setup # Production: MUST be changed to secure, randomly generated credentials for security # These credentials are used across all services that access file storage # Security note: Default credentials are well-known and should never be used in production AWS_ACCESS_KEY=minioadmin AWS_SECRET=minioadmin # ============================================================================= # ☁️ APPFLOWY SERVICES: Application service configuration # ============================================================================= # AppFlowy Cloud Service Configuration # 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 Service Configuration # Access Control System: Enables/disables permission-based access control # Controls workspace access, collaboration permissions, and realtime access restrictions APPFLOWY_ACCESS_CONTROL=true # WebSocket Mailbox Configuration: Controls realtime server message handling capacity # Sets the maximum number of messages that can be queued in the WebSocket actor's mailbox # Higher values allow more concurrent WebSocket messages but use more memory # Lower values may cause message drops under high load but reduce memory usage APPFLOWY_WEBSOCKET_MAILBOX_SIZE=6000 # Database Connection Pool: Maximum number of concurrent PostgreSQL connections # Controls the size of the database connection pool for the AppFlowy Cloud service # PostgreSQL has a default limit of ~100 connections total (15 reserved for superuser) # Higher values improve concurrency but consume more database resources # Lower values reduce database load but may cause connection timeouts under load APPFLOWY_DATABASE_MAX_CONNECTIONS=40 # URL that connects to the redis docker container APPFLOWY_REDIS_URI=redis://${REDIS_HOST}:${REDIS_PORT} # GoTrue database connection. If your password contains special characters, # instead of using ${POSTGRES_PASSWORD}, use the url encoded version. # For example, `p@ssword` will become `p%40ssword` GOTRUE_DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}?search_path=auth # ============================================================================= # 🔐 GOTRUE: Authentication service configuration # ============================================================================= # GoTrue Admin Credentials # 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=pwd # JWT Configuration # Authentication key, change this and keep the key safe and secret GOTRUE_JWT_SECRET=1234 # Expiration time in seconds for the JWT token GOTRUE_JWT_EXP=7200 # External URL where the GoTrue service is exposed API_EXTERNAL_URL=${APPFLOWY_BASE_URL}/gotrue # User Registration & Login Settings # 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 # Set this to true if users can only join by invite GOTRUE_DISABLE_SIGNUP=true # Number of emails that can be sent per minute GOTRUE_RATE_LIMIT_EMAIL_SENT=100 # Email Templates # Optional. You can provide a public http link (eg. github) to customize your magic link template. # Refer to https://github.com/supabase/auth?tab=readme-ov-file#configuration for details on how to create a custom email template. GOTRUE_MAILER_TEMPLATES_MAGIC_LINK= # ============================================================================= # 🎛️ ADMIN FRONTEND: Management interface configuration # ============================================================================= # 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 # ============================================================================= # 📧 EMAIL CONFIGURATION: SMTP settings (optional but recommended for production) # ============================================================================= # 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 # 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" # ============================================================================= # 🔑 OAUTH PROVIDERS: Third-party authentication (optional) # ============================================================================= # 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 # SAML 2.0. Refer to https://github.com/AppFlowy-IO/AppFlowy-Cloud/blob/main/doc/OKTA_SAML.md for example using Okta. GOTRUE_SAML_ENABLED=false GOTRUE_SAML_PRIVATE_KEY= # ============================================================================= # 💾 FILE STORAGE: S3/MinIO configuration (required for file uploads) # ============================================================================= # Storage Architecture Control: Determines the file storage backend for the entire system # Affects: User uploads, document attachments, collaboration snapshots, AI embeddings, import/export files # When true: Uses MinIO (S3-compatible) with path-style URLs and MinIO endpoint configuration # When false: Uses AWS S3 with region-based configuration and standard S3 URLs # Production options: Keep true for self-hosted MinIO, set false for AWS S3 APPFLOWY_S3_USE_MINIO=true # Bucket Management: Controls automatic bucket creation during AppFlowy startup # When true: AppFlowy automatically creates the storage bucket if it doesn't exist # When false: Assumes bucket exists and was created externally (recommended for production) APPFLOWY_S3_CREATE_BUCKET=true # MinIO Endpoint Configuration: URL for MinIO API access # Uses Docker service discovery variables for container networking # Format combines MINIO_HOST and MINIO_PORT for internal service communication # Change this URL if using external MinIO instance or different networking setup APPFLOWY_S3_MINIO_URL=http://${MINIO_HOST}:${MINIO_PORT} # Storage Authentication: Maps to the MinIO/AWS credentials defined above # These reference the AWS_ACCESS_KEY and AWS_SECRET variables for consistency # All AppFlowy services use these credentials to access the file storage backend APPFLOWY_S3_ACCESS_KEY=${AWS_ACCESS_KEY} APPFLOWY_S3_SECRET_KEY=${AWS_SECRET} # Storage Bucket: Default bucket name for all AppFlowy file storage # Contains: User files, document attachments, collaboration data, AI embeddings # Must exist in both MinIO and AWS S3 configurations APPFLOWY_S3_BUCKET=appflowy # AWS S3 Configuration: Required only when APPFLOWY_S3_USE_MINIO=false # Uncomment and configure these settings when using AWS S3 instead of MinIO # APPFLOWY_S3_REGION=us-east-1 # MinIO Presigned URL Endpoint: External URL for client-side file access (optional) # Enables direct file uploads/downloads from AppFlowy clients through presigned URLs # Set this to your public MinIO endpoint if using nginx proxy configuration # Format: Uses the external base URL with /minio-api path for API access # APPFLOWY_S3_PRESIGNED_URL_ENDPOINT=${APPFLOWY_BASE_URL}/minio-api # ============================================================================= # 🤖 AI FEATURES: Optional AI capabilities (configure only if needed) # ============================================================================= # AppFlowy AI # OpenAI API Authentication: Required API key for AI-powered features and semantic search # Controls access to OpenAI's embedding models (text-embedding-3-small) for document indexing # and ChatGPT models (gpt-4o-mini default) for search result summarization # When configured: Enables semantic document search, AI-powered search summaries, and document embeddings # When empty: AI features are disabled but core AppFlowy functionality remains fully operational AI_OPENAI_API_KEY= # If no summary model is provided, there will be no search summary when using AI search. AI_OPENAI_API_SUMMARY_MODEL= # Azure-hosted OpenAI API: # If you're using a self-hosted OpenAI API via Azure, leave AI_OPENAI_API_KEY empty # and set the following Azure-specific variables instead. If both are set, the standard OpenAI API will be used. AI_AZURE_OPENAI_API_KEY= AI_AZURE_OPENAI_API_BASE= AI_AZURE_OPENAI_API_VERSION= # AI Service Configuration (Docker container defaults) 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} AI_APPFLOWY_BUCKET_NAME=${APPFLOWY_S3_BUCKET} AI_APPFLOWY_HOST=${APPFLOWY_BASE_URL} AI_MINIO_URL=http://${MINIO_HOST}:${MINIO_PORT} # Embedding Configuration APPFLOWY_EMBEDDING_CHUNK_SIZE=2000 APPFLOWY_EMBEDDING_CHUNK_OVERLAP=200 # ============================================================================= # ⚙️ WORKER SERVICES: Background processing (good defaults for production) # ============================================================================= # AppFlowy Indexer (for search functionality) 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 Collaboration Service Configuration: # Controls real-time collaboration behavior and performance # Multi-thread: Whether collaboration service uses multiple threads (can be true for production) # When deployed as standalone service, can be set to true for better performance APPFLOWY_COLLABORATE_MULTI_THREAD=false # Remove batch size: Number of inactive collaboration groups to remove in a single batch (default: 100) # Higher values improve cleanup efficiency but may cause temporary blocking APPFLOWY_COLLABORATE_REMOVE_BATCH_SIZE=100 # AppFlowy Worker Service 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} # ============================================================================= # 🌐 WEB FRONTEND: AppFlowy Web interface # ============================================================================= # 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 # ============================================================================= # 🗄️ PGADMIN: Database Management Web Interface # ============================================================================= # PgAdmin credentials for database management web UI # You can access pgadmin at http://your-host/pgadmin # Use the APPFLOWY_DATABASE_URL values when connecting to the database PGADMIN_DEFAULT_EMAIL=admin@example.com PGADMIN_DEFAULT_PASSWORD=password # ============================================================================= # 🌐 NGINX: Reverse proxy and web server configuration # ============================================================================= # NGINX Configuration # We changes this from 80/443 to our custom ports to expose AppFlowy via these custom ports NGINX_PORT=800 NGINX_TLS_PORT=4430 # ============================================================================= # 🛠️ INFRASTRUCTURE: Networking, logging, and admin tools # ============================================================================= # Log level for the appflowy-cloud service RUST_LOG=info # Cloudflare Tunnel (Advanced Networking) # Leave empty unless you're using Cloudflare tunnel for secure connections CLOUDFLARE_TUNNEL_TOKEN= # Enable AI tests in production environment (usually false) # Set to true only if you want to run AI-related tests in production AI_TEST_ENABLED=false ``` docker-compse.yml ``` # Essential services for AppFlowy Cloud services: nginx: restart: on-failure image: nginx ports: - ${NGINX_PORT:-800}:80 # Disable this if you are using TLS - the port needs to match the port configured in '.env' - ${NGINX_TLS_PORT:-4430}:443 # The port needs to match the port configured in '.env' volumes: - ./nginx/nginx.conf:/etc/nginx/nginx.conf #- ./nginx/ssl/certificate.crt:/etc/nginx/ssl/certificate.crt - ./nginx/ssl/vmhomeserver.local.markert.live.crt:/etc/nginx/ssl/certificate.crt #Local certificate #- ./nginx/ssl/private_key.key:/etc/nginx/ssl/private_key.key - ./nginx/ssl/vmhomeserver.local.markert.live.key:/etc/nginx/ssl/private_key.key #Local key for certificate # You do not need this if you have configured to use your own s3 file storage minio: restart: on-failure image: minio/minio environment: - MINIO_BROWSER_REDIRECT_URL=${APPFLOWY_BASE_URL?:err}/minio - MINIO_ROOT_USER=${APPFLOWY_S3_ACCESS_KEY:-minioadmin} - MINIO_ROOT_PASSWORD=${APPFLOWY_S3_SECRET_KEY:-minioadmin} command: server /data --console-address ":9001" volumes: - minio_data:/data postgres: restart: on-failure image: pgvector/pgvector:pg16 environment: - POSTGRES_USER=${POSTGRES_USER:-postgres} - POSTGRES_DB=${POSTGRES_DB:-postgres} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-password} - POSTGRES_HOST=${POSTGRES_HOST:-postgres} healthcheck: test: [ "CMD", "pg_isready", "-U", "${POSTGRES_USER}", "-d", "${POSTGRES_DB}" ] interval: 5s timeout: 5s retries: 12 volumes: - postgres_data:/var/lib/postgresql/data redis: restart: on-failure image: redis gotrue: restart: on-failure build: context: docker/gotrue dockerfile: Dockerfile 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 image: appflowyinc/gotrue:${GOTRUE_VERSION:-latest} environment: # There are a lot of options to configure GoTrue. You can reference the example config: # https://github.com/supabase/auth/blob/master/example.env # The initial GoTrue Admin user to create, if not already exists. - GOTRUE_ADMIN_EMAIL=${GOTRUE_ADMIN_EMAIL} # The initial GoTrue Admin user password to create, if not already exists. # If the user already exists, the update will be skipped. - GOTRUE_ADMIN_PASSWORD=${GOTRUE_ADMIN_PASSWORD} - GOTRUE_DISABLE_SIGNUP=${GOTRUE_DISABLE_SIGNUP:-false} - GOTRUE_SITE_URL=appflowy-flutter:// # redirected to AppFlowy application - GOTRUE_URI_ALLOW_LIST=** # adjust restrict if necessary - GOTRUE_JWT_SECRET=${GOTRUE_JWT_SECRET} # authentication secret - GOTRUE_JWT_EXP=${GOTRUE_JWT_EXP} # Without this environment variable, the createuser command will create an admin # with the `admin` role as opposed to `supabase_admin` - GOTRUE_JWT_ADMIN_GROUP_NAME=supabase_admin - GOTRUE_DB_DRIVER=postgres - API_EXTERNAL_URL=${API_EXTERNAL_URL} - DATABASE_URL=${GOTRUE_DATABASE_URL} - PORT=9999 - GOTRUE_SMTP_HOST=${GOTRUE_SMTP_HOST} # e.g. smtp.gmail.com - GOTRUE_SMTP_PORT=${GOTRUE_SMTP_PORT} # e.g. 465 - GOTRUE_SMTP_USER=${GOTRUE_SMTP_USER} # email sender, e.g. noreply@appflowy.io - GOTRUE_SMTP_PASS=${GOTRUE_SMTP_PASS} # email password - 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_TEMPLATES_MAGIC_LINK=${GOTRUE_MAILER_TEMPLATES_MAGIC_LINK} - GOTRUE_SMTP_ADMIN_EMAIL=${GOTRUE_SMTP_ADMIN_EMAIL} # email with admin privileges e.g. internal@appflowy.io - GOTRUE_SMTP_MAX_FREQUENCY=${GOTRUE_SMTP_MAX_FREQUENCY:-1ns} # set to 1ns for running tests - GOTRUE_RATE_LIMIT_EMAIL_SENT=${GOTRUE_RATE_LIMIT_EMAIL_SENT:-100} # number of email sendable per minute - GOTRUE_MAILER_AUTOCONFIRM=${GOTRUE_MAILER_AUTOCONFIRM:-false} # change this to true to skip email confirmation # Google OAuth config - GOTRUE_EXTERNAL_GOOGLE_ENABLED=${GOTRUE_EXTERNAL_GOOGLE_ENABLED} - GOTRUE_EXTERNAL_GOOGLE_CLIENT_ID=${GOTRUE_EXTERNAL_GOOGLE_CLIENT_ID} - GOTRUE_EXTERNAL_GOOGLE_SECRET=${GOTRUE_EXTERNAL_GOOGLE_SECRET} - GOTRUE_EXTERNAL_GOOGLE_REDIRECT_URI=${GOTRUE_EXTERNAL_GOOGLE_REDIRECT_URI} # GITHUB OAuth config - GOTRUE_EXTERNAL_GITHUB_ENABLED=${GOTRUE_EXTERNAL_GITHUB_ENABLED} - GOTRUE_EXTERNAL_GITHUB_CLIENT_ID=${GOTRUE_EXTERNAL_GITHUB_CLIENT_ID} - GOTRUE_EXTERNAL_GITHUB_SECRET=${GOTRUE_EXTERNAL_GITHUB_SECRET} - GOTRUE_EXTERNAL_GITHUB_REDIRECT_URI=${GOTRUE_EXTERNAL_GITHUB_REDIRECT_URI} # Discord OAuth config - GOTRUE_EXTERNAL_DISCORD_ENABLED=${GOTRUE_EXTERNAL_DISCORD_ENABLED} - GOTRUE_EXTERNAL_DISCORD_CLIENT_ID=${GOTRUE_EXTERNAL_DISCORD_CLIENT_ID} - GOTRUE_EXTERNAL_DISCORD_SECRET=${GOTRUE_EXTERNAL_DISCORD_SECRET} - GOTRUE_EXTERNAL_DISCORD_REDIRECT_URI=${GOTRUE_EXTERNAL_DISCORD_REDIRECT_URI} # SAML 2.0 OAuth config - GOTRUE_SAML_ENABLED=${GOTRUE_SAML_ENABLED} - GOTRUE_SAML_PRIVATE_KEY=${GOTRUE_SAML_PRIVATE_KEY} appflowy_cloud: restart: on-failure environment: - RUST_LOG=${RUST_LOG:-info} - APPFLOWY_ENVIRONMENT=production - APPFLOWY_DATABASE_URL=${APPFLOWY_DATABASE_URL} - APPFLOWY_REDIS_URI=${APPFLOWY_REDIS_URI} - APPFLOWY_GOTRUE_JWT_SECRET=${GOTRUE_JWT_SECRET} - APPFLOWY_GOTRUE_JWT_EXP=${GOTRUE_JWT_EXP} - APPFLOWY_GOTRUE_BASE_URL=${APPFLOWY_GOTRUE_BASE_URL} - APPFLOWY_S3_CREATE_BUCKET=${APPFLOWY_S3_CREATE_BUCKET} - APPFLOWY_S3_USE_MINIO=${APPFLOWY_S3_USE_MINIO} - APPFLOWY_S3_MINIO_URL=${APPFLOWY_S3_MINIO_URL} - APPFLOWY_S3_ACCESS_KEY=${APPFLOWY_S3_ACCESS_KEY} - APPFLOWY_S3_SECRET_KEY=${APPFLOWY_S3_SECRET_KEY} - APPFLOWY_S3_BUCKET=${APPFLOWY_S3_BUCKET} - APPFLOWY_S3_REGION=${APPFLOWY_S3_REGION} - APPFLOWY_S3_PRESIGNED_URL_ENDPOINT=${APPFLOWY_S3_PRESIGNED_URL_ENDPOINT} - APPFLOWY_MAILER_SMTP_HOST=${APPFLOWY_MAILER_SMTP_HOST} - APPFLOWY_MAILER_SMTP_PORT=${APPFLOWY_MAILER_SMTP_PORT} - APPFLOWY_MAILER_SMTP_USERNAME=${APPFLOWY_MAILER_SMTP_USERNAME} - APPFLOWY_MAILER_SMTP_EMAIL=${APPFLOWY_MAILER_SMTP_EMAIL} - APPFLOWY_MAILER_SMTP_PASSWORD=${APPFLOWY_MAILER_SMTP_PASSWORD} - APPFLOWY_MAILER_SMTP_TLS_KIND=${APPFLOWY_MAILER_SMTP_TLS_KIND} - APPFLOWY_ACCESS_CONTROL=${APPFLOWY_ACCESS_CONTROL} - APPFLOWY_DATABASE_MAX_CONNECTIONS=${APPFLOWY_DATABASE_MAX_CONNECTIONS} - AI_SERVER_HOST=${AI_SERVER_HOST} - AI_SERVER_PORT=${AI_SERVER_PORT} - AI_OPENAI_API_KEY=${AI_OPENAI_API_KEY} - APPFLOWY_WEB_URL=${APPFLOWY_WEB_URL} build: context: . dockerfile: Dockerfile args: FEATURES: "" image: appflowyinc/appflowy_cloud:${APPFLOWY_CLOUD_VERSION:-latest} depends_on: gotrue: condition: service_healthy admin_frontend: restart: on-failure build: context: . dockerfile: ./admin_frontend/Dockerfile image: appflowyinc/admin_frontend:${APPFLOWY_ADMIN_FRONTEND_VERSION:-latest} environment: - RUST_LOG=${RUST_LOG:-info} - ADMIN_FRONTEND_REDIS_URL=${ADMIN_FRONTEND_REDIS_URL:-redis://redis:6379} - ADMIN_FRONTEND_GOTRUE_URL=${ADMIN_FRONTEND_GOTRUE_URL:-http://gotrue:9999} - ADMIN_FRONTEND_APPFLOWY_CLOUD_URL=${ADMIN_FRONTEND_APPFLOWY_CLOUD_URL:-http://appflowy_cloud:8000} - ADMIN_FRONTEND_PATH_PREFIX=${ADMIN_FRONTEND_PATH_PREFIX:-} depends_on: gotrue: condition: service_healthy appflowy_cloud: condition: service_started ai: restart: on-failure image: appflowyinc/appflowy_ai:${APPFLOWY_AI_VERSION:-latest} environment: - OPENAI_API_KEY=${AI_OPENAI_API_KEY} - APPFLOWY_AI_SERVER_PORT=${AI_SERVER_PORT} - APPFLOWY_AI_DATABASE_URL=${AI_DATABASE_URL} - APPFLOWY_AI_REDIS_URL=${AI_REDIS_URL} depends_on: postgres: condition: service_healthy appflowy_worker: restart: on-failure image: appflowyinc/appflowy_worker:${APPFLOWY_WORKER_VERSION:-latest} build: context: . dockerfile: ./services/appflowy-worker/Dockerfile environment: - RUST_LOG=${RUST_LOG:-info} - APPFLOWY_ENVIRONMENT=production - APPFLOWY_WORKER_REDIS_URL=${APPFLOWY_WORKER_REDIS_URL:-redis://redis:6379} - APPFLOWY_WORKER_ENVIRONMENT=production - APPFLOWY_WORKER_DATABASE_URL=${APPFLOWY_WORKER_DATABASE_URL} - APPFLOWY_WORKER_DATABASE_NAME=${APPFLOWY_WORKER_DATABASE_NAME} - APPFLOWY_WORKER_IMPORT_TICK_INTERVAL=30 - APPFLOWY_S3_USE_MINIO=${APPFLOWY_S3_USE_MINIO} - APPFLOWY_S3_MINIO_URL=${APPFLOWY_S3_MINIO_URL} - APPFLOWY_S3_ACCESS_KEY=${APPFLOWY_S3_ACCESS_KEY} - APPFLOWY_S3_SECRET_KEY=${APPFLOWY_S3_SECRET_KEY} - APPFLOWY_S3_BUCKET=${APPFLOWY_S3_BUCKET} - APPFLOWY_S3_REGION=${APPFLOWY_S3_REGION} - APPFLOWY_MAILER_SMTP_HOST=${APPFLOWY_MAILER_SMTP_HOST} - APPFLOWY_MAILER_SMTP_PORT=${APPFLOWY_MAILER_SMTP_PORT} - APPFLOWY_MAILER_SMTP_USERNAME=${APPFLOWY_MAILER_SMTP_USERNAME} - APPFLOWY_MAILER_SMTP_EMAIL=${APPFLOWY_MAILER_SMTP_EMAIL} - APPFLOWY_MAILER_SMTP_PASSWORD=${APPFLOWY_MAILER_SMTP_PASSWORD} - APPFLOWY_MAILER_SMTP_TLS_KIND=${APPFLOWY_MAILER_SMTP_TLS_KIND} depends_on: postgres: condition: service_healthy appflowy_web: restart: on-failure image: appflowyinc/appflowy_web:${APPFLOWY_WEB_VERSION:-latest} depends_on: - appflowy_cloud volumes: postgres_data: minio_data: ```
Author
Owner

@khorshuheng commented on GitHub (Aug 19, 2025):

Is there any containers that are crashing? Specifically, appflowy cloud container? In addition, are you able to login via /console , or the desktop app?

<!-- gh-comment-id:3199468555 --> @khorshuheng commented on GitHub (Aug 19, 2025): Is there any containers that are crashing? Specifically, appflowy cloud container? In addition, are you able to login via /console , or the desktop app?
Author
Owner

@maggiv8 commented on GitHub (Aug 22, 2025):

Ok, so I reset the whole setup. The 502 issue disappeared (based on the logs it was a database issue which caused it). However, now Iam facing another issue. Closing this one....

<!-- gh-comment-id:3212768976 --> @maggiv8 commented on GitHub (Aug 22, 2025): Ok, so I reset the whole setup. The 502 issue disappeared (based on the logs it was a database issue which caused it). However, now Iam facing another issue. Closing this one....
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
AppFlowy-IO/AppFlowy#3618
No description provided.