DEV Community

Cover image for Delete a container, lose your data? Docker volumes in 10 minutes
cuong do
cuong do

Posted on

Delete a container, lose your data? Docker volumes in 10 minutes

Picture this. You spend an afternoon setting up a container, save a few files inside it, then clean up with docker rm. Next morning you start a fresh container and... your files are gone. Docker did not eat them. You just never told Docker where to keep them.

This is the lab I ran on my own Windows laptop to finally get it. It takes about 10 minutes.

TL;DR

  • A container is a running copy of an image plus a thin writable layer. Remove the container and that layer goes with it.
  • A volume lives outside the container. Remove the container and the volume stays, ready for the next one.
  • Containers run as root by default, and a few "cleanup" commands delete more than you think. Gotchas at the end.

Table of contents

Where does your file live: writable layer vs volume

1. Image vs container in one minute

Think of a ready-made meal box. The image is the sealed box: code, runtime and libraries, all read-only. A container is the box opened on your table. You can add salt (write files), but that salt lives only on this plate.

Thing What it is Survives docker rm?
Dockerfile The recipe (FROM, COPY, RUN, CMD) n/a
Image Read-only layers built from the recipe Yes
Container Image + a thin writable layer, running No
Volume Storage managed by Docker, outside the container Yes

Each Dockerfile instruction adds a layer, so rebuilding only touches the layers that changed. That is why the second build is so much faster than the first.

2. Run your first container

Docker has a tiny sample app for this:

git clone https://github.com/docker/welcome-to-docker
Enter fullscreen mode Exit fullscreen mode

git clone of the welcome-to-docker sample

Open the folder in VS Code: the Dockerfile is the recipe, the rest is a small Node app. Build the image from the terminal:

cd welcome-to-docker
docker build -t welcome-to-docker .
Enter fullscreen mode Exit fullscreen mode

Project structure in VS Code and docker build

Then run it and map a host port to the container port. I picked 8089 because 80 and 8080 are usually taken by something else on a dev laptop.

Running the container from Docker Desktop with host port 8089

-p 8089:80 reads as "host 8089 goes to container 80". Open http://localhost:8089 and Docker throws you a little party:

Congratulations, you ran your first container

Enjoy the confetti. Now let's lose some data on purpose.

3. Lab: where does my file go without a volume?

Start a container with no volume and write a file:

docker run -it --name novol ubuntu bash
echo "hello" > /root/note.txt
exit
Enter fullscreen mode Exit fullscreen mode

Remove it and start a new one with the same name:

docker rm novol
docker run -it --name novol ubuntu bash
cat /root/note.txt
# cat: /root/note.txt: No such file or directory
Enter fullscreen mode Exit fullscreen mode

The file lived in the writable layer of the first container. docker rm deleted that layer. The new container got a fresh, empty one. Nothing is "broken": this is exactly how containers are supposed to behave.

4. Lab: the same file, with a volume

Step 1. Create a volume and write a file into it

docker volume create lab1
docker run -it -v lab1:/data ubuntu bash
echo "hello volume" > /data/test.txt
exit
Enter fullscreen mode Exit fullscreen mode

Create volume lab1 and write test.txt

Step 2. Delete the container and mount the volume in a new one

docker ps -a --filter volume=lab1      # find the container that used it
docker rm 58637ec992c2                 # your ID will differ
docker run -it -v lab1:/data ubuntu bash
ls /data
# test.txt
Enter fullscreen mode Exit fullscreen mode

A new container sees test.txt in the same volume

Step 3. Same test with a named container

docker run -it --name myubuntu2 -v lab1:/data ubuntu bash   # write the file, exit
docker start -ai myubuntu2                                  # still there: same container
docker rm myubuntu2
docker start -ai myubuntu2
# Error response from daemon: No such container: myubuntu2
Enter fullscreen mode Exit fullscreen mode

Step 4. Check who uses the volume, then mount it in a brand-new container

docker ps -a --filter volume=lab1      # empty: no container uses it now
docker run -it -v lab1:/data ubuntu bash
cat /data/test.txt
# hello volume
Enter fullscreen mode Exit fullscreen mode

The file survives after the container is deleted

The container is gone, the file is not. You can attach the same volume to one container, a new one, or several at once, which is why databases, logs and app state belong in volumes.

Small tip: -v is short and fine for labs. Docker's docs prefer --mount for real setups because it is more explicit:

docker run -it --mount source=lab1,target=/data ubuntu bash
Enter fullscreen mode Exit fullscreen mode

5. Security gotchas

Look at the prompt in the screenshots: root@.... That is not decoration.

  1. Containers run as root unless you say otherwise. Add a USER line in your Dockerfile for anything that does not need root. On shared hosts, look at rootless mode.
  2. docker rm $(docker ps -aq) removes every stopped container on the machine, not just the ones from your lab. Fine on your laptop, scary on a shared build server.
  3. docker volume prune only removes anonymous volumes by default. docker volume prune -a also removes unused named volumes, like lab1. Read the prompt before you type y.
  4. A volume is not a backup. It keeps data alive across containers, but docker volume rm lab1 and it is gone too. Back up what matters.
  5. Anything that mounts the volume can read it. Do not drop secrets in a volume that "some other container" also mounts.
  6. Docker Desktop is free for personal use and small businesses (under 250 employees and under $10M revenue). Bigger companies need a paid plan, which is why many teams use WSL2 + Docker CLI or Podman instead.

6. Checklist

  • [ ] I can explain image vs container vs volume in one sentence each
  • [ ] I ran a container with -p host:container and opened it in the browser
  • [ ] I lost a file on purpose without a volume
  • [ ] I kept a file with -v lab1:/data after docker rm
  • [ ] My Dockerfiles set a non-root USER where possible
  • [ ] I know what volume prune -a deletes before I run it

What is the most painful "where did my data go" moment you have had with containers? Tell me below, I promise I will not judge (much).

Sources

Top comments (0)