5.4 KiB
Mount remote storage to container using compose file
(https://oneuptime.com/blog/post/2025-12-15-how-to-use-nas-storage-with-docker-compose/view)
There are 3 types of remote connections possible, NFS, CIFS and iSCSI.
In addition to having the containers connect directly to the remote storage, it is also possible to simply let the host mount a remote storage location to a local mount point and then point the container to this location on the local host.
Quick Protocol Comparison
| Protocol | Best For | Strengths | Watch-outs |
|---|---|---|---|
| NFS | Linux hosts, shared access across containers | Simple setup, low overhead, native Docker support | No built-in encryption, UID/GID mapping can be tricky |
| SMB/CIFS | Windows hosts, mixed environments, AD integration | Works everywhere, credential-based auth | Higher overhead, requires cifs-utils on host |
| iSCSI | Containers that need block access to storage | ||
| Local mount + bind | Maximum performance, simple setups | No network latency, works offline | Requires NAS mounted on host first |
Prerequisites
Before starting:
- Your NAS is reachable from your Docker host (same network or routed)
- You have created a share/export on your NAS
- Your Docker host has the required client packages
Installing Required Packages
For NFS on Debian/Ubuntu:
The NFS client package allows your Docker host to mount NFS shares. This is a one-time setup required before Docker can create NFS volumes.
# Update package list and install NFS client utilities
# nfs-common includes mount.nfs required for NFS volume mounts
sudo apt-get update && sudo apt-get install -y nfs-common
For NFS on RHEL/Rocky/AlmaLinux:
# Install NFS utilities for Red Hat-based distributions
# Includes rpcbind and other NFS dependencies
sudo dnf install -y nfs-utils
For SMB/CIFS:
CIFS utilities are required when connecting to Windows shares or NAS devices configured for SMB protocol.
# Debian/Ubuntu - install CIFS mount utilities
sudo apt-get install -y cifs-utils
# RHEL/Rocky - same package, different package manager
sudo dnf install -y cifs-utils
NFS
This Docker Compose configuration demonstrates how to declare an NFS volume using the built-in local driver with NFS options. The volume is mounted into the container just like any other Docker volume.
Example 1:
# docker-compose.yml
version: "3.8"
services:
app:
image: nginx:alpine
volumes:
# Mount the NFS volume to serve static files
- nfs-data:/usr/share/nginx/html
ports:
- "8080:80"
# Volume definitions - NFS configuration lives here
volumes:
nfs-data:
# Use the local driver with NFS-specific options
driver: local
driver_opts:
# Specify NFS as the filesystem type
type: nfs
# Mount options: NAS IP, NFS version, and behavior flags
# soft = return errors on timeout, nolock = disable file locking
o: addr=192.168.1.100,nfsvers=4.1,soft,nolock
# NFS export path on your NAS (note the leading colon)
device: ":/volume1/docker-data"
Example 2:
volumes:
# Database volume: use 'hard' mount for data integrity
# 'hard' = retry indefinitely on failure (prevents data corruption)
# 'intr' = allow interrupt to prevent hung processes
postgres-data:
driver: local
driver_opts:
type: nfs
o: addr=192.168.1.100,nfsvers=4.1,hard,intr
device: ":/volume1/docker/postgres"
NFS Mount Options Explained
| Option | Purpose |
|---|---|
| addr= | NAS IP address |
| nfsvers=4.1 | NFS version (use 4.1 or 4.2 for best compatibility) |
| soft | Return errors on timeout instead of hanging (use hard for databases) |
| nolock | Disable file locking (faster, but don't use for databases) |
| rw | Read-write mount (default) |
| noatime | Don't update access times (better performance) |
CIFS
For Windows environments or when your NAS only offers SMB shares.
Basic SMB Volume
version: "3.8"
services:
app:
image: nginx:alpine
volumes:
- smb-data:/usr/share/nginx/html
volumes:
smb-data:
driver: local
driver_opts:
type: cifs
o: addr=192.168.1.100,username=myuser,password=mypassword,file_mode=0777,dir_mode=0777
device: "//192.168.1.100/docker-data"
SMB with Credentials File (More Secure)
Storing passwords in docker-compose.yml is a bad idea. Use a credentials file instead:
# Create credentials file on Docker host
sudo nano /etc/docker-smb-credentials
username=myuser
password=mypassword
domain=WORKGROUP
sudo chmod 600 /etc/docker-smb-credentials
version: "3.8"
services:
app:
image: nginx:alpine
volumes:
- smb-data:/usr/share/nginx/html
volumes:
smb-data:
driver: local
driver_opts:
type: cifs
o: addr=192.168.1.100,credentials=/etc/docker-smb-credentials,uid=1000,gid=1000,file_mode=0644,dir_mode=0755
device: "//192.168.1.100/docker-data"
SMB Mount Options
| Option | Purpose |
|---|---|
| credentials= | Path to credentials file |
| uid= / gid= | Map files to specific user/group ID |
| file_mode= / dir_mode= | Set permissions for files/directories |
| vers=3.0 | SMB protocol version (try 2.1 or 3.0) |
| seal | Enable encryption (SMB 3.0+) |
iSCSI
Example:
version: "3"
services:
app:
image: your-image
volumes:
- myiscsi:/data
volumes:
myiscsi:
driver: local
driver_opts:
type: iscsi
device: "iqn.2025-10.com.example:storage"
o: "addr=192.168.1.100"