Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

dockerize a CLI that prompts for password

Tags:

docker

stdout

tty

Struggling to get a docker app to both pipe output to a file, and read input. Running the same command in bash works fine.

The command is a CLI I created called envwarden (a simple bash script wrapping around the Bitwarden CLI).

Easiest to show an example:

locally

Running it locally (not inside docker), it works as expected:

$ ./envwarden --dotenv >/tmp/secrets.txt
.envwarden file not found in /home/user ... prompting for credentials
? Email address: [email protected]
? Master password: [hidden]

The prompts work fine. I can type in my email (shown), password (hidden), and the output goes to /tmp/secrets.txt just fine.

with docker

With docker, things behave a bit differently.

With docker run -ti (or just docker run -t), there's no prompt at all for email or password...

$ docker run --rm -ti envwarden/envwarden envwarden --dotenv >/tmp/secrets.txt

# ... no output ... 

With docker run -i, the prompt shows, but anything I type is repeated, and password is shown as well! :-/

$ docker run --rm -i envwarden/envwarden envwarden --dotenv >/tmp/secrets.txt
.envwarden file not found in /root ... prompting for credentials
? Email address: [email protected]
? Email address: [email protected]
? Master password: [input is hidden] my password
? Master password: [hidden]

docker run, without -t or -i it shows the prompt, but fails to get input

$ docker run --rm envwarden/envwarden envwarden --dotenv >/tmp/secrets.txt
.envwarden file not found in /root ... prompting for credentials
? Email address: unable to login or sync with bitwarden.

Further details

Here's the Dockerfile and docker-entrypoint.sh

Question

How can I get docker to match the same behaviour as running locally? i.e. prompt for password without showing it, and redirect output to stdout.

like image 978
gingerlime Avatar asked Sep 03 '25 03:09

gingerlime


1 Answers

The behavior you observe is due to the way docker run handles standard streams.

In particular, this is related to moby/moby#725 and PR moby/moby#741:

  • If you pass no -i nor -t flag to docker run: your terminal is not attached to the standard input of your main program, which thereby behaves as if you had typed empty strings as credentials.

  • If you only pass the -i flag to docker run, your terminal is attached to your program's stdin, but no pseudo-TTY is allocated, implying you get a not very user-friendly CLI interaction (no hiding feature during password typing, and possible duplication of output lines).

  • If you pass the -it flags to docker run: a pseudo-TTY is allocated, so the password prompt should work (hiding what you type), but at the same time, the stdout and stderr streams are mixed, so when you append the >/tmp/secrets.txt redirection, you don't actually see the prompt as everything is sent to your /tmp/secrets.txt file!

All in all, to achieve what you want I guess you should stick to the -it option, but rather use a bash redirection "inside" the container (not outside) and also rely on some bind-mount option.

Hence the following proof of concept:

export out="/tmp/secrets.txt"  # absolute path to the output file in the host
docker run --rm -it -v "$out:$out" envwarden/envwarden \
  /bin/bash -c "envwarden --dotenv >$out"
cat "$out"

(This should work normally, but I did not try it on your particular instance, so comments are welcome.)

like image 61
ErikMD Avatar answered Sep 05 '25 01:09

ErikMD