如题,看过Dockerfile常识的肯定都知道这个EXPOSE指令是暴露容器的端口。
docker run 的时候指定 -P 或者 -p 将容器的端口映射到宿主机上。这样外界访问宿主机就可以获取到容器提供的服务了。
-P命令可以结合这个dockerfile文件中的EXPOSE暴露的端口。会将容器中的EXPOSE端口随机映射到宿主机的端口。
实际操作一下。
例如dockerfile中这么写。没错,这两句足够了。
然后是运行起来的结果,可以看到容器的80映射到宿主机的32776了。(-P大P是随机映射的。)
docker build -t nginx:test .
这样我们访问宿主机每次都是需要访问不一样的端口,这不是我们想要的。这也显得EXPOSE除了提醒外不起啥很有用的作用。
EXPOSE的一种其他的玩法
其实这个题目一直是困扰我的问题,直到有一天它被解开了。
如果我们将容器的端口直接占用宿主机的端口,启动容器就相当于宿主机对应端口被占用。从而访问宿主机的端口就直接访问容器的对应端口提供的服务,那EXPOSE不就显得很有用了吗。(不要说:那直接跑在宿主机不就得了。那用docker干吗)
没错。是存在这个解的。
docker run 运行容器的时候 指定参数 --net=host 便是问题的解。
我们先把刚才容器停掉。然后用我说的 --net=host运行这个容器。可以看到PORTS啥也没写。因为使用的是宿主机的网络端口、不存在映射的关系。
你用docker inspect containerID 查,也是没有宿主机的端口映射信息的。
先来查看 -P参数run起来的容器inspect信息来进行对比。可以看到80端口映射到了宿主机的32777(不要问为啥不是32776)
再来看一下--net=host run起来的容器inspect情况。可以看到Ports啥也没有
综上得出结论:
EXPOSE在dockerfile中暴露出容器将要提供服务所开放的端口。run的时候直接 docker run -d --net=host image:tag 这样可以不手动-p指定端口映射关系,更简洁了,从而使EXPOSE发挥最大的作用。而不是简单的随机映射宿主机&&起到注释作用。
而这么做不灵活点在于宿主机的端口被EXPOSE固定。如果宿主机端口被其他进程占用,就port already in use了。