以下内容均来自个人笔记并重新梳理,如有错误欢迎指正!
如果对您有帮助,烦请点赞、关注、转发!如果您有其他想要了解的,欢迎私信联系我~
相关概念
1、登录镜像仓库
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 参数:构建完成后推送至仓库