反馈请求 - 文件更改时重新启动 Docker 容器
Feedback Request - Restarting Docker container on file change
我有这个工作,但想知道是否有任何潜在的副作用或者更好的方法来做到这一点。下面的例子是通用的。
我有一个包含两个容器(container_1
和 container_2
)的 docker-compose 文件。
container_1
公开了一个卷,其中包含用于 运行 已安装服务的各种配置文件。
container_2
从 container_1
安装卷并定期 运行s 一个脚本来提取文件并更新 运行ning 在 container_1
中的服务配置.
每次更新配置时,我都想在 container_1
中重新启动服务,而不必使用 cron
或我看到讨论过的其他一些方法。
我的解决方案:
我在 container_1
上放置了一个脚本,用于检查配置文件是否已更新(文件最初为空并且 md5sum 存储在单独的文件中)以及文件是否已根据 md5sum 进行更改更新当前哈希并终止进程。
在撰写文件中,我有一个 healthcheck
,它会定期 运行 脚本并且 restart
设置为 always
。当 container_2
运行 中的脚本更新 container_1
中的配置文件时 monitor_configs.sh
container_1
中的脚本将终止服务进程和容器将重新启动并重新加载配置。
monitor_config.sh
# current_hash contains md5sum of empty file initially
#!/bin/sh
echo "Checking if config has updated"
config_hash=$(md5sum /path/to/config_file)
current_hash=$(cat /path/to/current_file_hash)
if [ "$rules_hash" != "$current_hash" ]
then
echo "config has been updated, restarting service"
md5sum /path/to/config_file > /path/to/current_file_hash
kill $(pgrep service)
else
echo "config unchanged"
fi
docker-compose.yml
version: '3.2'
services:
service_1:
build:
context: /path/to/Dockerfile1
healthcheck:
test: ["CMD-SHELL", "/usr/bin/monitor_config.sh"]
interval: 1m30s
timeout: 10s
retries: 1
restart: always
volumes:
- type: volume
source: conf_volume
target: /etc/dir_from_1
service_2:
build:
context: /path/to/Dockerfile2
depends_on:
- service_1
volumes:
- type: volume
source: conf_volume
target: /etc/dir_from_1
volumes:
conf_volume:
我知道这不是 healthcheck
的预期用途,但它似乎是获得预期效果的最干净的方法,同时仍然在每个容器中仅维护一个 运行ning 进程。
我在 container_1
中尝试了使用和不使用 tini
,并且在这两种情况下它似乎都按预期工作。
我计划将 healthcheck
的 interval
延长到 24 小时,因为 container_2
中的脚本每天只有 运行s 一次。
用例
我在 运行ning Suricata container_1
和 pulledpork 在 container_2
更新 Suricata 的规则。我想每天 运行 pulledpork 一次,如果规则已更新,请重新启动 Suricata 以加载新规则。
您可能想了解 confd 等工具的工作原理,这将 运行 作为您的 container_1 入口点。它 运行 在前台,轮询外部配置源,并在发生更改时重写容器内的配置文件并重新启动生成的应用程序。
要制作像 confd 这样的您自己的工具,您需要包含重启触发器,也许是您的健康监控脚本,然后让 stdin/stdout/stderr 与任何信号一起通过,以便您的重启工具变得透明在容器内。
我有这个工作,但想知道是否有任何潜在的副作用或者更好的方法来做到这一点。下面的例子是通用的。
我有一个包含两个容器(container_1
和 container_2
)的 docker-compose 文件。
container_1
公开了一个卷,其中包含用于 运行 已安装服务的各种配置文件。
container_2
从 container_1
安装卷并定期 运行s 一个脚本来提取文件并更新 运行ning 在 container_1
中的服务配置.
每次更新配置时,我都想在 container_1
中重新启动服务,而不必使用 cron
或我看到讨论过的其他一些方法。
我的解决方案:
我在 container_1
上放置了一个脚本,用于检查配置文件是否已更新(文件最初为空并且 md5sum 存储在单独的文件中)以及文件是否已根据 md5sum 进行更改更新当前哈希并终止进程。
在撰写文件中,我有一个 healthcheck
,它会定期 运行 脚本并且 restart
设置为 always
。当 container_2
运行 中的脚本更新 container_1
中的配置文件时 monitor_configs.sh
container_1
中的脚本将终止服务进程和容器将重新启动并重新加载配置。
monitor_config.sh
# current_hash contains md5sum of empty file initially
#!/bin/sh
echo "Checking if config has updated"
config_hash=$(md5sum /path/to/config_file)
current_hash=$(cat /path/to/current_file_hash)
if [ "$rules_hash" != "$current_hash" ]
then
echo "config has been updated, restarting service"
md5sum /path/to/config_file > /path/to/current_file_hash
kill $(pgrep service)
else
echo "config unchanged"
fi
docker-compose.yml
version: '3.2'
services:
service_1:
build:
context: /path/to/Dockerfile1
healthcheck:
test: ["CMD-SHELL", "/usr/bin/monitor_config.sh"]
interval: 1m30s
timeout: 10s
retries: 1
restart: always
volumes:
- type: volume
source: conf_volume
target: /etc/dir_from_1
service_2:
build:
context: /path/to/Dockerfile2
depends_on:
- service_1
volumes:
- type: volume
source: conf_volume
target: /etc/dir_from_1
volumes:
conf_volume:
我知道这不是 healthcheck
的预期用途,但它似乎是获得预期效果的最干净的方法,同时仍然在每个容器中仅维护一个 运行ning 进程。
我在 container_1
中尝试了使用和不使用 tini
,并且在这两种情况下它似乎都按预期工作。
我计划将 healthcheck
的 interval
延长到 24 小时,因为 container_2
中的脚本每天只有 运行s 一次。
用例
我在 运行ning Suricata container_1
和 pulledpork 在 container_2
更新 Suricata 的规则。我想每天 运行 pulledpork 一次,如果规则已更新,请重新启动 Suricata 以加载新规则。
您可能想了解 confd 等工具的工作原理,这将 运行 作为您的 container_1 入口点。它 运行 在前台,轮询外部配置源,并在发生更改时重写容器内的配置文件并重新启动生成的应用程序。
要制作像 confd 这样的您自己的工具,您需要包含重启触发器,也许是您的健康监控脚本,然后让 stdin/stdout/stderr 与任何信号一起通过,以便您的重启工具变得透明在容器内。