Dockerfile构建镜像比commit语句更简洁直观易于维护.
一 基本步骤为:
1. 新建一个文件夹,创建一个文件, 名字为Dockerfile
2. 编写Dockerfile
3. 利用build语句构建镜像
$ docker build -t="仓库名/镜像名:标签" 文件所在路径
4. run运行容器或push推送到远程repo.
Dockerfile构建镜像是从上到下进行的,每执行一条语句就会创建一个临时镜像,并将前面创建的临时镜像删除. 如果在某一步出错了, 并不会失去所有的镜像,而是保留最后一次执行成功的镜像. 这对调试非常有帮助, 可以运行并进入查看是什么原因导致无法执行下一条语句.
二 Dockerfile指令
1. CMD 用于指定要一个容器启动时要运行的命令. 这有点类似于RUN指令,只是RUN指令是指定镜像被构建时要运行的命令,而 CMD是指定容器被启动时要运行的命令.
CMD命令与运行docker容器时指定的命令是等效的,以下两个命令的效果时相同.
sudo docker run -i -t jamtur01/static_web /bin/true
CMD ["/bin/true"]
CMD 一般用数组形式, 设定参数:
CMD ["/bin/bash", "-l"]
注意,docker run 命令会覆盖CMD中的命令.
并且, CMD只能设置一句,设置多句只会执行最后一条.
2. ENTRYPOINT
ENTRYPOINT指令与CMD指令非常类似,也很容易和CMD指令弄混. CMD指令会被docker run 覆盖, 而ENTRYPOINT指令则会与docker run的指令拼接在一起, 或者说, docker run中的指令会成为ENTRYPOINT的参数,添加在ENTRYPOINT数组后面.
常用的一个用法是,讲ENTRYPOINT 和CMD结合起来使用, 可以达到默认启动并且和动态改变的效果:
ENTRYPOINT ["/usr/sbin/nginx"]
CMD ["-h"]
此时当我们启动容器, 任何命令行中的参数都会传递给ENTRYPOINT, 比如docker run -t -i 镜像名 -g "daemon off" , 这时,在启动容器时就会执行 /usr/sbin/nginx -g "daemon off" 命令. 这时CMD命令被覆盖了. 而当docker run没有传递参数时,则会使用CMD命令, 这时将会执行 /usr/sbin/nginx -h 命令.
3. WORKDIR
WORKDIR指令用来在从镜像创建一个新容器时,在容器内部设置一个工作目录, ENTRYPOINT和/或CMD所指定的程序会在这个目录下执行.
docker run -w会覆盖工作目录
4. ENV 用来设置环境变量.
docker run -e也能添加环境变量,并不覆盖.
5. USER 用来指定该镜像会以什么样的用户取运行. 有多种用法:
USER user
USER user:group
USER uid
USER uid:git
USER user:gid
USER uid:group
docker run -u 可覆盖
6 VOLUME 向容器添加卷,用于数据共享和数据持久化
卷可以在容器间共享和重用
一个容器可以不是必须和其他容器共享卷
对卷的修改是立时生效的
对卷的修改不会对更新镜像产生影响
卷会一直存在知道没有容器再使用它
例如 VOLUME ["/opt/porject"] 这条指令会为基于此镜像创建的任何容器创建一个名为/opt/project的挂载点. 这样, 容器内嵌docker的/opt/project 目录将保存在宿主机系统的/opt/project/volumes目录的某个位置.
通过数组可指定多个卷.
7. ADD 用来将指定目录上的文件和目录复制到镜像中, 通常用来部署环境.
若不加路径,则默认为Dockerfile文件所在目录. 还可以用url作为文件源
ADD http://wordpress.org/latest.zip /root/wordpress.zip
另外, ADD指令还可以自动解压,如:
ADD latest.tar.gz /var/www/wordpress/
会自动解压到/var/www/wordpress/目录下
8. COPY 和ADD一样,只是不做自动解压的工作.
COPY指令只允许复制当前环境目录(即Dockerfile文件所在目录)下的文件,不能复制该目录以外的任何文件.因为复制实在守护进程中进行的,而任何位于构建环境之外的东西都是不可用的. 而且COPY指令的目的位置则必须是容器内部的一个绝对路径.
9. ONBUILD 该指令能为镜像添加触发器.
当一个镜像被用做其他镜像的基础镜像时,触发器将被执行. 触发器可以添加任何构建指令.
如果在Dockerfile1中写入了 ONBUILD ADD . /app/src 这条指令
创建镜像之后, 又在Dockerfile2 中的from 引用了该镜像,则在用Dockerfile2创建镜像时,将会首先执行 ADD . /app/src这条指令.