Reusing postgresql database from volume in docker-compose

Viewed 1355

When I created volume in Docker using command:

docker volume create pg-data

Then I set up basic postgresql database from postgres image:

docker run --rm -v pg-data:/var/lib/postgresql/data --name pg-docker -e POSTGRES_PASSWORD=docker -p 5433:5432 postgres

Everything worked fine. Database persist and I can even access it directly from the host. I created several roles here like app_user_1.

Now then I wanted to spin up postgresql in container using docker-compose. I shutdown the above postgresql container beforehand.

There I have this settting:

version: '3.7'

services:
  db:
    image: postgres
    volumes:
      - pg-data:/var/lib/postgresql/data/
    expose:
      - 5432
    restart: always
    environment:
      - POSTGRES_PASSWORD=docker
      - POSTGRES_USER=postgres
  web:
    build: .
    volumes:
      - ./app:/app
    ports:
      - 8001:8000
    environment:
      - ENVIRONMENT=dev
      - TESTING=0
    depends_on:
      - db

volumes:
  pg-data:

However it seems that even though I mapped the same volume and used same env settings as in docker run command the postgresql instance in container created with docker-compose has no databases and no roles at all. I get the following error:

psql: error: FATAL: role "postgres" does not exist

or

psql: error: FATAL: role "app_user_1" does not exist

So it seems it behaves as though as it is different instance of postgresql. When I restarted the first container with docker run everything was there (all the databases and roles).

Any idea why this is happening? How can I reuse the databases from the first container in the docker-compose?

1 Answers

You need to define the volume you wish to use (the one you created manually with docker volume create as external to docker-compose as it was created externally

This is because the volumes created by docker-compose are 'internal' to it, so using ones created by just docker are 'external'. =)

Ref the offical docs at https://docs.docker.com/storage/volumes/#use-a-volume-with-docker-compose

The change to your compose file would be as follows:

...
volumes:
  pg-data:
    external: true

(Just that last line)

Hope that helps! =)


Additional Note You can confirm this, by performing a docker volume ls | grep pg-data command which will list all volumes, then only show you the ones referencing 'pg-data'. On my system where I was testing before I gave my answer, I get the following:

docker volume ls | grep pg-data
local     pg-data
local     postgresstackoverflow_pg-data

As you can see, the docker volume create one is listed first, as a local volume called 'pg-data', then the docker-compose.yml created one is next prefixed by the naming convention of docker-compose with the directory name that it was in at the time.

Related