The Tips About Dockerfile

This article is also posted on my blog, feel free to check the latest revision: The Tips About Dockerfile

Normally, we often write a Dockerfile in the current directory.

  • The Dockerfile is a configuration file that describes how to build the image. You can refer to the official documentation for more details.
  • If you list more than one CMD, only the last one takes effect. So if you have multiple commands to run, you better write them in a script file.
  • Docker is not the VMware, there is no systemd in the container. Its startup program is the container application process. The container exists for the main process. Once the main process exits, the container loses its meaning of existence and thus exits. So when you execute multiple commands and if they are blocking, you better write the previous commands in nohup and the last command in the blocking command. (never use the command such as CMD service nginx start, the CMD only will execute as CMD [ "sh", "-c", "service nginx start"], when the sh is executed, the container will exit, the correct way is run it directly CMD ["nginx", "-g", "daemon off;"])

Then, run the following command to build the image:

docker build -t my_image:1.0 .: the -t means tag, the . means the current directory(actually, it is the context of the dockerfile, but considering many people only use the same method, so here call it current). Besides, you can also build from .tar.gz file.

You can just refer to the official docs, but there is only one command that you should pay attention to: ENTRYPOINT.

If you want to tell the difference between CMD and ENTRYPOINT, you should first understand the shell pattern and the exec pattern.

exec pattern

The feature of exec pattern is that it will not pass the command through the shell. So the environment variables such as $HOME will not be passed.

复制代码
CMD [ "echo", "$HOME" ]
... run docker run ...
... output: $HOME

But use the exec to run the shell you can get the correct result.

复制代码
CMD [ "sh", "-c", "echo", "$HOME" ]
... run docker run ...
... output: /root

shell pattern

The shell pattern will execute the command via /bin/sh -c "task command", which means the no.1 process is not the task process but the bash process.

复制代码
CMD top
... run docker run ...
PID1 /bin/sh -c top
PID7 top

CMD

There are three ways to use CMD.

  • CMD ["executable","param1","param2"] (exec pattern)
    • CMD ["param1","param2"] (provide the entrypoint parameters)
  • CMD command param1 param2 (shell pattern) == CMD ["sh", "-c", "command param1 param2"]

The both pattern of CMD command will be overwritten by the command in the end of the docker run command.

The overwrite command will also run in the same pattern.

dockerfile 复制代码
# Example 1
CMD echo "hello"
# docker run my_image:1.0 top
# top

# Example 2
ENTRYPOINT ["/bin/echo", "Hello,"]
CMD ["world!"]
# docker run myimage "GPT3"
# Hello, GPT3

ENTRYPOINT

There are two ways to use ENTRYPOINT.

  • ENTRYPOINT ["executable","param1","param2"] (exec pattern)
  • ENTRYPOINT command param1 param2 (shell pattern)

In exec pattern, the ENTRYPOINT command will not be overwritten by the command in the end of the docker run command. Such as docker run my_image:1.0 -c. The -c will not overwrite the ENTRYPOINT [ "top", "-b" ], but it will be added to the ENTRYPOINT command as ENTRYPOINT [ "top", "-b", "-c" ].

In shell pattern, your custom command will be ignored by the ENTRYPOINT command. Such as docker run my_image:1.0 -c. The -c will be ignored by the ENTRYPOINT top, and the command will still be top.

You can also overwrite the ENTRYPOINT command by using the --entrypoint xxx follow the docker run command.

You can choose CMD or ENTRYPOINT according to your specific needs.

  • If you want to create an image with default behavior, and allow users to override the default behavior, you can use CMD.
  • If you want to create an image that always executes a specific command, and allows users to pass parameters, you can use ENTRYPOINT.
  • At the same time, CMD and ENTRYPOINT can also be used together, in which case the parameters specified in CMD will be used as the default parameters for the command specified by ENTRYPOINT.

conclusion

  • shellmode: The main process(pid 1) is the /bin/sh process, which can resolve the environment variables.
  • execmode: The main process is the command you specify, and the environment variables will not be resolved.
  • If ENTRYPOINT uses shellmode, the default CMD instruction will be ignored.
  • If ENTRYPOINT uses execmode, the content specified in default CMD instruction will be appended as parameters for the command specified by ENTRYPOINT. If ENTRYPOINT uses execmode, the default CMD instruction should also use exec mode.
相关推荐
深色風信子13 分钟前
Docker newapi
运维·docker·容器·newapi
就叫飞六吧3 小时前
Docker Hub 上主流的nginx发行
java·nginx·docker
GL_Rain3 小时前
快速搭建Halo博客 + 崩溃秒恢复方案(Docker极简部署)
运维·docker·容器
无巧不成书02185 小时前
2026最新Next-AI-Draw-io全攻略:AI驱动专业图表生成,Docker/Node.js本地部署零踩坑指南
人工智能·docker·node.js·next-ai-draw-io
jingyu飞鸟6 小时前
Linux系统发送邮件,解决信誉等级低问题 docker compose修改启动一键使用
linux·运维·docker
杨浦老苏7 小时前
数据库备份管理工具DBackup
数据库·docker·备份·群晖
郝开9 小时前
Docker Compose 本地环境搭建:redis
redis·docker·容器
爱莉希雅&&&10 小时前
Ansible+Docker案例(含ansible配置安装docker)
linux·运维·mysql·nginx·docker·容器·ansible
郝开12 小时前
Docker Compose 本地环境搭建:独立 Compose + 共享网络 + .env 统一管理(架构设计篇)
网络·docker·容器
岳来12 小时前
docker 容器文件 hostconfig.json 和 config.v2.json 的区别
docker·容器·hostconfig.json·config.v2.json