dockerize一个提示输入密码的CLI

时间:2019-02-22 09:07:29

标签: docker stdout tty

努力让docker应用程序将输出输出到文件并读取输入。在bash中运行相同的命令可以正常工作。

该命令是我创建的CLI,名为envwarden(包裹在Bitwarden CLI上的简单bash脚本)。

最容易显示示例:

本地

在本地运行(不在docker内部),它按预期运行:

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

提示工作正常。我可以输入我的电子邮件(显示),密码(隐藏),然后输出进入/tmp/secrets.txt就好了。

与docker

使用docker,事情的表现会有所不同。

使用docker run -ti(或仅docker run -t),根本没有提示输入电子邮件或密码...

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

# ... no output ... 

使用docker run -i,会显示提示,但是会重复输入所有内容,并同时显示密码! :-/

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

docker run,不带-t-i,它显示提示,但无法获取输入

$ 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.

更多详细信息

这里是Dockerfiledocker-entrypoint.sh

问题

如何让docker匹配与本地运行相同的行为?即提示输入密码而不显示密码,然后将输出重定向到stdout。

1 个答案:

答案 0 :(得分:1)

您观察到的行为归因于docker run处理标准流的方式。

尤其是,这与moby/moby#725和PR moby/moby#741有关:

  • 如果您没有向-i传递-tdocker run标志:您的终端未连接到主程序的标准输入,则其行为就好像您有输入空字符串作为凭据。

  • 如果仅将-i标志传递给docker run,则您的终端将附加到程序的stdin,但未分配伪TTY,这意味着您获得的用户界面不太友好CLI交互(在密码键入过程中没有隐藏功能,并且可能会重复输出行)。

  • 如果将-it标志传递给docker run:分配了一个伪TTY,因此密码提示应该起作用(隐藏您键入的内容),但同时< strong> stdout和stderr流是混合的,因此,当您附加>/tmp/secrets.txt重定向时,由于所有内容都已发送到/tmp/secrets.txt文件中,因此您实际上看不到提示!

总而言之,要实现您想要的功能,我想您应该坚持使用-it选项,而应在容器内部(而不是外部)使用bash重定向,并且还依赖于某些bind-mount选项

因此有以下概念证明:

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"

(这应该可以正常工作,但是我没有在您的特定实例上尝试过,因此欢迎发表评论。)