什么是 Dockerfile?
Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
指令详解
点击参考:使用 Dockerfile 定制镜像
注意事项
-
RUN (docker镜像越来越大的原因之一)
RUN <命令行命令> # <命令行命令> 等同于,在终端操作的 shell 命令。
注意: Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大。例如:
FROM centos RUN yum install wget RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" RUN tar -xvf redis.tar.gz 以上执行会创建 3 层镜像。可简化为以下格式: FROM centos RUN yum install wget \ && wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \ && tar -xvf redis.tar.gz
如上,以 && 符号连接命令,这样执行后,只会创建 1 层镜像。
-
CMD
作用:为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。
注意:如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。
格式:
CMD <shell 命令>
CMD ["<可执行文件或命令>","","",…]
CMD ["","",…] # 该写法是为 ENTRYPOINT 指令指定的程序提供默认参数推荐使用第二种格式,执行过程比较明确。第一种格式实际上在运行的过程中也会自动转换成第二种格式运行,并且默认可执行文件是 sh。
-
ENTRYPOINT
类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。
但是, 如果运行 docker run 时使用了 --entrypoint 选项,此选项的参数可当作要运行的程序覆盖 ENTRYPOINT 指令指定的程序。
优点:在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。
注意:如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。
格式:
ENTRYPOINT ["","","",…]
可以搭配 CMD 命令使用:一般是变参才会使用 CMD ,这里的 CMD 等于是在给 ENTRYPOINT 传参。
示例:
假设已通过 Dockerfile 构建了 nginx:test 镜像:
FROM nginx
ENTRYPOINT [“nginx”, “-c”] # 定参
CMD ["/etc/nginx/nginx.conf"] # 变参1、不传参运行
docker run nginx:test
容器内会默认运行以下命令,启动主进程。
nginx -c /etc/nginx/nginx.conf
2、传参运行
docker run nginx:test -c /etc/nginx/new.conf
容器内会默认运行以下命令,启动主进程(/etc/nginx/new.conf:假设容器内已有此文件)
nginx -c /etc/nginx/new.conf
-
FROM
多个FROM声明
尝试使用多个FROM声明来将不同的镜像组合到一起,这样不会起任何作用。Docker仅使用最后一个FROM并且忽略前面所有的。所以如果你有这样的Dockerfile:
# !!! ANTIPATTERN !!! FROM node:6.2.1 FROM python:3.5 CMD ["sleep", "infinity"] # !!! ANTIPATTERN !!!
那么docker exec进入运行的容器中,会得到下面的结果:
$ docker exec -it d86fcf0775d3 bash root@d86fcf0775d3:/# which python /usr/local/bin/python root@d86fcf0775d3:/# which node root@d86fcf0775d3:/#
这其实是GitHub上的一个问题:合并不同的镜像,但它看起来不会很快就增加的功能。
dockerfile常见错误
-
COPY时提示no such file or directory
例如如下错误信息:
COPY failed: stat /var/lib/docker/..... no such file or directory
可能的原因:
文件不存在 文件路径写法错误
docker镜像打包的COPY 指令将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 <目标路径> 位置。
实际操作中正确的方式和错误的方式参考如下:
正确:COPY ./package.json /app/ COPY package.json /usr/src/app/
错误:
COPY ../package.json /app 或者 COPY /opt/xxxx /app
-
Permission denied问题
执行
RUN chmod +x configure
时报错
chmod: cannot access 'configure': Permission denied
提升权限即可,如数据/程序在‘/home/’
RUN chmod 777 /home/