node.js ECONNREFUSED for Postgres on nodeJS with dockers
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33357567/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ECONNREFUSED for Postgres on nodeJS with dockers
提问by Stainz42
I'm building an app running on NodeJS using postgresql. I'm using SequelizeJS as ORM. To avoid using real postgres daemon and having nodejs on my own device, i'm using containers with docker-compose.
我正在使用 postgresql 构建在 NodeJS 上运行的应用程序。我使用 SequelizeJS 作为 ORM。为了避免使用真正的 postgres 守护进程并在我自己的设备上使用 nodejs,我使用带有 docker-compose 的容器。
when I run docker-compose upit starts the pg database
当我运行docker-compose up它时会启动 pg 数据库
database system is ready to accept connections
and the nodejs server. but the server can't connect to database.
和 nodejs 服务器。但是服务器无法连接到数据库。
Error: connect ECONNREFUSED 127.0.01:5432
If I try to run the server without using containers (with real nodejs and postgresd on my machine) it works.
如果我尝试在不使用容器的情况下运行服务器(在我的机器上使用真正的 nodejs 和 postgresd),它就可以工作。
But I want it to work correctly with containers. I don't understand what i'm doing wrong.
但我希望它与容器一起正常工作。我不明白我做错了什么。
here is the docker-compose.ymlfile
这是docker-compose.yml文件
web:
image: node
command: npm start
ports:
- "8000:4242"
links:
- db
working_dir: /src
environment:
SEQ_DB: mydatabase
SEQ_USER: username
SEQ_PW: pgpassword
PORT: 4242
DATABASE_URL: postgres://username:[email protected]:5432/mydatabase
volumes:
- ./:/src
db:
image: postgres
ports:
- "5432:5432"
environment:
POSTGRES_USER: username
POSTGRES_PASSWORD: pgpassword
Could someone help me please?
有人可以帮我吗?
(someone who likes docker :) )
(喜欢 docker 的人 :) )
回答by Andy
Your DATABASE_URLrefers to 127.0.0.1, which is the loopback adapter(more here). This means "connect to myself".
您DATABASE_URL指的是127.0.0.1,它是环回适配器(更多在这里)。这意味着“连接到我自己”。
When running both applications (without using Docker) on the same host, they are both addressable on the same adapter (also known as localhost).
在同一主机上运行两个应用程序(不使用 Docker)时,它们都可以在同一个适配器(也称为localhost)上寻址。
When running both applications in containers they are not both on localhost as before. Instead you need to point the webcontainer to the dbcontainer's IP address on the docker0adapter - which docker-composesets for you.
在容器中运行这两个应用程序时,它们不像以前那样都在 localhost 上。相反,您需要将web容器指向适配器db上容器的 IP 地址docker0- 这是docker-compose为您设置的。
Change:
改变:
DATABASE_URL: postgres://username:[email protected]:5432/mydatabase
to
到
DATABASE_URL: postgres://username:pgpassword@db:5432/mydatabase
This works thanks to Docker links: the webcontainer has a file (/etc/hosts) with a dbentry pointing to the IP that the dbcontainer is on. This is the first place a system (in this case, the container) will look when trying to resolve hostnames.
这要归功于 Docker 链接:web容器有一个文件 ( /etc/hosts),其中的db条目指向db容器所在的 IP 。这是系统(在本例中为容器)在尝试解析主机名时首先查看的位置。
回答by Abu Shumon
For further readers, if you're using Docker desktop for Macuse host.docker.internalinstead of localhostor 127.0.0.1as it's suggested in the doc. I came across same connection refused...problem. Backend api-servicecouldn't connect to postgresusing localhost/127.0.0.1. Below is my docker-compose.yml and environment variables as a reference:
欲了解更多的读者,如果您使用的Docker desktop for Mac使用host.docker.internal,而不是localhost或127.0.0.1作为它的建议的文档。我遇到了同样的connection refused...问题。后端api-service无法连接到postgres使用localhost/127.0.0.1. 下面是我的 docker-compose.yml 和环境变量作为参考:
version: "2"
services:
api:
container_name: "be"
image: <image_name>:latest
ports:
- "8000:8000"
environment:
DB_HOST: host.docker.internal
DB_USER: <your_user>
DB_PASS: <your_pass>
networks:
- mynw
db:
container_name: "psql"
image: postgres
ports:
- "5432:5432"
environment:
POSTGRES_DB: <your_postgres_db_name>
POSTGRES_USER: <your_postgres_user>
POSTGRES_PASS: <your_postgres_pass>
volumes:
- ~/dbdata:/var/lib/postgresql/data
networks:
- mynw
回答by MEDZ
If you send database vars separately. You can assign a database host.
如果您单独发送数据库变量。您可以分配数据库主机。
DB_HOST=<POSTGRES_SERVICE_NAME> #in your case "db" from docker-compose file.
回答by leventov
If none of the other solutions worked for you, consider manual wrapping of PgPool.connect()with retry upon having ECONNREFUSED:
如果其他解决方案都不适合您,请考虑PgPool.connect()在使用 ECONNREFUSED 后手动包装with 重试:
const pgPool = new Pool(pgConfig);
const pgPoolWrapper = {
async connect() {
for (let nRetry = 1; ; nRetry++) {
try {
const client = await pgPool.connect();
if (nRetry > 1) {
console.info('Now successfully connected to Postgres');
}
return client;
} catch (e) {
if (e.toString().includes('ECONNREFUSED') && nRetry < 5) {
console.info('ECONNREFUSED connecting to Postgres, ' +
'maybe container is not ready yet, will retry ' + nRetry);
// Wait 1 second
await new Promise(resolve => setTimeout(resolve, 1000));
} else {
throw e;
}
}
}
}
};
(See this issuein node-postgres for tracking.)
(请参阅node-postgres 中的此问题以进行跟踪。)
回答by Philip Jay Fry
I had two containers one called postgresdb, and another call node
我有两个容器,一个叫做 postgresdb,另一个调用节点
I changed my node queries.js from:
我从以下位置更改了我的节点 query.js:
const pool = new Pool({
user: 'postgres',
host: 'localhost',
database: 'users',
password: 'password',
port: 5432,
})
To
到
const pool = new Pool({
user: 'postgres',
host: 'postgresdb',
database: 'users',
password: 'password',
port: 5432,
})
All I had to do was change the host to my container name ["postgresdb"] and that fixed this for me. I'm sure this can be done better but I just learned docker compose / node.js stuff in the last 2 days.
我所要做的就是将主机更改为我的容器名称 ["postgresdb"] 并为我解决了这个问题。我确信这可以做得更好,但我在过去 2 天内刚刚学习了 docker compose / node.js 的东西。

