Dockerfile的EXPOSE

文章目录

环境

  • RHEL 9.3
  • Docker Community 24.0.7

总结

如果懒得看测试的详细信息,可以直接看结果:

docker run 选项 在Dockerfile里 EXPOSE 80 在Dockerfile里不 EXPOSE 80 备注
无 在容器外无法访问容器的80端口 在容器外无法访问容器的80端口
-p 8080:80 8080 8080 显式指定映射端口
-P 随机端口 随机端口 随机映射端口
--network=host 80 80 直接使用容器的端口

所以,EXPOSE并不会真正开放端口,它更像是一个说明文档,由image的开发者声明image所监听的端口,使用者以此为依据,在启动容器时,可以以不同的策略来开放端口。

测试

使用EXPOSE

创建 Dockerfile 文件如下:

powershell 复制代码
FROM nginx:alpine

EXPOSE 80

构建:

powershell 复制代码
docker build -t kai0107_1 .

测试1:不做端口映射

启动容器:

powershell 复制代码
docker run kai0107_1

查看容器:

powershell 复制代码
➜  ~ docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED         STATUS         PORTS     NAMES
430b0c2bee65   kai0107_1   "/docker-entrypoint...."   5 seconds ago   Up 5 seconds   80/tcp    recursing_noyce

检查该容器:

powershell 复制代码
➜  ~ docker container inspect 430b0c2bee65 | grep -i3 port
                "Config": {}
            },
            "NetworkMode": "default",
            "PortBindings": {},
            "RestartPolicy": {
                "Name": "no",
                "MaximumRetryCount": 0
--
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": false,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": null,
            "UTSMode": "",
--
            "AttachStdin": false,
            "AttachStdout": true,
            "AttachStderr": true,
            "ExposedPorts": {
                "80/tcp": {}
            },
            "Tty": false,
--
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {
                "80/tcp": null
            },
            "SandboxKey": "/var/run/docker/netns/c762f4dc271b",

注:可以用 -f 选项指定输出格式,参见 https://docs.docker.com/engine/reference/commandline/inspect 。

打开浏览器,访问 http://localhost:80 ,如下:

可见,在容器之外,无法访问80端口。

测试2:-p 8080:80

启动容器:

powershell 复制代码
docker run -p 8080:80 kai0107_1

查看容器:

powershell 复制代码
➜  ~ docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED              STATUS              PORTS                                   NAMES
dd9ea9e98b4b   kai0107_1   "/docker-entrypoint...."   About a minute ago   Up About a minute   0.0.0.0:8080->80/tcp, :::8080->80/tcp   naughty_almeida

注: 0.0.0.0 和 :: 都是代表匹配所有IP地址。前者是IPv4的写法,后者是IPv6的写法。

检查该容器:

powershell 复制代码
➜  ~ docker container inspect dd9ea9e98b4b | grep -i3 port
                "Config": {}
            },
            "NetworkMode": "default",
            "PortBindings": {
                "80/tcp": [
                    {
                        "HostIp": "",
                        "HostPort": "8080"
                    }
                ]
            },
--
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": false,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": null,
            "UTSMode": "",
--
            "AttachStdin": false,
            "AttachStdout": true,
            "AttachStderr": true,
            "ExposedPorts": {
                "80/tcp": {}
            },
            "Tty": false,
--
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {
                "80/tcp": [
                    {
                        "HostIp": "0.0.0.0",
                        "HostPort": "8080"
                    },
                    {
                        "HostIp": "::",
                        "HostPort": "8080"
                    }
                ]
            },

打开浏览器,访问 http://localhost:8080 ,如下:

可见,在容器外部,可以通过8080端口访问容器里的80端口。

测试3:-P

启动容器:

powershell 复制代码
docker run -P kai0107_1

查看容器:

powershell 复制代码
➜  ~ docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED         STATUS         PORTS                                     NAMES
241fd7f0ee87   kai0107_1   "/docker-entrypoint...."   5 seconds ago   Up 4 seconds   0.0.0.0:32768->80/tcp, :::32768->80/tcp   jovial_haslett

检查该容器:

powershell 复制代码
➜  ~ docker container inspect 241fd7f0ee87 | grep -i3 port
                "Config": {}
            },
            "NetworkMode": "default",
            "PortBindings": {},
            "RestartPolicy": {
                "Name": "no",
                "MaximumRetryCount": 0
--
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": false,
            "PublishAllPorts": true,
            "ReadonlyRootfs": false,
            "SecurityOpt": null,
            "UTSMode": "",
--
            "AttachStdin": false,
            "AttachStdout": true,
            "AttachStderr": true,
            "ExposedPorts": {
                "80/tcp": {}
            },
            "Tty": false,
--
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {
                "80/tcp": [
                    {
                        "HostIp": "0.0.0.0",
                        "HostPort": "32768"
                    },
                    {
                        "HostIp": "::",
                        "HostPort": "32768"
                    }
                ]
            },

打开浏览器,访问 http://localhost:32768 ,如下:

可见,在容器外部,可以通过32768端口访问容器里的80端口。

注意:32768是一个随机端口。下次再启动容器时,可能就是另外一个端口了。

测试4:--network=host

启动容器:

powershell 复制代码
docker run --network=host kai0107_1

查看容器:

powershell 复制代码
➜  ~ docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED         STATUS         PORTS     NAMES
adcbcdd4698c   kai0107_1   "/docker-entrypoint...."   6 seconds ago   Up 6 seconds             quizzical_hugle

检查该容器:

powershell 复制代码
➜  ~ docker container inspect adcbcdd4698c | grep -i3 port
                "Config": {}
            },
            "NetworkMode": "host",
            "PortBindings": {},
            "RestartPolicy": {
                "Name": "no",
                "MaximumRetryCount": 0
--
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": false,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": null,
            "UTSMode": "",
--
            "AttachStdin": false,
            "AttachStdout": true,
            "AttachStderr": true,
            "ExposedPorts": {
                "80/tcp": {}
            },
            "Tty": false,
--
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {},
            "SandboxKey": "/var/run/docker/netns/default",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,

打开浏览器,访问 http://localhost:80 ,如下:

可见,在容器外部,可以通过80端口访问容器里的80端口。

不使用EXPOSE

创建 Dockerfile 文件如下:

powershell 复制代码
FROM nginx:alpine

再次做测试1到测试4,其结果和使用EXPOSE时是完全一致的。

参考

  • https://docs.docker.com/engine/reference/run/#expose-incoming-ports
  • https://blog.csdn.net/qq_33801641/article/details/121122334
  • https://www.php.cn/faq/494255.html
  • https://yeasy.gitbook.io/docker_practice/network/port_mapping
相关推荐
杨浦老苏13 小时前
把项目管理搬回自己服务器:Windshift部署与避坑
docker·项目管理·群晖
木雷坞14 小时前
Baserow Docker部署:导入设备借用CSV,再用表单新增登记
运维·docker·容器
wefg115 小时前
【Docker】基本指令
运维·docker·容器
牛马工作号16 小时前
Copyparty 轻量文件共享:Docker Compose 部署、权限与多协议使用全指南
运维·docker·容器
oioihoii17 小时前
Windows部署MySpeed自建测速服务:Docker运行后直接测速,再配置固定公网地址远程查看
运维·docker·容器
Jack N19 小时前
【Strapi 系列之八】二次开发 + 生产部署,Docker + PostgreSQL + Nginx 一把梭
nginx·docker·postgresql·strapi
岁月宁静1 天前
一个 AI 项目从本地到上线,要经过哪些步骤?全流程讲清楚
python·docker·agent
正经教主1 天前
【FDE系列】阶段2:Day 42(UP详细版):Dockerfile 实战 — 把你的应用打包成镜像
人工智能·docker·fde
刘马想放假1 天前
Copyparty 轻量文件共享:Docker Compose 部署、权限与多协议使用全指南
docker·容器
岁寒良木2 天前
麒麟 V10 (x86_64) 离线/联网部署 Docker 26.1.4 与 MaxKB v2.10 LTS 实战指南
python·docker·kylin