Dockerfile 的 EXPOSE 和 Docker Compose 的 ports 有什么区别?

文章目录

在容器化部署时,我们经常会在 Dockerfile 里看到:

dockerfile 复制代码
EXPOSE 18010

同时在 docker-compose.yml 里又写了:

yaml 复制代码
ports:
  - "18010:18010"

这两者看起来都涉及端口,但却常常让人搞不清楚它们到底有什么区别?特别是初学者看到这两个就懵了:端口是不是重复写了?到底哪个负责映射?写了 EXPOSE 会不会自动对外开放端口?


一、Dockerfile 中的 EXPOSE 是什么?

EXPOSE 的作用是 声明容器内部服务监听的端口 ,它只是一个 元数据(Metadata),用于告诉其他开发者或工具:

"这个镜像内部有一个服务会监听这个端口。"

例如你的 Dockerfile 里:

dockerfile 复制代码
EXPOSE 18010

说明:

✔ 这个镜像内部有程序监听 18010

❗但 EXPOSE 不会自动开放端口到宿主机

也就是说外界依然访问不到此端口。

它是一种 文档式说明,便于阅读/维护/工具自动化。


二、Docker Compose 中的 ports 又是什么?

在 docker-compose.yml 里:

yaml 复制代码
ports:
  - "18010:18010"

这是一个真正的 端口映射(Port Mapping)

复制代码
宿主机端口 18010  ↔  容器内部 18010

作用:

✅ 将容器内部监听的端口映射到宿主机

✅ 外部可以直接通过宿主机访问该端口

例如:

bash 复制代码
curl http://your-server-ip:18010

不写 ports:,容器内部服务再跑得再好,宿主机和外部是访问不到的


三、两者到底有什么区别?

配置位置 是否映射到宿主机 是否让外界可访问 作用
EXPOSE ❌ 不映射 ❌ 不可访问 只是声明/提示
ports ✅ 映射 ✅ 可访问 真正对外映射端口

四、端口映射

🔹 如果你只是构建镜像,在 Dockerfile 里写:

dockerfile 复制代码
EXPOSE 18010

是一个良好的习惯,它说明了镜像内部的监听端口。

🔹 但如果你要让容器对外可访问,则 必须在 Compose 或 docker run 时写端口映射

yaml 复制代码
ports:
  - "18010:18010"

⚠️ 只有 EXPOSE 是不会自动映射端口的!


五、实例演示

1️⃣ Dockerfile

dockerfile 复制代码
FROM eclipse-temurin:17-jdk-jammy

WORKDIR /app

COPY hikvoice-relay-1.0-SNAPSHOT.jar /app/app.jar
COPY lib/ /app/lib/
COPY AudioFile/ /app/AudioFile/

ENV LD_LIBRARY_PATH=/app/lib:/usr/lib:/usr/local/lib

EXPOSE 18010

ENTRYPOINT ["java", "-jar", "/app/app.jar"]

这里的 EXPOSE 18010 表示:

👉 镜像内部这个服务在监听 18010(例如 Spring Boot 默认端口)


2️⃣ docker-compose.yml(关键部分)

你不想写 environment 变量,而是把所有配置放到 .env 里:

yaml 复制代码
version: "3.8"

services:
  wvp:
    network_mode: "host"
    image: wvp-gb28181:latest
    container_name: wvp
    restart: always
    env_file:
      - .env
    volumes:
      - ./:/app/config
      - ./config.json:/app/static/config.json
      - /opt/media/bin/www:/opt/media/bin/www
    ports:
      - "18080:18080"
      - "18081:18081"
      - "8116:8116/udp"

  hikvoice:
    image: hikvoice:latest
    container_name: hikvoice
    restart: unless-stopped
    ports:
      - "18010:18010"
    env_file:
      - .env

这里:

env_file: - .env 用来注入 .env 里的所有变量

ports: - "18010:18010" 把容器内部监听的 18010 映射到宿主机


六、总结

项目 推荐写法
表示服务监听端口 EXPOSE 18010
映射端口给宿主机访问 ports: - "18010:18010"
注入环境变量 env_file: - .env
相关推荐
wsad053217 分钟前
Docker 常用命令:中英文对照、示例、参数详解及白话解释
运维·docker·容器
认真的薛薛25 分钟前
10.k8s中水平和垂直伸缩-Jenkins
容器·kubernetes·jenkins
@hdd12 小时前
实战:在 Kubernetes 上部署微服务应用
微服务·容器·kubernetes
Elastic 中国社区官方博客18 小时前
在 Kubernetes 上的依赖管理
大数据·elasticsearch·搜索引擎·云原生·容器·kubernetes·全文检索
星星乘坐的船19 小时前
Centos7.9系统下docker安装
运维·docker·容器
Elastic 中国社区官方博客21 小时前
Agentic CI/CD:使用 Kubernetes 部署门控,结合 Elastic MCP Server
大数据·人工智能·elasticsearch·搜索引擎·ci/cd·容器·kubernetes
切糕师学AI21 小时前
Kubernetes 中的 StatefulSet
云原生·容器·kubernetes
阿乐艾官1 天前
【K8s思维导图及单节点容器启动流程】
java·容器·kubernetes
礼拜天没时间.1 天前
企业级Docker镜像仓库Harbor部署实战
linux·运维·docker·云原生·容器·sre
阿寻寻1 天前
【云原生技术】Pod 列表新增时间字段:取值口径与获取方式
docker·云原生·kubernetes