Skip to content

7.01 Storage in Docker

Abstract

Docker stores images, containers, and volumes on the host file system.
Understanding Docker storage helps you manage persistent data, optimize image builds, and troubleshoot container storage issues in production.


Docker File System Location

By default, Docker stores its data under:

/var/lib/docker

Common folders:

Directory Purpose
/var/lib/docker/containers Container metadata and logs
/var/lib/docker/image Image metadata
/var/lib/docker/volumes Docker-managed volumes
/var/lib/docker/overlay2 Image and container layers

Note

The exact folders may vary depending on the Docker storage driver used by the host.


Docker Layered Architecture

Docker images are built using a layered architecture.

Each instruction in a Dockerfile creates a new layer.

Example:

FROM ubuntu
RUN apt-get update && apt-get -y install python
RUN pip install flask flask-mysql
COPY . /opt/source-code
ENTRYPOINT FLASK_APP=/opt/source-code/app.py flask run

Layers created:

  1. Base Ubuntu layer
  2. APT package layer
  3. Python package layer
  4. Source code layer
  5. Entrypoint layer

Tip

Docker reuses unchanged layers from cache, which makes image builds faster and saves disk space.


Image Layers vs Container Layer

Docker image layers are read-only.

When a container starts, Docker adds a new read-write container layer on top.

Layer Type Permission Purpose
Image Layers Read-only Base image and application files
Container Layer Read-write Runtime changes, logs, temp files
Container Layer   β†’ Read Write
Image Layers      β†’ Read Only

Warning

Data written to the container layer is deleted when the container is removed.


Copy-on-Write

Docker uses copy-on-write.

If a container modifies a file from a read-only image layer:

  1. Docker copies the file into the writable container layer
  2. The container modifies the copied version
  3. The original image layer remains unchanged

Example:

Image Layer:
  app.py   β†’ read-only

Container Layer:
  app.py   β†’ modified copy
  temp.txt β†’ new file

Note

Copy-on-write keeps images immutable while still allowing containers to modify files at runtime.


Why Volumes Are Needed

Container writable layers are temporary.

If the container is deleted:

  • runtime files are deleted
  • temporary changes are deleted
  • database data is deleted unless mounted externally

For persistent data, use Docker volumes.

Danger

Never store important database data only inside the container writable layer.


Docker Volumes

Create a volume:

docker volume create data_volume

Docker stores the volume under:

/var/lib/docker/volumes/data_volume

Run MySQL with a volume:

docker run -v data_volume:/var/lib/mysql mysql

This mounts the Docker volume into the container at:

/var/lib/mysql

Success

Data stored in a Docker volume remains even if the container is deleted.


Auto-Created Volumes

If the volume does not exist, Docker can create it automatically.

docker run -v data_volume2:/var/lib/mysql mysql

Docker creates:

/var/lib/docker/volumes/data_volume2

Tip

Named volumes are preferred for container-managed persistent data.


Volume Mount vs Bind Mount

Docker supports two common mount types.

Mount Type Source Location Use Case
Volume Mount /var/lib/docker/volumes Docker-managed persistent data
Bind Mount Any host path Mount existing host directory

Volume Mount Example

docker run -v data_volume:/var/lib/mysql mysql

This uses Docker-managed storage.


Bind Mount Example

docker run -v /data/mysql:/var/lib/mysql mysql

This mounts an existing host directory.

Warning

Bind mounts depend on host paths and can reduce portability across environments.


Preferred Mount Syntax

The older syntax uses -v.

docker run -v /data/mysql:/var/lib/mysql mysql

The newer and clearer syntax uses --mount.

docker run \
  --mount type=bind,source=/data/mysql,target=/var/lib/mysql \
  mysql

Tip

Use --mount in production because it is more explicit and easier to audit.


Storage Drivers

Docker storage drivers manage:

  • image layers
  • writable container layers
  • copy-on-write behavior
  • file system operations

Common storage drivers:

Driver Notes
AUFS Older layered driver
ZFS Advanced filesystem support
BTRFS Snapshot-based filesystem
Device Mapper Common on older RHEL/CentOS systems
Overlay Overlay filesystem driver
Overlay2 Modern default on many Linux systems

Note

Docker usually selects the best available storage driver based on the host operating system.


Production Best Practices

Recommended

  • Use volumes for persistent application data
  • Use --mount instead of legacy -v
  • Keep container writable layers small
  • Store databases on dedicated volumes
  • Monitor disk usage under /var/lib/docker
  • Use appropriate storage drivers for your OS
  • Back up important Docker volumes regularly

Do's

  • Use named volumes for persistent data
  • Use bind mounts only when host path access is required
  • Keep images small and layered efficiently
  • Rebuild images instead of modifying containers manually
  • Monitor Docker disk usage

Don'ts

  • Don't store important data in the container layer
  • Don't rely on temporary container files
  • Don't use bind mounts carelessly in production
  • Don't manually edit files inside /var/lib/docker
  • Don't ignore storage driver compatibility

Danger

Manually modifying files under /var/lib/docker can corrupt Docker images, containers, or volumes.


Quick Commands

Check Docker disk usage:

docker system df

List volumes:

docker volume ls

Inspect a volume:

docker volume inspect data_volume

Remove unused data:

docker system prune

Warning

Be careful with prune commands in production. They can delete unused containers, images, networks, and build cache.


Summary

Quote

  • Docker stores data under /var/lib/docker
  • Images are built using read-only layers
  • Containers get a temporary read-write layer
  • Docker uses copy-on-write
  • Volumes persist data beyond container lifecycle
  • Storage drivers manage image and container layers