Dockerfile 参考
概述
Dockerfile 是一个文本文件,包含了构建 Docker 镜像所需的所有命令。Docker 通过读取 Dockerfile 中的指令自动构建镜像。本文档详细介绍了 Dockerfile 的格式和支持的指令。
Dockerfile
,除非使用 -f
参数指定其他文件名。基本结构
Dockerfile 由一系列指令和参数组成。每条指令都必须大写,后面跟随相应的参数。
# 注释
FROM ubuntu:20.04
LABEL maintainer="[email protected]"
RUN apt-get update && apt-get install -y nginx
COPY . /app
WORKDIR /app
CMD ["nginx", "-g", "daemon off;"]
基础指令
FROM
指定基础镜像,是 Dockerfile 中必须存在的第一条指令。
语法
FROM 指令支持以下几种格式:
FROM <image>
FROM <image>:<tag>
FROM <image>@<digest>
WORKDIR
设置工作目录,影响后续的 RUN、CMD、ENTRYPOINT、COPY 和 ADD 指令。
语法
WORKDIR /path/to/workdir
COPY
从构建上下文复制文件或目录到容器中。
语法
COPY [--chown=<user>:<group>] <src>... <dest>
COPY [--chown=<user>:<group>] ["<src>",... "<dest>"]
ADD
类似 COPY,但支持 URL 和自动解压 tar 文件。建议优先使用 COPY,除非需要 ADD 的特殊功能。
语法
ADD [--chown=<user>:<group>] <src>... <dest>
ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]
RUN
在当前镜像之上执行命令并创建新的镜像层。每个 RUN 指令都会创建一个新的镜像层。
语法
RUN 指令支持 shell 格式和 exec 格式:
# Shell 格式
RUN command
# Exec 格式
RUN ["executable", "param1", "param2"]
CMD
指定容器启动时要运行的命令。一个 Dockerfile 中只能有一个 CMD 指令。如果指定了多个,只有最后一个会生效。
语法
CMD 指令支持三种格式:
# Exec 格式(推荐)
CMD ["executable","param1","param2"]
# 作为 ENTRYPOINT 的默认参数
CMD ["param1","param2"]
# Shell 格式
CMD command param1 param2
ENTRYPOINT
配置容器启动时运行的可执行文件。ENTRYPOINT 的主要用途是将容器作为可执行程序使用。
语法
# Exec 格式(推荐)
ENTRYPOINT ["executable", "param1", "param2"]
# Shell 格式
ENTRYPOINT command param1 param2
环境和参数
ENV
设置环境变量,这些变量在构建过程中和容器运行时都可用。
语法
ENV <key>=<value> ...
ENV <key> <value>
ARG
定义构建参数,这些参数只在构建过程中可用,容器运行时不可用。
语法
ARG <name>[=<default value>]
元数据
LABEL
为镜像添加元数据,比如维护者信息、版本信息等。
语法
LABEL <key>=<value> <key>=<value> <key>=<value> ...
最佳实践
使用多阶段构建
使用多阶段构建可以显著减小最终镜像的大小。在编译阶段使用包含编译工具的镜像,在运行阶段只复制编译后的文件。
FROM golang:1.21 AS builder
WORKDIR /app
COPY . .
RUN go build -o main
FROM alpine:latest
COPY --from=builder /app/main /main
CMD ["/main"]
合并 RUN 指令
合并多个 RUN 指令可以减少镜像层数,从而减小镜像大小。使用 && 连接多个命令,并在最后清理缓存。
RUN apt-get update && apt-get install -y package1 package2 && rm -rf /var/lib/apt/lists/*
使用 .dockerignore
使用 .dockerignore 文件排除不需要的文件,可以加快构建速度并减小构建上下文的大小。
node_modules
npm-debug.log
Dockerfile
.dockerignore
.git
.gitignore
选择合适的基础镜像
使用官方镜像,优先选择 alpine 版本以减小镜像大小。确保使用具体的标签而不是 latest。
FROM node:18-alpine
完整示例
Node.js 应用示例
# 使用 Node.js Alpine 作为基础镜像
FROM node:18-alpine
# 设置工作目录
WORKDIR /app
# 复制 package.json 和 package-lock.json
COPY package*.json ./
# 安装依赖
RUN npm ci --only=production
# 复制源代码
COPY . .
# 暴露端口
EXPOSE 3000
# 启动应用
CMD ["npm", "start"]
Go 应用多阶段构建示例
# 构建阶段
FROM golang:1.21-alpine AS builder
WORKDIR /app
# 复制 Go 模块文件
COPY go.* ./
RUN go mod download
# 复制源代码
COPY . .
# 构建应用
RUN CGO_ENABLED=0 GOOS=linux go build -o main
# 运行阶段
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
# 从构建阶段复制二进制文件
COPY --from=builder /app/main .
# 运行应用
CMD ["./main"]