EXPOSE 暴露容器端口,格式为:
EXPOSE <端口1> [<端口2>...]
EXPOSE 指令是声明运行时容器提供服务端口,这只是一个声明,在运行时并不会因为这个声明应用就会开启这个端口的服务。在 Dockerfile 中写入这样的声明有两个好处,一个是帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射;另一个用处则是在运行时使用随机端口映射时,也就是 docker run -P时,会自动随机映射 EXPOSE 的端口。
要将 EXPOSE 和在运行时使用 -p <宿主端口>:<容器端口> 区分开来。-p,是映射宿主端口和容器端口,换句话说,就是将容器的对应端口服务公开给外界访问,而 EXPOSE 仅仅是声明容器打算使用什么端口而已,并不会自动在宿主进行端口映射。
EXPOSE 可以用来暴露端口,或者在 docker run 时指定 --expose=1234,这两种方式作用相同。但是,--expose 可以接受端口范围作为参数,比如 --expose=2000-3000。但是,EXPOSE 和 --expose 都不依赖于宿主机器。默认状态下,这些规则并不会使这些端口可以通过宿主机来访问。
基于 EXPOSE 指令的上述限制,Dockerfile 的作者一般在包含 EXPOSE 规则时都只将其作为哪个端口提供哪个服务的提示。使用时,还要依赖于容器的操作人员进一步指定网络规则,需要配合 docker run -p PORT:EXPORT 使用,这样 EXPOSE 设置的端口号会被指定需要映射到宿主机器的端口,这时要确保宿主机器上的端口号没有被使用。如果直接指定 docker run-p EXPORT,这样 EXPOSE 设置的端口号会被随机映射成宿主机器中的一个端口号。不过通过 EXPOSE 命令文档化端口的方式十分有用。
本质上说,EXPOSE 或者 --expose 只是为其他命令提供所需信息的元数据(比如容器间 link 操作就依赖 EXPOSE 元数据),或者只是告诉容器操作人员有哪些已知选择。格式:
EXPOSE <port> [<port>...]
EXPOSE 指令可以一次设置多个端口号,相应的运行容器的时候,可以配套的多次使用 -p 选项。
实例:使用 EXPOSE 暴露一个端口。
# 暴露一个端口 EXPOSE port1
运行容器的命令:
# 如果想代理 EXPOSE 端口, 相应的运行容器使用的命令 # 此时,端口被随机映射到宿主机 $ docker run -p port1 image # 可以指定映射到宿主主机的端口 $ docker run -p host_port1:port1 image
实例:使用 EXPOSE 暴露多个端口。
# 暴露多个端口; EXPOSE port1 port2 port3
运行容器的命令:
# 如果想代理EXPOSE端口, 相应的运行容器使用的命令; # 宿主端口随机 $ docker run -p port1 -p port2 -p port3 image # 还可以指定需要映射到宿主机器上的某个端口号; # 指定宿主主机端口 $ docker run -p host_port1:port1 -p host_port2:port2 -p host_port3:port3 image
注意:EXPOSE 仅仅是暴露一个端口,一个标识,在没有定义任何端口映射时,外部是无法访问到容器提供的服务。而端口映射(-p)是 docker 比较重要的一个功能,原因在于我们每次运行容器的时候容器的IP地址不能指定,而是在桥接网卡的地址范围内随机生成的。宿主机器的IP地址是固定的,我们可以将容器的端口的映射到宿主机器上的一个端口,免去每次访问容器中的某个服务时都要查看容器的IP的地址。对于一个运行的容器,可以使用 docker port 加上容器ID 和 EXPOSE 暴露的端口来查看该端口号在宿主机器上的映射端口。
$ docker port redis 6379 0.0.0.0:6380