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
相关推荐
鸠摩智首席音效师2 小时前
Docker 中如何限制CPU和内存的使用 ?
docker·容器
Michaelwubo2 小时前
Docker dockerfile镜像编码 centos7
运维·docker·容器
jingyu飞鸟2 小时前
centos-stream9系统安装docker
linux·docker·centos
好像是个likun3 小时前
使用docker拉取镜像很慢或者总是超时的问题
运维·docker·容器
玖疯子5 小时前
介绍 Docker 的基本概念和优势,以及在应用程序开发中的实际应用。
docker
暴富的Tdy5 小时前
【快速上手Docker 简单配置方法】
docker·容器·eureka
Karoku0666 小时前
【k8s集群应用】kubeadm1.20高可用部署(3master)
运维·docker·云原生·容器·kubernetes
豆豆豆豆变6 小时前
docker之compose篇
docker·容器·自动化运维
saynaihe7 小时前
安全地使用 Docker 和 Systemctl 部署 Kafka 的综合指南
运维·安全·docker·容器·kafka
G_whang8 小时前
centos7下docker 容器实现redis主从同步
redis·docker·容器