Lef-F adds full docker-compose self-host stack: Postgres, GoTrue, PostgREST, Garage, Caddy
Lef-F replaced Supabase Cloud and Cloudflare R2 with a single-host docker-compose stack. Run `docker compose up` and you have the full service mesh with no external managed services.
The stack lands via PR #1 (325510e) on a lef/docker-compose branch. Services: Postgres 16 as the database, GoTrue v2.166.0 for auth, PostgREST v12.2.3 for the REST layer, Garage v2 as S3-compatible object storage, dedicated Dockerfiles for backend (Node 22 + LibreOffice) and frontend (Next.js 16 standalone), and Caddy 2 as the single ingress routing everything onto one configurable port. Two one-shot init containers handle first-boot bootstrap idempotently and then exit.
Setup is: cp .env.example .env, run ./scripts/generate-secrets.sh (POSIX shell + openssl, no Node required), set your LLM key, docker compose up -d --build. The secrets script mints JWTs from scratch and writes chmod 600 files; --force regenerates everything.
A few specific issues surfaced during first-boot testing that are worth reading before adopting. The init-garage container was changed from the full Garage image to alpine:3.20 with the /garage binary copied in via a multi-stage Dockerfile - the original image's RPC CLI didn't work cleanly in the bootstrap context, so the script was rewritten to use the v2 HTTP admin API instead. For backend auth, SUPABASE_URL was changed to point at Caddy rather than directly at GoTrue (http://caddy:${MIKE_PORT}), with header_up Host {upstream_hostport} added to each Caddy reverse_proxy block - this is required because supabase-js constructs auth paths relative to the base URL in ways that break if the backend talks directly to GoTrue. For S3, Garage needs a mike.garage Docker network alias and s3_region = "auto" / root_domain = ".garage" in garage.toml to satisfy the AWS SDK's virtual-hosted-style URL construction.
The frontend image size was cut from 1.98 GB to ~465 MB by switching to Next.js standalone output (output: "standalone" in frontend/next.config.ts, runtime stage copies .next/standalone instead of node_modules). That next.config.ts change is the only edit that touches a non-self-host file.
Known constraints: changing MIKE_PORT requires docker compose build mike-frontend because Next.js bakes URLs at build time. The Garage network alias is hardcoded to bucket name mike; renaming R2_BUCKET_NAME requires a compose edit. TLS, real SMTP, multi-node Garage, and backups are all explicitly out of scope.
Spotted something wrong? Or know the PR text has fresher detail than the writeup above?