Skip to content

App Suggestion: Full Issue Supabase + Stalwart and Roundcube #1243

@rootacc3ss

Description

@rootacc3ss

Below is a config for Caprover I was trying to write for Supabase's full issue, including vectors and deno based edge functions, but Caprover doesn't support relative mounts ofc:

captainVersion: 4

caproverOneClickApp:
  instructions:
    start: Deploying Supabase Full Stack with Edge Functions integration.
    end: Supabase is ready.

########

version: "3.8"

services:

  supabase-kong:
    image: kong:2.8.1
    entrypoint: bash -c "eval \"echo $(cat /home/kong/temp.yml)\" && kong docker-entrypoint.sh kong docker-start"
    volumes:
      - ./volumes/api/kong.yml:/home/kong/temp.yml:ro
    environment:
      SERVICE_URL_SUPABASE_KONG: "http://supabase-kong:8000"
      KONG_PORT_MAPS: "443:8000"
      JWT_SECRET: "servicepasswordjwt"
      KONG_DATABASE: "off"
      KONG_DECLARATIVE_CONFIG: "/home/kong/kong.yml"
      KONG_DNS_ORDER: "LAST,A,CNAME"
      KONG_PLUGINS: "request-transformer,cors,key-auth,acl,basic-auth"
      SUPABASE_ANON_KEY: "supabaseanonkey"
      SUPABASE_SERVICE_KEY: "supabaseservicekey"
      DASHBOARD_USERNAME: "serviceuseradmin"
      DASHBOARD_PASSWORD: "servicepasswordadmin"
    depends_on:
      supabase-analytics:
        condition: service_healthy

  supabase-db:
    image: supabase/postgres:15.8.1.048
    environment:
      POSTGRES_PASSWORD: "servicepasswordpostgres"
      POSTGRES_DB: "postgresdb-postgres"
      JWT_SECRET: "servicepasswordjwt"
      JWT_EXP: 3600
    volumes:
      - supabase-db-data:/var/lib/postgresql/data
      - ./volumes/db/realtime.sql:/docker-entrypoint-initdb.d/migrations/99-realtime.sql
      - ./volumes/db/supabase.sql:/docker-entrypoint-initdb.d/migrations/97-supabase.sql
      - ./volumes/db/pooler.sql:/docker-entrypoint-initdb.d/migrations/99-pooler.sql
      - ./volumes/db/webhooks.sql:/docker-entrypoint-initdb.d/init-scripts/98-webhooks.sql
      - ./volumes/db/roles.sql:/docker-entrypoint-initdb.d/init-scripts/99-roles.sql
      - ./volumes/db/jwt.sql:/docker-entrypoint-initdb.d/init-scripts/99-jwt.sql
      - ./volumes/db/logs.sql:/docker-entrypoint-initdb.d/migrations/99-logs.sql
      - ./volumes/db/postgresql-custom.conf:/etc/postgresql/postgresql.conf
    command:
      - postgres
      - -c
      - config_file=/etc/postgresql/postgresql.conf
      - -c
      - log_min_messages=fatal
    healthcheck:
      test: ["CMD", "pg_isready", "-U", "postgres", "-h", "127.0.0.1"]
      interval: 5s
      timeout: 5s
      retries: 10

  supabase-analytics:
    image: supabase/logflare:1.4.0
    environment:
      LOGFLARE_NODE_HOST: "127.0.0.1"
      DB_USERNAME: "supabaseadmin"
      DB_DATABASE: "supabase"
      DB_HOSTNAME: "supabase-db"
      DB_PORT: 5432
      DB_PASSWORD: "servicepasswordpostgres"
      DB_SCHEMA: "analytics"
      LOGFLARE_API_KEY: "servicepasswordlogflare"
      LOGFLARE_SINGLE_TENANT: "true"
      LOGFLARE_SINGLE_TENANT_MODE: "true"
      LOGFLARE_SUPABASE_MODE: "true"
      LOGFLARE_MIN_CLUSTER_SIZE: 1
    depends_on:
      supabase-db:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-sSfL", "-I", "http://127.0.0.1:4000/health"]
      interval: 5s
      timeout: 5s
      retries: 10

  supabase-minio:
    image: minio/minio:latest
    environment:
      MINIO_ROOT_USER: "serviceusermin.io"
      MINIO_ROOT_PASSWORD: "servicepasswordminio"
    command: server /data --console-address ":9001"
    ports:
      - "9000:9000"
      - "9001:9001"
    volumes:
      - supabase-minio-data:/data
    healthcheck:
      test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:9000/minio/health/live"]
      interval: 5s
      timeout: 5s
      retries: 3

  minio-createbucket:
    image: minio/mc
    depends_on:
      supabase-minio:
        condition: service_healthy
    entrypoint: ["/bin/sh", "-c"]
    command: |
      /usr/bin/mc alias set local http://supabase-minio:9000 $MINIO_ROOT_USER $MINIO_ROOT_PASSWORD
      sleep 5
      /usr/bin/mc mb local/supabase-storage
      /usr/bin/mc mb local/supabase-storage-tmp
      /usr/bin/mc policy set public local/supabase-storage
      /usr/bin/mc policy set public local/supabase-storage-tmp
    environment:
      MINIO_ROOT_USER: "serviceusermin.io"
      MINIO_ROOT_PASSWORD: "servicepasswordminio"

  supabase-storage:
    image: supabase/storage-api:v1.14.6
    environment:
      SERVER_PORT: 5000
      SERVER_REGION: local
      MULTITENANT: "false"
      AUTH_JWT_SECRET: "servicepasswordjwt"
      DB_INSTALL_ROLES: "false"
      DATABASE_URL: "postgresql://supabasestorageadmin:servicepasswordpostgres@supabase-db:5432/postgresdb-postgres"
      STORAGE_BACKEND: "s3"
      STORAGE_S3_BUCKET: "supabase-storage"
      STORAGE_S3_ENDPOINT: "http://supabase-minio:9000"
      STORAGE_S3_FORCE_PATH_STYLE: "true"
      STORAGE_S3_REGION: "us-east-1"
      AWS_ACCESS_KEY_ID: "serviceusermin.io"
      AWS_SECRET_ACCESS_KEY: "servicepasswordminio"
      UPLOAD_FILE_SIZE_LIMIT: 524288000
      UPLOAD_FILE_SIZE_LIMIT_STANDARD: 524288000
      UPLOAD_SIGNED_URL_EXPIRATION_TIME: 120
      TUS_URL_PATH: "upload/resumable"
      TUS_MAX_SIZE: 3600000
      ENABLE_IMAGE_TRANSFORMATION: "true"
      IMGPROXY_URL: "http://imgproxy:8080"
      IMGPROXY_REQUEST_TIMEOUT: 15
      DATABASE_SEARCH_PATH: "storage"
      NODE_ENV: "production"
      REQUEST_ALLOW_X_FORWARDED_PATH: "true"
    depends_on:
      supabase-db:
        condition: service_healthy
      supabase-rest:
        condition: service_started
      imgproxy:
        condition: service_started
    volumes:
      - supabase-storage-data:/var/lib/storage
    ports:
      - "5000:5000"
    healthcheck:
      test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:5000/status"]
      interval: 5s
      timeout: 5s
      retries: 3

  supabase-rest:
    image: postgrest/postgrest:v12.2.12
    command: postgrest
    environment:
      PGRST_DB_URI: "postgresql://authenticator:servicepasswordpostgres@supabase-db:5432/postgresdb-postgres"
      PGRST_DB_SCHEMAS: "public,storage,graphql_public"
      PGRST_DB_ANON_ROLE: "anon"
      PGRST_JWT_SECRET: "servicepasswordjwt"
      PGRST_DB_USE_LEGACY_GUCS: "false"
      PGRST_APP_SETTINGS_JWT_SECRET: "servicepasswordjwt"
      PGRST_APP_SETTINGS_JWT_EXP: 3600
    depends_on:
      supabase-db:
        condition: service_healthy
      supabase-analytics:
        condition: service_healthy
    ports:
      - "3000:3000"
    healthcheck:
      test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:3000"]
      interval: 5s
      timeout: 5s
      retries: 3

  supabase-auth:
    image: supabase/gotrue:v2.174.0
    environment:
      GOTRUE_API_HOST: "0.0.0.0"
      GOTRUE_API_PORT: 9999
      API_EXTERNAL_URL: "http://supabase-kong:8000"
      GOTRUE_DB_DRIVER: "postgres"
      GOTRUE_DB_DATABASE_URL: "postgresql://supabaseauthadmin:servicepasswordpostgres@supabase-db:5432/postgresdb-postgres"
      GOTRUE_SITE_URL: "http://supabase-kong:8000"
      GOTRUE_DISABLE_SIGNUP: "false"
      GOTRUE_JWT_ADMIN_ROLES: "service_role"
      GOTRUE_JWT_AUD: "authenticated"
      GOTRUE_JWT_DEFAULT_GROUP_NAME: "authenticated"
      GOTRUE_JWT_EXP: 3600
      GOTRUE_JWT_SECRET: "servicepasswordjwt"
      GOTRUE_EXTERNAL_EMAIL_ENABLED: "true"
      GOTRUE_EXTERNAL_ANONYMOUS_USERS: "false"
      GOTRUE_EMAILER_AUTOCONFIRM: "false"
      GOTRUE_SMTP_ADMIN_EMAIL: "[email protected]"
      GOTRUE_SMTP_HOST: "smtp.example.com"
      GOTRUE_SMTP_PORT: 587
      GOTRUE_SMTP_USER: "smtpuser"
      GOTRUE_SMTP_PASS: "smtppassword"
      GOTRUE_SMTP_SENDER_NAME: "supabase"
    depends_on:
      supabase-db:
        condition: service_healthy
      supabase-analytics:
        condition: service_healthy
    ports:
      - "9999:9999"
    healthcheck:
      test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:9999/health"]
      interval: 5s
      timeout: 5s
      retries: 3

  realtime-dev:
    image: supabase/realtime:v2.34.47
    container_name: realtime-dev.supabase-realtime
    environment:
      PORT: 4000
      DB_HOST: "supabase-db"
      DB_PORT: 5432
      DB_USER: "supabaseadmin"
      DB_PASSWORD: "servicepasswordpostgres"
      DB_NAME: "postgresdb-postgres"
      DB_AFTER_CONNECT_QUERY: "SET search_path TO realtime"
      DB_ENC_KEY: "supabaserealtime"
      API_JWT_SECRET: "servicepasswordjwt"
      LOG_LEVEL: "error"
    depends_on:
      supabase-db:
        condition: service_healthy
      supabase-analytics:
        condition: service_healthy
    ports:
      - "4000:4000"
    healthcheck:
      test: ["CMD", "curl", "-sSfL", "-I", "-o", "/dev/null", "-H", "Authorization: Bearer SERVICE_SUPABASE_ANON_KEY", "http://127.0.0.1:4000/api/tenants/realtime-dev/health"]
      interval: 5s
      timeout: 5s
      retries: 3

  imgproxy:
    image: darthsim/imgproxy:v3.8.0
    volumes:
      - ./volumes/storage:/var/lib/storage
    environment:
      IMGPROXY_LOCAL_FILESYSTEM_ROOT: ""
      IMGPROXY_USE_ETAG: "true"
      IMGPROXY_ENABLE_WEBP_DETECTION: "true"
    ports:
      - "8080:8080"
    healthcheck:
      test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:8080/health"]
      interval: 5s
      timeout: 5s
      retries: 3

  supabase-meta:
    image: supabase/postgres-meta:v0.89.3
    environment:
      PGMETA_PORT: 8080
      PGMETA_DB_HOST: "supabase-db"
      PGMETA_DB_PORT: 5432
      PGMETA_DB_NAME: "postgresdb-postgres"
      PGMETA_DB_USER: "supabaseadmin"
      PGMETA_DB_PASSWORD: "servicepasswordpostgres"
    depends_on:
      supabase-db:
        condition: service_healthy
      supabase-analytics:
        condition: service_healthy
    ports:
      - "8080:8080"

  supabase-edge-functions:
    image: supabase/edge-runtime:v1.67.4
    depends_on:
      supabase-analytics:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "echo", "Edge Functions is healthy"]
      interval: 5s
      timeout: 5s
      retries: 3
    environment:
      JWT_SECRET: "servicepasswordjwt"
      SUPABASE_URL: "http://supabase-kong:8000"
      SUPABASE_ANON_KEY: "supabaseanonkey"
      SUPABASE_SERVICE_ROLE_KEY: "supabaseservicerolekey"
      SUPABASE_DB_URL: "postgresql://postgres:servicepasswordpostgres@supabase-db:5432/postgresdb-postgres"
      VERIFY_JWT: "false"
    volumes:
      - ./volumes/functions:/home/deno/functions
      - ./volumes/functions/mainindex.ts:/home/deno/functions/mainindex.ts:ro
    ports:
      - "9000:9000"

  supabase-supavisor:
    image: supabase/supavisor:v2.5.1
    environment:
      POOLER_TENANT_ID: "dev-tenant"
      POOLER_POOL_MODE: "transaction"
      POOLER_DEFAULT_POOL_SIZE: 20
      POOLER_MAX_CLIENT_CONN: 100
      PORT: 4000
      POSTGRES_PORT: 5432
      POSTGRES_HOSTNAME: "supabase-db"
      POSTGRES_DB: "postgresdb-postgres"
      POSTGRES_PASSWORD: "servicepasswordpostgres"
      DATABASE_URL: "postgresql://supabaseadmin:servicepasswordpostgres@supabase-db:5432/postgresdb-postgres"
      CLUSTER_POSTGRES: "true"
      SECRET_KEY_BASE: "servicepasswordsupavisorsecret"
      VAULT_ENC_KEY: "servicepasswordvault"
      API_JWT_SECRET: "servicepasswordjwt"
      METRICS_JWT_SECRET: "servicepasswordjwt"
      REGION: "local"
      ERL_FLAGS: "-proto_dist inet_tcp"
    depends_on:
      supabase-db:
        condition: service_healthy
      supabase-analytics:
        condition: service_healthy
    command: ["/bin/sh", "-c", "app/bin/migrate && app/bin/supavisor eval 'cat etc/pooler/pooler.exs' && app/bin/server"]
    ports:
      - "4001:4001"

  vector:
    image: timberio/vector:0.28.1-alpine
    command: --config /etc/vector/vector.yml
    volumes:
      - ./volumes/logs/vector.yml:/etc/vector/vector.yml:ro
      - /var/run/docker.sock:/var/run/docker.sock
      - supabase-logs:/var/log/supabase
    environment:
      VECTOR_LOG: "info"
    ports:
      - "8686:8686"
    depends_on:
      supabase-db:
        condition: service_healthy
      supabase-analytics:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:8686/health"]
      interval: 5s
      timeout: 5s
      retries: 3

volumes:
  supabase-db-data:
  supabase-minio-data:
  supabase-storage-data:
  supabase-imgproxy-data:
  supabase-logs:

This won't work with the nature of how Caprover is set up. If you want to fix it and make a guide, be my guest, but I've spent 3 hrs on this and I'm just going to go back to frustrating ass Coolify as it's simply better right now with the allowance of complex docker-compose/nixpacks. I was really impressed with how easy it was to spin up Caprover and start services that the terrible coolify proxy system would usually spazz on me for or break.

I've also noticed that the only one click email solutions are solutions I hadn't heard of -- because they charge $599 a year to allow you to configure SMTP and DMARC, making them all useless.

It seems a ton of companies that are shilling shit get included in the Caprover repositories, or do the work to make their costly stuff work and suggest their own service.

One click email is amazingly easy on Caprover (HELL ON COOLIFY... F-ING HORRID) but I'm not paying Poste.io or iRedMail $700 a year for bundling open source software with a management portal.

I suggest someone figure out a Stalwart + Roundcube package for Caprover, but I'm done with the platform for the time being.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions