
Docker - Dockerfile及优化技巧
...大约 2 分钟
Dockerfile 是描述容器应该如何构建的文件。也就是描述如何从一个基础镜像开始,执行一项项指令,最终构建我们需要的需要的程序及其运行环境的自定义镜像。
命令
指令 | 说明 | 示例 |
---|---|---|
FROM | 指定基础镜像,用于后续的指令构建 | FROM ubuntu:22.04 |
RUN | 创建镜像时执行的命令 | RUN apt-get update |
COPY | 复制文件到镜像中 | COPY . /app |
WORKDIR | 设置工作目录 | WORKDIR /app |
EXPOSE | 暴露端口 | EXPOSE 8080 |
CMD | 容器启动时执行的命令(可以被覆盖) | CMD ["python", "app.py"] |
ENTRYPOINT | 设置入口点(不可被覆盖) | ENTRYPOINT ["python"] |
ENV | 设置环境变量 | ENV LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH |
USER | 设置用户 | USER root |
ARG | 定义参数 | ARG version=1.0 |
优化技巧
多阶段构建
项目运行时,我们只需要执行编译好的二进制文件,而不需要编译环境。
因此,我们可以使用多阶段构建,将编译环境与运行环境分开,从而减小最终镜像的大小。
注意
如果项目为静态编译,执行时只需要使用最简的 alpine
或空白镜像 scratch
即可。
如果项目为动态编译,则执行时还可能需要复制/安装一些运行时依赖。
# 构建阶段
FROM ubuntu:22.04 AS builder
RUN apt-get update && apt-get install -y --no-install-recommends python3 python3-pip
COPY . /app
WORKDIR /app
RUN pip3 install -r requirements.txt
RUN python3 setup.py build
# 运行阶段
FROM alpine:3.17
WORKDIR /app
COPY /app/main . # 复制编译好的二进制文件
CMD ["./main"]
减少镜像层数
在 dockerfile 中,每一条指令都会创建一个新的镜像层,因此,可以通过合并RUN
指令数量减少镜像层数,从而减小镜像大小。
将 COPY 放在 apt 安装之后
由于每次修改都会导致缓存失效,为了充分利用缓存,可以将COPY
指令放在RUN
指令之后,从而使项目文件修改后不必重新花费时间重复安装依赖。
apt 安装后清除缓存
在安装依赖后,使用apt-get clean
清除缓存,从而减小镜像大小。
RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
将版本分离为 ARG 参数
将版本号分离为 ARG 参数,有助于项目解耦。
# 定义构建阶段
ARG UBUNTU_VERSION=22.04
# 构建阶段
FROM ubuntu:${UBUNTU_VERSION} AS builder