【Docker】专题三:Dockerfile 相关

以下内容均来自个人笔记并重新梳理,如有错误欢迎指正!如果对您有帮助,烦请点赞、关注、转发!欢迎扫码关注个人公众号!

公众号二维码


一、相关概念

1、Dockerfile

Dockerfile 是一个文本文件,用于在执行 docker build 命令构建 Docker 镜像时,定义所需的基础镜像以及相关命令。

2、构建上下文

构建上下文是执行 docker build 命令时所在的目录。

默认情况下 Dockerfile 位于该目录,也可以使用 -f 参数来指定其他路径下 Dockerfile 文件。

一般来说,构建上下文应该创建一个空目录,并只放置 Dockerfile 以及构建镜像所需的文件。如果目录中存在多余的文件且不希望构建到镜像中,可以将其写入 .dockerignore 文件,构建镜像时会自动忽略。


二、常用指令

1、FROM

指定构建 Docker 镜像所使用的基础镜像,如 alpine:latest。

2、RUN

指定 docker build 时执行的命令。可以用 && 符号连接多条命令以精简镜像层数。

RUN apt-get update \
    && apt-get install -y wget \
    && rm -rf /var/lib/apt/lists/*

3、CMD

指定 docker run 启动容器时执行的默认命令。存在多个 CMD 时仅最后一个生效。

4、ENTRYPOINT

指定 docker run 启动容器时执行的主要命令。如 MySQL 官方镜像指定的启动入口:

ENTRYPOINT ["docker-entrypoint.sh"]

5、WORKDIR

指定容器中服务的工作目录,需要使用绝对路径。

6、COPY

将构建上下文中指定的文件、目录复制到镜像中。COPY 命令会增加镜像层数。

7、ADD

将构建上下文中指定的文件、目录、远程URL复制到镜像中,特定格式的压缩文件会直接解压到镜像目录。ADD 命令会增加镜像层数。

8、VOLUME

指定主机、容器之间的映射目录。


9、ENV

指定容器所需的环境变量,key=value 形式。


10、LABEL

指定容器所需的标签信息,key=value 形式。

11、EXPOSE

指定容器中服务的监听端口。


三、多阶段构建

多阶段构建是通过在一个 Dockerfile 中使用多个 FROM 语句来实现的。

每个 FROM 指令都可以使用不同的基础镜像,并表示开始一个新的构建阶段。

# 第一阶段:在 golang 镜像中编译go代码
FROM golang AS build-env     # 定义索引,用于被其他阶段引用

ADD /go/src/app
WORKDIR /go/src/app
RUN go get -u -v github.com/kardianos/govendor
RUN govendor sync
RUN GOOS=linux GOARCH=amd64 go build -v -o /go/src/app/app-server


# 第二阶段:在 alpine 镜像中直接引用第一阶段产生的二进制文件,并完成其他构建内容
FROM alpine

COPY --from=build-env /go/src/app/app-server /usr/local/bin/app-server
RUN apk add -U tzdata
RUN In -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
EXPOSE 8080
CMD "app-server"


四、反向解析 Dockerfile

笔者文章【Docker】MySQL 源码构建 Docker 镜像(基于 ARM 64 架构)中曾提到通过镜像获取 Dockerfile,本文再介绍几种通过镜像文件反向解析 Dockerfile 的方法。

1、dfimage 工具

alias dfimage="docker run --rm -v /var/run/docker.sock:/var/run/docker.sock alpine/dfimage"
dfimage -sV=1.36 nginx:latest

🔔 参数 -sV=1.36 用于指定客户端版本,若不指定,部分 docker 版本下可能报错:
Error response from daemon: client version 1.41 is too new. Maximum supported API version is 1.40
Use the -sV flag to change your client version

2、whaler 工具

alias whaler="docker run --rm -v /var/run/docker.sock:/var/run/docker.sock:ro pegleg/whaler"
whaler -sV=1.36 nginx:latest

3、dive 工具

相比上述两种工具,dive 可以获取更详细信息,如每一层文件增减等。

alias dive="docker run -ti --rm -v /var/run/docker.sock:/var/run/docker.sock wagoodman/dive"
dive nginx:latest


五、构建多架构镜像

当我们使用 AMD64 架构的镜像在 ARM64 架构的服务器上运行时会出现报错: standard_init_linux.go:211: exec user process caused "exec format error",原因就是镜像与服务器架构不一致。这就需要考虑构建镜像时生成支持多种架构的镜像。本文介绍两种构建多架构镜像的方法。

1、docker manifest 方法

# 第一步:构建不同架构镜像
docker build --pull --platform=linux/amd64 -f Dockerfile -t demo:v1-amd64 .
docker build --pull --platform=linux/arm64 -f Dockerfile -t demo:v1-arm64 .

🔔 若出现报错:failed to solve with frontend dockerfile.v0: failed to create LLB > definition: unexpected status code [manifests 3.17]: 403 Forbidden
请修改 /etc/docker/daemon.json 文件,添加:
"features": {"buildkit": false}


# 第二步:推送至镜像仓库
docker push demo:v1-amd64
docker push demo:v1-arm64


# 第三步:创建 manifest list
docker manifest create demo:v1 --amend demo:v1-amd64 --amend demo:v1-arm64
docker manifest inspect demo:v1
docker manifest push demo:v1

2、docker-buildx 方法

# 下载安装 docker-buildx
wget https://github.com/docker/buildx/releases/download/v0.13.1/buildx-v0.13.1.linux-amd64
mv buildx-v0.13.1.linux-amd64 /usr/bin/docker-buildx
chmod +x /usr/bin/docker-buildx


# 查看 docker-buildx 实例列表
docker-buildx ls
NAME/NODE     DRIVER/ENDPOINT    STATUS    BUILDKIT   PLATFORMS
default*      docker                        
 \_ default    \_ default        running   v0.9.3     linux/amd64, linux/386


# 构建镜像
export DOCKER_CLI_EXPERIMENTAL=enabled
docker-buildx build --platform linux/amd64,linux/arm64 --push -t demo:v1 -f Dockerfile .
🔔 --push 参数:构建完成后推送至仓库


附录

Dockerfile 最佳实践

Dockerfile reference

官方仓库 Dockerfile 汇总

多架构镜像

  • 16
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值