title: Can't reach postgres container from app container
body: <p>I have a docker-composer.yml that is setting up two services: <code>server</code> and <code>db</code>. The Node.js server, which is the <code>server</code> service, uses <code>pg</code> to connect to the PostgreSQL database; and the <code>db</code> service is a PostgreSQL image.</p>
  <p>On the server startup, it tries to connect to the database but gets a timeout.</p>
  <hr />
  <p><code>docker-compose.yml</code></p>
  <pre class="lang-yaml prettyprint-override"><code>version: '3.8'
  
  services:
    server:
      image: myapi
      build: .
      container_name: server
      env_file: .env
      environment:
        - PORT=80
        - DATABASE_URL=postgres://postgres:postgres@db:15432/mydb
        - REDIS_URL=redis://redis
      ports:
        - 3000:80
      depends_on:
        - db
      command: node script.js
      restart: unless-stopped
  
    db:
      image: postgres
      container_name: db
      environment:
        POSTGRES_USER: postgres
        POSTGRES_PASSWORD: postgres
        POSTGRES_DB: mydb
      ports:
        - 15432:15432
      volumes:
        - db-data:/var/lib/postgresql/data
      command: -p 15432
      restart: unless-stopped
  
  volumes:
    db-data:
  </code></pre>
  <p><em>Edit: code above changed to remove <code>links</code> and <code>expose</code>.</em></p>
  <hr />
  <p><code>db</code> service output:</p>
  <pre><code>db        | 
  db        | PostgreSQL Database directory appears to contain a database; Skipping initialization
  db        | 
  db        | 2020-11-05 20:18:15.865 UTC [1] LOG:  starting PostgreSQL 13.0 (Debian 13.0-1.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit
  db        | 2020-11-05 20:18:15.865 UTC [1] LOG:  listening on IPv4 address &quot;0.0.0.0&quot;, port 15432
  db        | 2020-11-05 20:18:15.865 UTC [1] LOG:  listening on IPv6 address &quot;::&quot;, port 15432
  db        | 2020-11-05 20:18:15.873 UTC [1] LOG:  listening on Unix socket &quot;/var/run/postgresql/.s.PGSQL.15432&quot;
  db        | 2020-11-05 20:18:15.880 UTC [25] LOG:  database system was shut down at 2020-11-05 20:18:12 UTC
  db        | 2020-11-05 20:18:15.884 UTC [1] LOG:  database system is ready to accept connections
  </code></pre>
  <hr />
  <p><code>script.js</code> - used by the command from the <code>server</code> service.</p>
  <pre class="lang-js prettyprint-override"><code>const pg = require('pg');
  
  console.log(process.env.DATABASE_URL);
  
  const pool = new pg.Pool({
    connectionString: process.env.DATABASE_URL,
    connectionTimeoutMillis: 5000,
  });
  pool.connect((err, _, done) =&gt; {
    if (err) {
      console.error(err);
      done(err);
    }
    done();
  });
  pool.query('SELECT NOW()', (err, res) =&gt; {
    console.log(err, res);
    pool.end();
  });
  
  const client = new pg.Client({
    connectionString: process.env.DATABASE_URL,
    connectionTimeoutMillis: 5000,
  });
  client.connect(console.error);
  client.query('SELECT NOW()', (err, res) =&gt; {
    console.log(err, res);
    client.end();
  });
  </code></pre>
  <p><code>server</code> service output:</p>
  <p><em>NOTE: The first line is the output of the first <code>console.log</code> call from <code>script.js</code>.</em></p>
  <p><em>NOTE: Since the <code>server</code> service is set up with <code>restart: unless-stopped</code>, it will repeat this output forever.</em></p>
  <pre><code>server    | postgres://postgres:postgres@db:15432/mydb
  server    | Error: Connection terminated due to connection timeout
  server    |     at Connection.&lt;anonymous&gt; (/home/node/app/node_modules/pg/lib/client.js:255:9)
  server    |     at Object.onceWrapper (events.js:421:28)
  server    |     at Connection.emit (events.js:315:20)
  server    |     at Socket.&lt;anonymous&gt; (/home/node/app/node_modules/pg/lib/connection.js:78:10)
  server    |     at Socket.emit (events.js:315:20)
  server    |     at emitCloseNT (net.js:1659:8)
  server    |     at processTicksAndRejections (internal/process/task_queues.js:79:21)
  server    |     at runNextTicks (internal/process/task_queues.js:62:3)
  server    |     at listOnTimeout (internal/timers.js:523:9)
  server    |     at processTimers (internal/timers.js:497:7)
  server    | Error: Connection terminated due to connection timeout
  server    |     at Connection.&lt;anonymous&gt; (/home/node/app/node_modules/pg/lib/client.js:255:9)
  server    |     at Object.onceWrapper (events.js:421:28)
  server    |     at Connection.emit (events.js:315:20)
  server    |     at Socket.&lt;anonymous&gt; (/home/node/app/node_modules/pg/lib/connection.js:78:10)
  server    |     at Socket.emit (events.js:315:20)
  server    |     at emitCloseNT (net.js:1659:8)
  server    |     at processTicksAndRejections (internal/process/task_queues.js:79:21)
  server    |     at runNextTicks (internal/process/task_queues.js:62:3)
  server    |     at listOnTimeout (internal/timers.js:523:9)
  server    |     at processTimers (internal/timers.js:497:7) undefined
  server    | Error: timeout expired
  server    |     at Timeout._onTimeout (/home/node/app/node_modules/pg/lib/client.js:95:26)
  server    |     at listOnTimeout (internal/timers.js:554:17)
  server    |     at processTimers (internal/timers.js:497:7)
  server    | Error: Connection terminated unexpectedly
  server    |     at Connection.&lt;anonymous&gt; (/home/node/app/node_modules/pg/lib/client.js:255:9)
  server    |     at Object.onceWrapper (events.js:421:28)
  server    |     at Connection.emit (events.js:315:20)
  server    |     at Socket.&lt;anonymous&gt; (/home/node/app/node_modules/pg/lib/connection.js:78:10)
  server    |     at Socket.emit (events.js:315:20)
  server    |     at emitCloseNT (net.js:1659:8)
  server    |     at processTicksAndRejections (internal/process/task_queues.js:79:21) undefined
  server    | postgres://postgres:postgres@db:15432/mydb
  ...
  </code></pre>
  <hr />
  <p>From the host computer, I can reach the PostgreSQL database at the <code>db</code> service, <strong>connecting successfully</strong>, using the same script from the <code>server</code> service.</p>
  <p>The output of the script running from the host computer:</p>
  <pre class="lang-js prettyprint-override"><code>➜  node script.js
  postgres://postgres:postgres@localhost:15432/mydb
  null Client { ... }
  undefined Result { ... }
  null Result { ... }
  </code></pre>
  <p>This output means the connection succeeded.</p>
  <hr />
  <h3>In summary:</h3>
  <p>I can't reach the <code>db</code> container from the <code>server</code> container, getting timeouts on the connection, but I can reach the <code>db</code> container from the host computer, connecting successfully.</p>
  <hr />
  <h3>Considerations</h3>
  <p>First, thanks for the answer so far. Addressing some points raised:</p>
  <ul>
  <li><p><strong>Missing network:</strong></p>
  <p>It isn't required because docker-compose has a default network. A tested with a custom network but it didn't work either.</p>
  </li>
  <li><p><strong>Order of initialization:</strong></p>
  <p>I'm using <code>depends_on</code> to ensure the <code>db</code> container is started first but I know it isn't ensuring the database is in fact initialized first then the server. It isn't the problem because the server breaks when a timeout happens and it runs again because it is set up with <code>restart: unless-stopped</code>. So if the database is still initializing on the first or second try to start the server, there is no problem because the server will continue to be restarted until it succeeds in the connection (which never happened.)</p>
  </li>
  <li><p><strong>UPDATE:</strong></p>
  <p>From the <code>server</code> container, I could reach the database at the <code>db</code> service using <code>psql</code>. I still can't connect from the Node.js app there.</p>
  <p>The <code>DATABASE_URL</code> isn't the problem because the URI I used in the <code>psql</code> command is the same URI used by the <code>script.js</code> and printed by the first <code>console.log</code> call there.</p>
  <p>Command-line used:</p>
  <pre><code>docker exec -it server psql postgres://postgres:postgres@db:15432/mydb
  </code></pre>
  </li>
  </ul>
  <p><em>Edit: Improved code by removing the dependency for Sequelize. Now it uses only <code>pg</code> and calls the script directly.</em></p>