Docker
Cloud Computing
Persistent Storage
Database Management
Containerization

How to deal with persistent storage (e.g. databases) in Docker

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Docker has revolutionized the way applications are deployed by providing a lightweight alternative to traditional VMs. One of the critical challenges when using Docker, especially in production, is dealing with persistent storage, such as databases. Persistent storage is important because, by default, all data written to a Docker container's writable layer is lost once the container is deleted, which doesn't work for stateful applications like databases that need to save data permanently.

Understanding Volumes in Docker

Docker volumes are the preferred mechanism for handling persistent data created by and used by Docker containers. Here's why:

  • Data persistence: Volumes are stored in part of the host filesystem which is managed by Docker (/var/lib/docker/volumes/ on Linux). Data stored here persists across container restarts and even after the container itself is deleted.
  • Decoupling of data from containers: Volumes allow you to separate your application from your data. You can rebuild or re-deploy your Docker container without losing data.
  • Data sharing: Volumes can be shared among multiple containers, which is particularly useful when you want to separate different aspects of an application but have them access the same data sources.
  • Performance: As they exist as normal directories and files on the host machine, the I/O performance of Docker volumes is comparable to that of accessing the host filesystem directly.

Example: Creating and Using a Docker Volume with a Database

Consider a scenario where you're deploying a MySQL database inside a Docker container. Instead of writing the database directly inside the container layer, use a volume:

bash
1# Create a volume
2docker volume create mysql_data
3
4# Run a MySQL container with the volume attached
5docker run -d \
6  --name mysql_server \
7  -e MYSQL_ROOT_PASSWORD=my-secret-pw \
8  -v mysql_data:/var/lib/mysql \
9  mysql:latest

Here, mysql_data is the volume where MySQL stores its data, ensuring it persists across restarts and removals of the container.

Bind Mounts

Another type of persistent storage in Docker is the bind mount, a mapping of a host file or directory to a container file or directory. Essentially, the file or directory is directly mounted into the container.

Example: Using a Bind Mount

bash
1# Run a container with a bind mount
2docker run -d \
3  --name dev_container \
4  -v /path/on/host:/path/in/container \
5  nginx:latest

Here, a host path is directly mounted into the Nginx container allowing direct editing and updating from the host.

Temporary File Storage - tmpfs Mounts

For situations where you want data to be stored temporarily, such as cache, Docker provides tmpfs mounts:

bash
1docker run -d \
2  --name temp_data_container \
3  --mount type=tmpfs,destination=/app/temp \
4  my-app:latest

Here, data saved to /app/temp doesn't persist across container restarts and is stored in the host system's memory only which can be faster than writing to disk.

Comparing Storage Options

OptionsPersistenceScope of AvailabilityUse case
VolumesYesAcross all containersProduction databases, important data
Bind MountsYesSingle containerDevelopment environments, configuration
tmpfsNoSingle containerCaching, temporary data

Advanced Topics

Backup and Restore

To manage data durability and availability, regular backups are crucial. Docker volumes can be backed up by copying data from the volume to a backup storage location and restored by copying data back into the volume.

Data Migration

Moving data from one Docker volume to another can be useful when upgrading volume drivers or when migrating data between servers. This can be achieved via Docker’s cp command or by using data migration tools provided by third-party volume drivers.

Security Considerations

Managing sensitive data within Docker requires encapsulated volumes that are encrypted, either on the disk or during transfer. Further, enforcing access control using Docker's user and group ID settings can prevent unauthorized access.

Handling persistent storage in Docker is paramount to deploying effective, reliable, and scalable applications. By correctly implementing Docker volumes, bind mounts, or tmpfs mounts, developers can ensure their applications run efficiently while maintaining the safety and integrity of their data.


Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.