我想在Docker容器中运行M/Monit(https://mmonit.com/)并找到此Dockerfile:https://github.com/mlebee/docker-mmonit/blob/master/Dockerfile

我在测试环境中使用了一个简单的docker-compose.yml:

version: '3'
services:
    mmonit:
        build: .
        ports:
        - "8080:8080"
        #volumes:
            #- ./db/:/opt/mmonit/db/

它确实有效,但是我想扩展Dockerfile,以便将/opt/mmonit/db/路径导出为一个卷。我正在努力实现以下行为:
  • 当映射到/opt/mmonit/db/的卷为空时(例如,在首次安装时),应将安装归档文件中的文件写入该卷。 db文件夹是归档文件的一部分。
  • 卷中已经存在数据库文件/opt/mmonit/db/mmonit.db时,在任何情况下都不应覆盖它。

  • 我确实有一个想法,该如何在bash中编写所需的操作/检查脚本,但是我什至不确定用自定义的启动脚本替换ENTRYPOINT会更好还是应该仅通过修改Dockerfile来完成。
    这就是为什么我要求推荐的方法。

    最佳答案

    一般来说,您制定的策略是正确的路径;从本质上讲,这就是标准Docker Hub数据库镜像的工作。

    链接到的图像是社区图像,因此您不应特别受该图像的决定的束缚。鉴于GitHub存储库中缺少任何类型的许可证文件,您可能无法原样复制它,但它也不是特别复杂。

    Docker支持运行命令的两个“一半”,即ENTRYPOINTCMD。可以在Docker命令行上轻松提供CMD,如果同时拥有,可以将Docker combines them together集成到一个命令中。因此,一种非常典型的模式是将要运行的实际命令(mmmonit -i)作为CMD,并将ENTRYPOINT用作包装器脚本,该脚本执行所需的设置,然后执行exec "$@"

    #!/bin/sh
    # I am the Docker entrypoint script
    
    # Create the database, but only if it does not already exist:
    if ! test -f /opt/mmonit/db/mmonit.db; then
      cp -a /opt/monnit/db_base /opt/monnit/db
    fi
    
    # Replace this script with the CMD
    exec "$@"
    

    然后,在Dockerfile中,同时指定CMDENTRYPOINT:

    # ... do all of the installation ...
    
    # Make a backup copy of the preinstalled data
    RUN cp -a db db_base
    
    # Install the custom entrypoint script
    COPY entrypoint.sh /opt/monit/bin
    RUN chmod +x entrypoint.sh
    
    # Standard runtime metadata
    USER monit
    EXPOSE 8080
    # Important: this must use JSON-array syntax
    ENTRYPOINT ["/opt/monit/bin/entrypoint.sh"]
    # Can be either JSON-array or bare-string syntax
    CMD /opt/monit/bin/mmonit -i
    

    我肯定会在Dockerfile中进行此类更改,要么启动该社区镜像的FROM,要么构建您自己的。

    09-11 23:52