Volumes - how does persistent storage work in Swarm
Docker Swarm - Overview and how to use it
4 min read
Published Jul 13 2025, updated Jul 14 2025
Guide Sections
Guide Comments
Docker Swarm provides a powerful platform for managing containerised applications across a cluster of machines. One critical aspect to understand when designing and deploying services in a Swarm is how data is handled, particularly persistent data. This is where volumes come into play.
In a standalone Docker setup, managing volumes is relatively straightforward. However, in a multi-node Swarm, volume management requires careful architectural planning to avoid pitfalls related to data availability and consistency.
Volumes Are Node-Local in Docker Swarm
By default, Docker volumes are local to the node on which they are created. This means that if you create a volume on Node A, it will not be automatically available on Node B. Each node has its own local storage, and Docker does not synchronise these volumes across the cluster.
This behaviour presents a challenge in Swarm mode because services can be scheduled on any node in the cluster. If a container that depends on a volume is restarted on a different node, the data in that volume may not be present unless you've taken steps to share storage across nodes.
Shared Storage Solutions (and Their Tradeoffs)
To address this, one option is to create shared volumes using distributed file systems or network file shares. Some common solutions include:
1. NFS (Network File System)
- NFS is a simple and widely supported network file system.
- Easy to set up but can suffer from performance issues under load.
- Not optimised for container workloads.
- Single point of failure unless configured redundantly.
2. GlusterFS
- A distributed file system that aggregates storage from multiple nodes.
- Offers better scalability and redundancy compared to NFS.
- More complex to manage and tune.
- Performance may still lag behind local volumes, especially under high I/O workloads.
3. Ceph
- Highly scalable, distributed storage system designed for high performance and fault tolerance.
- Provides object, block, and file storage.
- Complex to deploy and manage.
- Suitable for enterprise environments where high availability and performance are critical.
While these systems can provide shared volumes across Swarm nodes, they come with a tradeoff in performance and complexity. Shared storage is often significantly slower than local storage, particularly for I/O-heavy applications like databases.
Best Practice: Local Volumes + Service Constraints
For applications that require high performance and consistency, such as databases (e.g., PostgreSQL, MySQL, MongoDB), a better approach is to use local volumes combined with service constraints.
How It Works:
- You deploy your database container with a volume mounted on the local filesystem.
- You constrain the service to run only on a specific node using Swarm's placement constraints (e.g., by node hostname or labels).
- This ensures the container always starts on the node that has access to its volume.
Example:
To achieve high availability, rather than relying on shared volumes, you run replicated instances of the database on other nodes using the database system’s native replication mechanisms. Each instance uses its own local volume and is bound to a specific node. This design ensures both performance and redundancy, and it aligns with Swarm’s decentralised nature.
Handling Configuration Files with Docker Configs & Secrets
For lightweight, mostly-read-only data like configuration files, Docker Swarm provides a built-in solution: Docker Configs and Secrets.
Docker Configs/Secrets allow you to:
- Store config data securely in the Swarm manager.
- Attach config files to containers at runtime.
- Ensure the same configuration is available to containers regardless of which node they run on.
This feature solves a key problem in distributed environments—ensuring consistency without relying on external shared file systems. With Docker Configs/Secrets, you gain portability, security, and consistency, all while avoiding the complexity of mounting persistent volumes across nodes for static data.
Recommendations
Use case | Recommended approach |
High-performance data (e.g., databases) | Use local volumes + node constraints + native DB replication |
Static config files | Use Docker Configs |
Static sensitive data | Use Docker Secrets |
Shared working directories or logs (non-critical performance) | Consider NFS or Ceph/GlusterFS if needed |