Files
docker_practice/07_dockerfile/7.9_expose.md
T
yeasy ef2625531d style: 含中文的括号统一为全角(336 处 / 110 文件)
全书此前是真·五五开:含中文的括号 336 处半角 : 336 处全角,而且**在同一文件
内混用**——`18_security/18.1_kernel_ns.md` 第 11/17/20 行写 `(如 runC)`,
第 31 行写 `(用户命名空间映射)`。这不是体例问题,是它自己跟自己不一致。

集群里其余 13 本都一边倒(llm_internals 5 : 1049、oc_guide 2 : 713、
forward_deployed_engineering_guide 0 : 108),blockchain_guide 已在 2026-08-05
按同一方向统一过 97 处,故取全角,而非另立新规。全角括号前后不留空格,
原先 `概念 (镜像、容器、仓库) 和` 两侧的空格一并收掉。

**纯拉丁内容的半角括号一个没动**——`新建一个层 (Layer)`、`项目 (project)`
保持原样:改动前后「半角且内容纯拉丁」的数量都是 **1163**,而「半角且含中文」
从 **336 变成 0**。

其余验证:改动前后各自抹掉全部空白与圆括号后**逐字节相同**(两侧均 19559 字符);
左右括号总数改动前后都是 399 : 399,证明没有吞括号也没有配错对。
`check_project_rules` 202/202、`check_emphasis` 202/202、37 tests OK、
根 `format_checker` 与 `validate_codeblocks` 干净、`git diff --check` 干净。
2026-08-24 13:13:23 -07:00

3.2 KiB
Raw Blame History

7.9 EXPOSE 暴露端口

7.9.1 基本语法

EXPOSE <端口> [<端口>/<协议>...]

EXPOSE 声明容器运行时提供服务的端口。这是一个 文档性质的声明,告诉使用者容器会监听哪些端口。


7.9.2 基本用法

## 声明单个端口

EXPOSE 80

## 声明多个端口

EXPOSE 80 443

## 声明 TCP 和 UDP 端口

EXPOSE 80/tcp
EXPOSE 53/udp

7.9.3 EXPOSE 的作用

1. 文档说明

告诉镜像使用者,容器将在哪些端口提供服务:

## 使用者一看就知道这是 web 应用

EXPOSE 80 443
## 查看镜像暴露的端口

$ docker inspect nginx --format '{{.Config.ExposedPorts}}'
map[80/tcp:{}]

2. 配合 -P 使用

使用 docker run -P 时,Docker 会自动映射 EXPOSE 的端口到宿主机随机端口:

## Dockerfile

EXPOSE 80
$ docker run -P nginx
$ docker port $(docker ps -q)
80/tcp -> 0.0.0.0:32768

7.9.4 EXPOSE vs -p

特性 EXPOSE -p
位置 Dockerfile docker run 命令
作用 声明/文档 实际端口映射
是否必需 否 是(外部访问时)
映射发生时 不发生 运行时发生
flowchart TD
    Expose["EXPOSE 80<br/>仅声明意图"]
    Run["docker run -p<br/>实际端口映射<br/>宿主机 ←→ 容器"]
    Expose ~~~ Run

没有 EXPOSE 也能 -p

## 即使没有 EXPOSE,也可以使用 -p

FROM nginx

## 没有 EXPOSE

...
## 仍然可以映射端口

$ docker run -p 8080:80 mynginx

7.9.5 常见误解

误解:EXPOSE 会打开端口

## ❌ 错误理解:这不会让容器可从外部访问

EXPOSE 80

EXPOSE 不会:

  • 自动进行端口映射
  • 让服务可从外部访问
  • 在容器启动时开启端口监听

EXPOSE 只是元数据声明。容器是否实际监听该端口,取决于容器内的应用。

正确理解

## Dockerfile

FROM nginx
EXPOSE 80    # 1. 声明:这个容器会在 80 端口提供服务
## 运行:需要 -p 才能从外部访问

$ docker run -p 8080:80 nginx    # 2. 映射:宿主机 8080 → 容器 80

7.9.6 最佳实践

1. 总是声明应用使用的端口

## Web 服务

FROM nginx
EXPOSE 80 443

## 数据库

FROM postgres
EXPOSE 5432

## Redis

FROM redis
EXPOSE 6379

2. 使用明确的协议

## 默认是 TCP

EXPOSE 80

## 明确指定 UDP

EXPOSE 53/udp

## 同时支持 TCP 和 UDP

EXPOSE 53/tcp 53/udp

3. 与应用实际端口保持一致

## ✅ 好:EXPOSE 与应用端口一致

ENV PORT=3000
EXPOSE 3000
CMD ["node", "server.js"]

## ❌ 差:EXPOSE 与应用端口不一致(误导)

EXPOSE 80
CMD ["node", "server.js"]  # 实际监听 3000

7.9.7 使用环境变量

ARG PORT=80
EXPOSE $PORT

7.9.8 在 Compose 中

在 Compose 中配置如下:

services:
  web:
    build: .
    ports:
      - "8080:80"    # 映射端口(类似 -p)
    expose:
      - "80"         # 仅声明(类似 EXPOSE)

expose 在 Compose 中仅用于容器间通信的文档说明,不进行端口映射。