feat(resolve): derive DATABASE_URL/REDIS_URL from the database cast created (#60) #65
No reviewers
Labels
No labels
blocked
blocker:ci-red
blocker:conflict
blocker:drill-pending
blocker:unrequested
bug
claimed
documentation
enhancement
epic
merge-next
needs-triage
ready
release
scope:apply
scope:capture
scope:coolify-api
scope:fleet
scope:manifest
scope:secrets
stale
state:addressing
state:bots-reviewing
state:building
state:needs-human
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: heavy-duty/cast#65
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/derive-resource-url"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #60.
What
A new env-template ref,
${resource:<name>.url}, resolves to the internal URL of a database the same manifest declares — read back from the live resource'sinternal_db_url, never stored in the age store, never decrypted, never printed:This deletes the two-pass generated-secret bootstrap for a database's own URL rather than automating it (cf. #48): no placeholder, no stored copy to drift or overwrite (#47), and a rotated password is simply followed on the next apply.
How
envtemplate.ts):${resource:…}parses as a distinct derived ref —capturenever treats it as a store secret,templateRefsnever lists it.fillDerivedEnv): at diff time against databases already on the box (so a matching app shows no drift — killing thesecret DATABASE_URL differsline that ran on every plan), and in the executor at apply time against a database created earlier in the same run (from-nothing; apply acts databases-before-applications, #45).assertResourceRefs): a${resource:X.url}naming an undeclared database, or an attr other than.url, is a hard error in every verb that opens a template (apply, diff, capture) — mirroring the dead-generated_secretscheck.DATABASE_URL: derived from database postgres …, never the value.generated_secretsand the two-pass bootstrap remain for the residual non-derivable class.The one unverified assumption
internal_db_urlis a Coolify model accessor built from credentials minted at create time (not from a running container), so the URL is expected the moment the create returns — making a from-nothing apply single-pass. If a given Coolify only publishes it once the container is up, the executor refuses with a re-run instruction rather than writing a blank, and the second apply resolves it as an update. Graceful either way; single-pass in the expected case. I could not verify against a live instance.Docs
docs/semantics.mdgains a Derived resource URLs section; the README's capture walkthrough gains a pointer.Downstream (separate, in the product repo)
The
heavy-duty/incubatormigration is a manifest edit, not part of this PR: switch the two templates to${resource:…}, dropDATABASE_URL_*/REDIS_URL_*fromgenerated_secrets, and drop the two keys from the store.npm run build/npm test(477 passing) /npm run checkall green.🤖 Generated with Claude Code