Docker-撰写,在容器启动后运行脚本?

我有一个服务,我带来了通过牧场通过码头组成。我遇到的问题是,在部署容器之后需要设置密码。

牧场主的秘密工作方式是,我设置我的秘密,牧场主将挂载一个卷在我的容器与文件包含我的秘密。我希望能够执行一个脚本来获取这个秘密,并将其设置为我的配置文件的密码。

我不相信我有办法通过 Docker 文件获得这个秘密,因为我不想让这个秘密被放在 git 中,所以我只能通过 docker-compose 来完成它。

有人知道这是否可行吗?

251253 次浏览

Docker-撰写指定如何启动容器,而不是如何修改现有的运行容器。

牧场主文件提到,对于机密的默认用法,您可以在 docker-compose.yml中的机密数组中按名称引用机密。

目标文件名将与秘密的名称相同。
默认情况下,目标文件名将创建为 UserID 和 GroupID0,文件模式为0444。
设置外部真实的秘密部分将确保它知道的秘密已经被创建。

基本 docker-compose.yml的例子:

version: '2'
services:
web:
image: sdelements/lets-chat
stdin_open: true
secrets:
- name-of-secret
labels:
io.rancher.container.pull_image: always
secrets:
name-of-secret:
external: true

如“ 如何更新单个运行的码头组合容器”所示,更新容器将涉及“构建、杀死和向上”序列。

docker-compose up -d --no-deps --build <service_name>

技巧是在调用原始命令之前覆盖撰写 COMMAND 以执行任何您需要的 init 操作。

  1. 在您的映像中添加一个脚本,该脚本将执行您想要的 init 工作,如设置密码、更改内部配置文件等。我们叫它 init.sh。将其添加到图像中。

文件夹:

FROM: sourceimage:tag
COPY init.sh /usr/local/bin/
ENTRYPOINT []

上面的代码覆盖了 sourceimage中定义的 ENTRYPOINT。为了让这个例子更简单。确保您从 sourceimage中了解 ENTRYPOINT 在 Dockerfile 中做什么,并在 docker 的 command:中调用它——撰写。Yml 文件。

译文:

services:
myservice:
image: something:tag
...
command: sh -c "/usr/local/bin/init.sh && exec myexecutable"

在调用 main 命令之前使用 exec非常重要。这将安装命令作为第一个进程(PID1) ,使其接收信号,如停止,杀死(键盘上的 Ctrl-C)或 HUP。

这是我在启动容器后调用脚本而不重写入口点时使用的方法。

在我的示例中,我使用它来初始化本地 MongoDB 的副本集

services:
mongo:
image: mongo:4.2.8
hostname: mongo
container_name: mongodb
entrypoint: ["/usr/bin/mongod","--bind_ip_all","--replSet","rs0"]
ports:
- 27017:27017
mongosetup:
image: mongo:4.2.8
depends_on:
- mongo
restart: "no"
entrypoint: [ "bash", "-c", "sleep 10 && mongo --host mongo:27017 --eval 'rs.initiate()'"]
  • 在第一部分中,我只是简单地启动我的服务(mongo)
  • 第二个服务使用“ bash”入口点和 restart: no < = 很重要

我还在服务和安装服务之间使用 depends_on来管理启动订单。

您还可以使用卷来完成这项工作:

services:
example:
image: <whatever>
volume: ./init.sh:/init.sh
entrypoint: sh -c "/init.sh"

注意,这将把 init.sh挂载到容器中,没有复制它(如果这很重要,通常不会)。基本上,容器内的进程可以修改 init.sh,它会修改文件,因为它存在于您的实际计算机中。