docker/compose

[BUG] `docker compose --env-file path up -d` hangs when `path` is a named pipe

felixfontein opened this issue · 1 comments

Description

See getsops/sops#1470. When sops exec-file is used, it by default uses a named pipe (instead of writing the decrypted file to disk).

It seems that Compose tries to read the file three times, and two times of these happen in the call here:

envFromFile, err := dotenv.GetEnvFromFile(composegoutils.GetAsEqualsMap(os.Environ()), options.EnvFiles)
I added fmt.Printf statements before and after that line, and I only got the second print after step 5 completed.

I'm not sure what is happening, since the code called there only seems to read the file once (https://github.com/compose-spec/compose-go/blob/main/dotenv/env.go#L51). Also I have no clue how to build Compose with modified source from other packages, so I cannot easily add more print statements there to try to get an idea :)

Steps To Reproduce

  1. Create a minimal Compose project with a single service.
  2. Run mkfifo envfile
  3. Run docker compose --env-file envfile up --detach
  4. In a separate window, run cat > envfile and press CTRL+D. This stops the first read.
  5. Run cat > envfile and press CTRL+D again. This stops the second read.
  6. Run cat > envfile and press CTRL+D again. This stops the third read, and Compose starts doing some work.

Compose Version

latest source version

Docker Environment

No response

Anything else?

No response

env file is indeed read once early as compose command is executed (as some COMPOSE_XX variables can be declared and change the model loading logic), then again while parsing with compose-go library. I'm not sure about a 3rd time, anyway code is definitely not optimized to avoid multi-read of such a file.