This tutorial will demonstrate how to persist PostgreSQL database data when running PostgreSQL in Docker, by storing the data outside of the container.
Docker lets you run PostgreSQL without having to install it directly – instead keeping it in an isolated container. This is useful if you want to run different versions of PostgreSQL for different projects, or just don’t want to (or can’t) install it on your system.
The downside of this is that PostgreSQL’s data is stored inside the container – if the container is destroyed or recreated, the data is lost. If data needs to be kept through these processes, the data must be persisted by storing it outside of the Docker container using one of the below two methods.
Method 1: Using Docker Volumes to Persist PostgreSQL Data
Docker volumes allow docker containers to store data on the host file system in a separate file. When the container is deleted, the data stored in the volume of it will remain. As Docker volumes are self-contained themselves (representing a file system in a single file), they are portable, encapsulating all of the data within them as a single file that can be mounted in a running docker container.
Here is an example of creating a Docker volume named postgres-data:
docker volume create postgres-data
Now, when you run a Docker PostgreSQL container, you can attach the volume to it, setting the point in the filesystem in the PostgreSQL container where the volume will be mounted:
docker run --name postgres_server -v postgres-data:/var/lib/postgresql/data -d postgres
This will create a container named postgres_server and mount the postgres-data volume to the /var/lib/postgresql/data directory within the container using the -v option. When PostgreSQL writes to that directory, the data will be written to the volume outside of the container, persisting it.
Docker volumes can be listed by running:
docker volume ls
This is the preferred method for persisting data in Docker if you are looking for the simplest, easiest the manage solution.
Method 2: Using Docker Bind Mounts to Persist PostgreSQL Data
If you want to store your PostgreSQL data outside of Docker completely, and be in full control of it for the purposes of backing it up or moving it about, this alternative method for persisting PostgreSQL data in Docker works well.
Docker bind mounts mount a directory from the host directly to one inside a running Docker container. Changes made in the directory by either the host or the container will be reflected in each – they will be the same.
To create a bind mount, first create the directory on the host that will be mapped to the directory inside the container:
Choose a path that the docker service will be able to write to.
Now, when launching a Docker container, the bind mount can be specified:
docker run --name postgres_server -v /path/to/postgres/data:/var/lib/postgresql/data -d postgres
Like volumes, bind mounts uses the -v option. Above, the path /path/to/postgres/data on the host is mapped to /var/lib/postgresql/data inside the container. When data is written to /var/lib/postgresql/data by PostgreSQL in the container, it is also written to /var/lib/postgresql/data on the host machine, meaning that it will be available if the container is destroyed.