Skip to content

fix: preserve # in unquoted environment variable values - #5107

Open
AbiRaditya wants to merge 1 commit into
Dokploy:canaryfrom
AbiRaditya:fix/env-comment-truncation
Open

fix: preserve # in unquoted environment variable values#5107
AbiRaditya wants to merge 1 commit into
Dokploy:canaryfrom
AbiRaditya:fix/env-comment-truncation

Conversation

@AbiRaditya

@AbiRaditya AbiRaditya commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #5095 (related: #4694)

User environment variables containing # were silently truncated. prepareEnvironmentVariables parsed all user env text (service, project, and environment level) with dotenv.parse, whose unquoted-value regex [^#\r\n]+ treats any # as the start of an inline comment:

  • PASSWORD=secret#secret
  • MID=sec#retsec

The truncated values propagated to Docker service Env arrays (applications and databases), the generated .env for Compose deployments, and shell env preparation. In #5095, the reporter's Postgres password ended with #: the database container received the full password (Dokploy's internal template quotes it), but their app's env var was truncated — so the app authenticated with the wrong password and crashed.

Fix

Replace dotenv.parse on user env text with a parser (packages/server/src/utils/docker/env-parser.ts, a modified copy of dotenv v16.4.5's parse, BSD-2-Clause) that follows Docker Compose comment semantics: a # starts an inline comment only at line start or when preceded by whitespace. This also makes Dokploy's parsing agree with how docker compose itself reads the .env files Dokploy generates.

Input Before After
KEY=secret# secret secret#
KEY=sec#ret sec sec#ret
KEY=#foo (empty) #foo
KEY=value # comment value value (unchanged)
KEY="val#ue" val#ue val#ue (unchanged)

Quoted values, inline comments after whitespace, multiline values, \n/\r escape expansion, the export prefix, and empty values all behave exactly as before — the three pre-existing env test files pass unchanged.

Note: values relying on dotenv's no-space inline comments (KEY=value#comment) now keep the literal value. This is the intended semantic change and matches Docker Compose.

dotenv remains a dependency (still used for Dokploy's own boot env in apps/dokploy).

Tests

  • New apps/dokploy/__test__/env/comment-handling.test.ts (14 tests), written before the fix — the 7 # cases failed with the exact truncated values, locking in the repro.
  • All 92 env tests pass; full suite, typecheck, and Biome clean.

Manual verification (local dev, Docker Swarm)

  • Created a Postgres database with password mysecret#: container env shows POSTGRES_PASSWORD=mysecret#; psql over the overlay network (where scram auth is enforced) authenticates with mysecret# and rejects the truncated mysecret with password authentication failed — the exact error from Incorrect Postgres password parsing for Spring Boot apps #5095, now only occurring for genuinely wrong passwords.
  • Compose deployment (drawio template) with TEST_PASSWORD=mysecret# in Environment Settings, referenced as ${TEST_PASSWORD}: running container env shows the full value.
  • docker compose config round-trip on a generated .env confirms Docker parses mysecret#/sec#ret identically to Dokploy's new parser.
  • Regression: KEY=value # comment entries still resolve to value.

Tested with app

app-3 app-4 app-2 app-1

Tested with postgres

pg-3 pg-2 pg-1

Greptile Summary

The PR replaces dotenv.parse for user-supplied environment text with a Compose-compatible parser that preserves unquoted # characters unless preceded by whitespace.

  • Applies the parser consistently to service, project, and environment-level variables.
  • Exports the parser from the server package.
  • Adds regression coverage for comments, references, quoted values, multiline values, escapes, and empty values.

Confidence Score: 5/5

The PR appears safe to merge, with no concrete blocking or non-blocking defects identified in the changed behavior.

The parser retains dotenv’s established parsing behavior outside the explicitly documented hash-comment semantic change, and the shared deployment paths receive the intended untruncated values.

Reviews (1): Last reviewed commit: "fix: preserve # in unquoted environment ..." | Re-trigger Greptile

Context used:

User environment variables were parsed with dotenv, which truncates
unquoted values at any #, so passwords like 'secret#' reached
containers as 'secret'. Replace dotenv.parse with a parser that
follows Docker Compose comment semantics: # starts an inline comment
only at line start or when preceded by whitespace. Quoted values,
inline comments after whitespace, multiline values and escape
expansion behave as before.

Fixes Dokploy#5095
Related Dokploy#4694
@AbiRaditya
AbiRaditya force-pushed the fix/env-comment-truncation branch from fade246 to a47157e Compare August 17, 2026 13:33
@AbiRaditya
AbiRaditya marked this pull request as ready for review August 17, 2026 13:45
@dosubot dosubot Bot added the size:M This PR changes 30-99 lines, ignoring generated files. label Aug 17, 2026
@narcisonunez

Copy link
Copy Markdown
Collaborator

This PR is too complex for the issue is fixing. Can you check https://github.com/Dokploy/dokploy/pull/5119/changes#diff-b781cff2d9de42192bd4d8a3315140d2299e52187af2c715f561c484568af1edR462 and try to get a close implementation to that one? Simpler if possible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M This PR changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Incorrect Postgres password parsing for Spring Boot apps

2 participants