IMO people don’t understand how
VOLUME1 works so they don’t use it. It’s generally used far too rarely!
VOLUME means two things:
- Whatever is left in directory marked as
VOLUME, stays there and can’t be changed in later layers (actually it can be changed but changes won’t be persistent).
- Volumes are not part of layered image FS. They’re mounted as anonymous volumes located on standard file system. This means they’re working much faster.
Let me explain it a bit.
Use VOLUME for temporary files directories
That’s one of things that piss me off in the official base images. They just don’t set up volumes for temporary directories by default. That’s why in my base images I always have something like that, somewhere at beginning:
# on Debian VOLUME ["/tmp", "/var/tmp", "/var/cache/apt", "/var/lib/apt/lists"] # on CentOS VOLUME ["/tmp", "/var/tmp", "/var/cache/yum", "/var/cache/dnf"]
What it does? It keeps images clean. Earlier, I was installing packages like this:
FROM debian RUN apt-get update && \ apt-get install -y nginx && \ apt-get clean && \ rm -rf /var/lib/apt/lists/*
Debian by default saves package lists (that’s what
apt-get update downloads) in
/var/cache/apt/lists. Then it’s downloading
deb packages to
/var/cache/apt/archives and all of this rubbish will be left in image by default, unless you remove it. But by marking
/var/cache/apt as a
VOLUME, all content became immutable and is removed/dropped at the end of each directive (like each RUN). So I can do it right now like this:
FROM debian VOLUME ["/tmp", "/var/tmp", "/var/cache/apt", "/var/lib/apt/lists"] RUN apt-get update && \ apt-get install -y nginx
It just makes life easier 😄
Add clean-up task for anonymous volumes
Sadly, those anonymous volumes are just left after you deploy new image version or shut it down. You have to clean them from time to time!
Which you probably should already know, if you manage cluster of docker hosts. It might be as simple as running in cron:
docker volume prune -f