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:
- Stopping the container.
- Removing the container.
- Recreating the container.
- 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/dataNow stop the container and delete it:
docker stop demo-postgres
docker rm demo-postgresWe 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:17If 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/dataActually, 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:
- Stop the container.
- Delete the container.
- Create the volume.
- Run the container, instructing it to use the newly-created volume.
So, again, stop and delete the container:
docker rm --force demo-postgresYou can make sure it has, actually, been deleted by using the
docker ps -acommand.
Volumes are managed using the docker volume command. Let’s create a volume for our PostgreSQL database:
docker volume create postgres-dataWe 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:17In 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 demodbThen 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;
\qRestart the container:
docker restart demo-postgresAnd 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-postgresThen 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:17And verify, again, data persistence:
docker exec -it demo-postgres psql -U demouser -d demodb -c "SELECT * FROM users;"