Skip to Content
Named Volume vs Bind Mount for a Database
Intermediate
0 likes
Tutorials

Named Volume vs Bind Mount for a Database

Run PostgreSQL 18 on a named volume and on a bind mount and compare what each leaves on your disk. After this, you can pick the right mount for a database and mount the right folder.

A database writes constantly, in many small files, and it must still be there after the container is gone. Docker gives you two places to keep those files: a named volume and a folder from your computer. Both work with PostgreSQL on Docker Desktop. This page runs both and shows what differs, so you can choose without guessing.

Where PostgreSQL 18 keeps its data

The image decides the path. Since version 18 the official image keeps its data in a version folder under /var/lib/postgresql, and that parent is the folder to mount.

docker run --rm postgres:18-alpine printenv PGDATA
/var/lib/postgresql/18/docker

Older tutorials mount /var/lib/postgresql/data. With version 18 that path is wrong, and the data would sit in an anonymous volume that you did not name. All the commands here use the parent folder. The password is made up, for a throwaway container.

A named volume

Start a database on a named volume, add a row, remove the container, and start a new one on the same volume.

docker volume create db-data | Out-Null
docker run -d --name db-one -e POSTGRES_PASSWORD=not-a-real-password -v db-data:/var/lib/postgresql postgres:18-alpine | Out-Null
do { Start-Sleep -Seconds 1; docker exec db-one pg_isready -q 2>$null } until ($LASTEXITCODE -eq 0)
docker exec db-one psql -U postgres -c "create table notes (id int, body text); insert into notes values (1, 'still here');"
docker rm -f db-one | Out-Null
docker run -d --name db-two -e POSTGRES_PASSWORD=not-a-real-password -v db-data:/var/lib/postgresql postgres:18-alpine | Out-Null
do { Start-Sleep -Seconds 1; docker exec db-two pg_isready -q 2>$null } until ($LASTEXITCODE -eq 0)
docker exec db-two psql -U postgres -c "select * from notes"
CREATE TABLE
INSERT 0 1
 id |    body
----+------------
  1 | still here
(1 row)

The second container found the table, because the data belongs to the volume. The pg_isready loop waits until the database accepts connections. The first start of an empty database takes a few seconds while it creates its files.

A bind mount

The same with a folder from your computer.

New-Item -ItemType Directory -Force db-files | Out-Null
docker run -d --name db-bind -e POSTGRES_PASSWORD=not-a-real-password -v "${PWD}/db-files:/var/lib/postgresql" postgres:18-alpine | Out-Null
do { Start-Sleep -Seconds 1; docker exec db-bind pg_isready -q 2>$null } until ($LASTEXITCODE -eq 0)
docker exec db-bind psql -U postgres -c "select 'works on a bind mount' as result"
"files in the Windows folder: " + @(Get-ChildItem db-files -Recurse -File).Count
        result
-----------------------
 works on a bind mount
(1 row)

files in the Windows folder: 973

It works too. But look at the last line. Hundreds of database files are now in a folder on your Windows disk. Your backup tool, search indexer and antivirus can all see them, and any of them can slow the database down or, in the worst case, lock a file while PostgreSQL is writing it.

How I choose

WorksYesYes, on Docker Desktop
Speed on WindowsStays on the Linux side, fasterCrosses into the Windows file system, slower
Files you can browseNo, use a throwaway containerYes, in Explorer
Riskdocker volume rm deletes the dataDeleting or syncing the folder deletes or corrupts it

For a database I use a named volume every time. I want the files to be Docker's business, not my backup tool's. I use a bind mount for a database only when I need to look at the files, and never in a folder that OneDrive or another sync tool watches.

⚠ Warning: Do not copy a bind-mounted database folder while the container runs, and do not open the files with other programs. For a backup, use pg_dump from inside the container, or stop the container first.

Clean up

docker rm -f db-two db-bind
docker volume rm db-data

Related course: Docker Intermediate.

About

Run PostgreSQL 18 on a named volume and on a bind mount and compare what each leaves on your disk. After this, you can pick the right mount for a database and mount the right folder.

Responsible
Jay P
Last Update
08/06/2026
Reading Time
4 min
Was this helpful?
​ 0 ​ 0

Comments (0)

Sign in to comment

No comments yet.