第九篇:《Dockerfile 指令精讲(二):WORKDIR、ENV、ARG、EXPOSE》

继续 Dockerfile 的学习。本文将讲解 WORKDIR、ENV、ARG、EXPOSE 这四个指令,它们在设置工作目录、环境变量、构建参数和声明端口方面发挥着关键作用。掌握这些指令可以让你的 Dockerfile 更灵活、更安全、更易维护。

一、WORKDIR:设置工作目录

语法:

dockerfile

WORKDIR /path/to/dir

作用:为后续的 RUN、CMD、ENTRYPOINT、COPY、ADD 指令设置工作目录。如果目录不存在,Docker 会自动创建。

特性:

可以多次使用,后续的相对路径会基于上一个 WORKDIR。

支持环境变量引用(如 WORKDIR $APP_HOME)。

示例:

dockerfile

WORKDIR /app

RUN pwd # 输出 /app

WORKDIR src

RUN pwd # 输出 /app/src

WORKDIR /root

RUN pwd # 输出 /root

最佳实践:

每个 Dockerfile 中至少使用一个 WORKDIR,避免默认的根目录(/)导致文件混乱。

建议使用绝对路径,避免相对路径带来的歧义。

将 WORKDIR 放在 COPY 之前,以便使用相对路径复制文件。

二、ENV:设置环境变量

语法:

dockerfile

ENV

ENV = = ...

作用:设置环境变量,在构建过程和容器运行时均可使用。

特性:

变量值可以在后续指令中通过 VARIABLE 或 {VARIABLE} 引用。

持久化到最终镜像中,容器启动时也会包含这些变量。

示例:

dockerfile

ENV NODE_VERSION=18.17.0

ENV APP_HOME=/app

WORKDIR $APP_HOME

RUN echo $NODE_VERSION > version.txt

覆盖方式:

构建时可通过 --build-arg 覆盖 ENV(但需要先定义 ARG)。

运行时可通过 docker run -e KEY=value 覆盖。

最佳实践:

将需要频繁修改的值(如版本号)定义为环境变量,便于维护。

避免在 ENV 中存储敏感信息(密码、密钥),因为镜像层可以被 docker history 查看。可使用 Docker Secret 或构建时传入 ARG 并多阶段清理。

三、ARG:构建参数

语法:

dockerfile

ARG <变量名>=\<默认值\>

作用:定义构建时的变量,仅在构建过程中有效,不会保留在最终镜像中。

与 ENV 的区别:

示例:

dockerfile

ARG VERSION=latest

FROM alpine:$VERSION

ARG BUILD_DATE

RUN echo "Built on: $BUILD_DATE" > /build-info

ENV APP_VERSION=$VERSION # 将 ARG 传递给 ENV

构建时传递参数:

bash 复制代码
docker build --build-arg VERSION=3.18 --build-arg BUILD_DATE=$(date +%Y-%m-%d) -t myimage .

最佳实践:

使用 ARG 定义可配置的版本号、基础镜像标签、代理设置等。

敏感信息可通过 ARG 传入,但请注意 --build-arg 的值会在构建历史中可见(docker history),多阶段构建可以清理。

定义默认值,使构建仍可无参运行。

四、EXPOSE:声明端口

语法:

dockerfile

EXPOSE /...

作用:声明容器运行时监听的端口,主要用于文档目的和与编排工具(如 Docker Compose)的协作。它并不会实际发布端口。

协议默认为 TCP,可指定 /udp。

可以多次 EXPOSE 或多个端口写在一行。

示例:

dockerfile

EXPOSE 80

EXPOSE 443/tcp

EXPOSE 53/udp

与 -p 和 -P 的关系:

docker run -P:随机映射所有 EXPOSE 的端口到宿主机。

docker run -p 8080:80:手动映射端口,无论是否 EXPOSE 都可以。

最佳实践:

显式声明应用监听的端口,方便协作和自动化工具(如 Kubernetes 识别端口)。

即使不使用 -P,建议仍写 EXPOSE 作为文档。

五、综合示例:结合多个指令

dockerfile

构建参数

ARG BASE_IMAGE=node:18-alpine

ARG APP_HOME=/app

FROM $BASE_IMAGE

设置环境变量(持久化)

ENV NODE_ENV=production

APP_HOME=${APP_HOME}

创建工作目录并切换

WORKDIR $APP_HOME

复制依赖文件并安装(利用缓存)

COPY package*.json ./

RUN npm ci --only=production

复制源代码

COPY . .

声明端口

EXPOSE 3000

运行命令

CMD "node", "server.js"

构建并运行:

bash 复制代码
docker build --build-arg BASE_IMAGE=node:20-alpine -t myapp .
docker run -d -p 3000:3000 myapp

六、常见问题与解决

七、小结

WORKDIR 设置工作目录,建议使用绝对路径。

ENV 定义环境变量,持久化到镜像和容器中。

ARG 定义构建参数,仅构建时有效,适用于可配置的构建行为。

EXPOSE 声明端口,是文档和工具协作的好习惯。

这些指令让 Dockerfile 更灵活、更清晰。结合上一讲的 FROM、RUN、COPY、ADD,你已经可以编写复杂的生产级 Dockerfile。

相关推荐
小锋java12349 小时前
Maven 4 要来了:15 年后,Java 构建工具迎来"彻底重构"
java·maven
卓怡学长10 小时前
w269基于spring boot + vue 候鸟监测数据管理系统
java·数据库·spring boot·spring·intellij-idea
AAA@峥10 小时前
容器数据不丢失:Docker 分层存储 + Volume 共享、备份迁移完整指南
运维·docker·容器
孫治AllenSun10 小时前
【MDC】使用 MDC 封装一个 LogMdcUtil 工具类
java·spring boot·后端
济*沧*海10 小时前
BaseMapper的介绍
java·windows·tomcat
李燚10 小时前
Go 项目怎么组织:DDD 4 层 vs MVC vs 脚本式
开发语言·golang·mvc·ddd·agent框架·eino
plainGeekDev10 小时前
依赖管理 → Version Catalog
android·java·kotlin
2zcode11 小时前
免费开源项目文档:基于MATLAB图像处理的啤酒瓶口缺陷检测系统设计与实现
开发语言·图像处理·matlab
人工智能时代 准备好了吗11 小时前
AI回答内容进入率监测:引用识别、文本匹配与语义判断
开发语言·人工智能·python
LONGZETECH11 小时前
新能源汽车动力电池检测仿真教学系统:C/S 分层架构与数字化实训落地全解析
大数据·c语言·开发语言·人工智能·架构·系统架构·汽车