# 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" ```