version: '3'
services:
  tunnel:
    container_name: cloudflared-tunnel
    image: cloudflare/cloudflared
    restart: unless-stopped
    command: tunnel --no-autoupdate run
    environment:
      - TUNNEL_TOKEN=${CLOUDFLARE_TUNNEL_TOKEN}
    depends_on:
      - nginx

  portainer:
    restart: on-failure
    image: portainer/portainer-ce:latest
    ports:
      - 9442:9000
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

  portainer_init:
    depends_on:
      - portainer
    image: alpine/curl
    restart: on-failure
    environment:
      - PORTAINER_PASSWORD=${PORTAINER_PASSWORD}
    volumes:
      - ./docker/portainer/setup.sh:/setup.sh
    command: ./setup.sh

  nginx:
    restart: on-failure
    image: nginx
    ports:
      - 80:80
      - 443:443
    depends_on:
      - minio
      - appflowy_cloud
      - gotrue
      - admin_frontend
      - portainer
    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

  minio:
    restart: on-failure
    image: minio/minio
    ports:
      - 9000:9000
      - 9001:9001
    environment:
      - MINIO_BROWSER_REDIRECT_URL=http://localhost/minio
    command: server /data --console-address ":9001"
    volumes:
      - minio_data:/data

  postgres:
    restart: on-failure
    image: postgres
    environment:
      - POSTGRES_USER=${POSTGRES_USER:-postgres}
      - POSTGRES_DB=${POSTGRES_DB:-postgres}
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-password}
      - POSTGRES_HOST=${POSTGRES_HOST:-postgres}
    ports:
      - 5433:5432
    volumes:
      - ./migrations/before:/docker-entrypoint-initdb.d
      - postgres_data:/var/lib/postgresql/data

  pgadmin:
    restart: on-failure
    image: dpage/pgadmin4
    depends_on:
      - postgres
    environment:
      - PGADMIN_DEFAULT_EMAIL=${PGADMIN_DEFAULT_EMAIL}
      - PGADMIN_DEFAULT_PASSWORD=${PGADMIN_DEFAULT_PASSWORD}
    ports:
      - 5400:80
    volumes:
      - ./docker/pgadmin/servers.json:/pgadmin4/servers.json

  redis:
    restart: on-failure
    image: redis
    ports:
      - 6380:6379

  gotrue:
    restart: on-failure
    build:
      context: .
      dockerfile: docker/gotrue.Dockerfile
    depends_on:
      - postgres
    environment:
      # Gotrue config: https://github.com/supabase/gotrue/blob/master/example.env
      - GOTRUE_SITE_URL=appflowy-flutter://                           # redirected to AppFlowy application
      - URI_ALLOW_LIST=*                                              # adjust restrict if necessary
      - GOTRUE_JWT_SECRET=${GOTRUE_JWT_SECRET}                        # authentication secret
      - GOTRUE_DB_DRIVER=postgres
      - API_EXTERNAL_URL=${API_EXTERNAL_URL}
      - DATABASE_URL=postgres://supabase_auth_admin:root@postgres:5432/postgres
      - 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_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_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}
      # Prometheus Metrics
      - GOTRUE_METRICS_ENABLED=true
      - GOTRUE_METRICS_EXPORTER=prometheus
    ports:
      - 9998:9999

  appflowy_cloud:
    restart: on-failure
    environment:
      - RUST_LOG=${RUST_LOG:-info}
      - APP_ENVIRONMENT=production
      - APP__GOTRUE__JWT_SECRET=${GOTRUE_JWT_SECRET}
      - APP__GOTRUE__EXT_URL=${API_EXTERNAL_URL}
      - APP__GOTRUE__ADMIN_EMAIL=${GOTRUE_ADMIN_EMAIL}
      - APP__GOTRUE__ADMIN_PASSWORD=${GOTRUE_ADMIN_PASSWORD}
      - APP__S3__USE_MINIO=${USE_MINIO}
      - APP__S3__MINIO_URL=${MINIO_URL:-http://minio:9000}
      - APP__S3__AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}
      - APP__S3__AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}
      - APP__S3__AWS_S3_BUCKET=${AWS_S3_BUCKET}
      - APP__S3__AWS_REGION=${AWS_REGION}
    build:
      context: .
      dockerfile: Dockerfile
    image: appflowyinc/appflowy_cloud:${BACKEND_VERSION:-latest}
    depends_on:
      - redis
      - postgres
      - gotrue
    ports:
      - 8000:8000

  admin_frontend:
    restart: on-failure
    build:
      context: .
      dockerfile: ./admin_frontend/Dockerfile
    image: appflowyinc/admin_frontend:${BACKEND_VERSION:-latest}
    depends_on:
      - gotrue
    ports:
      - 3000:3000

volumes:
  postgres_data:
  minio_data:
