Add fat Docker image for treq Supabase server stack - #248
Conversation
Single container packs Postgres, GoTrue, PostgREST, Edge Runtime, and nginx with treq migrations and Edge Functions baked in — useful for local/CI self-hosting without nested multi-container supabase start. Co-authored-by: Ziinc <Ziinc@users.noreply.github.com>
Wait for the durable postmaster after init (not the temp server), set role passwords only for roles that exist, vendor supabase-js for Edge Functions, and verify JWTs in the main router without JSR fetches. Co-authored-by: Ziinc <Ziinc@users.noreply.github.com>
There was a problem hiding this comment.
Boot order is the hard part: supabase/postgres init uses a temporary postmaster that also answers pg_isready.
- Wait for 5 consecutive successful admin connections with
migrate.shnot running before applying passwords/migrations — lands on the durable postmaster - Role passwords are set only when the role exists (
supabase_functions_adminis absent in this image)
There was a problem hiding this comment.
Kong-compatible /functions/v1/<name> router, matching local CLI behavior for JWT:
- HS256 verify via Web Crypto — no
jsr:/esm.shfetch at main-worker boot (this environment has no egress to those hosts) github-webhookskips JWT (HMAC inside the function), same asconfig.tomlverify_jwt = false
There was a problem hiding this comment.
Single-process fat image instead of compose: copies GoTrue/PostgREST/Edge Runtime binaries onto supabase/postgres, then supervisord + nginx front them.
- Alpine base needs a small glibc runtime for
edge-runtime deno.jsonremapsesm.sh/@supabase/supabase-js→ vendorednode_modulesso functions boot without registry egress- Build context is
supabase/only (see.dockerignore)
Co-authored-by: Ziinc <Ziinc@users.noreply.github.com>
Base the API image on alpine:3.23 and layer GoTrue, PostgREST, Edge Runtime, and nginx incrementally. supabase/postgres runs as a separate compose service; prepare-network.sh fixes nested-Docker bridge TCP. Co-authored-by: Ziinc <Ziinc@users.noreply.github.com>
Co-authored-by: Ziinc <Ziinc@users.noreply.github.com>
Co-authored-by: Ziinc <Ziinc@users.noreply.github.com>
There was a problem hiding this comment.
Base is now alpine:3.23 — Postgres is not in this image.
- Layers are additive: apk packages → GoTrue → PostgREST → Edge Runtime (+glibc) → treq app → vendored supabase-js
- Compose runs
supabase/postgresasdb; entrypoint waits onPGHOST
Drop GoTrue from the Alpine API image for self-hosted single-tenant mode (VERIFY_JWT=false). Add docker-compose.test.yml, verify-self-hosted.sh covering health, data APIs, and edge functions, plus a GitHub Actions workflow to build and run that suite. Co-authored-by: Ziinc <Ziinc@users.noreply.github.com>
There was a problem hiding this comment.
Single-tenant checks against the test compose stack (service_role for data APIs; no user sessions).
- Asserts
/auth/v1is gone - Data: OpenAPI,
profiles,merge_queue_metrics - Edge: token exchange validation, worker nudge, webhook HMAC accept/reject
There was a problem hiding this comment.
CI path for the fat image: compose up with --wait, then verify-self-hosted.sh.
- Triggers on
supabase/**and this workflow file prepare-network.shkeeps nested-Docker / DinD bridge TCP working when needed- Dumps compose logs on failure; always tears down with
-v
Summary
Single-tenant self-hosted fat API image (no GoTrue) plus CI that builds and verifies it.
Image
alpine:3.23— PostgREST + Edge Runtime + nginx only/auth/v1VERIFY_JWT=falsesupabase/postgrescompose sidecarCI / test
.github/workflows/supabase-docker.ymlbuildsdocker-compose.test.ymland runstest/verify-self-hosted.sh/health,/auth/v1absent, data API (OpenAPI, profiles,merge_queue_metrics), edge (exchange-desktop-token,merge-queue-worker,github-webhookHMAC)make supabase.docker.test # local equivalentTest plan
make supabase.docker.test— 13/13 passed locallySupabase Dockerworkflow green on this PR