edgexfoundry / edgexfoundry/edgex-compose
database service loses all data on container restart — PostgreSQL 18 anonymous volume shadows named volume
- Dominant language
- Makefile
- Stars
- 113
- Forks
- 127
- PR merge metrics
- No merged PRs in 30d
Description
Affected Services [REQUIRED]
The issue is located in: database service (edgex-postgres) — docker-compose-no-secty.yml and all compose file variants that use postgres:18.1-alpine3.22
Is this a regression?
Yes, the previous version in which this bug was not present was: EdgeX Foundry v3.x (which used PostgreSQL 16/17)
Description and Minimal Reproduction [REQUIRED]
All data stored in PostgreSQL (devices, profiles, readings) is lost every time containers are stopped with docker compose down and restarted with docker compose up -d. No -v flag is used. The named volume edgex_db-data persists on disk but PostgreSQL never reads it — it initialises a fresh empty database on every restart.
Steps to reproduce:
bash# 1. Start stack
docker compose -f docker-compose-no-secty.yml up -d
# 2. Register a device via API
curl -s -X POST http://localhost:59881/api/v3/device ...
# 3. Confirm device exists
docker exec edgex-postgres psql -U postgres -d edgex_db \
-c "SELECT COUNT(*) FROM core_metadata.device;"
# Returns: 1
# 4. Stop containers (no -v flag)
docker compose -f docker-compose-no-secty.yml down
# 5. Restart
docker compose -f docker-compose-no-secty.yml up -d
# 6. Check again
docker exec edgex-postgres psql -U postgres -d edgex_db \
-c "SELECT COUNT(*) FROM core_metadata.device;"
# Returns: 0 ← all data lost
Root cause:
PostgreSQL 18 changed its VOLUME declaration in the official Docker image from /var/lib/postgresql/data to /var/lib/postgresql (parent path). Because the EdgeX compose file mounts the named volume db-data only at /var/lib/postgresql/data, Docker automatically creates an anonymous volume at the parent path /var/lib/postgresql on every container start. This anonymous volume shadows the named volume at the child path. PostgreSQL sees an empty directory, runs initdb, and all existing data is discarded.
Confirmed via docker inspect edgex-postgres — two volumes are present:
edgex_db-data at /var/lib/postgresql/data — named, persistent ✓
a8f3bc92... at /var/lib/postgresql — anonymous, recreated fresh on every restart ✗
This is a known PostgreSQL 18 breaking change tracked upstream at [docker-library/postgres #1400](https://github.com/docker-library/postgres/issues/1400).
🔥 Exception or Error
No exception is thrown. PostgreSQL silently reinitialises with a fresh database.
The only indicator is this log line on every restart:
PostgreSQL Database directory appears to contain a database; Skipping initialization
followed immediately by a clean empty database with no schemas or data from previous runs.
🌍 Your Environment
Deployment Environment: macOS (Apple Silicon M-series) — Docker Desktop
EdgeX Version [REQUIRED]: 4.0.1 (Odesa) — docker-compose-no-secty.yml from the odesa branch
Anything else relevant?
PostgreSQL image: postgres:18.1-alpine3.22
The issue affects all compose file variants in this repo that use PostgreSQL 18 (docker-compose.yml, docker-compose-no-secty.yml, etc.)
The bug does not occur if docker compose down -v is avoided — the named volume edgex_db-data is never deleted, but it is never read either because the anonymous volume always shadows it
Reference: [docker-library/postgres #1400](https://github.com/docker-library/postgres/issues/1400)
Contributor guide
Assessment
This issue has not been assessed yet.