?? 在 Dockerfile 中定义了很多关键字, 通过关键字来完成 Dockerfile 的编写.
??Dockerfile 官方文档 https://docs.docker.com/engine/reference/builder/
9.1 FROM
?? 在 Dockerfile 中 FROM 主要是指定这个 Dockerfile 基于哪一个 base image 构建. Docker Dockerfile 按顺序运行指令. 一个 Dockerfile 必须用 FROM 指令启动, 放在第一行.
- FROM scratch # 制作 base image
- FROM CentOS # 使用 base image
- FROM Ubuntu:14.04 # 使用指定版本的 base image
安全起见, 尽量使用官方的 image 作为 base image.
9.2 LABEL
?? 在 Dockerfile 中 LABEL 实际上是英译了 Metadata, 就像是代码中的注释. 主要包含了该镜像的作者, 版本和描述信息.
- LABEL maintainer="staryjie@163.com"
- LABEL version="1.0"
- LABEL description="This is description"
Metadata 不可少!
9.3 RUN
?? 在 Dockerfile 中 RUN 用来运行命令, 其中命令必须是在第一行 FROM 中指定的 base image 所能运行的. 每运行一次 RUN, 构建的 image 都会生成新的一层 layer.
- RUN yum update && yum install -y VIM python-dev # 反斜杠换行
- RUN apt-get update && apt-get install -y perl pwgen --no-install-recommends && rm -rf /var/lib/apt/lists/* # 注意清理 cache
- RUN /bin/bash -C 'source $HOME/.bashrc;echo $HOME'
为了美观, 复杂的 RUN 可以使用反斜杠换行.
为了避免无用分层, 多条命令尽量合并一行.
9.4 WORKDIR
?? 在 Dockerfile 中 WORKDIR 用来设定当前工作目录, 类似 Linux 系统中的 cd 命令.
- WORKDIR /root
- WORKDIR /test # 如果没有该目录, 则会自动创建
- WORKDIR demo
- RUN pwd # 输出的结果应该是 / test/demo
用 WORKDIR, 不要使用 RUN cd !!!
为了避免出错, 尽量使用绝对路径.
9.4 ADD 和 COPY
?? 在 Dockerfile 中 ADD 和 COPY 作用相似, 都是把本地的文件添加到 docker image 中. 区别: ADD 不仅可以添加文件, 还可以解压缩文件, COPY 不可以解压缩文件.
- ADD hello /
- ADD test.tar.gz / # 添加到 image 的根目录并且解压
- WORKDIR /root
- ADD hello test/ # 将 hello 添加到 image 的 / root/test/hello
- WORKDIR /root
- COPY hello test/ # 跟上面的效果一样
大部分情况下 COPY 优于 ADD.
ADD 除了 COPY 还有额外功能 (解压).
添加远程文件 / 目录, 请使用 curl 或者 wget.
9.5 ENV
?? 在 Dockerfile 中 ENV 来设置环境变量或者一些常量. 可以在 ENV 设置的常量后面直接使用.
- ENV MYSQL_VERSION 5.6 # 设置常量
- RUN apt-get install -y MySQL-server="${MYSQL_VERSION}" && rm -rf /var/lib/apt/lists/* #引用常量
尽量使用 ENV 增加可维护性!
9.6 VOLUME
?? 在 Dockerfile 中 VOLUME 用于向基于镜像创建的容器添加卷, 一个卷可以存在于一个或多个容器的特定目录, 这个目录可以绕过联合文件系统, 并提供共享数据, 数据持久化的功能.
- VOLUME ["/data"]
- 9.7 EXPOSE
?? 在 Dockerfile 中 EXPOSE 设置容器暴露的端口, 可以指定一个或多个端口.
EXPOSE 80
虽然在 EXPOSE 指令中已经暴露了指定的端口, 但是在启动容器的时候还是要指定端口信息, 容器本身不会自动暴露端口.
9.8 CMD
?? 在 Dockerfile 中 CMD 设置容器启动后默认执行的命令和参数. 如果定义了多个 CMD, 只会执行最后一个.
- CMD ["executable","param1","param2"] # 执行形式, 这是首选形式
- CMD ["param1","param2"] # 作为进入点的默认参数
- CMD command param1 param2 # 壳形式
不要定义多个 CMD, 多个 CMD 只有最后一个会执行.
9.9 ENTRYPOINT
?? 在 Dockerfile 中 ENTRYPOINT 设置容器启动时运行的命令, 可以让容器以应用程序或者服务器的形式运行, 而且 ENTRYPOINT 设定的命令不会被忽略, 一定会执行.
- COPY docker-entrypoint.sh /usr/local/bin/
- ENTRYPOINT ["docker-entrypoint.sh"]
可以写一个 shell 脚本作为 ENTRYPOINT 的入口.
RUN,CMD,ENTRYPOINT 对比
RUN 执行命令并创建新的 image layer
CMD 设置容器启动后默认执行的命令和参数
ENTRYPOINT 设置容器启动时运行的命令
shell 格式和 exec 格式
shell 格式
- RUN apt-get install -y VIM
- CMD echo "hello docker"
- ENTRYPOINT echo "hello docker"
- ??Dockerfile
- FROM CentOS
- ENV name Docker
- ENTRYPOINT echo "hello $name"
?? 构建镜像:
docker build -t staryjie/CentOS-entrypoint-shell .
?? 运行容器:
- docker run staryjie/CentOS-entrypoint-shell
- hello Docker
exec 格式
- RUN ["apt-get","install","-y","vim"]
- CMD ["/bin/echo","hello docker"]
- ENTRYPOINT ["/bin/echo","hello docker"]
- ??Dockerfile
- FROM CentOS
- ENV name Docker
- ENTRYPOINT ["/bin/echo","hello $name"]
?? 构建镜像:
docker build -t staryjie/CentOS-entrypoint-exec .
?? 运行容器:
- docker run staryjie/CentOS-entrypoint-exec
- hello $name
?? 改写 Dockerfile
- FROM CentOS
- ENV name Docker
- ENTRYPOINT ["/bin/bash","-c","echo hello $name"]
?? 构建镜像:
docker build -t staryjie/CentOS-entrypoint-exec-new .
?? 运行容器:
- docker run staryjie/CentOS-entrypoint-exec-new
- hello Docker
- CMD
容器启动时默认执行的命令
如果 docker run 指定了其他命令, CMD 命令会被忽略
如果定义了多个 CMD, 只有最后一个会执行
ENTRYPOINT
让容器以应用程序或者服务的形式运行
不会被忽略, 一定会执行
来源: http://www.bubuko.com/infodetail-2923289.html