Skip to main content
  1. Posts/
  2. Docker/

·483 words·3 mins·
Jaume Sabater
Author
Jaume Sabater
CTO and systems engineer

Volume management with Docker
#

Volumes allow data to persist beyond the lifecycle of a container. This ensures that important data remains safe and accessible across container restarts. Let us demonstrate a data persistence issue with how our container is configured right now by following these steps:

  1. Stopping the container.
  2. Removing the container.
  3. Recreating the container.
  4. Showing container filesystem.

First, let’s show the filesystem inside the container where PostgreSQL is storing our users table:

docker exec demo-postgres ls -la /var/lib/postgresql/data

Now stop the container and delete it:

docker stop demo-postgres
docker rm demo-postgres

We are now back at the beginning. Let’s create the container again, as we did in the previous section:

docker run --name demo-postgres \
  -e POSTGRES_PASSWORD=mypassword \
  -e POSTGRES_USER=demouser \
  -e POSTGRES_DB=demodb \
  -p 5432:5432 \
  -d postgres:17

If we now check the filesystem, using the same command we used before, we will notice the data has changed:

docker exec demo-postgres ls -la /var/lib/postgresql/data

Actually, it is gone, as we can verify using the psql utility:

docker exec --interactive --tty demo-postgres psql \
  --username=demouser \
  --dbname=demodb \
  --command="SELECT * FROM pg_catalog.pg_tables WHERE schemaname = 'public';"

To ensure data persistence, we need to use volumes. We will follow these steps:

  1. Stop the container.
  2. Delete the container.
  3. Create the volume.
  4. Run the container, instructing it to use the newly-created volume.

So, again, stop and delete the container:

docker rm --force demo-postgres

You can make sure it has, actually, been deleted by using the docker ps -a command.

Volumes are managed using the docker volume command. Let’s create a volume for our PostgreSQL database:

docker volume create postgres-data

We are now ready to run the container, mapping the volume we just created in our local disk to the path where PostgreSQL stores the databases inside the ccontainer:

docker run --name demo-postgres \
  --env POSTGRES_PASSWORD=mypassword \
  --env POSTGRES_USER=demouser \
  --env POSTGRES_DB=demodb \
  --publish 5432:5432 \
  --volume "postgres-data:/var/lib/postgresql/data" \
  --detach \
  postgres:17

In order to test our setup, let’s begin by adding a table and some data. Connect to the PostgreSQL server using psql:

docker exec -it demo-postgres psql -U demouser -d demodb

Then add a table and insert some data into it:

CREATE TABLE users (
  id SERIAL PRIMARY KEY,
  name VARCHAR(50)
);
INSERT INTO users (name) VALUES ('Alice'), ('Bob'), ('Charlie');
INSERT INTO users (name) VALUES ('David'), ('Elisabeth'), ('Ferdinand');
SELECT id, name FROM users ORDER BY id ASC;
\q

Restart the container:

docker restart demo-postgres

And verify data persistence:

docker exec -it demo-postgres psql -U demouser -d demodb -c "SELECT * FROM users;"

Even better, delete the container:

docker rm --force demo-postgres

Then create it again, using the volume, as we did before:

docker run --name demo-postgres \
  -e POSTGRES_PASSWORD=mypassword \
  -e POSTGRES_USER=demouser \
  -e POSTGRES_DB=demodb \
  -p 5432:5432 \
  -v "postgres-data:/var/lib/postgresql/data" \
  -d postgres:17

And verify, again, data persistence:

docker exec -it demo-postgres psql -U demouser -d demodb -c "SELECT * FROM users;"

Related

·1287 words·7 mins

·1504 words·8 mins

·917 words·5 mins