如題,看過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了。