在之前的几个笔记中我们所做的都是拉取镜像,然后进行配置,将配置映射到容器内这么些操作,然而有些满足自己项目需求的环境还是需要自己进行定制化的构建,需要用到dockerfile,本来是想跳过这个继续往后学的,但是后面要作一个支持flask的python镜像,还需要预装一些自己需要的模块,所以必须要先走一遍dockerfile了,下面我们看看dockerfile,教程基本是百度的,但是自己实践了一遍并且将一些说明自己梳理了一番
Dockerfile是一个包含用于组合映像的命令的文本文档。可以使用在命令行中调用任何命令。 Docker通过读取Dockerfile中的指令自动生成映像。
docker build命令用于从Dockerfile构建映像。可以在docker build命令中使用-f标志指向文件系统中任何位置的Dockerfile
docker build [OPTIONS] PATH | URL | -
构建基础镜像有如何下参数
OPTIONS说明: --build-arg=[] :设置镜像创建时的变量; --cpu-shares :设置 cpu 使用权重; --cpu-period :限制 CPU CFS周期; --cpu-quota :限制 CPU CFS配额; --cpuset-cpus :指定使用的CPU id; --cpuset-mems :指定使用的内存 id; --disable-content-trust :忽略校验,默认开启; -f :指定要使用的Dockerfile路径; --force-rm :设置镜像过程中删除中间容器; --isolation :使用容器隔离技术; --label=[] :设置镜像使用的元数据; -m :设置内存最大值; --memory-swap :设置Swap的最大值为内存+swap,"-1"表示不限swap; --no-cache :创建镜像的过程不使用缓存; --pull :尝试去更新镜像的新版本; --quiet, -q :安静模式,成功后只输出镜像 ID; --rm :设置镜像成功后删除中间容器; --shm-size :设置/dev/shm的大小,默认值是64M; --ulimit :Ulimit配置。 --squash :将 Dockerfile 中所有的操作压缩为一层。 --tag, -t: 镜像的名字及标签,通常 name:tag 或者 name 格式;可以在一次构建中为一个镜像设置多个标签。 --network: 默认 default。在构建期间设置RUN指令的网络模式
Dockerfile的基本结构
Dockerfile 一般分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令,’#’ 为 Dockerfile 中的注释
Dockerfile文件说明
Docker以从上到下的顺序运行Dockerfile的指令。为了指定基本映像,第一条指令必须是FROM。一个声明以#字符开头则被视为注释。可以在Docker文件中使用RUN,CMD,FROM,EXPOSE,ENV等指令
FROM:指定基础镜像,必须为第一个命令
FROM <image>|<image>:<tag>|<image>@<digest> FROM mysql:5.7.28
注意:tag或digest是可选的,如果不使用这两个值时,会使用latest版本的基础镜像
MAINTAINER: 维护者信息
MAINTAINER <name> MAINTAINER sukki
RUN:构建镜像时执行的命令,可以使用shell命令或者exec(可以执行文件)
RUN <shell command>|["exec", "param1", "param2",...]
shell示例
RUN yum install wget -y && wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" && tar -xvf redis.tar.gz
exec示例
RUN ["/opt/test.py", "sukki", "35"]
注意:RUN指令创建的中间镜像会被缓存,并会在下次构建中使用。如果不想使用这些缓存镜像,可以在构建时指定--no-cache参数,如:docker build --no-cache
COPY:复制指令,从上下文目录中复制文件或者目录到容器里指定路径
COPY [--chown=<user>:<group>] <src>... <dest> COPY /data/www/* /var/www/html/ #将/data/www/下所有的文件复制到容器中的/var/www/html/目录下
ADD:将本地文件添加到容器中,tar类型文件会自动解压(网络压缩资源不会被解压),可以访问网络资源,类似wget
ADD <src>... <dest>
同COPY命令,只是没有改变文件所属用户组和用户的操作
CMD:构建容器后调用,也就是在容器启动时才进行调用
CMD <shell command>|["exec", "param1", "param2",...] CMD command param1 param2 #或者 CMD ["/opt/test.py", "sukki", "35"]
ENTRYPOINT:类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序
ENTRYPOINT ["<executeable>","<param1>","<param2>",...]
可以搭配 CMD 命令使用:一般是变参才会使用 CMD ,这里的 CMD 等于是在给 ENTRYPOINT 传参,以下示例会提到。
示例:
假设已通过 Dockerfile 构建了 nginx:test 镜像:
FROM nginx ENTRYPOINT ["nginx", "-c"] # 定参 CMD ["/etc/nginx/nginx.conf"] # 变参
1、不传参运行
docker run nginx:test
容器内会默认运行以下命令,启动主进程。
nginx -c /etc/nginx/nginx.conf
2、传参运行
docker run nginx:test -c /etc/nginx/new.conf
容器内会默认运行以下命令,启动主进程(/etc/nginx/new.conf:假设容器内已有此文件)
nginx -c /etc/nginx/new.conf
LABEL:用于为镜像添加元数据
LABEL <key>=<value> <key>=<value> <key>=<value> LABEL version="1.0" description="test dockerfile"
ENV:设置环境变量,在后续的指令中,就可以使用这个环境变量
ENV <key> <value>|<key>=<value> ... ENV python_version 3 RUN python$python_version test.py
EXPOSE:声明外界交互的端口,帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射
EXPOSE <端口1> [<端口2>...] EXPOSE 80 443
注意:EXPOSE并不会让容器的端口访问到主机。要使其可访问,需要在docker run运行容器时通过-p来发布这些端口,或通过-P参数来发布EXPOSE导出的所有端口
VOLUME:定义匿名数据卷,在启动容器时忘记挂载数据卷,会自动挂载到匿名卷,避免重要的数据
VOLUME <路径>|["<路径1>", "<路径2>"...] VOLUME ["/data"] VOLUME ["/var/www","/data/mysql",...]
注意:在启动容器 docker run 的时候,我们可以通过 -v 参数修改挂载点
WORKDIR:工作目录,类似于cd命令
WORKDIR <工作目录路径> WORKDIR /data #这时工作目录为/data WORKDIR work #这时工作目录为/data/work
注意:用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在。(WORKDIR 指定的工作目录,必须是提前创建好的),docker build 构建镜像过程中的,每一个 RUN 命令都是新建的一层。只有通过 WORKDIR 创建的目录才会一直存在
USER:用于指定执行后续命令的用户和用户组,这边只是切换后续命令执行的用户(用户和用户组必须提前已经存在)
USER <用户名>[:<用户组>] USER mysql USER mysql:group
注意:使用USER指定用户后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT都将使用该用户。镜像构建完成后,通过docker run运行容器时,可以通过-u参数来覆盖所指定的用户
ARG:构建参数,与 ENV 作用一至。不过作用域不一样。ARG 设置的环境变量仅对 Dockerfile 内有效,也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量
ARG <参数名>[=<默认值>] ARG site ARG build_user=www
ONBUILD:用于延迟构建命令的执行。简单的说,就是 Dockerfile 里用 ONBUILD 指定的命令,在本次构建镜像的过程中不会执行(假设镜像为 test-build)。当有新的 Dockerfile 使用了之前构建的镜像 FROM test-build ,这时执行新镜像的 Dockerfile 构建时候,会执行 test-build 的 Dockerfile 里的 ONBUILD 指定的命令
ONBUILD <其它指令>
后面我们来构建一个我常用的flask框架的镜像,然后预装一些我提前需要的模块