如何使用 docker 容器名称而不是 IP 与 knex 进行数据库连接
How to use a docker container name instead of IP for DB connection with knex
我在 docker 容器中有一个 postgresql 数据库,在另一个 docker 容器 (nodeJS) 中有一个后端 API。这两个容器都是使用 docker-compose 启动的,因此正在使用桥接网络。
如果我在节点后端使用标准的 http post 请求 API 我可以使用数据库的 docker 容器名称(如预期的那样)连接到数据库,如下所示(片段仅显示设置):
const UN = 'postgres';
const PW = '<PW>';
const host = 'myContainerName:5432';
const database = '<DB>';
const expireDuration = 120;
//DB Connection object (client)
var conString = "postgres://" + UN + ":" + PW + "@" + host + "/" + database;
...
这是可行的,因为容器名称(向下 3 行)由 Docker 中的某种 NAT 关联解释(我不太了解 Docker 的内部工作原理)。但我知道使用容器名称是必要的,因为容器的 IP 地址可能会发生变化。
然而,我现在的愿望是在后端 API 中使用 Knex 连接到 postgresql 数据库,因为我希望开始使用数据库迁移,而 Knex 是我选择的工具这个。
但是,Knex 只允许我使用 docker 容器的 IP 地址进行连接,而不是它的容器名称,例如(这是 Knex 设置):
development: {
client: 'pg',
connection: {
host : 'myContainerName:5432',
//host : '172.20.0.3:5432',
user : 'postgres',
password : '<PW>',
database : '<DB>'
},
migrations: {
tableName: 'knex_migrations'
}
}
如果我将主机名的注释切换为容器名称,它将无法连接。
有谁知道我期望它起作用是不是做错了什么?有没有办法在 Knex 中使用容器名称?
使用容器名称的 Docker DNS 解析仅在容器内有效,但您可以将端口发布到主机 IP/localhost 并连接到该主机。
这看起来像这样:
docker run -p 192.168.2.1:1234:1234
- 如果您想从
Knex
从您的主机连接到数据库容器,您将必须公开数据库容器中的端口。这是通过使用 -p
选项完成的:
docker container run -p 5432:5432 dbImageName
您将能够使用 localhost:5432
作为主机从 knex 连接到您的数据库。
如果您正在使用 docker-compose 并且想要 运行 knex 在另一个容器中,只需将服务定义放在 docker-compose
中。它将创建默认网络并将所有容器连接到它。然后,由于在下面创建了 DNS 服务器,容器将可以从该网络上的其他容器通过它们的名称访问。
如果您不使用 docker 撰写。您可以自己创建网络:
docker network create my_net
驱动程序默认为 bridge
。然后当 运行 连接你的容器时,你必须传递 --network
选项:
docker container run --network=my_net imageName
当然,如果需要,您仍然可以为您的主机公开端口。
- 另外,请尝试在您的配置中分隔主机和端口:
connection: {
host : 'myContainerName',
port : 5432
...
- 您也可以尝试将
connection
作为字符串连接:
var pg = require('knex')({
client: 'pg',
connection: 'postgres://postgres:pass@myContainerName:5432/db'
})
我在 docker 容器中有一个 postgresql 数据库,在另一个 docker 容器 (nodeJS) 中有一个后端 API。这两个容器都是使用 docker-compose 启动的,因此正在使用桥接网络。
如果我在节点后端使用标准的 http post 请求 API 我可以使用数据库的 docker 容器名称(如预期的那样)连接到数据库,如下所示(片段仅显示设置):
const UN = 'postgres';
const PW = '<PW>';
const host = 'myContainerName:5432';
const database = '<DB>';
const expireDuration = 120;
//DB Connection object (client)
var conString = "postgres://" + UN + ":" + PW + "@" + host + "/" + database;
...
这是可行的,因为容器名称(向下 3 行)由 Docker 中的某种 NAT 关联解释(我不太了解 Docker 的内部工作原理)。但我知道使用容器名称是必要的,因为容器的 IP 地址可能会发生变化。
然而,我现在的愿望是在后端 API 中使用 Knex 连接到 postgresql 数据库,因为我希望开始使用数据库迁移,而 Knex 是我选择的工具这个。
但是,Knex 只允许我使用 docker 容器的 IP 地址进行连接,而不是它的容器名称,例如(这是 Knex 设置):
development: {
client: 'pg',
connection: {
host : 'myContainerName:5432',
//host : '172.20.0.3:5432',
user : 'postgres',
password : '<PW>',
database : '<DB>'
},
migrations: {
tableName: 'knex_migrations'
}
}
如果我将主机名的注释切换为容器名称,它将无法连接。
有谁知道我期望它起作用是不是做错了什么?有没有办法在 Knex 中使用容器名称?
使用容器名称的 Docker DNS 解析仅在容器内有效,但您可以将端口发布到主机 IP/localhost 并连接到该主机。 这看起来像这样:
docker run -p 192.168.2.1:1234:1234
- 如果您想从
Knex
从您的主机连接到数据库容器,您将必须公开数据库容器中的端口。这是通过使用-p
选项完成的:
docker container run -p 5432:5432 dbImageName
您将能够使用 localhost:5432
作为主机从 knex 连接到您的数据库。
如果您正在使用 docker-compose 并且想要 运行 knex 在另一个容器中,只需将服务定义放在
docker-compose
中。它将创建默认网络并将所有容器连接到它。然后,由于在下面创建了 DNS 服务器,容器将可以从该网络上的其他容器通过它们的名称访问。如果您不使用 docker 撰写。您可以自己创建网络:
docker network create my_net
驱动程序默认为 bridge
。然后当 运行 连接你的容器时,你必须传递 --network
选项:
docker container run --network=my_net imageName
当然,如果需要,您仍然可以为您的主机公开端口。
- 另外,请尝试在您的配置中分隔主机和端口:
connection: {
host : 'myContainerName',
port : 5432
...
- 您也可以尝试将
connection
作为字符串连接:
var pg = require('knex')({
client: 'pg',
connection: 'postgres://postgres:pass@myContainerName:5432/db'
})