Repository navigation
fix: preserve ${VAR} interpolation in .env values - #5197
Conversation
Escaping in prepareEnvironmentVariablesForFile escaped every $,
including inside a deliberate ${VAR} reference, breaking Compose's
documented .env variable interpolation. Only escape $ that isn't
part of a ${IDENTIFIER} sequence.
Fixes #5151
| .replace(/\\/g, "\\\\") | ||
| .replace(/"/g, '\\"') | ||
| .replace(/\$/g, "\\$"); | ||
| .replace(/\$(?!\{[A-Za-z_][A-Za-z0-9_]*\})/g, "\\$"); |
There was a problem hiding this comment.
Parameter expansion stays escaped
When a Compose environment value uses parameter expansion such as ${DB_HOST:-localhost}, this regex escapes its dollar sign because the expression is not exactly ${IDENTIFIER}, preventing Compose from applying the fallback and causing the deployed service to receive a literal or otherwise incorrect value.
Knowledge Base Used: Build and Compose workflows
| .replace(/\\/g, "\\\\") | ||
| .replace(/"/g, '\\"') | ||
| .replace(/\$/g, "\\$"); | ||
| .replace(/\$(?!\{[A-Za-z_][A-Za-z0-9_]*\})/g, "\\$"); |
There was a problem hiding this comment.
Literal references become interpolation
When a password, template, command, or configuration is intended to contain literal ${VAR} text, this rule leaves the dollar sign unescaped with no way to distinguish that intent, causing Compose to substitute or remove the reference and deliver a changed value to the container.
Knowledge Base Used: Build and Compose workflows
|
Good catch @greptile-apps — fixed in b67519e. Broadened the negative lookahead to cover bash-style parameter expansion ( |
|
Thanks — this closes the original gap for the four parameter-expansion operators, and the Docker-backed One issue remains before the serializer is fully correct: the lookahead uses Tip: You can customize Greptile's behavior for this repo with |
|
Hey @Siumauricio, just letting you know that the The test spawns a real Maybe we should skip this test on CI or adjust the workflow runner? |
Fixes #5151
prepareEnvironmentVariablesForFileunconditionally escaped every$before writing.env, which broke Docker Compose's documented.envvariable interpolation (ASSET_URL="${APP_URL}"never resolved). Now only escapes a$that isn't part of a${IDENTIFIER}reference, so braced variable references still interpolate while literal$(e.g. in passwords) stays escaped as before.Before
written to
.envasASSET_URL="\${APP_URL}"→ app receives literal${APP_URL}.After
ASSET_URL="${APP_URL}"is written unescaped → Compose interpolates it tohttps://example.com, matching plaindocker composebehavior.Added a regression case to
env-file-literals.test.tscovering the${VAR}reference alongside the existing literal-$cases (e.g.pa$$word), confirming both keep working.Greptile Summary
This PR changes Compose
.envserialization so simple${VAR}references remain available for Docker Compose interpolation while other dollar signs remain escaped.${APP_URL}.${VAR}text.Confidence Score: 3/5
The PR should not merge until Compose parameter-expansion syntax and an explicit way to preserve literal
${VAR}values are handled.The new regex silently changes valid environment values in two reachable cases: supported Compose expressions containing operators remain escaped, while literal simple references become active interpolation.
Files Needing Attention: packages/server/src/utils/docker/utils.ts and apps/dokploy/test/compose/env-file-literals.test.ts
Reviews (1): Last reviewed commit: "fix: preserve ${VAR} interpolation in .e..." | Re-trigger Greptile
Context used: