fix(docker): make the preview policy fail closed - #1459
Conversation
Coolify materialises a relative bind mount as an empty managed directory, so the mounted sanitize.sql was a directory inside the container. `test -s` passes on a directory and `psql < <directory>` reads nothing and exits 0, so the seeder wrote its success marker having applied nothing: a preview came up on a clone that still had every workspace trigger, the practice review binding, the source instance's OAuth apps and its signing key. The policy moves back inline, which is the form this Coolify version runs, and the marker is now written only against the database's own answer. Any live trigger, binding, job or inherited identity fails the deployment instead of starting an application server on a clone that can act as the instance it was copied from. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EZADQeSx6zQNNqsdu7AAqZ
|
Warning Review limit reached
Next review available in: 2 minutes Limit details: You’ve used the included review currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?Wait for the limit to reset, then comment An organization admin can change what happens after included review limits in Billing. How do review limits work?CodeRabbit enforces per-developer PR review limits within each organization. For paid Pro and Pro+ reviews, CodeRabbit uses a developer's included PR review attempts over the past 7 days to set the current hourly allowance. At typical activity levels, the full plan allowance applies. Higher sustained activity can lower the allowance until earlier attempts leave the 7-day window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (4)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
📚 Documentation Preview
|
Description
#1457 moved the preview policy into a mounted
sanitize.sql. On this Coolify version that mount does not work, and it failed in the worst possible way — silently, with a success marker.Coolify materialises a relative bind mount as an empty managed directory, so
/preview/sanitize.sqlwas a directory inside the container:test -s <directory>passes — a directory reports a non-zero size;psql < <directory>reads nothing and exits 0.So the seeder printed "Applying the preview policy", wrote
.hephaestus-preview-seeded, and started the application server on a clone where nothing had been applied. Observed on the first preview seeded after #1457 merged: three workspaces with practice-review triggers enabled, thePRACTICE_REVIEWbinding enabled, the source instance's OAuth apps, and its JWT signing key — with the agent runtime on and the preview attached to shared NATS. That is precisely the state the policy exists to prevent.What changes
The policy moves back inline, which is the form this Coolify version actually runs. The
.sqlfile was better to read; it does not survive contact with the deployment, and correctness wins.The marker is now written only against the database's own answer. After applying the policy the seeder counts what is still live — enabled triggers, enabled
PRACTICE_REVIEWbindings, enabled sweep schedules, queued or running agent and sync jobs, and any survivinglogin_provider,jwt_signing_keyorissued_jwtrow — and fails the deployment unless that total is zero.That second part is the real fix. The first failure was a mount; the next one will be something else, and a seeder that reports success without checking will hide that one too. Fail-closed now means "the database says so", not "the command exited 0".
How to test
Coolify parses the Compose file from
main, so this is not exercised by its own preview (documented in the README). Verified by hand on the staging host against a real clone:psql -v ON_ERROR_STOP=1 -d hephaestus < <a directory>→ no statements, exit 0;0and seeding proceeds; with any trigger, binding or provider row restored it returns non-zero and the seeder exits 1 before the marker is written.The heredoc indentation is byte-identical to the form that has been running since #1455, and
docker compose -f docker/preview/compose.app.yaml configrenders.After this merges, the next preview created re-seeds through this path; the affected preview has already been re-sanitized by hand and now holds its own login apps and signing key.
Checklist
.changeset/README.md**Operators:** …) andMIGRATION.mdis updatedNo new variable and no operator action.