Skip to content

Self-hosted Supabase with Docker. API docs page is not available. http://localhost:8000/api/projects/default/api/rest | 500 Internal Server Error  #28459

@rusakovic

Description

@rusakovic

Bug report

  • I confirm this is a bug with Supabase, not with my own application.
  • I confirm I have searched the Docs, GitHub Discussions, and Discord.

Describe the bug

Self hosted supabase on local shows 500 error during accessing http://localhost:8000/project/default/api

To Reproduce

Steps to reproduce the behavior, please provide code snippets or a repository:

  1. Use https://github.com/supabase/supabase/blob/master/docker/docker-compose.yml files
  2. run the docker docker compose up -d
  3. Open http://localhost:8000/project/default/api and get
http://localhost:8000/api/projects/default/api/rest
500 Internal Server Error
Response: {"error":{}}

Expected behavior

API docs page should be opened.
All other pages work!

Screenshots

image

System information

Docker: 4.33.0

docker-compose.yml
# Usage
#   Start:          docker compose up
#   With helpers:   docker compose -f docker-compose.yml -f ./dev/docker-compose.dev.yml up
#   Stop:           docker compose down
#   Destroy:        docker compose -f docker-compose.yml -f ./dev/docker-compose.dev.yml down -v --remove-orphans

name: supabase-doindex
version: "3.8"

services:
studio:
  container_name: supabase-studio
  image: supabase/studio:20240805-476542f
  restart: unless-stopped
  healthcheck:
    test:
      [
        "CMD",
        "node",
        "-e",
        "require('http').get('http://localhost:3000/api/profile', (r) => {if (r.statusCode !== 200) throw new Error(r.statusCode)})",
      ]
    timeout: 5s
    interval: 5s
    retries: 3
  depends_on:
    analytics:
      condition: service_healthy
  environment:
    STUDIO_PG_META_URL: http://meta:8080
    POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}

    DEFAULT_ORGANIZATION_NAME: ${STUDIO_DEFAULT_ORGANIZATION}
    DEFAULT_PROJECT_NAME: ${STUDIO_DEFAULT_PROJECT}

    SUPABASE_URL: http://kong:8001
    SUPABASE_PUBLIC_URL: ${SUPABASE_PUBLIC_URL}
    SUPABASE_ANON_KEY: ${ANON_KEY}
    SUPABASE_SERVICE_KEY: ${SERVICE_ROLE_KEY}
    AUTH_JWT_SECRET: ${JWT_SECRET}

    LOGFLARE_API_KEY: ${LOGFLARE_API_KEY}
    LOGFLARE_URL: http://analytics:4000
    NEXT_PUBLIC_ENABLE_LOGS: true
    # Comment to use Big Query backend for analytics
    NEXT_ANALYTICS_BACKEND_PROVIDER: postgres
    # Uncomment to use Big Query backend for analytics
    # NEXT_ANALYTICS_BACKEND_PROVIDER: bigquery

kong:
  container_name: supabase-kong
  image: kong:2.8.1
  restart: unless-stopped
  # https://unix.stackexchange.com/a/294837
  entrypoint: bash -c 'eval "echo \"$$(cat ~/temp.yml)\"" > ~/kong.yml && /docker-entrypoint.sh kong docker-start'
  ports:
    - "8000:8000/tcp"
    - "8443:8443/tcp"
  depends_on:
    analytics:
      condition: service_healthy
  environment:
    KONG_DATABASE: "off"
    KONG_DECLARATIVE_CONFIG: /home/kong/kong.yml
    # https://github.com/supabase/cli/issues/14
    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}
    SUPABASE_SERVICE_KEY: ${SERVICE_ROLE_KEY}
    DASHBOARD_USERNAME: ${DASHBOARD_USERNAME}
    DASHBOARD_PASSWORD: ${DASHBOARD_PASSWORD}
  volumes:
    # https://github.com/supabase/supabase/issues/12661
    - ./volumes/api/kong.yml:/home/kong/temp.yml:ro

auth:
  container_name: supabase-auth
  image: supabase/gotrue:v2.151.0
  depends_on:
    db:
      # Disable this if you are using an external Postgres database
      condition: service_healthy
    analytics:
      condition: service_healthy
  healthcheck:
    test:
      [
        "CMD",
        "wget",
        "--no-verbose",
        "--tries=1",
        "--spider",
        "http://localhost:9999/health",
      ]
    timeout: 5s
    interval: 5s
    retries: 3
  restart: unless-stopped
  environment:
    GOTRUE_API_HOST: 0.0.0.0
    GOTRUE_API_PORT: 9999
    API_EXTERNAL_URL: ${API_EXTERNAL_URL}

    GOTRUE_DB_DRIVER: postgres
    GOTRUE_DB_DATABASE_URL: postgres://supabase_auth_admin:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}

    GOTRUE_SITE_URL: ${SITE_URL}
    GOTRUE_URI_ALLOW_LIST: ${ADDITIONAL_REDIRECT_URLS}
    GOTRUE_DISABLE_SIGNUP: ${DISABLE_SIGNUP}

    GOTRUE_JWT_ADMIN_ROLES: service_role
    GOTRUE_JWT_AUD: authenticated
    GOTRUE_JWT_DEFAULT_GROUP_NAME: authenticated
    GOTRUE_JWT_EXP: ${JWT_EXPIRY}
    GOTRUE_JWT_SECRET: ${JWT_SECRET}

    GOTRUE_EXTERNAL_EMAIL_ENABLED: ${ENABLE_EMAIL_SIGNUP}
    GOTRUE_EXTERNAL_ANONYMOUS_USERS_ENABLED: ${ENABLE_ANONYMOUS_USERS}
    GOTRUE_MAILER_AUTOCONFIRM: ${ENABLE_EMAIL_AUTOCONFIRM}
    # GOTRUE_MAILER_SECURE_EMAIL_CHANGE_ENABLED: true
    # GOTRUE_SMTP_MAX_FREQUENCY: 1s
    GOTRUE_SMTP_ADMIN_EMAIL: ${SMTP_ADMIN_EMAIL}
    GOTRUE_SMTP_HOST: ${SMTP_HOST}
    GOTRUE_SMTP_PORT: ${SMTP_PORT}
    GOTRUE_SMTP_USER: ${SMTP_USER}
    GOTRUE_SMTP_PASS: ${SMTP_PASS}
    GOTRUE_SMTP_SENDER_NAME: ${SMTP_SENDER_NAME}
    GOTRUE_MAILER_URLPATHS_INVITE: ${MAILER_URLPATHS_INVITE}
    GOTRUE_MAILER_URLPATHS_CONFIRMATION: ${MAILER_URLPATHS_CONFIRMATION}
    GOTRUE_MAILER_URLPATHS_RECOVERY: ${MAILER_URLPATHS_RECOVERY}
    GOTRUE_MAILER_URLPATHS_EMAIL_CHANGE: ${MAILER_URLPATHS_EMAIL_CHANGE}

    GOTRUE_EXTERNAL_PHONE_ENABLED: ${ENABLE_PHONE_SIGNUP}
    GOTRUE_SMS_AUTOCONFIRM: ${ENABLE_PHONE_AUTOCONFIRM}

    # Email templates
    GOTRUE_MAILER_TEMPLATES_MAGIC_LINK: ${MAILER_TEMPLATES_MAGIC_LINK}

    # Google OAuth
    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: http://localhost:8001/auth/v1/callback

rest:
  container_name: supabase-rest
  image: postgrest/postgrest:v12.2.0
  depends_on:
    db:
      # Disable this if you are using an external Postgres database
      condition: service_healthy
    analytics:
      condition: service_healthy
  restart: unless-stopped
  environment:
    PGRST_DB_URI: postgres://authenticator:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}
    PGRST_DB_SCHEMAS: ${PGRST_DB_SCHEMAS}
    PGRST_DB_ANON_ROLE: anon
    PGRST_JWT_SECRET: ${JWT_SECRET}
    PGRST_DB_USE_LEGACY_GUCS: "false"
    PGRST_APP_SETTINGS_JWT_SECRET: ${JWT_SECRET}
    PGRST_APP_SETTINGS_JWT_EXP: ${JWT_EXPIRY}
  command: "postgrest"

realtime:
  # This container name looks inconsistent but is correct because realtime constructs tenant id by parsing the subdomain
  container_name: realtime-dev.supabase-realtime
  image: supabase/realtime:v2.29.15
  depends_on:
    db:
      # Disable this if you are using an external Postgres database
      condition: service_healthy
    analytics:
      condition: service_healthy
  healthcheck:
    test:
      [
        "CMD",
        "curl",
        "-sSfL",
        "--head",
        "-o",
        "/dev/null",
        "-H",
        "Authorization: Bearer ${ANON_KEY}",
        "http://localhost:4000/api/tenants/realtime-dev/health",
      ]
    timeout: 5s
    interval: 5s
    retries: 3
  restart: unless-stopped
  environment:
    PORT: 4000
    DB_HOST: ${POSTGRES_HOST}
    DB_PORT: ${POSTGRES_PORT}
    DB_USER: supabase_admin
    DB_PASSWORD: ${POSTGRES_PASSWORD}
    DB_NAME: ${POSTGRES_DB}
    DB_AFTER_CONNECT_QUERY: "SET search_path TO _realtime"
    DB_ENC_KEY: supabaserealtime
    API_JWT_SECRET: ${JWT_SECRET}
    FLY_ALLOC_ID: fly123
    FLY_APP_NAME: realtime
    SECRET_KEY_BASE: UpNVntn3cDxHJpq99YMc1T1AQgQpc8kfYTuRgBiYa15BLrx8etQoXz3gZv1/u2oq
    ERL_AFLAGS: -proto_dist inet_tcp
    ENABLE_TAILSCALE: "false"
    DNS_NODES: "''"
    RLIMIT_NOFILE: "10000"
    APP_NAME: realtime
    SEED_SELF_HOST: true
  command: >
    sh -c "/app/bin/migrate && /app/bin/realtime eval 'Realtime.Release.seeds(Realtime.Repo)' && /app/bin/server"

# To use S3 backed storage: docker compose -f docker-compose.yml -f docker-compose.s3.yml up
storage:
  container_name: supabase-storage
  image: supabase/storage-api:v1.8.5
  depends_on:
    db:
      # Disable this if you are using an external Postgres database
      condition: service_healthy
    rest:
      condition: service_started
    imgproxy:
      condition: service_started
  healthcheck:
    test:
      [
        "CMD",
        "wget",
        "--no-verbose",
        "--tries=1",
        "--spider",
        "http://localhost:5000/status",
      ]
    timeout: 5s
    interval: 5s
    retries: 3
  restart: unless-stopped
  environment:
    ANON_KEY: ${ANON_KEY}
    SERVICE_KEY: ${SERVICE_ROLE_KEY}
    POSTGREST_URL: http://rest:3000
    PGRST_JWT_SECRET: ${JWT_SECRET}
    DATABASE_URL: postgres://supabase_storage_admin:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}
    FILE_SIZE_LIMIT: 52428800
    STORAGE_BACKEND: file
    FILE_STORAGE_BACKEND_PATH: /var/lib/storage
    TENANT_ID: stub
    # TODO: https://github.com/supabase/storage-api/issues/55
    REGION: stub
    GLOBAL_S3_BUCKET: stub
    ENABLE_IMAGE_TRANSFORMATION: "true"
    IMGPROXY_URL: http://imgproxy:5001
  volumes:
    - ./volumes/storage:/var/lib/storage:z

imgproxy:
  container_name: supabase-imgproxy
  image: darthsim/imgproxy:v3.8.0
  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}
  volumes:
    - ./volumes/storage:/var/lib/storage:z

meta:
  container_name: supabase-meta
  image: supabase/postgres-meta:v0.83.2
  depends_on:
    db:
      # Disable this if you are using an external Postgres database
      condition: service_healthy
    analytics:
      condition: service_healthy
  restart: unless-stopped
  environment:
    PG_META_PORT: 8080
    PG_META_DB_HOST: ${POSTGRES_HOST}
    PG_META_DB_PORT: ${POSTGRES_PORT}
    PG_META_DB_NAME: ${POSTGRES_DB}
    PG_META_DB_USER: supabase_admin
    PG_META_DB_PASSWORD: ${POSTGRES_PASSWORD}

functions:
  container_name: supabase-edge-functions
  image: supabase/edge-runtime:v1.55.0
  restart: unless-stopped
  depends_on:
    analytics:
      condition: service_healthy
  environment:
    JWT_SECRET: ${JWT_SECRET}
    SUPABASE_URL: http://kong:8000
    SUPABASE_ANON_KEY: ${ANON_KEY}
    SUPABASE_SERVICE_ROLE_KEY: ${SERVICE_ROLE_KEY}
    SUPABASE_DB_URL: postgresql://postgres:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}
    # TODO: Allow configuring VERIFY_JWT per function. This PR might help: https://github.com/supabase/cli/pull/786
    VERIFY_JWT: "${FUNCTIONS_VERIFY_JWT}"
  volumes:
    - ./volumes/functions:/home/deno/functions:Z
  command:
    - start
    - --main-service
    - /home/deno/functions/main

analytics:
  container_name: supabase-analytics
  image: supabase/logflare:1.4.0
  healthcheck:
    test: ["CMD", "curl", "http://localhost:4000/health"]
    timeout: 5s
    interval: 5s
    retries: 10
  restart: unless-stopped
  depends_on:
    db:
      # Disable this if you are using an external Postgres database
      condition: service_healthy
  # Uncomment to use Big Query backend for analytics
  # volumes:
  #   - type: bind
  #     source: ${PWD}/gcloud.json
  #     target: /opt/app/rel/logflare/bin/gcloud.json
  #     read_only: true
  environment:
    LOGFLARE_NODE_HOST: 127.0.0.1
    DB_USERNAME: supabase_admin
    DB_DATABASE: ${POSTGRES_DB}
    DB_HOSTNAME: ${POSTGRES_HOST}
    DB_PORT: ${POSTGRES_PORT}
    DB_PASSWORD: ${POSTGRES_PASSWORD}
    DB_SCHEMA: _analytics
    LOGFLARE_API_KEY: ${LOGFLARE_API_KEY}
    LOGFLARE_SINGLE_TENANT: true
    LOGFLARE_SUPABASE_MODE: true
    LOGFLARE_MIN_CLUSTER_SIZE: 1

    # Comment variables to use Big Query backend for analytics
    POSTGRES_BACKEND_URL: postgresql://supabase_admin:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}
    POSTGRES_BACKEND_SCHEMA: _analytics
    LOGFLARE_FEATURE_FLAG_OVERRIDE: multibackend=true

    # Uncomment to use Big Query backend for analytics
    # GOOGLE_PROJECT_ID: ${GOOGLE_PROJECT_ID}
    # GOOGLE_PROJECT_NUMBER: ${GOOGLE_PROJECT_NUMBER}
  ports:
    - 4000:4000

# Comment out everything below this point if you are using an external Postgres database
db:
  container_name: supabase-db
  image: supabase/postgres:15.1.1.78
  healthcheck:
    test: pg_isready -U postgres -h localhost
    interval: 5s
    timeout: 5s
    retries: 10
  depends_on:
    vector:
      condition: service_healthy
  command:
    - postgres
    - -c
    - config_file=/etc/postgresql/postgresql.conf
    - -c
    - log_min_messages=fatal # prevents Realtime polling queries from appearing in logs
  restart: unless-stopped
  ports:
    # Pass down internal port because it's set dynamically by other services
    - ${POSTGRES_PORT}:${POSTGRES_PORT}
  environment:
    POSTGRES_HOST: /var/run/postgresql
    PGPORT: ${POSTGRES_PORT}
    POSTGRES_PORT: ${POSTGRES_PORT}
    PGPASSWORD: ${POSTGRES_PASSWORD}
    POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    PGDATABASE: ${POSTGRES_DB}
    POSTGRES_DB: ${POSTGRES_DB}
    JWT_SECRET: ${JWT_SECRET}
    JWT_EXP: ${JWT_EXPIRY}
  volumes:
    - ./volumes/db/realtime.sql:/docker-entrypoint-initdb.d/migrations/99-realtime.sql:Z
    # Must be superuser to create event trigger
    - ./volumes/db/webhooks.sql:/docker-entrypoint-initdb.d/init-scripts/98-webhooks.sql:Z
    # Must be superuser to alter reserved role
    - ./volumes/db/roles.sql:/docker-entrypoint-initdb.d/init-scripts/99-roles.sql:Z
    # Initialize the database settings with JWT_SECRET and JWT_EXP
    - ./volumes/db/jwt.sql:/docker-entrypoint-initdb.d/init-scripts/99-jwt.sql:Z
    # PGDATA directory is persisted between restarts
    - ./volumes/db/data:/var/lib/postgresql/data:Z
    # Changes required for Analytics support
    - ./volumes/db/logs.sql:/docker-entrypoint-initdb.d/migrations/99-logs.sql:Z
    # Use named volume to persist pgsodium decryption key between restarts
    - db-config:/etc/postgresql-custom

