skip to Main Content

I want to expose 5432 port to be accessible externally, but before doing that I want to limit it to only specific IPs, so I want to do that via pg_hba.conf

If I use docker default settings, communication between containers, works fine (by specified networks).

But if I specify pg_hba.conf:

# TYPE  DATABASE        USER            ADDRESS                 METHOD

# "local" is for Unix domain socket connections only
local   all             all                                     trust
# IPv4 local connections:
host    all             all             127.0.0.1/32            trust
# IPv6 local connections:
host    all             all             ::1/128                 trust
# Allow replication connections from localhost, by a user with the
# replication privilege.
local   replication     all                                     trust
host    replication     all             127.0.0.1/32            trust
host    replication     all             ::1/128                 trust

host    all             all             all                     md5

And try to use this pg_hba.conf file (which is actually straight copy from container itself):

psycopg2.OperationalError: could not translate host name "db" to address: Temporary failure in name resolution (where db is postgres db service in docker-compose.yml).

My compose has this for postgres:

  other: # other service that connects to postgres using psycopg2
    networks:
      - backend
  db:
    image: postgres:13
    command: ["postgres", "-c", "config_file=/etc/postgresql.conf"]
    ports:
      - 5432:5432  # for external communications
    volumes:
      - db-data:/var/lib/postgresql/data
      - path/to/cfg:/etc/postgresql.conf
      - path/to/hba:/etc/postgresql/pg_hba.conf
  networks:
    - backend

  networks:
    backend:

And then in postgresql.conf I have edited this line:

hba_file = '/etc/postgresql/pg_hba.conf'

Also config has this set: listen_addresses = '*'

Inspecting docker network:

docker network inspect bridge 
[
    {
        "Name": "bridge",
        "Id": "fe4fe8b8eb4e0c06d43428eadd2bb3f44a2ac581fe55618b4c70c5c28c107b8d",
        "Created": "2022-11-26T09:34:03.461094956+02:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {
            "com.docker.network.bridge.default_bridge": "true",
            "com.docker.network.bridge.enable_icc": "true",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
            "com.docker.network.bridge.name": "docker0",
            "com.docker.network.driver.mtu": "1500"
        },
        "Labels": {}
    }
]

P.S. I checked

PostgreSQL in Docker – pg_hba.conf to allow access from host to container

And How can I allow connections by specifying docker-compose host names in postgres's pg_hba.conf file?

But none seem to make any difference.

UPDATE:

I retried again, using same thing. Just specifying pg_hba.conf and now I don’t get that error. Not sure how it was solved. But pg_hba.conf is picked up just fine and I can limit access with it.

2

Answers


  1. Try to keep both config files on the default place (in /var/lib/postgresql/data) and revert the change for hba_file location. Make sure the files have the same permission and ownership as in container: 600 postgres:postgres (999:999)

    EDIT:

    Just looked in the docs. They start pg with custom config like this:

    $ docker run -d --name some-postgres -v "$PWD/my-postgres.conf":/etc/postgresql/postgresql.conf -e POSTGRES_PASSWORD=mysecretpassword postgres -c 'config_file=/etc/postgresql/postgresql.conf'
    

    where postgres before "-c" is the image name. I think you should redirect "-c" part to entrypoint.

    EDIT2:

    You’re right, according to the entrypoint script this call with "postgres" as a parameter also works.

    Login or Signup to reply.
  2. You need to add the POSTGRES_PASSWORD as an environment variable on the docker-compose.yml for the the db container, otherwise the postgres will failed with:

    tmp-db-1     | Error: Database is uninitialized and superuser password is not specified.
    tmp-db-1     |        You must specify POSTGRES_PASSWORD to a non-empty value for the
    tmp-db-1     |        superuser. For example, "-e POSTGRES_PASSWORD=password" on "docker run".
    tmp-db-1     |
    tmp-db-1     |        You may also use "POSTGRES_HOST_AUTH_METHOD=trust" to allow all
    tmp-db-1     |        connections without a password. This is *not* recommended.
    tmp-db-1     |
    tmp-db-1     |        See PostgreSQL documentation about "trust":
    tmp-db-1     |        https://www.postgresql.org/docs/current/auth-trust.html
    

    If it still fails could you share the logs of the db container?

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