DEV Community

Cover image for Running PostgreSQL in Docker with Persistent Volume
Athreya aka Maneshwar
Athreya aka Maneshwar

Posted on

Running PostgreSQL in Docker with Persistent Volume

Hi there! I'm Maneshwar. Right now, I’m building LiveAPI, a first-of-its-kind tool that helps you automatically index API endpoints across all your repositories. LiveAPI makes it easier to discover, understand, and interact with APIs in large infrastructures.


When running PostgreSQL inside a Docker container, one common problem is data loss if the container is restarted or deleted.

This post shows how to persist PostgreSQL data using Docker volume mounts so your database survives container restarts.

Why Persistence Matters

By default, Docker containers are ephemeral. When they stop or are removed, any data inside them is lost — unless you've mapped it to persistent storage.

PostgreSQL stores all its data in /var/lib/postgresql/data. To persist that, you need to mount a volume from your host machine or a Docker-managed volume.

PostgreSQL with Named Volume

Here's a quick docker-compose.yml setup using a named volume:

version: '3.8'

services:
  db:
    image: postgres:16
    container_name: pg-container
    environment:
      POSTGRES_USER: admin
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: mydb
    volumes:
      - pgdata:/var/lib/postgresql/data
    ports:
      - "5432:5432"

volumes:
  pgdata:
Enter fullscreen mode Exit fullscreen mode

Restart & Data Survives

docker-compose up -d
# Create a table or insert some data
docker-compose down
docker-compose up -d
# Data is still there
Enter fullscreen mode Exit fullscreen mode

The pgdata volume is managed by Docker and won't be deleted unless you explicitly remove it.

PostgreSQL with Host Bind Mount

If you want the data stored in a specific host directory (e.g. ./pgdata), modify the compose like this:

services:
  db:
    image: postgres:16
    environment:
      POSTGRES_USER: admin
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: mydb
    volumes:
      - ./pgdata:/var/lib/postgresql/data
    ports:
      - "5432:5432"
Enter fullscreen mode Exit fullscreen mode

Make sure ./pgdata exists and is writable by Docker. This method is great if you want to inspect or back up the files directly from the host.

Check Volume Status

docker volume ls
docker volume inspect <volume_name>
Enter fullscreen mode Exit fullscreen mode

To clean up:

docker volume rm pgdata
Enter fullscreen mode Exit fullscreen mode

Testing Persistence

Run a test inside the container:

docker exec -it pg-container psql -U admin -d mydb
# Inside psql:
CREATE TABLE test (id SERIAL PRIMARY KEY, name TEXT);
INSERT INTO test (name) VALUES ('docker-pg');
\q
Enter fullscreen mode Exit fullscreen mode

Now restart the container:

docker-compose down
docker-compose up -d
Enter fullscreen mode Exit fullscreen mode

Recheck the table:

docker exec -it pg-container psql -U admin -d mydb -c "SELECT * FROM test;"
Enter fullscreen mode Exit fullscreen mode

Your data is still there.

Common Gotchas

  • Make sure the volume directory (host or named) has the correct permissions.
  • Avoid mounting empty host dirs over /var/lib/postgresql/data if you already ran the container before.
  • Don't forget to back up your volume if you're using named volumes — they're not visible in the filesystem.

Conclusion

Using Docker volumes, you can safely run PostgreSQL in containers without worrying about data loss on restart. Use named volumes for simplicity, or bind mounts for full control.


LiveAPI helps you get all your backend APIs documented in a few minutes.

With LiveAPI, you can generate interactive API docs that allow users to search and execute endpoints directly from the browser.

LiveAPI Demo

If you're tired of updating Swagger manually or syncing Postman collections, give it a shot.

Top comments (0)