资讯动态

第三部分-Dockerfile与镜像构建——12. Dockerfile 基础指令

发布时间:2026/8/8 13:45:33 来源:尧图企业网站定制
12. Dockerfile 基础指令1. Dockerfile 概述Dockerfile 是一个文本文件包含了一系列构建镜像的指令。通过docker build命令Docker 按顺序执行这些指令最终生成一个可运行的镜像。┌─────────────────────────────────────────────────────────────┐ │ Dockerfile 构建流程 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ Dockerfile Docker 构建过程 │ │ ┌─────────────┐ ┌─────────────────────┐ │ │ │ FROM ubuntu │─────────────▶│ 拉取基础镜像 │ │ │ ├─────────────┤ ├─────────────────────┤ │ │ │ RUN apt-get │─────────────▶│ 执行命令产生新层 │ │ │ ├─────────────┤ ├─────────────────────┤ │ │ │ COPY . /app │─────────────▶│ 复制文件产生新层 │ │ │ ├─────────────┤ ├─────────────────────┤ │ │ │ EXPOSE 8080 │─────────────▶│ 设置元数据 │ │ │ ├─────────────┤ ├─────────────────────┤ │ │ │ CMD [app] │─────────────▶│ 设置默认命令 │ │ │ └─────────────┘ └─────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────┐ │ │ │ 镜像 │ │ │ │ 多层结构 │ │ │ └─────────────┘ │ └─────────────────────────────────────────────────────────────┘2. 基础指令2.1 FROM - 指定基础镜像# 用法FROM image[:tag] [AS name] FROM ubuntu:20.04 FROM alpine:latest FROM nginx:1.21-alpine # 多阶段构建中的命名阶段 FROM golang:1.17 AS builder FROM alpine:latest # 使用 scratch 构建最小镜像 FROM scratch2.2 RUN - 执行命令# shell 格式默认 /bin/sh -c RUN apt-get update RUN apt-get install -y nginx # exec 格式 RUN [apt-get, update] RUN [/bin/bash, -c, echo hello] # 最佳实践合并命令减少层数 RUN apt-get update \ apt-get install -y nginx curl \ apt-get clean \ rm -rf /var/lib/apt/lists/*2.3 COPY - 复制文件# 用法COPY [--chownuser:group] src... dest COPY . /app COPY index.html /usr/share/nginx/html/ COPY --chownwww-data:www-data config.json /app/ # 复制多个文件 COPY package.json package-lock.json /app/ # 使用 --from 从多阶段复制 COPY --frombuilder /app/bin /app/bin # 保留文件属性 COPY --chmod755 script.sh /usr/local/bin/2.4 ADD - 增强版复制# ADD 具有自动解压和 URL 下载功能 ADD https://example.com/file.tar.gz /tmp/ # 自动解压 tar 文件 ADD app.tar.gz /app/ # 普通复制推荐使用 COPY ADD . /app # 注意官方建议尽量使用 COPYADD 仅在需要自动解压时使用2.5 WORKDIR - 设置工作目录# 设置工作目录不存在则创建 WORKDIR /app RUN npm install # 可以多次使用支持相对路径 WORKDIR /app WORKDIR src WORKDIR webapp # 最终目录/app/src/webapp # 使用环境变量 WORKDIR ${APP_HOME}2.6 ENV - 设置环境变量# 设置环境变量 ENV NODE_ENV production ENV PORT 8080 # 链式设置 ENV NODE_VERSION14.17.0 \ NPM_VERSION7.12.0 # 使用已定义的环境变量 ENV APP_HOME /app WORKDIR ${APP_HOME} # 运行时可通过 -e 覆盖 # docker run -e NODE_ENVdevelopment myapp2.7 ARG - 构建参数# 定义构建参数 ARG VERSIONlatest ARG BUILD_DATE # 使用构建参数 FROM ubuntu:${VERSION} # 在构建命令中传递参数 # docker build --build-arg VERSION20.04 -t myapp . # ARG 与 ENV 区别 # - ARG: 仅在构建过程中有效 # - ENV: 在镜像中持久化运行时可用2.8 EXPOSE - 声明端口# 声明端口不实际映射仅文档作用 EXPOSE 80 EXPOSE 8080/tcp EXPOSE 53/udp # 多端口声明 EXPOSE 80 443 8080 # 注意EXPOSE 不会实际映射端口运行时需 -p 或 -P2.9 CMD - 默认命令# exec 格式推荐 CMD [nginx, -g, daemon off;] CMD [node, app.js] # shell 格式 CMD nginx -g daemon off; # CMD 可以被 docker run 命令覆盖 # docker run myapp ls -la # 每个 Dockerfile 只能有一条 CMD多条时只有最后一条生效2.10 ENTRYPOINT - 入口点# exec 格式推荐 ENTRYPOINT [nginx] CMD [-g, daemon off;] # shell 格式 ENTRYPOINT nginx -g daemon off; # CMD 作为 ENTRYPOINT 的默认参数 ENTRYPOINT [curl] CMD [-s, https://example.com] # 运行时覆盖 # docker run myapp -s https://google.com2.11 VOLUME - 定义数据卷# 定义挂载点 VOLUME /data VOLUME /var/lib/mysql # 定义多个卷 VOLUME [/var/log, /var/backup] # 注意VOLUME 只是声明挂载点实际挂载需要运行时 -v 参数2.12 USER - 切换用户# 创建用户并切换 RUN useradd -m appuser USER appuser # 指定用户组 USER appuser:appgroup # 切换 root 用户 USER root # 最佳实践使用非 root 用户运行应用2.13 LABEL - 添加元数据# 添加标签 LABEL version1.0 LABEL maintaineruserexample.com # 单行多个标签 LABEL version1.0 \ descriptionMy application \ environmentproduction # 查看镜像标签 # docker inspect --format{{.Config.Labels}} myapp3. 完整示例# 多阶段构建示例 # 构建阶段 FROM golang:1.17-alpine AS builder # 设置工作目录 WORKDIR /app # 复制依赖文件 COPY go.mod go.sum ./ RUN go mod download # 复制源代码 COPY . . # 编译应用 RUN CGO_ENABLED0 GOOSlinux go build -a -installsuffix cgo -o main . # 运行阶段 FROM alpine:latest # 安装运行时依赖 RUN apk --no-cache add ca-certificates tzdata # 设置时区 ENV TZAsia/Shanghai # 创建应用用户 RUN addgroup -g 1000 -S appgroup \ adduser -u 1000 -S appuser -G appgroup # 从构建阶段复制二进制文件 COPY --frombuilder /app/main /app/main COPY --frombuilder /app/config.yml /app/config.yml # 设置权限 RUN chown -R appuser:appgroup /app # 切换到应用用户 USER appuser # 工作目录 WORKDIR /app # 声明端口 EXPOSE 8080 # 健康检查 HEALTHCHECK --interval30s --timeout3s --start-period5s --retries3 \ CMD curl -f http://localhost:8080/health || exit 1 # 运行应用 ENTRYPOINT [/app/main] CMD [--config, config.yml]4. 构建命令# 基础构建dockerbuild-tmyapp.# 指定 Dockerfiledockerbuild-fDockerfile.prod-tmyapp.# 构建时不使用缓存dockerbuild --no-cache-tmyapp.# 传递构建参数dockerbuild --build-argVERSION1.0-tmyapp.# 指定构建上下文dockerbuild-tmyapp /path/to/context# 使用 tar 文件作为上下文dockerbuild-tmyapp -context.tar.gz# 构建并推送标签dockerbuild-tmyapp:1.0-tmyapp:latest.dockerpush myapp:1.0dockerpush myapp:latest# 构建时输出详细信息dockerbuild--progressplain-tmyapp.5. 指令执行顺序# Dockerfile 执行顺序从上到下 FROM ubuntu:20.04 # 1. 拉取基础镜像 RUN apt-get update # 2. 执行更新 COPY . /app # 3. 复制文件 RUN make build # 4. 构建应用 EXPOSE 8080 # 5. 设置元数据 CMD [./app] # 6. 设置默认命令6. .dockerignore# .dockerignore 文件 .git node_modules *.log .DS_Store .vscode coverage tmp dist *.md !README.md # 例外7. 最佳实践✅ 指令选择指南需求推荐指令说明基础镜像FROM固定标签避免 latest执行命令RUN合并命令减少层数复制文件COPY比 ADD 更可预测解压文件ADD仅需要自动解压时使用设置目录WORKDIR替代频繁 cd环境变量ENV持久化配置构建参数ARG构建时配置端口声明EXPOSE文档作用默认命令CMD可被覆盖入口点ENTRYPOINT固定可执行文件数据卷VOLUME声明挂载点切换用户USER安全加固❌ 常见错误# ❌ 不好每层都创建新镜像 RUN apt-get update RUN apt-get install -y nginx RUN apt-get clean # ✅ 好合并为单层 RUN apt-get update \ apt-get install -y nginx \ apt-get clean # ❌ 不好在构建中包含大文件 COPY huge-file.zip . RUN unzip huge-file.zip # 两层都包含大文件 # ✅ 好解压后删除原文件 ADD huge-file.zip . RUN unzip huge-file.zip rm huge-file.zip8. 常用命令速查指令用途示例FROM基础镜像FROM alpine:3.14RUN执行命令RUN apk add nginxCOPY复制文件COPY . /appADD增强复制ADD app.tar.gz /appWORKDIR工作目录WORKDIR /appENV环境变量ENV PORT 8080ARG构建参数ARG VERSIONlatestEXPOSE声明端口EXPOSE 80CMD默认命令CMD [nginx]ENTRYPOINT入口点ENTRYPOINT [nginx]VOLUME数据卷VOLUME /dataUSER切换用户USER appuserLABEL元数据LABEL version1.0HEALTHCHECK健康检查HEALTHCHECK CMD curl9. 常见问题Q1: COPY 和 ADD 有什么区别COPY 只支持本地文件复制ADD 额外支持 URL 下载和 tar 自动解压。Q2: CMD 和 ENTRYPOINT 的区别CMD可被docker run覆盖ENTRYPOINT不可被覆盖CMD 作为参数组合使用ENTRYPOINT 固定可执行文件CMD 提供默认参数Q3: 如何减少镜像层数合并相关的 RUN 命令使用连接多条命令。10. 小结Dockerfile 定义镜像构建步骤每条指令创建一个新层使用最佳实践优化镜像大小合并 RUN 命令减少层数选择合适的指令完成特定任务使用 .dockerignore 排除无关文件理解 CMD vs ENTRYPOINT 的区别多阶段构建减小最终镜像体积

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价