在开发和部署前端应用时,常常需要将应用打包为一个 Docker 镜像,方便在不同的环境中迁移和部署。而在 Docker 容器中使用端口映射,可以让应用在容器内部使用固定的端口,同时对外暴露指定的端口,方便我们在宿主机或者网络中访问应用。
本文将介绍 Docker 容器的端口映射技巧及注意事项,涵盖以下内容:
- Docker 容器网络基础知识
- 端口映射的基本语法
- 端口映射的注意事项和技巧
- 示例代码
1. Docker 容器网络基础知识
在理解 Docker 容器的端口映射之前,我们需要了解 Docker 容器网络的基础知识。Docker 默认使用的是 Bridge 网络模式,即容器默认使用一个名为 docker0 的虚拟网络设备与主机的网络通信。
在 Bridge 网络模式下,Docker 容器会被分配一个独立的 IP 地址,该 IP 地址由 Docker Daemon 在容器启动时动态分配。我们可以使用 docker inspect
命令查看容器的 IP 地址。
2. 端口映射的基本语法
Docker 容器的端口映射通过 -p
参数实现,该参数需要指定映射的协议、内部端口、外部端口和 IP 地址(可选)。
下面是一个基本的语法示例:
docker run -p <ip>:<host-port>:<container-port>/<protocol> <image>
其中:
<ip>
:宿主机上的 IP 地址,可省略,默认为0.0.0.0
。<host-port>
:宿主机上的端口,用于接收外部请求。<container-port>
:容器内部的端口,用于接收容器内部的请求。<protocol>
:协议类型,可选值为tcp
或者udp
,默认为tcp
。
例如,我们可以使用以下命令启动一个 Docker 容器,并将容器内部的 80
端口映射到宿主机的 8080
端口:
docker run -p 8080:80/tcp nginx
这样,当我们在宿主机上访问 http://localhost:8080
时,即可访问到容器中运行的 nginx 服务,而实际上请求被转发到了容器的 80
端口。
3. 端口映射的注意事项和技巧
3.1 端口冲突的问题
在使用 Docker 容器的端口映射时,可能会出现宿主机上端口已被占用的情况。此时,我们需要选择一个未被占用的端口或者关闭冲突的程序,以便成功启动 Docker 容器。
3.2 防火墙的配置
当 Docker 容器内部的服务使用的是非默认端口时(如 8080
),我们需要确保防火墙已经开放了该端口的访问权限,否则无法从宿主机的浏览器中访问该服务。
Linux 系统通常自带了防火墙工具,如 iptables 和 firewalld。我们可以通过修改防火墙规则,开放指定的端口。
以 CentOS 7 系统为例,为了开放端口 8080
的访问权限,可以执行以下命令:
sudo firewall-cmd --zone=public --add-port=8080/tcp --permanent # 添加防火墙规则 sudo firewall-cmd --reload # 重新加载防火墙
3.3 Docker 容器内部访问服务
当 Docker 容器内部的服务需要访问自身的服务时,可以使用 localhost
或者 127.0.0.1
来访问自身服务,而不必使用容器的 IP 地址。
3.4 容器间通信
当在同一台宿主机上启动多个 Docker 容器时,容器之间可以使用服务名称来进行通信。Docker 会自动创建一个名为 bridge
的网络,将不同的容器连接在同一个网络中,容器可以通过服务名称和端口号来进行通信。
例如,如果在同一台宿主机上启动了 web
和 api
两个容器,可以使用以下方式互相访问彼此的服务:
web --> http://api:8080 api --> http://web:80
4. 示例代码
以下是一个使用 Docker 容器的端口映射的示例代码:
-- -------------------- ---- ------- -------- ----- --------- ---- ------ ------------ ------ - --------- -------- - --------------------------- --------- - ---------- ---- ------ ----------- -------- - -------------- --------- - ---------- --------- ----------- ------- ------展开代码
该代码使用 docker-compose 工具定义了两个 Docker 容器:web
和 api
。web
容器中运行的是 nginx 服务,api
容器中运行的是一个 Node.js 应用。
web
容器将容器内部的 80
端口映射到宿主机的 8000
端口,容器内部的 Web 页面文件挂载到宿主机的 ./web
目录中。api
容器不需要暴露端口,但是将容器内部的应用代码挂载到宿主机的 ./api
目录中,以便进行开发调试。
通过 networks
声明了一个名为 my-network
的网络,将 web
和 api
容器连接在同一个网络中,方便它们进行内部通信。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67c03341314edc268466c15d