Dockerfile
大约 2 分钟
1. 介绍
初次接触Docker的时候总是被各种常见的名次弄糊涂,这里先总结一下:
- Docker镜像(Image):指镜像文件
- Docker容器(Container):指基于镜像文件,外加一些自定义配置的容器,Docker使用这个容器提供具体的服务。比如
mysql:5.7
是一个镜像,那么可以用这个镜像创建多个mysql容器,分别设置不同的密码,创建不同的数据 - DockerCompose:用于编排多个docker容器的运行,以文件形式记录,相比正常的
docker run
更加直观 - DockerFile:用于构建镜像,比如将Java写的程序+JDK构建成一个镜像
- DockerHub:用于存放镜像,可以将构建好的镜像Push到DockerHub,也可以在DockerHub上拉取镜像
2. 使用
2.1 基本指令
ARG
:构建时传递给其他指令的变量,不保存在最终的镜像中FORM
:指定基础镜像,也就是运行程序所需的基本环境。比如Java一般需要JDK,前端需要Nginx等LABEL
:指定维护人等信息USER
:指定运行的用户WORKDIR
:指定工作目录COPY
:拷贝当前环境或上一阶段构建的文件到镜像中,比如拷贝前端的静态文件到镜像里ADD
:添加当前环境的文件到镜像中,和COPY
相比也可以添加网络资源,并可以自动解压文件RUN
:执行命令,后接想要调用的命令ENV
:环境变量VOLUME
:创建挂载点,用于映射到宿主机进行持久化(与直接-v指定的区别是VOLUME会创建匿名卷,相比文件目录其独立性更好)EXPOSE
:需要监听的端口ENTRYPOINT
:启动时执行的命令,不会被docker或docker-compose的cmd覆盖CMD
:启动时执行的命令,会被docker或docker-compose的cmd覆盖
2.2 优化构建文件
1. 压缩指令
上述指令除了ARG
和LABEL
都会产生一个新的layer,为了降低镜像的layer层数,最好将多个指令合并在一起
2.多阶段构建
- 在第一阶段中使用
AS builder
定义构建阶段,这样在后面的阶段可以引用 - 在最后阶段使用
COPY --from=builder
指定要复制的文件。这只会将需要的文件(如编译后的二进制可执行文件)复制到最终镜像中
比如需要在容器中构建golang,这就需要golang的环境,但实际上最终运行只需要最小的linux环境即可
# 第一阶段: 构建阶段
FROM golang:1.20 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp
# 第二阶段: 最终镜像
FROM alpine:latest
WORKDIR /app
# 从第一阶段复制构建好的可执行文件
COPY /app/myapp .
# 运行时不需要的文件,例如构建工具和源代码不会被复制
CMD ["./myapp"]