ECONNREFUSED for Postgres on nodeJS with dockers
For further readers, if you're using Docker desktop for Mac
use host.docker.internal
instead of localhost
or 127.0.0.1
as it's suggested in the doc. I came across same connection refused...
problem. Backend api-service
couldn't connect to postgres
using localhost/127.0.0.1
. Below is my docker-compose.yml and environment variables as a reference:
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
Your DATABASE_URL
refers to 127.0.0.1
, which is the loopback adapter (more here). This means "connect to myself".
When running both applications (without using Docker) on the same host, they are both addressable on the same adapter (also known as localhost
).
When running both applications in containers they are not both on localhost as before. Instead you need to point the web
container to the db
container's IP address on the docker0
adapter - which docker-compose
sets for you.
Change:
127.0.0.1
to CONTAINER_NAME
(e.g. db
)
Example:
DATABASE_URL: postgres://username:[email protected]:5432/mydatabase
to
DATABASE_URL: postgres://username:pgpassword@db:5432/mydatabase
This works thanks to Docker links: the web
container has a file (/etc/hosts
) with a db
entry pointing to the IP that the db
container is on. This is the first place a system (in this case, the container) will look when trying to resolve hostnames.