fix(self-hosting): stop publishing Postgres and require POSTGRES_PASSWORD - #8035
Conversation
…WORD The Compose files published the db service on every host interface, and the production file fell back to the password postgres when POSTGRES_PASSWORD was unset. The db is now reachable only over the Compose network, and the production file refuses to start without POSTGRES_PASSWORD. sim-setup writes the value an install needs before bringing it up: a generated password for a new database, and the legacy one for a volume created before it was required, since Postgres ignores POSTGRES_PASSWORD on an existing data directory.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
…ctive role A password exported only in the shell is now written to .env, so a later run without the export does not fall back to the legacy value. Rotation steps use the install's POSTGRES_USER and ALTER ROLE CURRENT_USER.
|
@cubic-dev-ai review this PR |
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
All reported issues were addressed across 12 files
Reply with feedback, questions, or to request a fix.
Fix all with cubic | Re-trigger cubic
…WORD An empty export, one that differs from .env, or one .env cannot hold verbatim now stops setup with instructions instead of silently picking a value the database may not have been created with.
|
@cubic-dev-ai review this PR |
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
All reported issues were addressed across 12 files
Reply with feedback, questions, or to request a fix.
Fix all with cubic | Re-trigger cubic
… POSTGRES_USER export
DATABASE_URL embeds the password unescaped, so a shell-only password is persisted only when it is made of URL-unreserved characters. An empty POSTGRES_USER export resolves to the Compose default, matching ${POSTGRES_USER:-postgres}.
|
@cubic-dev-ai review this PR |
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
All reported issues were addressed across 12 files
Reply with feedback, questions, or to request a fix.
Fix all with cubic | Re-trigger cubic
Compose interpolates a shell value over .env, so the wizard no longer copies it into .env and no longer needs rules for values .env or DATABASE_URL would change. An empty export is still refused, since Compose would use it and refuse to start.
|
@cubic-dev-ai review this PR |
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
docker-compose.prod.yml composes DATABASE_URL from them as written, so a value containing a URL delimiter initializes the database but breaks the connection string.
|
@cubic-dev-ai review this PR |
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
Summary
docker-compose.prod.yml,docker-compose.local.ymlanddocker-compose.ollama.ymlno longer publish thedbservice to the host. Every service already reaches it asdb:5432over the Compose network. Aports:mapping bound every interface, and Docker's iptables rules bypass host firewallsdocker-compose.prod.ymlnow requiresPOSTGRES_PASSWORD(${VAR:?}) in thedbservice and all threeDATABASE_URLs instead of falling back topostgres, matching the auth secrets next to it. The local and Ollama dev stacks keep their defaults, since every secret there is a dev default and the port is what made it reachablePOSTGRES_PASSWORDwhen it creates the volume, so an install that never set it must usepostgres; a freshly generated value would lock the app out of its own databasesim-setupwrites the value before bringing the stack up (setup,start,restart,update), but only when the compose file on disk requires it. It generates a password for a new install; for an existingpostgres_datavolume (found by Compose labels, project name read fromdocker compose config --no-interpolate) it keepspostgresand prints how to rotate it. A value set in the shell environment wins, matching ComposesimstudioCLI stops publishing 5432. Its containers already use their own Docker network, and it recreates them on every runPOSTGRES_PASSWORDType of Change
Testing
compose-database.test.ts: password choice (new vs. existing volume vs. already set), shell-env precedence, and checks on the real compose files: nodbport in any of them, and every prodPOSTGRES_PASSWORDreference required. All five compose-file checks fail against the previous filesdocker composeandpgvector/pgvector:pg17, three scenarios, all passing:sim-setupwritespostgres, and the app'sDATABASE_URLauthenticatessim-setupgenerates a 64-hex password and the app'sDATABASE_URLauthenticatesCOMPOSE_PROJECT_NAME:sim-setupfinds the existing volume, keepspostgres, and the app'sDATABASE_URLauthenticatesdocker portshows no host bindings, and a second run changes nothingsim-setup168/168,type-check(sim-setup, cli),lint,check:audits(47),docs-manifest:checkChecklist
🤖 Generated with Claude Code