必会系列!使用Dockerfile构建镜像

3,449 阅读5分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

本文已参与「掘力星计划」,赢取创作大礼包,挑战创作激励金。

Dockerfile简介

Dockerfile是Docker中用来自动化构建镜像的配置文件,在Dockerfile中,包含了构建镜像过程中需要执行的命令、参数以及其他操作,并且支持以#开头的注释行。

Dockerfile结构大致分为四部分:

  • 基础镜像信息
  • 维护者信息
  • 镜像操作指令
  • 镜像启动时执行的命令

DockerFile构建过程

  • docker从基础镜像运行一个容器
  • 执行一条指令并对容器做修改 
  • 执行类似docker commit的操作提交一个新的镜像层
  • docker再基于刚提交的镜像运行一个新的容器
  • 执行dockerfile中的下一条指令直到所有指令都执行完成

Dockerfile构建过程是以基础镜像为基础的,每一条指令构建一层镜像,因此每一条指令的内容,就是描述该层应当如何构建。以此,有了Dockerfile,我们可以方便的定制自己额外的需求,只需在Dockerfile里添加或者修改指令,重新构建即可。

Dockerfile常用指令

FROM

FROM 指令用于指定指定基础镜像,其后构建新镜像以此为基础进行构建。FROM指令是Dockerfile文件中除注释命令之外的第一条指令,也是必备的指令。如果在同一个Dockerfile中创建多个镜像时,可以使用多个FROM指令(每个镜像一次)。

格式

FROM <image>
# 
FROM <image>:<tag>
# 
FROM <image>:<digest>

tag或digest是可选参数,如果不使用这两个值时,会使用latest版本的基础镜像。

例如,指定ubuntu的14.04版本作为基础镜像:

FROM ubuntu:14.04

MAINTAINET

格式
MAINTAINET

指定维护者的信息。

RUN

在镜像的构建过程中执行特定的命令(执行某些动作、安装系统软件、配置系统信息之类),并生成一个中间镜像。

格式

# shell格式
RUN <命令>
# exec格式
RUN ["可执行文件", "参数1", "参数2"]

注意:如果有多行命令尽量不要写多个RUN,因为Dockerfile中每一个指令都会构建一层,多少个RUN就构建了多少层镜像,会造成镜像的臃肿,还增加了构件部署的时间,可以使用换行符\

COPY

COPY命令用于将宿主机器上的的文件(Dockerfile所在目录的相对路径)复制到镜像内,如果目的位置不存在,Docker会自动创建。

格式

COPY <源路径>...<目标路径>
COPY ["<源路径1>",..."<目标路径>"]

例如,把宿主机中的test.json文件复制到容器中/usr/src/app/目录下:

COPY test.json /usr/src/app/

ADD

ADD指令的作用和COPY基本一致,但是在COPY基础上增加了一些功能,源路径可以是URL,也可以是 tar.gz。语法格式也和COPY一致。

ENV

设置环境变量

格式

ENV <key> <value>
# 
ENV <key1>=<value1> <key2>=<value2>...

例如:

ENV name=tigeriaf version=1.1.1

EXPOSE

为构建的镜像设置监听端口,使容器在运行时监听。

格式

EXPOSE <port1> [<port2>...]

例如:

EXPOSE 8080

EXPOSE 8080其实等价于docker run -p 8080,如果需要把8081端口映射到宿主机中的某个端口(如8088)以便外界访问时,则可以用docker run -p 8088:8080

WORKDIR

WORKDIR用于在容器内指定工作目录:

WORKDIR /test/

通过WORKDIR设置工作目录后,Dockerfile中其后的命令RUNCMDENTRYPOINT等命令都会在该目录下执行。

USER

USER用于指定运行镜像所使用的用户。

格式

USER root

使用USER指定用户后,Dockerfile中其后的命令RUNCMDENTRYPOINT都将使用该用户执行。

CMD

格式

CMD ["可执行文件", "参数1", "参数2"]

指定启动容器时执行的命令,每个Dockerfile只能有一条CMD指令,如果指定了多条指令,则最后一条生效。

其作用是在启动容器的时候提供一个默认的命令项,如果用户执行docker run时提供了命令项,这个命令就会覆盖掉。

VOLUME

格式

VOLUME ["/data"]

创建一个可以从本地主机或其他容器挂载的挂载点,一般用来存放数据库和需要保持的数据等。

ENTRYPOINT

容器启动后执行的命令,这些命令不能被docker run提供的参数覆盖。和CMD一样,每个Dockerfile中只能有一个ENTRYPOINT,如果指定了多条指令,则最后一条生效。 格式

ENTRYPOINT ["可执行文件", "参数1", "参数2"]

ONBUILD

ONBUILD用于配置当前所创建的镜像作为其它新创建镜像的基础镜像时,所执行的操作指令。 格式

ONBUILD [INSTRUCTION]

DockerFile实例

编写Dockerfile

构建MySQL镜像

FROM ubuntu:bionic-20190612

LABEL maintainer xxxx@xxxx.com

ENV MYSQL_USER=mysql \
    MYSQL_VERSION=5.7 \
    MYSQL_DATA_DIR=/var/lib/mysql \
    MYSQL_RUN_DIR=/run/mysqld \
    MYSQL_LOG_DIR=/var/log/mysql

RUN apt-get update \
 && DEBIAN_FRONTEND=noninteractive apt-get install -y mysql-server=${MYSQL_VERSION}* \
 && rm -rf ${MYSQL_DATA_DIR} \
 && rm -rf /var/lib/apt/lists/*

EXPOSE 3306/tcp

CMD ["/usr/bin/mysqld_safe"]

运行构建命令构建

docker build命令用于使用Dockerfile创建镜像。
格式

docker build [OPTIONS] PATH | URL | -

常用OPTION如下:

  • --build-arg=[]:设置镜像创建时的变量
  • -f:指定要使用的Dockerfile路径
  • -m:设置内存最大值
  • --force-rm:设置镜像过程中删除中间容器
  • --rm:设置镜像成功后删除中间容器
  • --tag, -t:镜像的名字及标签,通常 name:tag 或者 name 格式

原创不易,如果小伙伴们觉得有帮助,麻烦点个赞再走呗~

最后,感谢女朋友在工作和生活中的包容、理解与支持 !