Lose a database, then keep it with a volume

short · 30 min · Objective 2.6

Task

Reproduce the most common serious container mistake -- data in the writable layer, gone on rm -- then fix it with a volume. Then set up name resolution between two containers and see why the default bridge does not provide it.

Steps

  1. Run a database container with NO volume: podman run -d --name db -e POSTGRES_PASSWORD=lab docker.io/library/postgres:16 (the image refuses to start without a password, and the tag is pinned: from version 18 the image keeps its data in a different directory). Create a table called lab and insert a row: podman exec db psql -U postgres -c 'create table lab(x int); insert into lab values (1)'.
  2. Stop and remove the container with podman rm, then run a fresh one from the same image. Confirm the data is gone -- not corrupted, gone.
  3. Now run it with a named volume mounted at the data directory (-v labdata:/var/lib/postgresql/data, same name db). Repeat: insert data, remove the container, run a new one against the same volume, and confirm the data survived.
  4. Demonstrate a read-only bind mount for configuration: mount a config file with :ro and confirm the container cannot write to it.
  5. On the default bridge, run two containers and confirm they CANNOT resolve each other by name.
  6. Create a user-defined network (podman network create labnet), run the db container and an app container on it (podman run -d --name app --network labnet rockylinux:9 sleep infinity), and confirm they now resolve each other by name -- the app reaches the db at db:5432 with no addresses anywhere.
  7. Publish a port two ways and inspect the exposure: -p 8080:80 binds every interface, -p 127.0.0.1:8080:80 binds loopback only. Confirm with ss.

Verify

# after step 3, against the new container on the same volume:
podman exec db psql -U postgres -tAc 'select count(*) from lab' 2>/dev/null   # non-zero
# name resolution on the user-defined network:
podman exec app getent hosts db && echo "resolves by name"
# exposure:
ss -tlnp | grep ':8080'      # 0.0.0.0 vs 127.0.0.1

The contrast between steps 2 and 3 is the whole lesson: the same image and the same data, lost without a volume and kept with one. Step 6's name resolution working only on the user-defined network is the practical reason to create one.

Notes

Anything written outside a volume lives in the container's thin writable layer and disappears with the container. A database in a container without a volume loses everything on the first rm, and it is the most common serious mistake in container deployments -- worth making once, deliberately, on data you do not care about.

This is an independent study companion for CompTIA Linux+ and is not produced by or endorsed by CompTIA.