Oct 9, 2025

Storage & Volumes

Blog Hero

Why Volumes Matter

Docker containers are temporary by nature. When a container is removed, everything inside it — data, logs, and configurations — disappears. Think of it as wiping a computer completely clean every time it’s shut down.

This behavior works fine for lightweight applications, but it’s a problem for anything that needs to store information — like a PostgreSQL database. You wouldn’t want your data to vanish every time you restart your app!

To solve this, Docker gives us Volumes — persistent storage spaces managed directly by Docker. They live outside your container but can be accessed from inside, letting your container read and write data safely.

Volume Explained:

Think of a volume as a shared “folder” that stays alive even after your container is gone. It’s like plugging in a USB drive or inserting a memory card — your app can use it to read and write data, but the information stays on the card even if the container (or the app) is removed.

In short, volumes:

  • Keep your data safe when containers are deleted
  • Can be shared between multiple containers
  • Are easy to back up or migrate
  • Behave consistently across environments

In this chapter, we’ll explore how to use volumes by running a PostgreSQL database inside Docker — creating a table and saving real data that persists even after the container stops.

Creating a Volume

Let’s create a Docker volume that we’ll use to persist PostgreSQL data. Volumes are created and managed separately from containers.

docker volume create pgdata

You can verify it was created using:

docker volume ls

And to inspect where Docker actually stores it on your system:

docker volume inspect pgdata

Docker automatically assigns a path under/var/lib/docker/volumes/ for the volume’s data. You don’t need to manually set this path — just use the volume name (in this case pgdata) and Docker handles the rest.

Using the volume name (e.g.-v pgdata:/var/lib/postgresql) tells Docker to mount the existing volume into the container at the specified location.

Running PostgreSQL with a Volume

Now let’s run PostgreSQL and tell Docker to use the pgdata volume for data storage.

docker run -d \ --name pg-demo \ -e POSTGRES_USER=demo \ -e POSTGRES_PASSWORD=demo123 \ -e POSTGRES_DB=demo_db \ -v pgdata:/var/lib/postgresql \ -p 5432:5432 \ postgres

  • -v pgdata:/var/lib/postgresql → mounts our named volume inside the container
  • -e flags → set PostgreSQL credentials and database name
  • -p 5432:5432 → maps the container’s PostgreSQL port to your local machine
⚠️Common Issues When Running PostgreSQL in Docker
1. Port Already in Use

If you already have PostgreSQL running on your system, you’ll see an error like:

ports are not available: listen tcp 0.0.0.0:5432: bind: address already in use

To temporarily stop your host PostgreSQL service:

sudo systemctl stop postgresql

After you finish testing Docker, you can restart it:

sudo systemctl start postgresql
2. Container Name Conflict

If you see an error like:

Conflict. The container name "/pg-demo" is already in use ...

This means a container with that name already exists. To fix:

# List all containers (including stopped) docker ps -a
# Remove the conflicting container docker rm pg-demo

Then you can run your container again

You can now connect to the running PostgreSQL container using:

docker exec -it pg-demo psql -U demo -d demo_db

Creating a Simple Table

Let’s create a simple table and insert a record inside PostgreSQL:

CREATE TABLE users ( id SERIAL PRIMARY KEY, name VARCHAR(50), email VARCHAR(100) ); INSERT INTO users (name, email) VALUES ('Alice', 'alice@example.com'); SELECT * FROM users;

You should see one row returned. This data is stored in the volume, not inside the temporary container filesystem.

Test Data Persistence

Let’s test if our volume really persists data after the container is removed.

# Stop and remove the container docker stop pg-demo docker rm pg-demo # Start a new container using the same volume docker run -d \ --name pg-demo-2 \ -e POSTGRES_USER=demo \ -e POSTGRES_PASSWORD=demo123 \ -e POSTGRES_DB=demo_db \ -v pgdata:/var/lib/postgresql \ -p 5432:5432 \ postgres

Connect again to the new container:

docker exec -it pg-demo-2 psql -U demo -d demo_db

Run:

SELECT * FROM users;

🎉 You should still see Alice in the table — meaning your data was preserved by the volume!

Clean Up

Once you’re done experimenting, you can clean up the containers and volumes to free space:

# Stop and remove containers docker ps -a docker stop pg-demo-2 docker rm pg-demo-2 # Remove volume docker volume ls docker volume rm pgdata

Remember, removing the volume deletes all the data permanently — use this only when you no longer need the database.

Key Takeaways

  • Containers are stateless — data disappears when they’re removed.
  • Volumes let containers store and retrieve persistent data.
  • Volumes live outside of containers but can be mounted inside them.
  • Using PostgreSQL is a great example: you can restart containers without losing your data.