skip to Main Content

I am using docker to create the postgresql database.
The installation guide isn’t detailed enough for me unfortunately, maybe because I am new to docker, and I may be missing something.

https://payloadcms.com/docs/production/deployment#docker

This is my docker-compose.yml:

version: '3'

services:
  payload:
    image: node:18-alpine
    ports:
      - '3000:3000'
    volumes:
      - .:/home/node/app
      - node_modules:/home/node/app/node_modules
    working_dir: /home/node/app/
    command: sh -c "yarn install && yarn dev"
    depends_on:
      - mongo
      - postgres
    env_file:
      - .env

  mongo:
    image: mongo:latest
    ports:
      - '27017:27017'
    command:
      - --storageEngine=wiredTiger
    volumes:
      - data:/data/db
    logging:
      driver: none

  postgres:
    image: postgres:latest
    ports:
      - '5432:5432'
    environment:
      POSTGRES_DB: ExperimentOne
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
    volumes:
      - pgdata:/var/lib/postgresql/data
    logging:
      driver: none

  pgadmin:
    image: dpage/pgadmin4
    environment:
      PGADMIN_DEFAULT_EMAIL: [email protected]
      PGADMIN_DEFAULT_PASSWORD: admin
    ports:
      - "5050:80"
    depends_on:
      - postgres

volumes:
  data:
  node_modules:
  pgdata:

This is my .env:

DATABASE_URI=postgres://user:[email protected]:5432/experimentOne
PAYLOAD_SECRET=1f9719d86d80cca708048d07
PAYLOAD_PUBLIC_SERVER_URL=http://localhost:3000
NEXT_PUBLIC_SERVER_URL=http://localhost:3000

I am quite certain that the password and username and ip address are correct, because I am using the same information to connect to the db using pgadmin. But the IP address inside docker is not always the same, so the last time I wanted to connect to pgadmin, I had to inspect the IP in docker using docker inspect [container_id].

PAYLOAD_SECRET is probably wrong, it has been generated during the payload setup, and I do not know what this does, but I would guess this isn’t the problem.

If I try to open:

http://localhost:3000/admin

It is unable to connect:

ns_error_connection_refused

Console error

Pgadmin

Any ideas?

I have tried to add variables to .env.

I am stuck because the error message isn’t helping.

UPDATE:

More images to help debug.

Docker container

Docker container log

3

Answers


  1. Change the IP address in your DATABASE_URI to postgres, the name of the service in Docker. Update it to:

    DATABASE_URI=postgres://user:password@postgres:5432/ExperimentOne
    

    This way, Docker handles the IP addresses internally.

    If you’re unsure about the PAYLOAD_SECRET, just create a new random string and replace the old one.

    Also, run docker-compose logs payload to see if there are any error messages when trying to start the Payload service. When you make the changes you can do:

    docker-compose down
    docker-compose up -d
    

    And lastly make sure nothing else on your machine is using port 3000. If everything is set up correctly, you should be able to access it at http://localhost:3000/admin

    Login or Signup to reply.
  2. A few things:

    But the IP address inside docker is not always the same

    This is by design. You generally don’t want to use the private IP address that Docker assigns to a container, and instead make use of the hostname that Docker automatically creates for bridge networks.

    As @Zerx pointed out, you would then refer to your Postgres URI as postgres://user:password@postgres:5432/ExperimentOne. Where postgres is the name of the service as defined in your compose file.

    You are also missing a network block in your compose file. The network block should look something like this:

    networks:
      myNetwork:
        driver: bridge
    

    Then in your services add a network key for each service that you want to join the network

    services:
      payload:
        ...
        networks:
          - myNetwork
    
      postgres:
        ...
        networks:
          - myNetwork
    

    When troubleshooting network issues, there are two things to check. First, after your containers are started, inspect them using docker inspect <container>, and look at the networking output. Make sure that all of your containers are on the same named network. Containers can belong to multiple networks, but in order for two containers to communicate over a bridge network, they must both be part of it explicitly.

    Second, install the nmap tool inside of your payload service (apk add nmap), start both the postgres and payload containers, exec into the payload container, then check the results of nmap postgres -p 5432. If nmap reports the port as closed or unreachable, then the inter-container network communication is not set up properly.

    A few other suggestions:

    1. Add the following to your payload service so that you can more easily shell into it.
        stdin_open: true
        tty: true
    

    then you can docker compose exec payload bash

    1. Temporarily remove the command section of your service definition. That way when you start the service (after adding the stdin and tty from above) you will just get a running alpine container that you can exec into. That will let you isolate the issue to network communication between that container and the postgres service, vs some other configuration that is causing the error.

    2. Don’t try upping everything at once. Start with just one service (payload), then add others one at a time (postgres, mongo, pgadmin).

    3. While debugging, don’t disable the logging drivers. While it sounds like your postgres database is up and running, by suppressing log output you may be hiding errors.

    Login or Signup to reply.
  3. I am using docker to create the postgresql database.

    You can use this in combination with a host-based development environment. If you run

    docker-compose up -d postgres
    

    then, since the postgres service declares ports:, the database will be reachable from the host as localhost (assuming you’re using Docker Desktop, or plain Docker on native Linux) on port 5432 (the first port number).

    Then in your host environment, you can run

    export DATABASE_URI=postgres://user:password@localhost:5432/experimentOne
    yarn dev
    

    From here, you’re using a totally normal Node/Yarn development environment, except that the database happens to be running in a container.

    This setup doesn’t use the payload container, and you can delete it. It’s just attempting a very indirect route to try to run Node in a container but otherwise ignoring Docker’s image ecosystem; you’ll find it easier to directly run Node without Docker in most cases.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search