Dockerfile的指令根据作用可分为:
1.构建指令:构建image,其指定操作不在运行image的容器上执行
|
FROM:指定基础image(必须指定且需在Dockerfile其他指令的前面。基础image可以是官方远程仓库中的,也可以位于本地仓库的tag版本。)
MAINTAINER:用来指定镜像创建者信息(docker inspect查看该信息。)
RUN:运行任何被基础image支持的命令(用于安装软件)
ENV:用于在image中设置环境变量(docker inspect查看此环境变量,也可通过docker run --env key=value时设置或修改环境变量)
ADD:从src(文件、目录、归档文件、URL等)复制文件到container的dest路径
COPY:只复制文件或者目录到容器里(ADD的一种简化版本)
ONBUILD:在子镜像中执行(在构建镜像时并不执行在子镜像中执行ONBUILD <Dockerfile关键字>
)
2.设置指令:设置image属性,其指定操作在运行image的容器中执行。
|
USER:设置启动容器的用户,默认是root用户
CMD:设置container启动时执行的操作(可执行自定义脚本,也可执行系统命令。只能在本文件中存在一次,多次执行仅最后一条有效)
ENTRYPOINT:设置container启动时执行的操作(多次设置仅最后一个有效)
EXPOSE:指定容器需要映射到宿主机器的端口(访问容器时,可不用容器IP地址而是用宿主机IP地址和映射后端口)
VOLUME:指定挂载点(使容器中的一个目录具有持久化存储数据的功能,该目录可以被容器本身使用,也可以共享给其他容器使用)
WORKDIR:切换目录(可以多次切换相当于cd命令,对RUN,CMD,ENTRYPOINT生效,如:WORKDIR /p1 WORKDIR p2 RUN vim a.txt # 在 /p1/p2 下执行 vim a.txt
)
另外:
1.Dockerfile的指令忽略大小写,建议使用大写
2.使用 # 作为注释,每一行只支持一条指令,每条指令可以携带多个参数
3.ENTRYPOINT指令的使用分为两种情况,若还使用CMD要注意:
①独自使用。若CMD是一个完整的可执行的命令,那么CMD和ENTRYPOINT会互相覆盖只有最后一个CMD或者ENTRYPOINT有效。
CMD echo “Hello, World!”
ENTRYPOINT ls -l
#以上CMD不执行
②和CMD指令配合使用。若CMD指令不是一个完整的可执行命令,仅仅是参数部分;ENTRYPOINT指令只能使用JSON方式指定执行命令,而不能指定参数
FROM ubuntu
CMD ["-l"]
ENTRYPOINT ["/usr/bin/ls"]
4.EXPOSE的完成整个操作要两步:
①在Dockerfile使用EXPOSE设置需要映射的容器端口;
②在运行容器时,指定 -p及EXPOSE设置的端口。
这样EXPOSE设置的端口号会被随机映射成宿主机器中的一个端口号。EXPOSE指令可以一次设置多个端口号,相应的运行容器的时候,可以配套的多次使用-p选项。对于一个已运行的容器,可使用docker port及EXPOSE设置的端口及容器ID来查看该端口号在宿主机器上的映射端口。
#映射多个端口
EXPOSE port1 port2 port3
# 相应的运行容器使用的命令
docker run -p port1 -p port2 -p port3 imageb
# 还可以指定需要映射到宿主机器上的某个端口号
docker run -p host_port1:port1 -p host_port2:port2 -p host_port3:port3 image
端口映射是docker比较重要的一个功能,原因在于我们每次运行容器的时候容器的IP地址不能指定而是在桥接网卡的地址范围内随机生成的。但宿主机器的IP地址是固定的,我们可以将容器的端口的映射到宿主机器上的一个端口,免去每次访问容器中的某个服务时都要查看容器的IP的地址。
5.ENV设置之后,后续的RUN命令都可以使用
# 假如你安装了JAVA程序,需要设置JAVA_HOME,那么可以在Dockerfile中这样写:
ENV JAVA_HOME /path/to/java/dirent
6.ADD <src> <dest>
<src>——相对被构建的源目录的相对路径,可以是文件或目录的路径,也可以是一个远程的文件url;
<dest>——container中的绝对路径
①所有拷贝到container中的文件和文件夹权限为0755,uid和gid为0;
②如果<src>是一个目录,那么会将该目录下的所有文件添加到container中,不包括目录;
③如果<src>是文件且<dest>中不使用斜杠结束,则会将<dest>视为文件,<src>的内容会写入<dest>;如果<src>是文件且<dest>中使用斜杠结束,则会<src>文件拷贝到<dest>目录下
④如果文件是可识别的压缩格式,则docker会帮忙解压缩(注意压缩格式)
7.VOLUME
使容器中的一个目录具有持久化存储数据的功能,该目录可以被容器本身使用,也可以共享给其他容器使用。容器使用的是AUFS,这种文件系统不能持久化数据,当容器关闭后,所有的更改都会丢失。当容器中的应用有持久化数据的需求时可以在Dockerfile中使用该指令。
8.ONBUILD(参考:dockerfile之ONBUILD指令)
dockerfileA中有ONBUILD指令
通过dockerfileA构建出imageA镜像,dockerfileA中的ONBUILD并不会对imageA产生任何影响;
编写一个dockerfileB文件,以dockerfileA构建的imageA镜像作为基础镜像。那么通过dockerfileB构建镜像imageB时,dockerfileA中的ONBUILD指令生效了:首先先执行dockerfileA中的ONBUILD指令,才会执行dockerfileB中的指令;
编写一个dockerfileC文件,以dockerfileB构建的imageB镜像为基础镜像。那么通过dockerfileC构建镜像imageC时,dockerfileA中的ONBUILD指令不再生效,因为在构建imageB时已经执行过一次了。
9.其他
使用Docker容器的十大误区
Best practices for writing Dockerfiles