How to persist data in a dockerized postgres database using volumes

My docker compose file has three containers, web, nginx, and postgres. Postgres looks like this:

postgres:
  container_name: postgres
  restart: always
  image: postgres:latest
  volumes:
    - ./database:/var/lib/postgresql
  ports:
    - "5432:5432

My goal is to mount a volume which corresponds to a local folder called ./database inside the postgres container as /var/lib/postgres. When I start these containers and insert data into postgres, I verify that /var/lib/postgres/data/base/ is full of the data I’m adding (in the postgres container), but in my local system, ./database only gets a data folder in it, i.e. ./database/data is created, but it’s empty. Why?

  • Clone a secure git repo in Kubernetes pod
  • Multi Docker Elastic Beanstalk: upload .ebextensions
  • docker of solr and nutch working together?
  • Run Eclim on the remote server
  • Unable to create Persistent Volume Claim for PetSet on CoreOS
  • https is not working on httpd docker container
  • Notes:

    • This suggests my above file should work.
    • This person is using docker services which is interesting

    — UPDATE 1 —

    Per Nick’s suggestion, I did a docker inspect and found:

        "Mounts": [
            {
                "Source": "/Users/alex/Documents/MyApp/database",
                "Destination": "/var/lib/postgresql",
                "Mode": "rw",
                "RW": true,
                "Propagation": "rprivate"
            },
            {
                "Name": "e5bf22471215db058127109053e72e0a423d97b05a2afb4824b411322efd2c35",
                "Source": "/var/lib/docker/volumes/e5bf22471215db058127109053e72e0a423d97b05a2afb4824b411322efd2c35/_data",
                "Destination": "/var/lib/postgresql/data",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],
    

    Which makes it seem like the data is being stolen by another volume I didn’t code myself. Not sure why that is. Is the postgres image creating that volume for me? If so, is there some way to use that volume instead of the volume I’m mounting when I restart? Otherwise, is there a good way of disabling that other volume and using my own, ./database?

    — UPDATE 2 —

    I found the solution, thanks to Nick! (and another friend) Answer below.


    The larger question is that I’d like to have all my data in my database every time I start these containers, without having to insert it at startup each time. Will my postgres instance, supplied with a volume full of data inserted by a previous postgres container, properly have all the data I want it to? Or is there a better way of getting my data to persist across containers?

  • How to deploy consul using Docker 1.12 swarm mode
  • update custom configuration file in Docker
  • Install Discourse (a docker image) on Openshift Online
  • Docker container can't connect to host application using IP whitelist
  • Is it possible to run match servers on Kubernetes for a Real Time Multiplayer game?
  • How can Services running in a Docker VM and running on localhost register at EUREKA dynamically?
  • 3 Solutions collect form web for “How to persist data in a dockerized postgres database using volumes”

    Strangely enough, the solution ended up being to change

    volumes:
      - ./postgres-data:/var/lib/postgresql
    

    to

    volumes:
      - ./postgres-data:/var/lib/postgresql/data
    

    I would avoid using a relative path. Remember that docker is a daemon/client relationship.

    When you are executing the compose, it’s essentially just breaking down into various docker client commands, which are then passed to the daemon. That ./database is then relative to the daemon, not the client.

    Now, the docker dev team has some back and forth on this issue, but the bottom line is it can have some unexpected results.

    In short, don’t use a relative path, use an absolute path.

    I think you just need to create your volume outside docker first with a docker create -v /location --name and then reuse it.

    And by the time I used to use docker a lot, it wasn’t possible to use a static docker volume with dockerfile definition so my suggestion is to try the command line (eventually with a script ) .

    Docker will be the best open platform for developers and sysadmins to build, ship, and run distributed applications.