vector:
  container_name: supabase-vector
  image: timberio/vector:0.28.1-alpine
  healthcheck:
    test:
      [
        "CMD",
        "wget",
        "--no-verbose",
        "--tries=1",
        "--spider",
        "http://vector:9001/health",
      ]
    timeout: 5s
    interval: 5s
    retries: 3
  volumes:
    - ./volumes/logs/vector.yml:/etc/vector/vector.yml:ro
    - ${DOCKER_SOCKET_LOCATION}:/var/run/docker.sock:ro
  environment:
    LOGFLARE_API_KEY: ${LOGFLARE_API_KEY}
  command: ["--config", "etc/vector/vector.yml"]

# Comment this in production. It's only for development purpose!
mail:
  container_name: supabase-mail
  image: inbucket/inbucket:3.0.3
  ports:
    - "2500:2500" # SMTP
    - "9000:9000" # web interface
    - "1100:1100" # POP3

volumes:
db-config:

docker compose ps

docker compose ps
docker compose ps
WARN[0000] The "MAILER_TEMPLATES_MAGIC_LINK" variable is not set. Defaulting to a blank string.
WARN[0000]  /apps/supabase/docker-compose.yml: the attribute `version` is obsolete, it will be ignored, please remove it to avoid potential confusion
NAME                             IMAGE                              COMMAND                   SERVICE     CREATED          STATUS                      PORTS
realtime-dev.supabase-realtime   supabase/realtime:v2.29.15         "/usr/bin/tini -s -g…"    realtime    34 seconds ago   Up 16 seconds (healthy)
supabase-analytics               supabase/logflare:1.4.0            "sh run.sh"               analytics   34 seconds ago   Up 21 seconds (healthy)     0.0.0.0:4000->4000/tcp
supabase-auth                    supabase/gotrue:v2.151.0           "auth"                    auth        34 seconds ago   Up 16 seconds (healthy)
supabase-db                      supabase/postgres:15.1.1.78        "docker-entrypoint.s…"    db          34 seconds ago   Up 27 seconds (healthy)     0.0.0.0:5432->5432/tcp
supabase-edge-functions          supabase/edge-runtime:v1.55.0      "edge-runtime start …"    functions   34 seconds ago   Up 16 seconds
supabase-imgproxy                darthsim/imgproxy:v3.8.0           "imgproxy"                imgproxy    34 seconds ago   Up 33 seconds (healthy)     8080/tcp
supabase-kong                    kong:2.8.1                         "bash -c 'eval \"echo…"   kong        34 seconds ago   Up 16 seconds (healthy)     0.0.0.0:8000->8000/tcp, 8001/tcp, 0.0.0.0:8443->8443/tcp, 8444/tcp
supabase-mail                    inbucket/inbucket:3.0.3            "/start-inbucket.sh …"    mail        34 seconds ago   Up 33 seconds (healthy)     0.0.0.0:1100->1100/tcp, 0.0.0.0:2500->2500/tcp, 0.0.0.0:9000->9000/tcp
supabase-meta                    supabase/postgres-meta:v0.83.2     "docker-entrypoint.s…"    meta        34 seconds ago   Up 16 seconds (healthy)     8080/tcp
supabase-rest                    postgrest/postgrest:v12.2.0        "postgrest"               rest        34 seconds ago   Up 16 seconds               3000/tcp
supabase-storage                 supabase/storage-api:v1.8.5        "docker-entrypoint.s…"    storage     33 seconds ago   Up 15 seconds (unhealthy)   5000/tcp
supabase-studio                  supabase/studio:20240805-476542f   "docker-entrypoint.s…"    studio      34 seconds ago   Up 16 seconds (unhealthy)   3000/tcp
supabase-vector                  timberio/vector:0.28.1-alpine      "/usr/local/bin/vect…"    vector      34 seconds ago   Up 33 seconds (healthy)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions