Dockerfile 关键字和最佳实践
1. FROM
尽量使用官方的 image作为base image
e.g.,
FROM scratch
FROM centos:7
2. LABEL
定义了 image 中的 metadata
e.g.,
LABEL maintainer=“xiaowu@gmail.com”
LABEL version=“1.0.0”
LABEL description=“This is xxx”
3. RUN
每次运行一次 RUN 对于 image 都会生成新的一层,为了避免无用分层,合并多条命令成一行。
e.g.,
RUN yum update && yum install -y htop \
iotop
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 ~/.bashrc; echo
$HOME’
4. WORKDIR
- 用 WORKDIR 来替换 RUN cd
- 尽量使用绝对路径。
e.g.,
WORKDIR /root
WORKDIR /test #如果目录不存在会自动创建
WORKDIR demo
RUN pwd #输出结果应该是 /test/demo
5. ADD and COPY
- 大部分情况,COPY 优于 ADD
- ADD 不光可以将文件复制,还能解压缩
- 添加远程文件/目录应该使用 RUN curl 或 wget
e.g.,
ADD app /
ADD archive.tar.gz /
WORKDIR /root
ADD app test/ #/root/test/app
WORKDIR /root
COPY app /test
6. ENV
尽量使用,增加可维护性
e.g.,
ENV MYSQL_VERSION 5.6
RUN apt-get install -y mysql-server="${MYSQL_VERSION}" \
&& rm -rf /var/lib/apt/lists/*
7. VOLUME
8. EXPOSE
9. CMD and ENTRYPOINT
都是设置容器启动后执行的命令
9.1. 编写格式
- Shell 格式:
RUN yum install -y htop
CMD echo “hello docker”
ENTRYPOINT echo “hello docker”
- Exec 格式:
RUN [“yum”, “install”, “-y”, “htop”]
CMD ["/bin/echo", “hello docker”]
ENTRYPOINT ["/bin/echo", “hello docker”]
9.2. CMD 详解
- 容器启动时默认执行的命令
- CMD 指令可被 run 命令指定要运行的程序所覆盖
FROM entos
ENV name Docker
CMD echo “hello $name”
如果执行 dockers run -it xxx /bin/bash,则hello Docker
不会输出。
- 如果定义了多个CMD,只有最后一个CMD会生效
9.3. ENTRYPOINT 详解
- 让容器以应用程序或服务的形式运行
- 不会被忽略,一定会执行
一般会一个shell脚本作为entrypoint
… …
COPY docker-entrypoint.sh /usr/local/bin/
ENTRYPOINT [“docker-entrypoint.sh”]EXPOSE 27017
CMD [“mongod”]
… …
9.2. 区别
9.2.1. RUN 和 CMD
RUN 运行的时间点不同在 build 阶段,CMD 在 docker run 时运行
区别:
FROM centos
ENV name Docker
ENTRYPOINT echo “hello $name”
容器build后运行会打印出 hello Docker
FROM centos
ENV name Docker
ENTRYPOINT ["/bin/echo", “hello $name”]
打印出 hello $name
如果想打印出 hello Docker
,需要使用以下方式
ENTRYPOINT ["/bin/bash", “-c”, “echo hello $name”]
官方的 Dockerfile 案例:
参考文档: