Docker CMD 命令在容器启动后未运行,而命令进入容器工作正常

时间:2021-02-16 10:05:34

标签: docker

这是我的 Dockerfile 内容:

from ubuntu:latest

#ARG DEBIAN_FRONTEND=noninteractive
COPY entrypoint.sh /sbin/entrypoint.sh
COPY info.php /var/www/html/
ENV TZ=Asia/Tehran
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN apt-get update && apt-get upgrade -y && apt-get install apache2 php -y
ENV APACHE_CONF_DIR=/etc/apache2
RUN chmod 755 /sbin/entrypoint.sh
CMD ['/sbin/entrypoint.sh']

这是我的 entrypoint.sh 内容:

#!/bin/bash

source /etc/apache2/envvars
exec apache2 -D FOREGROUND

图像正常运行,启动也没有任何问题,但文件 entrypoint.sh 没有启动。当我 exec -it 进入容器并手动运行此文件时,apache2 工作正常并且我的 info.php 可以通过网络访问。

我用这个命令创建容器(让它运行):

docker run -dp80:80 -v /logs:/var/log a2 bash

然后我转到容器 docker exec -it NAME,然后运行 ​​/sbin/entrypoint.sh,我看到没有问题。

我创建了另一个容器 docker run -dp81:80 a2,但我的文件没有运行。当我使用 docker run -dp81:80 a2 /sbin/entrypoint.sh 时,我的文件会运行并且我的 info.php 会显示在 Internet 浏览器中。

请您帮我看看我的问题在哪里,如果在命令末尾不使用我的文件名,容器在启动后会立即退出?

1 个答案:

答案 0 :(得分:1)

编辑

CMD docs 开始,当使用 exec 格式(在 [] 中指定 args)时,您需要使用双引号 " 而不是单引号 ',因为 args 被解析作为 JSON 数组。我认为您应该将命令更改为:

CMD [ "/sbin/entrypoint.sh" ]

有关详细信息,请参阅 this answer comparing CMD vs ENTRYPOINT

当您指定启动容器时要运行的命令时,您会覆盖容器的 CMD。例如,将 bash 放在图像名称之后:docker run -d -p 80:80 -v /logs:/var/log a2 bash。它不是运行 /sbin/entrypoint.sh 脚本,而是运行 bash

如果您想确保入口点脚本在容器启动时运行且不能被覆盖,您可以考虑使用 ENTRYPOINT 而不是 CMD

ENTRYPOINT ["/sbin/entrypoint.sh"]

正如 David Maze 在评论中指出的那样,您还可以修改入口点脚本以仅设置环境变量,并在 Dockerfile 中使用 CMD exec "$@" 将 apache 作为主容器进程运行。