# 多个 Docker Compose 的容器互联小贴士

随笔 7 / 8
阅读约需 2 分钟
目录

当你有两个不同的服务同时使用 Compose 部署,而这两个服务又需要相互通信时,你通常有三种方式来实现它们之间的连接:

host.docker.internal

Docker 提供了一个特殊的 DNS 名称 host.docker.internal,可以在容器中使用它来访问宿主机上的服务。
因此,你可以在不开放主机防火墙端口的情况下使用这个路径访问宿主机服务,你只需要确保互访的两个容器均暴露了需要访问的端口即可。

但!这个功能仅在 Docker Desktop 上可用,Linux Docker CE 用户需要使用其他方法。

使用外部网络

这是最为无脑,安全性也相应较低的方法。你只需要暴露需要互访的两个容器的端口,同时,开放主机的防火墙对应端口,随后在容器中使用主机网卡的 IP 地址进行访问即可。

使用自定义网络

这就是本文要介绍的方法了,通过将需要的服务同时连接到一个 Docker 网络中,你可以实现它们之间的直接通信,而无需暴露主机端口。

假设你有这样的两个服务,你需要让服务 2 中的 app 能够访问到服务 1 中的 app1
服务 1 中的 app1db 之间也需要互相通信,但你不需要服务 2 能够访问 db

两个初始的 docker-compose.yml
服务1
version: '3'
services:
app1:
image: app1
db:
image: postgres:latest
服务2
version: '3'
services:
app:
image: app-xxx

你只需要首先创建一个网络:

Terminal window
docker network create my-network

然后为两个 Compose 中需要互访的容器添加网络:

服务1
version: '3'
services:
app1:
image: app1
networks:
- default
- my-network
db:
image: postgres:latest
networks:
my-network:
external: true
服务2
version: '3'
services:
app:
image: app-xxx
networks:
- default
- my-network
networks:
my-network:
external: true

现在,你可以在 app 中通过 app1 的服务名来访问服务 1 中的 app1,而不需要暴露任何主机端口。为设置了自定义网络的容器显式配置 default 网络是必要的(除非你在 Compose 中预先设置过服务间的网络通信,不使用默认 Docker 网络),不配置会导致配置了自定义网络的容器没有连接到默认 Compose 网络,而无法相互访问。

下一篇: Tailwind CSS 小贴士
写下此篇时暂时不是懒狗的星语

这是开发的责任感和前瞻性的问题。不兼容的改变不应该轻易被加入到有许多依赖代码的软件中。升级所付出的代价可能是巨大的。
—— 《语义化版本》


随笔 系列