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
相关推荐
隔窗听雨眠17 小时前
生产级Kubernetes集群部署完全指南:从kubeadm到高可用架构落地
容器·架构·kubernetes
小小洋洋17 小时前
OpenWrt 从U盘迁移到内置 eMMC,并完成扩容与 Docker 安装
java·docker·eureka
Eloudy17 小时前
docker build 与 docker buildx build 的应用场景
docker·构建
瞬间&永恒~18 小时前
【Docker】(三)联合文件系统UnionFS + Overlay2
docker·云原生·容器
数据知道20 小时前
主机入侵检测(HIDS):OSSEC / Wazuh 部署与规则编写
安全·网络安全·docker
逐光老顽童21 小时前
第 5 章:搞懂 K8s Service:从 ClusterIP 到负载均衡
docker·云原生·容器
数智工坊1 天前
Conda 环境 Docker 标准化迁移完整方案,适配深度学习 GPU 训练
深度学习·docker·conda
花生了什么事o1 天前
Docker 部署 SpringBoot:从镜像构建到服务器运行
服务器·spring boot·docker
Eloudy1 天前
国内加速 docker pull 下载 docker images,特别是 nvidia 的cuda image
docker·gpu·rdma
Chief_fly1 天前
ARM 麒麟系统服务器构建docker镜像
运维·服务器·docker