本文翻译自我的英文博客,最新修订内容可随时参考:Dockerfile使用技巧
通常我们会在项目根目录编写 Dockerfile
,它是描述镜像构建流程的配置文件。官方文档提供了详细语法说明,但实际使用中需要注意一些关键细节,尤其是 CMD
和 ENTRYPOINT
的区别。
start.sh
),通过 CMD ["./start.sh"]
执行。 systemd
,其主进程即为应用进程。容器生命周期与主进程绑定,主进程退出则容器终止。 CMD service nginx start
(service
会在后台运行,导致容器主进程立即退出)。 CMD ["nginx", "-g", "daemon off;"]
(让 Nginx 前台运行成为主进程)。 docker build -t my-image:1.0 . # -t 指定镜像名和标签,. 表示构建上下文(通常为当前目录)
构建上下文会打包目录内文件传递给 Docker 引擎,需避免包含无关文件(可通过 .dockerignore
过滤)。
CMD ["executable", "param1", "param2"]
/bin/sh
)。 ENTRYPOINT ["echo", "$HOME"]
不会解析 $HOME
)。 CMD command param1 param2
/bin/sh -c
执行命令,主进程为 Shell(PID 1),目标程序为子进程(PID > 1)。 CMD echo $HOME
会输出 /root
)。 作用:定义容器默认执行的命令或参数,可被 docker run
命令覆盖。
CMD "python", "app.py" # 直接执行 Python 脚本
CMD python app.py # 等价于 CMD "sh", "-c", "python app.py"
ENTRYPOINT "curl"
CMD "https://example.com" # 可通过 docker run my-image https://baidu.com 覆盖
docker run my-image custom-command
时,CMD
会被 custom-command
替换。 CMD "echo", "hello" # Dockerfile 中的默认命令
docker run my-image ls # 实际执行 ls(覆盖 CMD)
作用:设置容器的固定入口命令,参数可通过 CMD
或 docker run
动态传递。
ENTRYPOINT "nginx", "-g", "daemon off;" # 前台运行 Nginx,主进程为 Nginx
ENTRYPOINT nginx -g "daemon off;" # 主进程为 sh,Nginx 为子进程
docker run
的参数会追加到 ENTRYPOINT
之后。 ENTRYPOINT "curl", "-X"
CMD "GET"
docker run my-image POST https://example.com # 实际执行 curl -X POST https://example.com
docker run
的参数会被忽略,仅执行 ENTRYPOINT
定义的命令。 ENTRYPOINT curl https://example.com
docker run my-image https://baidu.com # 仍执行 curl https://example.com
通过 --entrypoint
选项指定新的入口命令:
docker run --entrypoint ls my-image # 忽略 Dockerfile 中的 ENTRYPOINT,执行 ls
场景 | 配置示例 | 执行效果 |
---|---|---|
固定命令 + 默认参数 | ENTRYPOINT "curl" CMD "https://example.com" |
|
禁止参数覆盖 | ENTRYPOINT "nginx", "-g", "daemon off;" | 无论 |
需要解析环境变量 |
| 正确输出环境变量值(如通过 |
复杂初始化脚本 |
| 先执行初始化脚本,再运行主进程( |
sh -c
处理:undefinedENTRYPOINT "sh", "-c", "echo $HOME" # 正确解析 $HOME ENTRYPOINT
:定义不可变的入口命令(如程序二进制文件)。 CMD
:提供可覆盖的默认参数或备用命令。 .dockerignore
排除不必要的文件(如 node_modules
、日志文件),减少构建时间和镜像体积。 *.log
node_modules/
FROM golang:1.20 AS builder
WORKDIR /app
COPY . .
RUN go build -o my-app
FROM alpine:3.17
COPY --from=builder /app/my-app /usr/bin/my-app
ENTRYPOINT "my-app"
docker run -it my-image sh
进入容器,手动执行主进程命令,查看错误日志。 daemon
参数)。 ENTRYPOINT "sh", "-c", "echo $ENV_VAR && my-app" # 通过 Shell 解析环境变量
ENTRYPOINT "my-app" # 主进程为 my-app,可正确响应 docker stop
需求场景 | 推荐指令 | 示例 |
---|---|---|
定义默认执行命令且可覆盖 |
|
|
固定入口命令,参数可动态传递 |
|
|
需要解析环境变量 |
|
|
禁止任何参数覆盖 |
|
|
通过合理组合 CMD
和 ENTRYPOINT
,可以灵活控制容器的启动行为,同时保持镜像的可复用性和可扩展性。更多实战案例可参考博客:Dockerfile使用技巧。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。