Dockerfile中VOLUME与RUN mkdir的区别及VOLUME作用解析
Hey there! I totally get why this feels confusing at first—both VOLUME and RUN mkdir create directories inside a container, so it’s easy to think they’re interchangeable. But VOLUME is designed for persistent, external data management, which makes it way more than just a directory creator. Let’s break this down with simple explanations and hands-on examples.
First, the Surface Similarity
You’re right: if you run either of these Dockerfiles, you’ll end up with /my_directory1 or /my_directory2 in your container:
# Dockerfile with RUN mkdir FROM ubuntu:latest RUN mkdir /my_directory1
# Dockerfile with VOLUME FROM ubuntu:latest VOLUME /my_directory2
But that’s where the similarities end. Let’s dive into what makes VOLUME special.
1. VOLUME is a "Mount Point" for External Storage
The biggest difference is that VOLUME tells Docker: "This directory should be connected to storage outside the container’s own filesystem".
- With
RUN mkdir: The directory lives inside the container’s writable layer. If you delete the container, any data you added to/my_directory1is gone forever. - With
VOLUME: The directory is linked to a volume (either an anonymous one Docker creates automatically, or a named/host directory you specify). Even if the container is deleted, the data stays in the volume.
Hands-On Example
Let’s test this persistence:
Step 1: Test RUN mkdir
- Build the image:
docker build -t run-test .(using the RUN mkdir Dockerfile) - Run a container:
docker run --name run-container run-test - Add data to the directory:
docker exec run-container echo "Goodbye, data!" > /my_directory1/data.txt - Delete the container:
docker rm run-container - Run a new container from the same image:
docker run run-test cat /my_directory1/data.txt- Result: The file doesn’t exist—your data was deleted with the container.
Step 2: Test VOLUME
- Build the image:
docker build -t volume-test .(using the VOLUME Dockerfile) - Run a container:
docker run --name volume-container volume-test - Add data to the volume directory:
docker exec volume-container echo "Hello, persistent data!" > /my_directory2/data.txt - Delete the container:
docker rm volume-container - List Docker’s volumes:
docker volume ls(you’ll see an anonymous volume with a random ID) - Run a new container that mounts this volume:
docker run --name new-volume-container -v <YOUR_VOLUME_ID>:/my_directory2 volume-test cat /my_directory2/data.txt- Result: Your data is still there! It was stored in the external volume, not the container.
2. VOLUME Data Doesn’t Get Saved to New Images
When you use docker commit to create a new image from a running container, any data in VOLUME directories is not included in the new image. This is because volumes are meant to be separate from the image itself.
- With
RUN mkdir: Data in the directory is part of the container’s writable layer, so it will be included in the committed image.
Hands-On Example
For the RUN mkdir container:
- After adding
data.txt, rundocker commit run-container run-committed - Run a new container from the committed image:
docker run run-committed cat /my_directory1/data.txt - Result: The file is there—it was saved to the new image.
- After adding
For the VOLUME container:
- After adding
data.txt, rundocker commit volume-container volume-committed - Run a new container from the committed image:
docker run volume-committed cat /my_directory2/data.txt - Result: The file is missing—VOLUME data isn’t saved in the image.
- After adding
3. Docker Automatically Creates an Anonymous Volume for VOLUME Directories
If you don’t explicitly specify a host directory or named volume when running a container with a VOLUME directive, Docker will automatically create an anonymous volume and mount it to that directory. This ensures your data doesn’t get lost if the container is deleted (as we saw in the first example).
You can see this mount by running docker inspect volume-container—look for the Mounts section, which will show the anonymous volume’s path on your host machine (usually under /var/lib/docker/volumes/).
Quick Cheat Sheet
| Feature | RUN mkdir /dir | VOLUME /dir |
|---|---|---|
| Data persistence | Dies with the container | Persists in a volume |
Included in docker commit | Yes | No |
| Automatic external mount | No | Yes (anonymous volume) |
| Use case | Static directories in the image | Persistent data (databases, logs, etc.) |
内容的提问来源于stack exchange,提问作者Cheok Yan Cheng




