Dockerfile 基础与 C++ 镜像编写
对应 Dockerfile:
FROM centos:7
ENV VERSION 1.0
RUN sed -i.bak \
-e 's|^mirrorlist=|#mirrorlist=|g' \
-e 's|^#baseurl=http://mirror.centos.org/centos|baseurl=https://mirrors.ustc.edu.cn/centos-vault/centos|g' \
/etc/yum.repos.d/CentOS-Base.repo
WORKDIR /src
COPY demo.c .
RUN yum makecache && yum install -y gcc
RUN gcc demo.c -o demo && \
rm -f demo.c && \
yum remove -y gcc
CMD ["/src/demo"]
执行构建命令:
docker build -t my-cpp-image .
等待镜像制作完成并运行。
CMD 与 ENTRYPOINT 的正确使用
基本功能
ENTRYPOINT 和 CMD 均用于定义容器启动时执行的命令。若镜像未设置这两个指令,运行时会报错。
覆盖行为
Dockerfile 中后写的指令会覆盖同类型的前置指令。用户运行容器时可通过命令行参数覆盖 Dockerfile 中的 CMD,但 ENTRYPOINT 需用 --entrypoint 强制覆盖。
模式区别
- Shell 模式(如
CMD echo "hello"):命令通过/bin/sh -c启动,导致主进程 PID 非 1,无法正常接收信号(如优雅终止容器)。 - Exec 模式(如
CMD ["echo", "hello"]):直接运行命令,PID 为 1,支持信号转发,强烈推荐使用。
组合使用
ENTRYPOINT 定义固定执行命令,CMD 提供默认参数。最终命令为拼接形式:<ENTRYPOINT> <CMD>,运行时可覆盖 CMD 参数。
应用建议
- 若希望容器始终执行固定程序,使用 ENTRYPOINT;
- 若需保留参数灵活性,可组合使用 ENTRYPOINT(Exec 模式)+ CMD(提供默认参数)。
多次指令覆盖测试
如果 Dockerfile 出现两次 CMD 或 ENTRYPOINT,后面的指令会覆盖前面的指令。手动输入参数也会覆盖 CMD。
Exec 与 Shell 模式对比
Shell 模式下启动后容器主进程是 /bin/sh。Exec 模式下主进程是对应命令,PID 为 1。
CMD 配合 ENTRYPOINT 使用
CMD 做参数,ENTRYPOINT 做命令,实时修改 CMD,实现解耦性;两者相互配合,使得操作更加灵活。
使用 .dockerignore 测试
Docker 是 C/S 架构。构建镜像时,客户端会把当前目录所有文件打包发送给服务端,这个包叫做 build context。用 .dockerignore 文件可以忽略不需要的文件(如日志、缓存),让镜像更小更安全。
构建命令:
docker build -t image-name .
一句话总结:build context 是客户端发给服务端的'材料包',用 .dockerignore 过滤掉多余文件。
测试显示,忽略 txt 结尾的文件后,启动后发现只有指定文件,无 txt 结尾的文件,说明 ignore 成功。





