Docker Compose stack and admin-managed model endpoints land together

manueljpconde shipped a self-contained local deployment stack alongside a new `managedModels` subsystem that lets admins configure OpenAI-compatible model endpoints stored in the database with AES-256-GCM-encrypted API keys. These two changes arrived in the same PR and a three-day hardening follow-up.

infrastructuresecurity

The compose stack brings up frontend, backend, a Supabase-compatible auth/PostgREST/Postgres cluster, MinIO with bucket init, and a schema bootstrap container. A .env.docker.example file drives the whole thing. cp .env.docker.example .env.docker && docker compose --env-file .env.docker up --build is the complete install path.

The managedModels.ts module (289 lines) stores model endpoints in a new user_managed_models table. Encryption uses AES-256-GCM with a key derived from USER_API_KEYS_ENCRYPTION_SECRET, falling back to API_KEYS_ENCRYPTION_SECRET, then SUPABASE_SECRET_KEY. That last fallback couples key rotation to Supabase credentials, which is worth knowing before you rely on it. Two provider tags are defined: foundry and local_openai_compatible. A new openaiCompatible.ts adapter (231 lines) handles streaming and tool-call shapes for both. The routes/user.ts rewrite is 633 lines changed and touches non-model endpoints as well - splitting it for a cherry-pick will need care.

The hardening follow-up (PR #13) fixed a meaningful security issue: SUPABASE_SECRET_KEY was being passed as a frontend Dockerfile ARG and baked into the Next.js build context. That's a server-only credential that should never reach a client-side bundle. Removed from both the Dockerfile and compose runtime env. The same PR pinned minio/minio and minio/mc to specific dated releases instead of :latest (RELEASE.2025-09-07T16-13-09Z and RELEASE.2025-08-13T08-35-41Z respectively) and added extra_hosts: host.docker.internal:host-gateway so the backend can reach host-running model runtimes on Linux Docker (previously only Docker Desktop worked). Development JWTs in .env.docker.example were also regenerated to expire in 2040 rather than 2027.

632 lines of new tests cover the OpenAI adapter, config parsing, provider settings, and storage.

So what The `openaiCompatible` adapter and the `managedModels` encryption helpers are reusable independently of the Docker setup. Worth importing if you want per-admin Azure Foundry or local model configuration with encrypted keys stored in the DB. The compose stack is worth pulling only if you want the full self-host story - it bundles a local Supabase cluster rather than pointing at hosted. The `SUPABASE_SECRET_KEY` frontend leak in PR #13 should be cherry-picked regardless.

View this fork on GitHub →

Spotted something wrong? Or know the PR text has fresher detail than the writeup above?

Commits in this thread

6 commits from manueljpconde/mikeEU, oldest first. Source extracted verbatim from the harvested git log.

SHA Subject Author Date
d39706fc Add Docker stack and managed model support Manuel Conde 2026-05-10 ↗ GitHub
e9d96136 Merge pull request #7 from manueljpconde/codex/docker-local-stack Manuel Conde 2026-05-10 ↗ GitHub
[codex] Add Docker stack and managed model support
91ea79c4 Document managed model configuration Manuel Conde 2026-05-10 ↗ GitHub
ec1dc09a Merge pull request #8 from manueljpconde/codex/readme-managed-models Manuel Conde 2026-05-10 ↗ GitHub
[codex] Document managed model configuration
f8873309 Harden Docker quickstart config Manuel Conde 2026-05-10 ↗ GitHub
ec3c8758 Merge pull request #13 from manueljpconde/codex/docker-hardening-fixes Manuel Conde 2026-05-10 ↗ GitHub
[codex] Harden Docker quickstart config

Capture this thread into my fork

Download a single Markdown prompt that tells Claude how to port every commit above into your working tree — adapting paths and structure to match your repo. Run it via claude -p < capture-thread-217.md from inside the repo you want the changes in.

⬇ Download capture-thread-217.md