如何在 docker 图像 运行 时执行 运行 命令?
How to run commands when a docker image runs?
我有一个 consul docker 图像,它是 docker-compose
环境的一部分。
我必须 运行 docker 容器内的命令 consul acl bootstrap
,我相信在 command
或 entrypoint
中提及它会覆盖默认命令为consul设置,除了默认命令外,如何执行?
docker-compose 中没有允许您在容器启动后运行命令的选项。
您可以做的是构建您自己的映像,该映像将在启动时执行您想要的操作。为此,您需要:
- 找出容器的默认启动(
ENTRYPOINT
和 CMD
组合)。
- 创建一个 shell 脚本,它将调用带有所需参数的入口点,之后它将调用您的命令。
- 创建一个基于原始图像的 Dockerfile,复制图像中的 shell 脚本并将入口点更改为您的脚本
- 将您的图像和 docker 文件添加到 docker-compose(将当前的 consul 图像更改为指向您的图像并构建脚本)
这里是一个入口点示例 shell 脚本,它可以用来启动您的特定脚本。将您的代码放在 execute_after_start()
函数中。
entrypoint.sh
#!/bin/bash
set -e
execute_before_start() {
echo "Execute befor start" > /running.txt
}
execute_after_start() {
sleep 1
echo "Execute after start" >> /running.txt
}
execute_before_start
echo "CALLING ENTRYPOINT WITH CMD: $@"
exec /old_entrypoint.sh "$@" &
daemon_pid=$!
execute_after_start
wait $daemon_pid
echo "Entrypoint exited" >> running.txt
脚本将启动 execute_before_start
。当此命令结束时,将使用 CMD
提供的参数启动原始入口点并并行(这是 execute
末尾的 &
)它将启动 execute_after_start
. execute_after_start
结束后,会等待原入口点停止。
我在示例中使用 sleep
作为一种简单的方法来确保一些延迟,以便入口点可以接受命令。根据入口点,可能有更智能的方法来确保入口点已准备好接受命令。
正如其他人评论的那样,在容器启动后无法编写 运行 附加命令。
或者,您可以通过指定 acl.tokens.master
in the Consul server's configuration. The easiest way to do this with the Docker image is to pass the configuration using the CONSUL_LOCAL_CONFIG
environment variable (see Docker-Consul: Using the container).
明确指定主令牌的秘密 ID
例如:
---
version: "3.8"
services:
consul:
image: consul
ports:
- "8500:8500/tcp"
environment:
CONSUL_LOCAL_CONFIG: >
{"acl": {"enabled": true, "tokens": {"master": "A8D89992-A3DB-46E3-A528-8F97CFEDB183"} }}
这具有将令牌硬编码到您的 Compose 配置中的明显缺点,但也避免了尝试 运行 consul acl bootstrap
使用自定义入口点的复杂性。
您只需在集群首次初始化时提供该环境变量即可。之后,Consul 将此令牌数据保存在安装在 /consul/data 的 Docker 卷中。需要使用 consul acl token
或 /v1/acl/token
API 端点对令牌(包括主令牌)进行任何修改。
我有一个 consul docker 图像,它是 docker-compose
环境的一部分。
我必须 运行 docker 容器内的命令 consul acl bootstrap
,我相信在 command
或 entrypoint
中提及它会覆盖默认命令为consul设置,除了默认命令外,如何执行?
docker-compose 中没有允许您在容器启动后运行命令的选项。
您可以做的是构建您自己的映像,该映像将在启动时执行您想要的操作。为此,您需要:
- 找出容器的默认启动(
ENTRYPOINT
和CMD
组合)。 - 创建一个 shell 脚本,它将调用带有所需参数的入口点,之后它将调用您的命令。
- 创建一个基于原始图像的 Dockerfile,复制图像中的 shell 脚本并将入口点更改为您的脚本
- 将您的图像和 docker 文件添加到 docker-compose(将当前的 consul 图像更改为指向您的图像并构建脚本)
这里是一个入口点示例 shell 脚本,它可以用来启动您的特定脚本。将您的代码放在 execute_after_start()
函数中。
entrypoint.sh
#!/bin/bash
set -e
execute_before_start() {
echo "Execute befor start" > /running.txt
}
execute_after_start() {
sleep 1
echo "Execute after start" >> /running.txt
}
execute_before_start
echo "CALLING ENTRYPOINT WITH CMD: $@"
exec /old_entrypoint.sh "$@" &
daemon_pid=$!
execute_after_start
wait $daemon_pid
echo "Entrypoint exited" >> running.txt
脚本将启动 execute_before_start
。当此命令结束时,将使用 CMD
提供的参数启动原始入口点并并行(这是 execute
末尾的 &
)它将启动 execute_after_start
. execute_after_start
结束后,会等待原入口点停止。
我在示例中使用 sleep
作为一种简单的方法来确保一些延迟,以便入口点可以接受命令。根据入口点,可能有更智能的方法来确保入口点已准备好接受命令。
正如其他人评论的那样,在容器启动后无法编写 运行 附加命令。
或者,您可以通过指定 acl.tokens.master
in the Consul server's configuration. The easiest way to do this with the Docker image is to pass the configuration using the CONSUL_LOCAL_CONFIG
environment variable (see Docker-Consul: Using the container).
例如:
---
version: "3.8"
services:
consul:
image: consul
ports:
- "8500:8500/tcp"
environment:
CONSUL_LOCAL_CONFIG: >
{"acl": {"enabled": true, "tokens": {"master": "A8D89992-A3DB-46E3-A528-8F97CFEDB183"} }}
这具有将令牌硬编码到您的 Compose 配置中的明显缺点,但也避免了尝试 运行 consul acl bootstrap
使用自定义入口点的复杂性。
您只需在集群首次初始化时提供该环境变量即可。之后,Consul 将此令牌数据保存在安装在 /consul/data 的 Docker 卷中。需要使用 consul acl token
或 /v1/acl/token
API 端点对令牌(包括主令牌)进行任何修改。