Skip to content

Docker - Storage

Containers are ephemeral by default. Files created inside a container’s writable layer are lost when the container is removed. To persist data or share data between containers and the host, Docker provides storage mechanisms: Volumes and Bind Mounts.

Volumes are the preferred mechanism for persisting data generated by and used by Docker containers. Key characteristics:

  • Managed by Docker: Volumes are created and managed by Docker (/var/lib/docker/volumes/ on Linux by default).
  • Decoupled Lifecycle: Volumes exist independently of containers. They persist even if the container using them is stopped or removed.
  • Platform Agnostic: Volumes work consistently across Linux and Windows containers.
  • Performance: Often provide better performance for I/O heavy workloads compared to bind mounts from host OS filesystems (especially on Docker Desktop).
  • Features: Support volume drivers, allowing storage on remote hosts or cloud providers.
  • Safe Sharing: Can be safely shared among multiple containers.

You can explicitly create named volumes or let Docker create them automatically when starting a container.

# Create a named volume explicitly
docker volume create my-data-volume
# Run a container and mount the named volume to /app/data
docker run -d --name my-app -v my-data-volume:/app/data my-image
# If 'another-volume' doesn't exist, Docker creates it automatically here
docker run -d --name other-app -v another-volume:/var/log my-other-image

Data written to /app/data by my-app will be stored in the my-data-volume on the host, managed by Docker.

# List volumes
docker volume ls
# Inspect a volume (shows mount point on host, etc.)
docker volume inspect my-data-volume
# Remove a volume (must not be in use by any container)
docker volume rm my-data-volume
# Remove all unused volumes (dangling volumes)
docker volume prune

Bind mounts map a file or directory on the host machine directly into a container. The path on the host is specified explicitly.

  • Direct Host Access: Allows containers to access and modify host files directly.
  • Host Path Dependency: Tied to the specific directory structure of the host machine, making containers less portable.
  • Performance: Can have performance issues, especially with large numbers of files or frequent I/O on Docker Desktop.
  • Use Cases: Ideal for sharing configuration files from host to container, sharing source code during development for live-reloading, accessing host resources like the Docker socket.
# Mount local './src' directory into '/app' in the container
docker run -d --name dev-container -v "${PWD}/src":/app my-dev-image
# Mount a single config file (read-only)
docker run -d --name configured-app -v "${PWD}/config.yml":/etc/app/config.yml:ro my-app-image

Changes made to /app inside the dev-container will directly reflect in the ./src directory on the host, and vice-versa.

Tmpfs mounts store data in the host system’s memory only. They are temporary and are never written to the host filesystem or the container’s writable layer. Useful for sensitive data you don’t want persisted or for temporary state needing high performance.

# Mount a tmpfs at /app/cache inside the container
docker run -d --name temp-app --mount type=tmpfs,destination=/app/cache my-app-image
# Or using the older --tmpfs flag
# docker run -d --name temp-app --tmpfs /app/cache my-app-image

Storage drivers manage how images and the writable container layer interact with the host filesystem. They handle the layered architecture of Docker images (copy-on-write).

  • overlay2: The preferred storage driver on most modern Linux distributions. Generally efficient and performant.
  • btrfs, zfs: Use underlying filesystem features. Can offer advanced capabilities but require specific host filesystem setup.
  • aufs: An older layered filesystem driver, largely replaced by overlay2.
  • devicemapper: Another older driver, often used on RHEL/CentOS 7.
  • vfs: Simple but inefficient; not recommended for production.

You usually don’t need to change the default storage driver unless facing specific compatibility or performance issues. Check the current driver using docker info:

docker info | grep 'Storage Driver'

Configuring the storage driver is done via the Docker daemon configuration file (/etc/docker/daemon.json).