0

Today I try to dockerize an full app ( frontend , API and a database ) so that I could deploy it on a local machine or/and a virtual machine.

When doing :

docker-compose up

I got an "Connect ECONNREFUSED" when I try to start my API that will connect to the database (it uses Sequelize under the hood) with the following env variable :

DATABASE_URL: "postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-jy95}@db:5432/${POSTGRES_DB:-sourcecode}"

In docker docs, it is said :

Each container can now look up the hostname web or db and get back the appropriate container’s IP address. For example, web’s application code could connect to the URL postgres://db:5432 and start using the Postgres database.

In PostgreSQL docs, we can see that postgresql:// is also valid :

The URI scheme designator can be either postgresql:// or postgres://. Each of the URI parts is optional.

Here is my full docker-compose.yml file :

version: '3.7'
services:
  frontend:
    image: jy95/sourcecode-front
    restart: always
    depends_on:
      - api
    ports:
      - "80:3000"
      - "443:3000"
    environment:
      API_SERVER: "api:8080"
      CDN_SERVER: "api:8080/files"
  api:
    image: jy95/sourcecode_api
    restart: always
    ports:
      - "8080:3000"
    depends_on:
      - db
    environment:
      DATABASE_URL: "postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-jy95}@db:5432/${POSTGRES_DB:-sourcecode}"
      # use a env file if you want to use other values that default ones
      # https://docs.docker.com/compose/environment-variables/#the-env_file-configuration-option
  db:
    image: postgres:12-alpine
    restart: always
    ports:
      - "5432:5432"
    environment:
      # use a env file for that part later
      # https://docs.docker.com/compose/environment-variables/#the-env_file-configuration-option
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: jy95
      POSTGRES_DB: sourcecode
      POSTGRES_PORT: 5432
      # If we want to access more easily to the database (not recommended)
      # PGDATA: /var/lib/postgresql/data/pg_data
    #volumes:
    #  - pg_data:/var/lib/postgresql/data/pg_data

Thanks in advance for the help

PS: The images are already on the Docker Hub

3
  • Please can you try with real value instead of variable (e.g ${POSTGRES_PASSWORD:-jy95}) like this one DATABASE_URL=pgsql://test:test@postgresql:5432/test_db. You could export it in your terminal to test export DATABASE_URL.... Commented Feb 23, 2020 at 0:54
  • This can happen if the application tries to connect before the database is fully started. Run just docker-compose up, with no other options, and watch the error messages go by; are there database messages that come out after your application connect error? Commented Feb 23, 2020 at 1:10
  • @DavidMaze It is the command I used ( as I can see, I used "depends_on" to be sure the database is required before the API ). The error is : SequelizeConnectionRefusedError: connect ECONNREFUSED 127.0.0.1:5432 Which I don't understand : the docker docs isn't up to date ? Commented Feb 23, 2020 at 1:28

1 Answer 1

1

Your comment is actually a big clue: "It is the command I used ( as I can see, I used "depends_on" to be sure the database is required before the API ). The error is : SequelizeConnectionRefusedError: connect ECONNREFUSED 127.0.0.1:5432 Which I don't understand : the docker docs isn't up to date ?"

It looks that your api container is trying to shoot to localhost instead of db:5432 (as You have pointed out db is a DNS name and it's unlikely that it will resolve to 127.0.0.1 (IP reserved to localhost)

Quick debug: run: docker exec -it sh (in the container) apk add busybox-extras and then: telnet 127.0.0.1 5432 -> You will see that this is not reachable however telnet db 5432 -> this is perfectly fine furthermore You can run nslookup db -> as We've already established this dns name (db) should be resolvable

I have tried to add network_mode: host to api (in docker-compose.yml), but this causes your app to crash. At this point I would recommend reviewing the code for the api and looking for any references to 127.0.0.1:5432 If You run docker exec -it sh and then: printenv You will see that DB_URL environment variable is set to: postgresql://postgres:jy95@db:5432/sourcecode but are You sure that this ENV-VAR is used by the api? (maybe You have commented some code by example and You're still using a different connection string)

Sign up to request clarification or add additional context in comments.

4 Comments

It is strange indeed : in my dockerfile, I set NODE_ENV to production as a way to force Sequelize to load this variable
And printenv inside the container shows that NODE_ENV is set to production. If this is the case then maybe try to enable logging, and log the actual Environment (const env) at startup. You can see logs by using docker-compose logs -f -t
How it is even possible ? Obivious, with your tests (thanks in advance by the way) ,it seems to take the default value ("development") even with my instruction to set this variable to production ....
To anyone that got this problem, just add this in your docker-compose "environment: NODE_ENV: production" ( even if you set NODE_ENV to production in the dockerfile like me )

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.