Docker之Dockerfile

Docker之Dockerfile

  • [1 参考](#1 参考)
  • [2 Dockerfile讲解](#2 Dockerfile讲解)
    • [2.1 多个FROM](#2.1 多个FROM)
    • [2.2 COPY --from](#2.2 COPY --from)
    • [2.3 ARG指令](#2.3 ARG指令)
  • [3 Dockerfile示例](#3 Dockerfile示例)

1 参考

  1. dockerfile 多FROM
  2. dockerfile中多个FROM指令的意义(multistage)

2 Dockerfile讲解

2.1 多个FROM

  • Docker 17.05版本以后,新增了Dockerfile多阶段构建(multi-stage build)。所谓多阶段构建,实际上是允许一个Dockerfile 中出现多个 FROM 指令。
  • 使用多FROM指令可以完成多阶段编译。每一条 FROM 指令都是一个构建阶段,多条 FROM 就是多阶段构建,虽然最后生成的镜像只能是最后一个阶段的结果,但是,能够将前置阶段中产生的文件拷贝到后边的阶段中,这就是多阶段构建的最大意义。
  • 最大的使用场景是将编译环境和运行环境分离。

比如,之前我们需要构建一个Go语言程序,那么就需要用到go命令等编译环境,但是编译出来的镜像可能非常大,最终要用的只是一个可执行程序以及它运行时依赖的动态库,不需要编译工具以及编译时依赖的第三方库的源代码。
有了多FROM指令后,可以这样实现这个过程:在基础镜像上安装编译工具->下载第三方库源代码->编译安装第三方库->编译自己的模块代码->将编译好的可执行文件拷贝到新的镜像中->将运行时依赖的动态库拷贝到新镜像中->修改新镜像中的环境变量,使之指向运行时依赖库的位置。

2.2 COPY --from

Dockerfile的玄妙之处就在于COPY指令的--from=0参数,从前一阶段中拷贝文件到当前阶段中,多个FROM语句时,0代表第一个阶段。除了使用数字,我们还可以给阶段命名,比如:

bash 复制代码
# 编译阶段 命名为 builder
FROM golang:1.10.3 as builder

# ... 省略

# 运行阶段
FROM scratch

# 从编译阶段的中拷贝编译结果到当前镜像中
COPY --from=builder /build/server /

更为强大的是,COPY --from不但可以从前一阶段中拷贝,还可以直接从一个已经存在的镜像中拷贝。

bash 复制代码
FROM ubuntu:16.04

COPY --from=quay.io/coreos/etcd:v3.3.9 /usr/local/bin/etcd /usr/local/bin/

2.3 ARG指令

在Dockerfile中,ARG 指令用于定义一个变量,这个变量可以在后续的Dockerfile指令中使用。不过,与ENV定义的变量不同,ARG定义的变量只在构建镜像的过程中有效,不会存在于运行中的容器内。

3 Dockerfile示例

bash 复制代码
FROM golang:1.23 AS builder

LABEL stage=gobuilder

ENV GOOS linux
ENV GOARCH amd64
ENV CGO_ENABLED 0
ENV GO111MODULE on
ENV GOPROXY https://goproxy.cn,direct

ARG AppDir

WORKDIR /build

ADD ${AppDir}/go.mod .
ADD ${AppDir}/go.sum .
ADD core .

RUN go mod tidy && go mod download

COPY . .
COPY ${AppDir}/etc /app/etc

RUN cd ${AppDir} && go build -ldflags="-s -w" -o /app/app

FROM scratch

COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
COPY --from=builder /usr/share/zoneinfo/Asia/Shanghai /usr/share/zoneinfo/Asia/Shanghai
ENV TZ Asia/Shanghai

WORKDIR /app
COPY --from=builder /app/app /app/app
COPY --from=builder /app/etc /app/etc

CMD ["./app", "-f", "etc/config.yaml"]
相关推荐
晨陌y15 小时前
Flare自托管导航页教程:Docker部署、多用户、API与公网访问
运维·docker·容器
梅孔立17 小时前
Docker 容器网络不通:Tomcat 无法解析 MySQL、Nginx 无法反代 Tomcat 的生产级排查与治理
网络·docker·tomcat
螺蛳粉 螺蛳粉1 天前
第 05 篇:etcd 深入:Raft 共识、watch 机制与快照备份恢复实战(底座认知 05)
docker·云原生·容器·kubernetes·etcd·分布式存储·kube-apiserver
PellyKoo1 天前
【docker】cifs卷改smb密码后容器起不来的解决方法
运维·docker·容器
时早玖沐1 天前
放弃 QQ 官方机器人:用 SnowLuma + AstrBot 自建 QQ 机器人
docker·开源·agent
阿标在干嘛1 天前
容器编排的“场景适配”:我们为什么在部分服务中回归了Docker Compose?
运维·docker·容器
IT19951 天前
Docker 快速部署 DM8 达梦数据库|完整踩坑笔记
笔记·docker·容器
wzg20161 天前
ubuntu通过docker镜像部署安装onlyoffice
linux·ubuntu·docker
Star(up up up)1 天前
Docker系列---Docker容器基本命令(新手小白保姆级实操教程)
运维·学习·程序人生·青少年编程·docker·容器·dubbo
方便面不加香菜1 天前
Docker Image-- 镜像命令详解与使用示例
运维·docker·容器