Files
DevOps/Docker/Mount remote storage to container.md
2026-02-25 13:11:56 +01:00

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"