首页 > 解决方案 > 无法在 Dockerfile 中运行多个 CMD,最后一个被忽略

问题描述

我有以下运行良好的旧版 Dockerfile:

FROM some/service:base

WORKDIR /myapp


COPY frontend/nginx.conf /etc/nginx/sites-enabled/my-site
COPY frontend/build dist
COPY . .

CMD service nginx start && cd /myapp/server1 && exec python3 app.py

现在我需要稍微更新一下,让它再启动一个服务器,比如:

...
CMD service nginx start && cd /myapp/server1 && exec python3 app.py && cd /myapp/server2 && exec npm start server.js

这种方法失败了(即我没有看到我的 server.js 正在运行)。我在自己调试时迷失了方向。任何帮助将不胜感激。有没有办法在不添加多个 Docker 层的情况下做到这一点?如果可能的话,我想保持简单。

标签: dockerunixnginxdockerfile

解决方案


您的问题(至少)是由于exec在您的命令中使用。

exec命令将当前进程替换为它作为参数接收的命令,因此会中断您的&&命令链。

它如何失败的示例:

FROM alpine
CMD echo 1 && exec echo 2 && echo 3

构建并运行这个 Dockerfile,你只会看到12作为输出,而不是3.

从您的命令中删除execs ,它应该没问题。

进一步参考:

$ exec --help
exec: exec [-cl] [-a name] [command [arguments ...]] 
    Replace the shell with the given command.

    Execute COMMAND, replacing this shell with the specified program.

作为附加提示,我会考虑将所有这些命令放在一个entrypoint.sh脚本中,并在其中运行CMD而不是使用&&.


推荐阅读