Decoupling Data From a Container

It is great that we have set up our database so we can persist data in our Rails app. However, currently, there is a major failing in how it works. Let’s see what the problem is and see how to get around it.

The Postgres container problem

Part of the philosophy of using Docker is that we should treat containers as ephemeral, throwaway things that we spin up, use, and then delete.

However, our Postgres database runs in a container and persists our data by writing and modifying files on disk inside the container. What happens to our data if we delete our database container? Yep, you guessed it: we say bye-bye to all our lovely data. Not really what we want.

Now that we are going to be storing important data in our database, we need to think a bit more carefully about this. Just like in our code where we try to decouple things that change frequently from things that do not, here we want to decouple the containers that generate data from the containers that use them. Our data should be stored separately from the container running the database. That way, we could delete, remove, and recreate the container without affecting the data.

Solution

The answer to this problem is to store persistent data in volumes, which by their very nature are decoupled from the life cycle of containers. Even if we delete a container with a connected volume, the volume continues to exist independently, storing our data safely. We can then recreate the container, hook up the volume, and everything is hunky-dory.

Docker allows us to create a few different types of volumes, all of which would do the job. For example, we have already seen how to mount a local volume. However, there is another type of volume better suited to our purpose. We do not really care where or how the files are stored, we just care that they are stored somewhere separately. For this, we can create a named volume, a self-contained bucket of file storage, completely managed by Docker.

But enough of the theory. Let’s see how we do this in practice.

Adding named volumes to Compose

Named volumes can be created and managed through the docker volume command. While that is worth knowing about, since we are using Compose, we can let it handle the management of the volumes for us. Here is our docker-compose.yml modified to store our persistent data on a volume:

Get hands-on with 1200+ tech skills courses.