Dockerfile制作镜像
一、Dockerfile常用指令
指令 | 释义 |
---|---|
FROM | 指定基础镜像,必须放在首行。(注意,scratch是保留字,并不是镜像!如果使用了该关键字表示不依赖于任何镜像) && 调用基础镜像触发器(ONBUILD)。 |
ONBUILD | 基础镜像触发器。当镜像用作另一个构建的基础时触发。后面可以跟其他的镜像指令运行,所以当我们基于他人镜像构建新镜像时为安全考虑应当特别注意基础镜像是否有不安全的ONBUILD指令。 |
MAINTAINER | 管理者(维护者)标识,用于声明作者的信息。(已弃用) |
LABEL | 为镜像打标签。基于KEY=VALUE方式打标签。 |
USER | 指定容器的运行用户,若不指定,默认为root用户,一些服务可能会用到,比如ES服务… |
RUN | 在容器中运行指令。 |
WORKDIR | 指定容器的工作目录,当用户连接到容器时,就默认在该目录,若不指定,则默认在"/"路径。 |
VOLUME | 对容器的指定路径生成随机存储卷。 |
COPY | 将宿主机的文件拷贝到容器中。如果容器目录不存在,则会自动创建。 |
ADD | 与COPY作用不同的是,它可以自动解压tar包文件并删除源文件。 |
ENV | 将变量传递给容器,容器运行时会有该变量。在容器启动或创建时可以使用-e,–env选项替换默认值。 |
ARG | 在编译阶段生效的变量。容器运行时不会存在该变量!在编译的时候可以使用"–build-arg"选项替换默认值。 |
EXPOSE | 暴露容器内端口,外部使用随机端口映射时,可以暴露此处定义的服务端口,通常建议暴露的端口和服务有关。用户启动容器时使用"-P"时会为容器暴露的端口自动做映射 |
CMD | 容器启动时执行的指令,我们在制作容器时,通常会在此处阻塞终端。 |
ENTRYPOINT | 同CMD,容器启动时执行的指令,但是此处可传入参数,启动指令可能因参数产生变化。 |
HEALTHCHECK | 容器健康检查。 |
SHELL | 调用系统命令的shell。这对Windows很有用,Linux无需使用,默认就是linux的shell。 |
相似指令区分
1️⃣ COPY和ADD: COPY用于将宿主机文件拷贝至容器,或者在多阶段构建时用于将上一构建阶段的文件拷贝至本阶段构建。ADD指令同样可用于拷贝文件,但是该指令可以自动解压tar包,并删除源文件。
2️⃣ ARG和ENV: ARG指令和ENV指令的作用域不同,ARG指令指定的便令仅在镜像构建时起作用,镜像构建完成生命周期即结束。ENV指令将环境变量 <key>
设置为值 <value>
将在构建阶段的所有后续指令的环境中,并且也可以在许多指令中内联替换。
3️⃣ CMD和ENTRYPOINT: CMD指令设置从镜像运行容器时固定要执行的命令。Dockerfile中只能有一条 CMD
指令。如果您列出多个 CMD
,则只有最后一个生效。如果用户为 docker run
指定参数,那么他们将覆盖 CMD
中指定的默认值。ENTRYPOINT指令设置从镜像运行容器时要执行的命令,但用户可以为该指令传递参数,若CMD指令和ENTRYPOINT指令同时使用则CMD指令将作为ENTRYPOINT指令的参数传递。
二、Dockerfile制作镜像
1️⃣ 创建Dockerfile文件。 根据个人习惯而言,一般为了文件的可读性,我们需要先创建一个空目录,并在目录下创建Dockerfile文件,(约定俗成我们一般就以Dockerfile为名,编译时也会自动寻找这个文件,也可自定义文件名,但是我们在编译文件时需用 -f
指定需编译文件的绝对路径,自定义文件名语义混乱容易导致文件错落,不建议!)
2️⃣ 准备制作镜像的资源文件。(我们制作镜像需要的压缩包、源码文件、配置文件等等)
3️⃣ 编写Dockerfile文件。(以alpine为基础镜像打包制作游戏镜像为例)
1 | [root@nanxi ~/nanxi]# tree -L 1 |
4️⃣ 编译Dockerfile文件生成镜像
使用docker build -t <镜像名>:<版本号> .
编译文件生成镜像,或使用shell脚本调用docker命令进行编译
5️⃣ 启动一个容器并测试访问。
1 | [root@nanxi ~/nanxi/01-nanxi-game]# docker run -dP nanxi_game:v1.0 |
三、Dockerfile优化思路
1、从编译速度上说
① 指定的基础镜像建议是本地存在的或者是国内的镜像;② 将下载源修改为国内的软件源;③ 尽量利用Dockerfile构建的镜像缓存技术(将不经常修改的指令往前放,如:FROM 、MAINTAINER、LABEL、EXPOSE、WORKDIR、VOLUME… 将经常修改的指令往后放,如:RUN、COPY、ADD、CMD、ENTRYPOINT…)④ 使用".dockerignore",忽略我们不需要参与编译的文件(如不忽略,则编译前会当前文件夹所有文件传递给docker deamon进程,但我们真正编译时用不到这些与制作镜像不相关的文件。)
2、从镜像体积上说
① 删除无用的缓存;②卸载无用的软件;③ 使用较小的基础镜像,比如将centos基础环境改为Ubuntu或者alpine镜像。