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
相关推荐
仙柒4152 小时前
Docker存储原理
运维·docker·容器
快乐的哈士奇5 小时前
LangFuse 自托管实战:选型理由、Docker 部署与常用配置全解析
运维·人工智能·docker·容器
weixin_449290016 小时前
Docker + MySQL 在 Windows 11 上的本地安装部署文档
mysql·docker·容器
Ysn07196 小时前
中文乱码:在 Docker 容器中设置中文语言环境
运维·python·docker·容器
米高梅狮子6 小时前
01.CentOS-Stream-8-packstack安装OpenStack
linux·云原生·容器·kubernetes·centos·自动化·openstack
zxd0203117 小时前
EFK(Elasticsearch + Fluentd + Kibana) 日志收集系统
运维·docker·jenkins
终端行者7 小时前
Jenkins Pipeline 企业级用法 参数化构建+Ansible发布---上
docker·ansible·jenkins·cicd
亚空间仓鼠8 小时前
Docker容器化高可用架构部署方案(十三)
docker·容器·架构
米高梅狮子9 小时前
01.mysql的备份与恢复
运维·数据库·mysql·docker·容器·kubernetes·github
console.log('npc')9 小时前
Windows 11 → WSL2 → Ubuntu → Docker → Codex → Sub2API
windows·ubuntu·docker