version: '3.8' services: studio: image: supabase/studio:2025.06.30-sha-6f5982d healthcheck: test: - CMD - node - -e - fetch('http://studio:3000/api/platform/profile').then((r) => {if (r.status !== 200) throw new Error(r.status)}) timeout: 10s interval: 5s retries: 3 depends_on: - analytics environment: - STUDIO_PG_META_URL=http://meta:8080 - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-squirtle123456} - DEFAULT_ORGANIZATION_NAME=${STUDIO_DEFAULT_ORGANIZATION:-Default Organization} - DEFAULT_PROJECT_NAME=${STUDIO_DEFAULT_PROJECT:-Default Project} - OPENAI_API_KEY=${OPENAI_API_KEY:-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} - SUPABASE_URL=http://kong:8000 - SUPABASE_PUBLIC_URL=${SERVICE_URL_KONG} - SUPABASE_ANON_KEY=${ANON_KEY:-eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwiaWF0IjoxNjQxNzY5MjAwLCJleHAiOjE3OTk1MzU2MDAsInJvbGUiOiJhbm9uIn0.eO2Vi38564_lLqhEXR3s7nLbHL34014jYe05y9lpr1U} - SUPABASE_SERVICE_KEY=${SERVICE_ROLE_KEY:-eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwiaWF0IjoxNjQxNzY5MjAwLCJleHAiOjE3OTk1MzU2MDAsInJvbGUiOiJzZXJ2aWNlX3JvbGUifQ.l11N14S64uypRkNCbbWm4kV_DuqEIrsEySeBB4YNH1k} - AUTH_JWT_SECRET=${JWT_SECRET:-UhauiNFrEjOL4j0QfFyfSI3NrRyvvl24} - LOGFLARE_PRIVATE_ACCESS_TOKEN=${LOGFLARE_PRIVATE_ACCESS_TOKEN:-UhauiNFrEjOL4j0QfFyfSI3NrRyvvl24} - LOGFLARE_URL=http://analytics:4000 - NEXT_PUBLIC_ENABLE_LOGS=true - NEXT_ANALYTICS_BACKEND_PROVIDER=postgres networks: - supabase deploy: replicas: 1 placement: constraints: - node.hostname == little restart_policy: condition: any delay: 5s max_attempts: 3 kong: image: kong:2.8.1 expose: - ${KONG_HTTP_PORT:-8000} - ${KONG_HTTPS_PORT:-8443} volumes: - /home/trav/supabase/docker/volumes/api/kong.yml:/home/kong/temp.yml:ro,z depends_on: - analytics environment: - 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 - KONG_NGINX_PROXY_PROXY_BUFFER_SIZE=160k - KONG_NGINX_PROXY_PROXY_BUFFERS=64 160k - SUPABASE_ANON_KEY=${ANON_KEY:-eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwiaWF0IjoxNjQxNzY5MjAwLCJleHAiOjE3OTk1MzU2MDAsInJvbGUiOiJhbm9uIn0.eO2Vi38564_lLqhEXR3s7nLbHL34014jYe05y9lpr1U} - SUPABASE_SERVICE_KEY=${SERVICE_ROLE_KEY:-eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwiaWF0IjoxNjQxNzY5MjAwLCJleHAiOjE3OTk1MzU2MDAsInJvbGUiOiJzZXJ2aWNlX3JvbGUifQ.l11N14S64uypRkNCbbWm4kV_DuqEIrsEySeBB4YNH1k} - DASHBOARD_USERNAME=${SERVICE_USER_KONG} - DASHBOARD_PASSWORD=${SERVICE_PASSWORD_KONG} entrypoint: bash -c 'eval "echo \"$$(cat ~/temp.yml)\"" > ~/kong.yml && /docker-entrypoint.sh kong docker-start' networks: - supabase - public - badge-net deploy: replicas: 1 placement: constraints: - node.hostname == little restart_policy: condition: any delay: 5s max_attempts: 3 labels: - traefik.enable=true - traefik.swarm.network=public - traefik.http.services.supa-kong.loadbalancer.server.port=8000 - traefik.http.routers.supa.entrypoints=web - traefik.http.routers.supa.rule=Host(`supa.toy`) - traefik.http.routers.supa.service=supa-kong - traefik.http.routers.supa.tls=false auth: image: supabase/gotrue:v2.177.0 healthcheck: test: - CMD - wget - --no-verbose - --tries=1 - --spider - http://localhost:9999/health timeout: 5s interval: 5s retries: 3 depends_on: - db - analytics environment: - GOTRUE_API_HOST=0.0.0.0 - GOTRUE_API_PORT=9999 - API_EXTERNAL_URL=http://kong:8000 - GOTRUE_DB_DRIVER=postgres - GOTRUE_DB_DATABASE_URL=postgres://supabase_auth_admin:${POSTGRES_PASSWORD:-squirtle123456}@${POSTGRES_HOST:-db}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-postgres} - GOTRUE_SITE_URL=${SERVICE_URL_KONG} - GOTRUE_URI_ALLOW_LIST=${ADDITIONAL_REDIRECT_URLS:-} - GOTRUE_DISABLE_SIGNUP=${DISABLE_SIGNUP:-false} - GOTRUE_JWT_ADMIN_ROLES=service_role - GOTRUE_JWT_AUD=authenticated - GOTRUE_JWT_DEFAULT_GROUP_NAME=authenticated - GOTRUE_JWT_EXP=${JWT_EXPIRY:-3600} - GOTRUE_JWT_SECRET=${JWT_SECRET:-UhauiNFrEjOL4j0QfFyfSI3NrRyvvl24} - GOTRUE_EXTERNAL_EMAIL_ENABLED=${ENABLE_EMAIL_SIGNUP:-true} - GOTRUE_EXTERNAL_ANONYMOUS_USERS_ENABLED=${ENABLE_ANONYMOUS_USERS:-false} - GOTRUE_MAILER_AUTOCONFIRM=${ENABLE_EMAIL_AUTOCONFIRM:-false} - GOTRUE_SMTP_ADMIN_EMAIL=${SMTP_ADMIN_EMAIL:-admin@example.com} - GOTRUE_SMTP_HOST=${SMTP_HOST:-supabase-mail} - GOTRUE_SMTP_PORT=${SMTP_PORT:-2500} - GOTRUE_SMTP_USER=${SMTP_USER:-fake_mail_user} - GOTRUE_SMTP_PASS=${SMTP_PASS:-fake_mail_password} - GOTRUE_SMTP_SENDER_NAME=${SMTP_SENDER_NAME:-fake_sender} - GOTRUE_MAILER_URLPATHS_INVITE=${MAILER_URLPATHS_INVITE:-"/auth/v1/verify"} - GOTRUE_MAILER_URLPATHS_CONFIRMATION=${MAILER_URLPATHS_CONFIRMATION:-"/auth/v1/verify"} - GOTRUE_MAILER_URLPATHS_RECOVERY=${MAILER_URLPATHS_RECOVERY:-"/auth/v1/verify"} - GOTRUE_MAILER_URLPATHS_EMAIL_CHANGE=${MAILER_URLPATHS_EMAIL_CHANGE:-"/auth/v1/verify"} - GOTRUE_EXTERNAL_PHONE_ENABLED=${ENABLE_PHONE_SIGNUP:-true} - GOTRUE_SMS_AUTOCONFIRM=${ENABLE_PHONE_AUTOCONFIRM:-true} networks: - supabase deploy: replicas: 1 placement: constraints: - node.hostname == little restart_policy: condition: any delay: 5s max_attempts: 3 rest: image: postgrest/postgrest:v12.2.12 depends_on: - db - analytics environment: - PGRST_DB_URI=postgres://authenticator:${POSTGRES_PASSWORD:-squirtle123456}@${POSTGRES_HOST:-db}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-postgres} - PGRST_DB_SCHEMAS=${PGRST_DB_SCHEMAS:-public,storage,graphql_public} - PGRST_DB_ANON_ROLE=anon - PGRST_JWT_SECRET=${JWT_SECRET:-UhauiNFrEjOL4j0QfFyfSI3NrRyvvl24} - PGRST_DB_USE_LEGACY_GUCS=false - PGRST_APP_SETTINGS_JWT_SECRET=${JWT_SECRET:-UhauiNFrEjOL4j0QfFyfSI3NrRyvvl24} - PGRST_APP_SETTINGS_JWT_EXP=${JWT_EXPIRY:-3600} command: - postgrest networks: - supabase deploy: replicas: 1 placement: constraints: - node.hostname == little restart_policy: condition: any delay: 5s max_attempts: 3 realtime: image: supabase/realtime:v2.34.47 depends_on: - db - analytics healthcheck: test: - CMD - curl - -sSfL - --head - -o - /dev/null - -H - 'Authorization: Bearer ${ANON_KEY:-eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwiaWF0IjoxNjQxNzY5MjAwLCJleHAiOjE3OTk1MzU2MDAsInJvbGUiOiJhbm9uIn0.eO2Vi38564_lLqhEXR3s7nLbHL34014jYe05y9lpr1U}' - http://localhost:4000/api/tenants/realtime-dev/health timeout: 5s interval: 5s retries: 3 environment: - PORT=4000 - DB_HOST=${POSTGRES_HOST:-db} - DB_PORT=${POSTGRES_PORT:-5432} - DB_USER=supabase_admin - DB_PASSWORD=${POSTGRES_PASSWORD:-squirtle123456} - DB_NAME=${POSTGRES_DB:-postgres} - DB_AFTER_CONNECT_QUERY=SET search_path TO _realtime - DB_ENC_KEY=supabaserealtime - API_JWT_SECRET=${JWT_SECRET:-UhauiNFrEjOL4j0QfFyfSI3NrRyvvl24} - SECRET_KEY_BASE=${SECRET_KEY_BASE:-UpNVntn3cDxHJpq99YMc1T1AQgQpc8kfYTuRgBiYa15BLrx8etQoXz3gZv1/u2oq} - ERL_AFLAGS=-proto_dist inet_tcp - DNS_NODES= - RLIMIT_NOFILE=10000 - APP_NAME=realtime - SEED_SELF_HOST=true - RUN_JANITOR=true networks: - supabase deploy: replicas: 1 placement: constraints: - node.hostname == little restart_policy: condition: any delay: 5s max_attempts: 3 storage: image: supabase/storage-api:v1.25.7 volumes: - /home/trav/supabase/docker/volumes/storage:/var/lib/storage:z healthcheck: test: - CMD - wget - --no-verbose - --tries=1 - --spider - http://storage:5000/status timeout: 5s interval: 5s retries: 3 depends_on: - db - rest - imgproxy environment: - ANON_KEY=${ANON_KEY:-eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwiaWF0IjoxNjQxNzY5MjAwLCJleHAiOjE3OTk1MzU2MDAsInJvbGUiOiJhbm9uIn0.eO2Vi38564_lLqhEXR3s7nLbHL34014jYe05y9lpr1U} - SERVICE_KEY=${SERVICE_ROLE_KEY:-eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwiaWF0IjoxNjQxNzY5MjAwLCJleHAiOjE3OTk1MzU2MDAsInJvbGUiOiJzZXJ2aWNlX3JvbGUifQ.l11N14S64uypRkNCbbWm4kV_DuqEIrsEySeBB4YNH1k} - POSTGREST_URL=http://rest:3000 - PGRST_JWT_SECRET=${JWT_SECRET:-UhauiNFrEjOL4j0QfFyfSI3NrRyvvl24} - DATABASE_URL=postgres://supabase_storage_admin:${POSTGRES_PASSWORD:-squirtle123456}@${POSTGRES_HOST:-db}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-postgres} - FILE_SIZE_LIMIT=52428800 - STORAGE_BACKEND=file - FILE_STORAGE_BACKEND_PATH=/var/lib/storage - TENANT_ID=stub - REGION=stub - GLOBAL_S3_BUCKET=stub - ENABLE_IMAGE_TRANSFORMATION=true - IMGPROXY_URL=http://imgproxy:5001 networks: - supabase deploy: replicas: 1 placement: constraints: - node.hostname == little restart_policy: condition: any delay: 5s max_attempts: 3 imgproxy: image: darthsim/imgproxy:v3.8.0 volumes: - /home/trav/supabase/docker/volumes/storage:/var/lib/storage:z healthcheck: test: - CMD - imgproxy - health timeout: 5s interval: 5s retries: 3 environment: - IMGPROXY_BIND=:5001 - IMGPROXY_LOCAL_FILESYSTEM_ROOT=/ - IMGPROXY_USE_ETAG=true - IMGPROXY_ENABLE_WEBP_DETECTION=${IMGPROXY_ENABLE_WEBP_DETECTION:-true} networks: - supabase deploy: replicas: 1 placement: constraints: - node.hostname == little restart_policy: condition: any delay: 5s max_attempts: 3 meta: image: supabase/postgres-meta:v0.91.0 depends_on: - db - analytics environment: - PG_META_PORT=8080 - PG_META_DB_HOST=${POSTGRES_HOST:-db} - PG_META_DB_PORT=${POSTGRES_PORT:-5432} - PG_META_DB_NAME=${POSTGRES_DB:-postgres} - PG_META_DB_USER=supabase_admin - PG_META_DB_PASSWORD=${POSTGRES_PASSWORD:-squirtle123456} networks: - supabase deploy: replicas: 1 placement: constraints: - node.hostname == little restart_policy: condition: any delay: 5s max_attempts: 3 functions: image: supabase/edge-runtime:v1.69.6 volumes: - /home/trav/supabase/docker/volumes/functions:/home/deno/functions:Z depends_on: - analytics environment: - JWT_SECRET=${JWT_SECRET:-UhauiNFrEjOL4j0QfFyfSI3NrRyvvl24} - SUPABASE_URL=http://kong:8000 - SUPABASE_ANON_KEY=${ANON_KEY:-eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwiaWF0IjoxNjQxNzY5MjAwLCJleHAiOjE3OTk1MzU2MDAsInJvbGUiOiJhbm9uIn0.eO2Vi38564_lLqhEXR3s7nLbHL34014jYe05y9lpr1U} - SUPABASE_SERVICE_ROLE_KEY=${SERVICE_ROLE_KEY:-eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwiaWF0IjoxNjQxNzY5MjAwLCJleHAiOjE3OTk1MzU2MDAsInJvbGUiOiJzZXJ2aWNlX3JvbGUifQ.l11N14S64uypRkNCbbWm4kV_DuqEIrsEySeBB4YNH1k} - SUPABASE_DB_URL=postgresql://postgres:${POSTGRES_PASSWORD:-squirtle123456}@${POSTGRES_HOST:-db}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-postgres} - VERIFY_JWT=${FUNCTIONS_VERIFY_JWT:-false} command: - start - --main-service - /home/deno/functions/main networks: - supabase deploy: replicas: 1 placement: constraints: - node.hostname == little restart_policy: condition: any delay: 5s max_attempts: 3 analytics: image: supabase/logflare:1.14.2 expose: - 4000 healthcheck: test: - CMD - curl - http://localhost:4000/health timeout: 5s interval: 5s retries: 10 depends_on: - db environment: - LOGFLARE_NODE_HOST=127.0.0.1 - DB_USERNAME=supabase_admin - DB_DATABASE=_supabase - DB_HOSTNAME=db - DB_PORT=${POSTGRES_PORT:-5432} - DB_PASSWORD=${POSTGRES_PASSWORD:-squirtle123456} - DB_SCHEMA=_analytics - LOGFLARE_PUBLIC_ACCESS_TOKEN=${LOGFLARE_PUBLIC_ACCESS_TOKEN:-8NfbHaslrNnz9cLFa9ItO03y9Q0btpB1} - LOGFLARE_PRIVATE_ACCESS_TOKEN=${LOGFLARE_PRIVATE_ACCESS_TOKEN:-UhauiNFrEjOL4j0QfFyfSI3NrRyvvl24} - LOGFLARE_SINGLE_TENANT=true - LOGFLARE_SUPABASE_MODE=true - LOGFLARE_MIN_CLUSTER_SIZE=1 - POSTGRES_BACKEND_URL=postgresql://supabase_admin:${POSTGRES_PASSWORD:-squirtle123456}@db:5432/_supabase - POSTGRES_BACKEND_SCHEMA=_analytics - LOGFLARE_FEATURE_FLAG_OVERRIDE=multibackend=true networks: - supabase deploy: replicas: 1 placement: constraints: - node.hostname == little restart_policy: condition: any delay: 5s max_attempts: 3 db: image: supabase/postgres:15.8.1.060 ports: - 54323:5432 volumes: - /home/trav/supabase/docker/volumes/db/realtime.sql:/docker-entrypoint-initdb.d/migrations/99-realtime.sql:Z - /home/trav/supabase/docker/volumes/db/webhooks.sql:/docker-entrypoint-initdb.d/init-scripts/98-webhooks.sql:Z - /home/trav/supabase/docker/volumes/db/roles.sql:/docker-entrypoint-initdb.d/init-scripts/99-roles.sql:Z - /home/trav/supabase/docker/volumes/db/jwt.sql:/docker-entrypoint-initdb.d/init-scripts/99-jwt.sql:Z - /home/trav/supabase/docker/volumes/db/data:/var/lib/postgresql/data:Z - /home/trav/supabase/docker/volumes/db/_supabase.sql:/docker-entrypoint-initdb.d/migrations/97-_supabase.sql:Z - /home/trav/supabase/docker/volumes/db/logs.sql:/docker-entrypoint-initdb.d/migrations/99-logs.sql:Z - /home/trav/supabase/docker/volumes/db/pooler.sql:/docker-entrypoint-initdb.d/migrations/99-pooler.sql:Z - db-config:/etc/postgresql-custom healthcheck: test: - CMD - pg_isready - -U - postgres - -h - localhost interval: 5s timeout: 5s retries: 10 depends_on: - vector environment: - POSTGRES_HOST=/var/run/postgresql - PGPORT=${POSTGRES_PORT:-5432} - POSTGRES_PORT=${POSTGRES_PORT:-5432} - PGPASSWORD=${POSTGRES_PASSWORD:-squirtle123456} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-squirtle123456} - PGDATABASE=${POSTGRES_DB:-postgres} - POSTGRES_DB=${POSTGRES_DB:-postgres} - JWT_SECRET=${JWT_SECRET:-UhauiNFrEjOL4j0QfFyfSI3NrRyvvl24} - JWT_EXP=${JWT_EXPIRY:-3600} command: - postgres - -c - config_file=/etc/postgresql/postgresql.conf - -c - log_min_messages=fatal networks: - supabase deploy: replicas: 1 placement: constraints: - node.hostname == little restart_policy: condition: any delay: 5s max_attempts: 3 vector: image: timberio/vector:0.28.1-alpine volumes: - /home/trav/supabase/docker/volumes/logs/vector.yml:/etc/vector/vector.yml:ro,z - ${DOCKER_SOCKET_LOCATION:-/var/run/docker.sock}:/var/run/docker.sock:ro,z healthcheck: test: - CMD - wget - --no-verbose - --tries=1 - --spider - http://vector:9001/health timeout: 5s interval: 5s retries: 3 environment: - LOGFLARE_PUBLIC_ACCESS_TOKEN=${LOGFLARE_PUBLIC_ACCESS_TOKEN:-8NfbHaslrNnz9cLFa9ItO03y9Q0btpB1} command: - --config - /etc/vector/vector.yml security_opt: - label=disable networks: - supabase deploy: replicas: 1 placement: constraints: - node.hostname == little restart_policy: condition: any delay: 5s max_attempts: 3 supavisor: image: supabase/supavisor:2.5.7 expose: - ${POSTGRES_PORT:-5432} - ${POOLER_PROXY_PORT_TRANSACTION:-6543} volumes: - /home/trav/supabase/docker/volumes/pooler/pooler.exs:/etc/pooler/pooler.exs:ro,z healthcheck: test: - CMD - curl - -sSfL - --head - -o - /dev/null - http://127.0.0.1:4000/api/health interval: 10s timeout: 5s retries: 5 depends_on: - db - analytics environment: - PORT=4000 - POSTGRES_PORT=${POSTGRES_PORT:-5432} - POSTGRES_DB=${POSTGRES_DB:-postgres} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-squirtle123456} - DATABASE_URL=ecto://supabase_admin:${POSTGRES_PASSWORD:-squirtle123456}@db:5432/_supabase - CLUSTER_POSTGRES=true - SECRET_KEY_BASE=${SECRET_KEY_BASE:-UpNVntn3cDxHJpq99YMc1T1AQgQpc8kfYTuRgBiYa15BLrx8etQoXz3gZv1/u2oq} - VAULT_ENC_KEY=${VAULT_ENC_KEY:-1duecZi6cWfjxore5jbwee8kF1At8p4G} - API_JWT_SECRET=${JWT_SECRET:-UhauiNFrEjOL4j0QfFyfSI3NrRyvvl24} - METRICS_JWT_SECRET=${JWT_SECRET:-UhauiNFrEjOL4j0QfFyfSI3NrRyvvl24} - REGION=local - ERL_AFLAGS=-proto_dist inet_tcp - POOLER_TENANT_ID=${POOLER_TENANT_ID:-your-tenant-id} - POOLER_DEFAULT_POOL_SIZE=${POOLER_DEFAULT_POOL_SIZE:-20} - POOLER_MAX_CLIENT_CONN=${POOLER_MAX_CLIENT_CONN:-100} - POOLER_POOL_MODE=transaction - DB_POOL_SIZE=${POOLER_DB_POOL_SIZE:-5} command: - /bin/sh - -c - /app/bin/migrate && /app/bin/supavisor eval "$$(cat /etc/pooler/pooler.exs)" && /app/bin/server networks: - supabase deploy: replicas: 1 placement: constraints: - node.hostname == little restart_policy: condition: any delay: 5s max_attempts: 3 volumes: db-config: null networks: supabase: driver: overlay attachable: true public: external: true badge-net: external: true