容器是运行进程的包装器(该包装器是命名空间和cgroup)。正在运行的进程由dockerfile的entrypoint和cmd行定义。您可以重写运行容器时要运行的映像的默认进程,对于cmd的值,重写涉及在映像名称后传递另一个命令。
所以当你的dockerfile以:
COPY setup.sh /setup.sh
RUN ["chmod", "+x", "/setup.sh"]
CMD ["/setup.sh"]
您已经在图像中定义了cmd的默认值。但是当你跑的时候:
docker build -t docker-test .; docker run -it docker-test bash
这个
./setup.sh
CMD值替换为
bash
. 这意味着
setup.sh
永远不会跑。
你可以用几种方法解决这个问题。
-
你可以跑你的
塞特普什
作为图像构建的一部分。如果脚本不依赖于容器的运行方式(例如外部卷、传入的环境变量等),则这是更好的选择。
-
将脚本移动到入口点,并通过运行提供的命令完成脚本。当你同时定义一个入口点和一个CMD时,容器只运行一个进程,所以Docker的行为是把CMD作为参数传递给入口点。要运行cmd,需要在entrypoint脚本中执行该操作。
选项1看起来像您已经完成的解决方案,我建议您的答案是:
COPY setup.sh /setup.sh
RUN ["chmod", "+x", "/setup.sh"]
RUN ["/setup.sh"]
CMD bash
您需要在脚本的顶部包含shell,以便Linux知道如何运行它:
#!/bin/sh
# The #!/bin/sh above is important, you can also replace that with the path to bash
# get addons path
addons_path=`ls -d /mnt/extra-addons/* | paste -d, -s`
# can't use / because directory name contains, using #
sed -i -e "s#__addons__path__#${addons_path}#" /etc/odoo/odoo.cfg
如果每次运行容器时/mnt/extra addons/changes,选项2很有用。这看起来像:
COPY setup.sh /setup.sh
RUN ["chmod", "+x", "/setup.sh"]
ENTRYPOINT ["/setup.sh"]
CMD ["bash"]
在安装脚本中添加一行:
#!/bin/sh
# get addons path
addons_path=`ls -d /mnt/extra-addons/* | paste -d, -s`
# can't use / because directory name contains, using #
sed -i -e "s#__addons__path__#${addons_path}#" /etc/odoo/odoo.cfg
# this next line runs the passed arguments as pid 1, replacing this script
# this is how you run an entrypoint and fall through to a cmd
exec "$@"