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
相关推荐
Alsn868 小时前
等待学习-学习目录:Docker 容器安全攻防
学习·安全·docker
JLWcai2025100910 小时前
铸造领域树脂砂轮|金利威多场景解决方案,20 + 配方覆盖全需求
mongodb·zookeeper·eureka·spark·rabbitmq·memcached·storm
2601_9618752410 小时前
决战申论100题2026|最新|范文
linux·容器·centos·debian·ssh·fabric·vagrant
java_cj11 小时前
深入kube-apiserver认证机制:从Bearer Token到mTLS的完整认证链解析
linux·运维·服务器·云原生·容器·kubernetes
程序员老赵11 小时前
服务器没有桌面?Docker 跑个 Chrome,浏览器就能远程用
docker·容器·devops
杨浦老苏11 小时前
轻量级Docker仪表板Servedash
运维·docker·监控·群晖·仪表板
正经教主11 小时前
【docker基础】 第八周:容器监控与应用更新策略
运维·docker·容器
kiros_wang12 小时前
Docker 使用完整指南
运维·docker·容器
正经教主12 小时前
【docker基础】第九周:Docker安全与镜像优化
运维·docker·容器
CodeStats14 小时前
【虚拟机】 从 CPU 指令到虚拟机隔离:虚拟机就是一个“模拟了完整硬件的普通进程”
java·docker