我最近一直在尝试使用Docker构建一些服务,有一件事一直困扰着我,那就是把密码放在Dockerfile中。我是一名开发人员,所以在源代码中存储密码感觉就像在脸上打了一拳。这值得担心吗?Dockerfiles中有什么好的处理密码的约定吗?


当前回答

我的方法似乎有效,但可能有些幼稚。告诉我为什么这是错的。

在docker构建过程中设置的arg是由history子命令公开的,所以不要去那里。但是,在运行容器时,run命令中给出的环境变量对容器是可用的,但不是映像的一部分。

因此,在Dockerfile中,执行不涉及秘密数据的设置。设置一个类似于/root/finish.sh的CMD。在run命令中,使用环境变量将秘密数据发送到容器中。sh使用这些变量来完成构建任务。

为了更容易地管理秘密数据,将其放入一个文件中,由docker使用——env-file开关加载。当然,要保密。gitignore之类的。

对我来说,finish.sh运行一个Python程序。它检查以确保之前没有运行过,然后完成设置(例如,将数据库名称复制到Django的settings.py中)。

其他回答

Docker现在(版本1.13或17.06或更高)支持管理秘密信息。下面是概述和更详细的文档

kubernetes和DCOS也存在类似的特征

使用环境变量的另一种替代方法是使用卷使容器中可以访问主机上的目录,如果环境变量太多,环境变量会变得很混乱。

如果您将所有凭据作为文件放在该文件夹中,那么容器就可以读取这些文件并根据需要使用它们。

例如:

$ echo "secret" > /root/configs/password.txt
$ docker run -v /root/configs:/cfg ...

In the Docker container:

# echo Password is `cat /cfg/password.txt`
Password is secret

许多程序都可以从一个单独的文件中读取它们的凭据,因此通过这种方式,您可以将程序指向其中一个文件。

12因素应用程序方法告诉我们,任何配置都应该存储在环境变量中。

Docker compose可以在配置中进行变量替换,因此可以用来将密码从主机传递到Docker。

仅运行时解决方案

Docker-compose还提供了一个非群模式的解决方案(自v1.11起: 秘密使用绑定安装)。

这些秘密被docker-compose挂载为/run/secrets/下面的文件。这可以在运行时(运行容器)解决问题,但不能在构建时(构建映像)解决问题,因为/run/secrets/在构建时没有被挂载。此外,此行为依赖于使用docker-compose运行容器。


例子:

Dockerfile

FROM alpine
CMD cat /run/secrets/password

docker-compose.yml

version: '3.1'
services:
  app:
    build: .
    secrets:
      - password

secrets:
  password:
    file: password.txt

要构建,执行:

docker-compose up -d

进一步阅读:

mikesir87的博客-在开发过程中使用Docker秘密

我们的团队避免将凭证放在存储库中,因此这意味着Dockerfile中不允许使用凭证。我们在应用程序中的最佳实践是使用来自环境变量的信用。

我们使用docker-compose来解决这个问题。

docker-compose之内。Yml,你可以为容器指定一个包含环境变量的文件:

 env_file:
- .env

确保将.env添加到.gitignore,然后在.env文件中设置凭据,如下所示:

SOME_USERNAME=myUser
SOME_PWD_VAR=myPwd

将.env文件存储在本地或其他团队成员可以获取它的安全位置。

见:https://docs.docker.com/compose/environment-variables/ / the-env-file