docker之Dockerfile散记(From,ARG)

283 阅读2分钟

本文会陆续更新Dockerfile的一些知识。

什么是Dockerfile?

Dockerfile可以理解为一个具备组装一个docker镜像的所有指令的文本文件。即docker可以通过Dockerfile来新建一个镜像(Image)。

Dockerfile中可使用的指令

注释

Dockerfile中通过#来写注释,如# 这是一行注释

大小写不敏感以及惯例

Dockerfile中是大小写不敏感的,即from指令相当于FROM指令。但惯例是指令为大写,参数为小写,如FROM nginx:1.24.0

ARG

ARG是唯一一个会出现在FROM指令前面的指令,并且其出现在第一个FROM指令之前,用来定义一些变量。其作用主要是用来接收构建时期命令行所传递过来的变量,如

ARG NGINX_VERSION=1.24.0
ARG OTHER_VARIABLE=variable
FROM nginx:${NGINX_VERSION}

这里当我们新建镜像的是时候就会以nginx:1.24.0为基础镜像。

但假如我们想在构建时期指定nginx版本。可以使用如下命令

image.png

此时NGINX_VERSION的值就变成了stable-alpine3.17-slim,如图

image.png

ARG定义的变量是处于构建阶段之外(即默认情况下,不能在FROM指令之外使用)。要在构建阶段内使用这些变量,需要使用不带值的ARG指令

ARG NGINX_VERSION=1.24.0
ARG OTHER_VARIABLE=variable
FROM nginx:${NGINX_VERSION}

ARG OTHER_VARIABLE
RUN echo $OTHER_VARIABLE > other_variable

的输出为

image.png

ARG NGINX_VERSION=1.24.0
ARG OTHER_VARIABLE=variable
FROM nginx:${NGINX_VERSION}

RUN echo $OTHER_VARIABLE > other_variable

的输出为

image.png

FROM

FROM指令用来指定一个新的构建阶段,语法如下

FROM [--platform=<platform>] <image> [AS <name>]
Or
FROM [--platform=<platform>] <image>[:<tag>] [AS <name>]
Or
FROM [--platform=<platform>] <image>[@<digest>] [AS <name>]

其中[]包裹的都为可选部分。<image>为镜像名。

  1. 如果省略tag,则tag默认为lastest

  2. AS为该构建阶段命名,一个Dockerfile允许有多个FROM指令来表示多个构建阶段,一个新的构建阶段会清除其他构建阶段的状态,我们可以通过“构建阶段名”为引用构建阶段的状态。

如下

  1. 我们为第一阶段命名为builder,意味着打包阶段,一般情况下打包都会产出一个名为dist的目录(这里指的是前端项目)。
  2. 在nginx构建阶段,我们想要复制该文件夹,需要在COPY指令的--from参数加上第一阶段的构建名。
FROM node:18.16.0 AS builder
WORKDIR /app
COPY . .
RUN npm run build

FROM NGINX:stable-alpine
COPY --from=builder /app/dist/. /etc/nginx/html/

COPY

COPY 用来复制docker构建上下文(一般指docker build的根路径)的文件到容器中,其语法如下

COPY [--chown=<user>:<group>] [--chmod=<perms>] <src>... <dest>
COPY [--chown=<user>:<group>] [--chmod=<perms>] ["<src>",... "<dest>"]

其中src为源文件路径,dest为容器中的目标文件路径。当文件或目录为相对路径时,相对的是docker构建上下文。

COPY例子

  1. 添加所有以hom开头的文件到容器的/mydir/目录 COPY hom* /mydir/
  2. 假如想要复制hom开头,并且第四个字母为任意字符的任意文件时,可以使用以下命令
COPY home? /mydir/

3. 目标文件路径除了可以指定绝对路径在nginx为以/开头的路径,也可以指定相对路径,相对路径为相对WORKDIR的路径,如

 COPY test.txt relativeDir/

WORKDIR

WORKDIR指令用来为出现在其后面的RUN,CMD,ENTRYPOINT,COPY,ADD指令指定工作目录,可以简单理解为为出现在其后的上述指令指定当前目录(如未指定过,默认值为linux系统的根目录/)。如果WORKDIR指定的目录不存在,甚至在后续没有指令用到该目录,系统也会自动创建该目录。如

image.png

ENV

可通过ENV指令添加环境变量。而可以通过$variable_name或者${variable_name}来获取定义的环境变量,两种获取变量的方式为等效的,如。

image.png

ENV指令允许同时添加多个,通过docker inspect可以查看某个镜像中环境变量的值,如

image.png

image.png

在运行该容器时,也可以通过docker run --env <key>=<value>选项进行修改

环境变量会存在于运行时期,因此可能造成一些意外的影响

如DEBIAN_FRONTEND=noninteractive变量会影响到apt-get的行为。因此涉及到可能会影响到操作系统的系统变量时候,可以使用RUN指令或者运行时变量ARG。如

image.png

RUN

RUN指令可以用来执行一些命令,并且会在当前的镜像中创建一个新的层,被添加的层会在Dockerfile的下一步被使用。简单来说可以使用RUN指令来执行一些构建阶段需要执行的脚本。

RUN语法

RUN指令可以通过两种exec格式或者shell格式运行(常用),如

  • RUN ["executable","param1","param2"] (exec form)
  • RUN command param1 param2 (shell form)

RUN执行可通过转义符或"heredocs"来实现一个RUN执行执行多行

image.png

其中 <<EOF EOF 格式即为"heredocs"格式

RUN指令允许在构建阶段挂载文件,其用法为

RUN --mount=[type=<TYPE>][,option=<value>[,option=<value>]...] 默认的type为bind。表示挂载到构建阶段的文件对构建容器来说是只读的。其选在有

  1. target

    绑定到容器的目标地址

  2. source

    源文件路径。默认是源镜像的根目录。

  3. from

    构建阶段或源的镜像名称。默认为构建上下文。

  4. rw/readwrite

    允许在挂载上进行写操作。写入的数据将被丢弃。

例子

RUN --mount=type=bind,source=./node_modules,target=./node_modules

表示将本地node_modules文件挂载到构建阶段当前工作路径(WORKDIR)的node_modules文件夹下

未完待续...