这种类型的通信 docker 直接支持。代码不需要作任何修改,例如,使用 axios 从 https://swapi.dev/api/films 获取数据:
app.get("/movies", async (req, res) => {
try {
const response = await axios.get("https://swapi.dev/api/films");
res.status(200).json({ movies: response.data });
} catch (error) {
res.status(500).json({ message: "Something went wrong." });
}
});
2. 容器与本机上的服务通信
例如,容器内的 Node app 要访问安装在本机上的 MongoDB,必须将代码中的 localhost 修改为 host.docker.internal
mongoose.connect(
// 'mongodb://localhost:27017/swfavorites', 修改成下面的代码
'mongodb://host.docker.internal:27017/swfavorites',
{ useNewUrlParser: true },
(err) => {
if (err) {
console.log(err);
} else {
app.listen(3000);
}
}
);
docker 能够理解 host.docker.internal 并将其翻译为本机 ip 地址。
3. 容器与容器的通信(即跨容器通信)假定现在有两个容器,一个容器装的是 Node App,一个容器装的是 MongoDB,Node App 容器想要与这个 MongoDB 容器通信,进行数据存储访问等操作。
方法1: 使用 ip 地址,这个方法繁琐,步骤如下: 1. 创建 MongoDB 容器,不需要 Dockerfile,运行下述命令创建并运行一个名称为 mongodb 的容器:
docker run -d --name mongodb mongo2. 查看容器的 ip 地址
使用下述命令查看刚生成的 mongodb 的 ip 地址:
docker container inspect mongodb
可以看到显示的此容器的ip地址为172.18.0.2:
"IPAddress": "172.18.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "MacAddress": "02:42:ac:12:00:02", "DriverOpts": null3. 修改代码中的 localhost 替换为上述 ip 地址:
mongoose.connect(
// 'mongodb://localhost:27017/swfavorites',
'mongodb://172.18.0.2:27017/swfavorites',
{ useNewUrlParser: true },
(err) => {
if (err) {
console.log(err);
} else {
app.listen(3000);
}
}
);
方法 2,使用容器网络
1. 首先创建 docker 内部网络:
docker network create favorites-net
可以使用命令: docker network ls 查看所有的现有的 docker 网络。
2. 创建使用这一网络的容器 创建使用网络favorites-net的node app 容器:docker run -d --name mongodb --network favorites-net mongo创建使用网络 favorite-net 的MongoDB 容器:
docker run --name favorites --network favorites-net -d --rm -p 3000:3000 favorites-node
--name : 容器命名
--network:容器将要使用的内部网络
--d: 容器以 detached 模式运行
--rm:容器在停止后将被自动删除
-p: publish,映射本机端口到容器端口
mongoose.connect(
// 'mongodb://localhost:27017/swfavorites',
// 要访问另一个容器,只需要将 localhost 改为该容器的名称
// 这里数据库容器的名称是 mongodb (容器创建时由 --name 选项指定)
"mongodb://mongodb:27017/swfavorites",
{ useNewUrlParser: true },
(err) => {
if (err) {
console.log(err);
} else {
app.listen(3000);
}
}
);
任何容器都可以成某个 docker 网络的一部分,只要两个容器属于同一网络,它们之间就可以互相自由通信,端口不需要指定。
只要一个容器向另一个容器发送请求,docker 将自动解析容器名称,并将其替换为实际的 ip 地址,
Docker 网络驱动Docker 网络支持多种不同类型的驱动,不同的驱动对应不同的网络行为。
默认的驱动是 bridge ,使用这种驱动类型,处于同一网络中的容器可以通过容器名称发现对方。
设置网络驱动的命令如下:
docker network create --driver bridge my-net
如果省略 --driver 选项,创建的网络的驱动的类型就是 bridge,驱动类型为bridge的网络实际最常用,所以创建网络时, --driver 一般可以省略。
其他类型的驱动有 host,overlay,macvlan, none, 等等。



