Skip to content

feat(run): forward decrypted secrets into docker compose env_file services - #392

Open
cvince wants to merge 1 commit into
mainfrom
feat/compose-env-forwarding
Open

cvince wants to merge 1 commit into
mainfrom
feat/compose-env-forwarding

Conversation

@cvince

@cvince cvince commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

Problem

Laravel/Docker test feedback (Finding 1): capy run -- docker compose up with the standard env_file: .env boots containers with ciphertext (CACHE_DRIVER=capy:… → Laravel crash). Containers don't inherit compose's environment; env_file reads the encrypted file off disk.

Fix

When the command is docker compose … / docker-compose …, capy run now:

  1. Asks docker compose config --format json --no-interpolate which services have env_file pointing at the Capy .env (no YAML parsing on our side).
  2. Builds a names-only override: {"services":{"app":{"environment":["APP_KEY","DB_PASSWORD"]}}}. A bare name tells compose to forward the value from its own env, which capy run populated.
  3. Re-runs as docker compose -f <user files> -f /dev/fd/3 …, piping the override on fd 3 (stdin stays free for run/exec/tinker). Windows has no /dev/fd, so it uses a names-only temp file deleted on exit.

No values are ever written anywhere. Services that don't read .env (db, phpmyadmin) get nothing. User's own -f flags, COMPOSE_FILE, and the default *.override.yml are preserved. Anything ambiguous (e.g. --project-directory without -f, config failing) leaves argv unchanged.

Not covered

  • docker inspect still shows plaintext in the container config (inherent to host-side decryption).
  • Recreating containers outside capy run still gets ciphertext.
  • php artisan config:cache (Finding 3).

Testing

  • tests/commands/composeForward.test.ts: arg parsing, file resolution, service filtering, POSIX pipe + Windows temp file.
  • Manual with Docker Compose 2.31: run and up → app gets SECRET=plaintext, a service without env_file gets nothing.
  • bun run build && bun run test: 2415 pass, 0 fail. Typecheck clean.

…vices

`env_file: .env` makes compose read the encrypted file off disk, so
`capy run -- docker compose …` handed containers ciphertext. capy run now
detects compose, asks `docker compose config --no-interpolate` which
services read the Capy .env, and appends a names-only override
(`environment: [KEY, …]`) on fd 3 so compose forwards the decrypted values
from its own environment. Windows (no /dev/fd) uses a names-only temp file
removed on exit. Anything ambiguous leaves argv unchanged.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant