FROM
为了安全,尽量使用官方(official)的image作为base image!
#制作base image
FROM scratch
#使用base image
FROM centos FROM ubuntu:14.04
LABEL
包含作者、版本、描述,Metadata不可少,相当于代码注释!
LABEL maintainer="Phantom3389@qq.com" LABEL version="1.0" LABEL description="This is description"
RUN
运行命令,安装软件,每次RUN对于image都会生成新的一层
为了美观,复杂的RUN请用反斜线换行!
避免无用分层,合并多条命令成一行!
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/* RUN /bin/bash -c 'source $HOME/.bashrc;echo $HOME'
WORKDIR
设定当前工作目录或者创建目录
用WORKDIR ,不要用RUN cd!
尽量使用绝对目录!
WORKDIR /root WORKDIR /test #如果没有会自动创建test目录 WORKDIR demo RUN pwd #输出结果应该是 /test/demo
ADD or COPY
大部分情况,COPY优于ADD!
ADD除了COPY还有额外功能(解压)!
添加远程文件/目录请使用Curl或者wget!
ADD hello / ADD test.tar.gz / #添加到根目录并解压 WORKDIR /root ADD hello test/ #/root/test/hello WORKDIR /root COPY hello test/
ENV
设置环境变量、常量
ENV MYSQL_VERSION 5.6 #设置常量 RUN apt-get install -y mysql-server= "${MYSQL_VERSION}" && rm -rf /var/lib/apt/lists/* #引用常量
VOLUME and EXPOSE
存储和网络
RUN vs CMD vs ENTRYPOINT
RUN:执行命令并创建新的image Layer
CMD:设置容器启动后默认执行的命令和参数
- 容器启动时默认执行的命令
- 如果docker run指定了其他命令,CMD命令会被忽略
- 如果定义了多个CMD,只有最后一个会执行
ENTRYPOINT:设置容器启动时运行的命令
- 让容器以应用程序或者服务的形式运行
- 不会被忽略,一定会执行
- 最佳实践:写一个shell脚本作为ENTRYPOINT
COPY docker-entrypoint.sh /usr/local/bin ENTRYPOINT ['docker-entrypoint.sh'] EXPOSE 27017 CMD["mongod"]
Shell格式 vs EXEC格式
- Shell格式
RUN apt-get install -y vim CMD echo "hello docker" ENTRYPOINT echo "hello docker"
- EXEC格式
RUN ["apt-get", "install", "-y", "vim"] CMD ["/bin/echo", "hello docker"] ENTRYPOINT ["/bin/echo", "hello docker"]