Skip to content

fix: allow docker compose command chaining - #4997

Merged
narcisonunez merged 4 commits into
Dokploy:canaryfrom
ews-pgasser:fix/chaining-canary
Aug 7, 2026
Merged

fix: allow docker compose command chaining#4997
narcisonunez merged 4 commits into
Dokploy:canaryfrom
ews-pgasser:fix/chaining-canary

Conversation

@ews-pgasser

@ews-pgasser ews-pgasser commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

What is this PR about?

This PR updates the sanitizeCommand logic to safely allow && chaining in custom compose deployment commands. Currently, the strict blocklist on & prevents users from executing standard multi-step deployments (such as compose pull && docker compose down && docker compose up -d --build). This is critical for stacks that require full teardowns to clear in-memory caches (e.g., Redis) or sync volume mounts during image updates. The updated logic blocks single & (backgrounding) and strictly enforces that any chained command must securely start with docker compose or docker-compose , maintaining security while unblocking legitimate DevOps workflows.

Checklist

Before submitting this PR, please make sure that:

  • You created a dedicated branch based on the canary branch.
  • You have read the suggestions in the CONTRIBUTING.md file https://github.com/Dokploy/dokploy/blob/canary/CONTRIBUTING.md#pull-request
  • You have tested this PR in your local instance. If you have not tested it yet, please do so before submitting. This helps avoid wasting maintainers' time reviewing code that has not been verified by you.

Issues related (if applicable)

closes #4992

Screenshots (if applicable)

Greptile Summary

This PR permits guarded && chaining in custom Docker Compose deployment commands while continuing to reject unsafe shell metacharacters and non-Compose chain segments.

  • Adds validation for paired ampersands and Compose-only chained commands.
  • Adds focused acceptance and rejection tests for the new command grammar.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Reviews (3): Last reviewed commit: "chore: add tests" | Re-trigger Greptile

Context used:

@dosubot dosubot Bot added the size:S This PR changes 10-29 lines, ignoring generated files. label Aug 6, 2026
Comment thread packages/server/src/utils/builders/compose.ts Outdated
@ews-pgasser

Copy link
Copy Markdown
Contributor Author

@Siumauricio @narcisonunez please check this PR, we urgently need the docker compose command chaining feature back and there is no possibility to downgrade versions too.

@narcisonunez

Copy link
Copy Markdown
Collaborator

@ews-pgasser

Add tests (compose-command-injection.test.ts)
Run Biome check

@dosubot dosubot Bot added size:M This PR changes 30-99 lines, ignoring generated files. and removed size:S This PR changes 10-29 lines, ignoring generated files. labels Aug 7, 2026
@ews-pgasser

ews-pgasser commented Aug 7, 2026

Copy link
Copy Markdown
Contributor Author

@ews-pgasser

Add tests (compose-command-injection.test.ts) Run Biome check

✅ done, both succeded properly @narcisonunez


Biome Check (node_modules/.bin/biome check packages/server/src/utils/builders/compose.ts apps/dokploy/__test__/compose/compose-command-injection.test.ts)

Checked 2 files in 8ms. No fixes applied.

Tests (pnpm vitest run --config __test__/vitest.config.ts __test__/compose/compose-command-injection.test.ts)

 ✓ __test__/compose/compose-command-injection.test.ts (13 tests) 43ms
   ✓ compose createCommand injection (13)
     ✓ escapes composePath (docker-compose) 15ms
     ✓ escapes composePath (stack deploy) 10ms
     ✓ escapes appName 10ms
     ✓ rejects a custom command containing shell control characters 2ms
     ✓ allows a legitimate custom command 0ms
     ✓ keeps a legitimate composePath intact 2ms
     ✓ allows chained docker compose commands with '&&' 0ms
     ✓ allows chaining with the legacy 'docker-compose' spelling 0ms
     ✓ rejects a single '&' used for backgrounding 0ms
     ✓ rejects a malformed '&&&' chain 0ms
     ✓ rejects chained segments that are not docker compose invocations 0ms
     ✓ rejects an attempted injection smuggled inside a chained segment 0ms
     ✓ rejects a chain that only pretends to start with docker compose later in the string 0ms
 Test Files  1 passed (1)
      Tests  13 passed (13)
   Start at  11:57:57
   Duration  3.45s (transform 991ms, setup 56ms, import 3.22s, tests 43ms, environment 0ms)

@dosubot dosubot Bot added the lgtm This PR has been approved by a maintainer label Aug 7, 2026
@narcisonunez narcisonunez added the hotfix Cherry-pick this fix to main for next patch release label Aug 7, 2026
@narcisonunez
narcisonunez merged commit 91258d0 into Dokploy:canary Aug 7, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

hotfix Cherry-pick this fix to main for next patch release lgtm This PR has been approved by a maintainer size:M This PR changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

docker-compose redeploys leave stale containers/orphans instead of cleanly recreating the stack

2 participants