简体   繁体   English

反馈请求-在文件更改时重新启动Docker容器

[英]Feedback Request - Restarting Docker container on file change

I have this working but was wondering if there is any potential side effects or even a better way to do this. 我正在进行这项工作,但想知道是否存在任何潜在的副作用,甚至是更好的方法。 The example below is generic. 下面的示例是通用的。

I have a docker-compose file with two containers ( container_1 and container_2 ). 我有一个包含两个容器( container_1container_2 )的docker-compose文件。

container_1 exposes a volume that contains various config files that it uses to run the installed service. container_1公开了一个卷,其中包含用于运行已安装服务的各种配置文件。

container_2 mounts the volume from container_1 and periodically runs a script that pulls files and updates the config of the service running in container_1 . container_2安装从成交量container_1并定期运行该文件拉和更新运行的服务的配置脚本container_1

Every time the configs are updated I want to restart the service in container_1 without having to use cron or some of the other methods I have seen discussed. 每次更新配置时,我都想重新启动container_1的服务,而不必使用cron或我已经讨论过的其他一些方法。

My solution: 我的解决方案:

I put a script on container_1 that checks if the config file has been updated (the file is initially empty and that md5sum is stored in a separate file) and if the file has changed based on md5sum it updates the current hash and kills the process. 我在container_1上放置了一个脚本,该脚本检查配置文件是否已更新(该文件最初为空,并且md5sum存储在单独的文件中),并且如果文件基于md5sum进行了更改,它会更新当前哈希并终止该进程。

In the compose file I have a healthcheck that runs the script periodically and restart is set to always . 在撰写文件中,我进行了运行状况healthcheck ,该检查会定期运行脚本并将restart设置为always When the script in container_2 runs and updates the config files in container_1 the monitor_configs.sh the script on container_1 will kill the process of the service and the container will be restarted and reload the configs. 当脚本container_2运行并更新配置文件container_1monitor_configs.sh上的脚本container_1将杀死服务的过程中,容器将重新启动,并重新加载CONFIGS。

monitor_config.sh 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 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:

I know this is not the intended use of healthcheck but it seemed like the cleanest way to get the desired effect while still maintaining only one running process in each container. 我知道这是不是有意使用的healthcheck ,但它似乎得到预期的效果,同时仍保持唯一一个在每个容器运行过程中最彻底的方法。

I have tried with and without tini in container_1 and it seems to work as expected in both cases. 我尝试在container_1使用和不使用tini ,并且在两种情况下都可以正常工作。

I plan on extending the interval of the healthcheck to 24 hours as the script in container_2 only runs once a day. 我计划在延伸interval的的healthcheck 24小时为脚本container_2每天只运行一次。

Use case 用例

I'm running Suricata in container_1 and pulledpork in container_2 to update the rules for Suricata. 我跑Suricata在container_1在和手撕猪肉container_2来更新Suricata规则。 I want to run pulledpork once a day and if the rules have been update, restart Suricata to load the new rules. 我想每天运行一次pullpork,如果规则已更新,请重新启动Suricata以加载新规则。

You may want to look at how tools like confd work, which would run as your container_1 entrypoint. 您可能想看看像confd这样的工具如何工作,这些工具将作为container_1入口点运行。 It runs in the foreground, polls an external configuration source, and upon a change it rewrites the config files inside the container and restarts the spawned application. 它在前台运行,轮询外部配置源,更改后将重写容器内的配置文件,然后重新启动生成的应用程序。

To make your own tool like confd you'd need to include your restart trigger, maybe your health monitoring script, and then make the stdin/stdout/stderr pass through along with any signals so that your restart tool becomes transparent inside the container. 要使自己的工具像confd一样,您需要包括重新启动触发器(也许是运行状况监视脚本),然后使stdin / stdout / stderr与所有信号一起通过,以便重新启动工具在容器内透明。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM