Docker容器启动后,需要宿主机和容器端口进行映射,以便容器内服务对外暴露,这可以在启动是通过docker run -p host:port ...
指定,也可以在镜像构建时通过dockerfile
的EXPOSE
指令指定,本文本来具体对EXPOSE
指令进行解析。
EXPOSE 语法
EXPOSE <port> [<port>/<protocol>...]
EXPOSE 语义
· EXPOSE
指令声明Docker容器在运行时侦听的网络端口。
· 通过指定监听协议是TCP
还是UDP
,若未指定协议,则默认为TCP
。
· EXPOSE
并不会发布端口,仅作为镜像构建者和容器运行者之间的协议文档,描述需要发布哪些端口。
· 实际发布端口,需要运行容器时通过docker run -p
指定,或通过docker run -P
随机映射EXPOSE
指令声明的端口列表中优先级最高的。
· EXPOSE
与docker run --expose
作用相同。docker run --expose
可以指定端口范围,如:docker run --expose=2000-3000
.
· EXPOSE
声明发布端口好处:
1) 清晰描述镜像的端口行为,便于镜像的后期维护。
2) 运行容器时,可以通过docker run -P
指定端口。
EXPOSE 示例
· dockerfile
中通过EXPOSE
指定端口,容器启动时使用docker run -p host:port
指定端口。
1) 进入/securitit/dockerfile/目录(根据个人选择,这是本文使用的目录),创建dockerfile
文件。
FROM nginx
MAINTAINER Securitit
# 9181是随便定义的端口,容器内并没有此服务.
EXPOSE 9181
CMD ["usr/sbin/nginx", "-g", "daemon off;"]
配置文件中暴露了9181端口,同时nginx:latest默认会暴露80端口,也就是此镜像声明暴露两个端口:80和9181。
2) 执行如下的构建命令,基于dockerfile
构建镜像。
docker build -f /securitit/dockerfile/dockerfile -t securitit-nginx-expose:1.0.0.1 .
3) 查看镜像信息。
docker images
4) 查看镜像元数据。
可以看到构建的镜像声明开放80和8080两个端口。
docker inspect -f {{".ContainerConfig.ExposedPorts"}} abde875b8b42
5) 指定通过dockerfile
生成的镜像启动容器。
docker run --name securitit-nginx-expose -it -d -p 9191:80 securitit-nginx-expose:1.0.0.1
6) 查看容器信息。
docker ps -a
7) 通过docker run -p
指定的端口访问服务。
· dockerfile
中通过EXPOSE
指定多个端口,容器启动时使用docker run -P
使用随机端口。
1) 进入/securitit/dockerfile/目录(根据个人选择,这是本文使用的目录),创建dockerfile
文件。
FROM nginx
MAINTAINER Securitit
EXPOSE 9181
EXPOSE 9182
EXPOSE 9183
EXPOSE 9184
EXPOSE 9185
CMD ["usr/sbin/nginx", "-g", "daemon off;"]
配置文件中暴露了9181、9182、9183、9184、9185端口,同时nginx:latest默认会暴露80端口,也就是此镜像声明暴露六个端口:80、9181、9182、9183、9184、9185。
2) 执行如下的构建命令,基于dockerfile
构建镜像。
docker build -f /securitit/dockerfile/dockerfile -t securitit-nginx-expose:1.0.0.2 .
3) 查看镜像信息。
docker images
4) 查看镜像元数据。
可以看到构建的镜像声明开放80和8080两个端口。
docker inspect -f {{".ContainerConfig.ExposedPorts"}} abde875b8b42
5) 指定通过dockerfile
生成的镜像启动容器。
docker run --name securitit-nginx-expose-v2 -it -d -P securitit-nginx-expose:1.0.0.2
6) 查看容器信息。
docker ps -a
总结
EXPOSE
目的不是为了发布端口,而是为了形成镜像文档约定,用于镜像发布者和容器运行者之间进行约定,同时可有效保证镜像和容器维护者能高效的了解镜像和容器的信息。
若文中存在错误和不足,欢迎指正!