NFS Provider (LOCAL with Shared Usage)
The NFS provider uses NFS (Network File System) network shares for storing files in cluster deployments. NFS support is implemented through the LOCAL provider with sharedUsage enabled, making it ideal for Linux/Unix cluster environments.
Overview
- Provider Name:
LOCAL(withsharedUsage: true) - Supports: File Storage only
- Configuration File:
provider-local.json - Use Case: Linux/Unix clusters, NFS-based infrastructure, cross-platform file sharing
- Protocol: NFS v3/v4
Features
- ✓ Native Linux/Unix NFS support
- ✓ High-performance network file system
- ✓ Cluster-ready with shared network storage
- ✓ POSIX-compliant file operations
- ✓ No additional external services required
- ✓ Cost-effective (uses existing NFS infrastructure)
- ✗ Requires NFS server and mount configuration
- ✗ Network latency considerations
How NFS Support Works
Unlike other providers, NFS is not a separate provider but rather a special mode of the LOCAL provider:
- Mount an NFS share on all cluster nodes at the same mount point
- Configure
LOCALprovider with the mount point path - Enable
sharedUsage: trueto indicate shared network storage - webPDF validates the folder exists and is accessible (does not auto-create)
The key difference: With sharedUsage: false (default), LOCAL creates temporary folders that are automatically deleted. With sharedUsage: true, LOCAL uses the provided path as persistent shared storage.
Prerequisites
- NFS server with exported file share
- NFS client installed on all webPDF cluster nodes
- NFS share mounted on all nodes at identical mount points
- Read/write permissions configured for webPDF process user
NFS Server Setup
Linux NFS Server Configuration
Install NFS Server
# Ubuntu/Debian
sudo apt-get update
sudo apt-get install nfs-kernel-server
# RHEL/CentOS/Rocky
sudo yum install nfs-utils
sudo systemctl enable nfs-server
sudo systemctl start nfs-server
Create Export Directory
# Create directory for webPDF files
sudo mkdir -p /export/webpdf-files
sudo chown nobody:nogroup /export/webpdf-files
sudo chmod 755 /export/webpdf-files
Configure NFS Export
Edit /etc/exports:
# Export for specific cluster nodes
/export/webpdf-files 192.168.1.10(rw,sync,no_subtree_check,no_root_squash)
/export/webpdf-files 192.168.1.11(rw,sync,no_subtree_check,no_root_squash)
/export/webpdf-files 192.168.1.12(rw,sync,no_subtree_check,no_root_squash)
# Or export for entire subnet
/export/webpdf-files 192.168.1.0/24(rw,sync,no_subtree_check,no_root_squash)
Export Options Explained
rw– Read/write accesssync– Synchronous writes (more reliable)no_subtree_check– Improved reliabilityno_root_squash– Preserve root permissions (use with caution)all_squash– Map all users to anonymous (more secure alternative)
Apply Export Configuration
# Export the shares
sudo exportfs -a
# Restart NFS server
sudo systemctl restart nfs-server
# Verify exports
sudo exportfs -v
NFS Client Setup (Cluster Nodes)
Install NFS Client
# Ubuntu/Debian
sudo apt-get install nfs-common
# RHEL/CentOS/Rocky
sudo yum install nfs-utils
Create Mount Point
# Create identical mount point on ALL cluster nodes
sudo mkdir -p /mnt/webpdf-shared
sudo chmod 755 /mnt/webpdf-shared
Mount NFS Share
Manual Mount (Testing)
# Mount NFS share
sudo mount -t nfs nfs-server.example.com:/export/webpdf-files /mnt/webpdf-shared
# Verify mount
df -h | grep webpdf-shared
ls -la /mnt/webpdf-shared
Permanent Mount (Production)
Add to /etc/fstab:
# NFS mount for webPDF cluster
nfs-server.example.com:/export/webpdf-files /mnt/webpdf-shared nfs defaults,_netdev 0 0
Options explained:
defaults– Use default mount options_netdev– Wait for network before mounting (important for boot)
Mount all filesystems:
sudo mount -a
Verify NFS Mount
# Check mount
mount | grep webpdf-shared
# Test write access
sudo touch /mnt/webpdf-shared/test.txt
sudo rm /mnt/webpdf-shared/test.txt
# Check from another node
ls -la /mnt/webpdf-shared/
webPDF Configuration
provider.json
{
"fileStorage": {
"name": "LOCAL",
"checks": {
"enabled": true,
"interval": 15000
}
}
}
Use LOCAL as the provider name, not NFS. The NFS behavior is controlled by the provider-specific configuration.
provider-local.json
Configuration for NFS-mounted file storage:
{
"url": "/mnt/webpdf-shared",
"sharedUsage": true
}
Configuration Attributes
| Attribute | Type | Required | Description |
|---|---|---|---|
url | string | Yes | Absolute path to NFS mount point |
sharedUsage | boolean | Yes | Must be true for NFS/shared storage |
The url path must be:
- An absolute path (e.g.,
/mnt/webpdf-shared) - The same on all cluster nodes
- An existing, accessible directory
- Writable by the webPDF process user
Environment Variables
# NFS file storage configuration
export WEBPDF_LOCAL_FILE_STORAGE_SETTINGS_URL=/mnt/webpdf-shared
export WEBPDF_LOCAL_FILE_STORAGE_SETTINGS_SHARED_USAGE=true
# Provider selection
export WEBPDF_PROVIDER_SETTINGS_FILE_STORAGE_NAME=LOCAL
Validation Behavior
When sharedUsage: true, webPDF validates the folder on startup:
- Folder must exist – webPDF will NOT create the folder
- Must be a directory – Not a file or symlink
- Must be writable – webPDF must have write permissions
- Folder persists – Unlike temporary LOCAL folders, NFS folders are never deleted
Error examples:
Folder '/mnt/webpdf-shared' does not exist
Folder '/mnt/webpdf-shared' is not a directory
Folder '/mnt/webpdf-shared' is not writeable
Health Checks
Health checks monitor NFS mount availability:
{
"fileStorage": {
"name": "LOCAL",
"checks": {
"enabled": true,
"interval": 15000
}
}
}
enabled: Enable health checks (recommended:true)interval: Check interval in milliseconds (recommended:15000-30000)
Health checks verify:
- NFS mount is still mounted
- Directory is accessible
- Write permissions are intact
NFS Mount Options
Performance Tuning
Optimize NFS mount options in /etc/fstab:
# High-performance NFS mount
nfs-server:/export/webpdf-files /mnt/webpdf-shared nfs rw,hard,intr,rsize=131072,wsize=131072,_netdev 0 0
Recommended Options
| Option | Description | Recommendation |
|---|---|---|
rw | Read-write access | Required |
hard | Retry failed operations indefinitely | Recommended for reliability |
soft | Return errors after timeout | Alternative (less reliable) |
intr | Allow interruption of NFS requests | Recommended |
rsize=131072 | Read buffer size (128KB) | Tune for performance |
wsize=131072 | Write buffer size (128KB) | Tune for performance |
timeo=600 | Timeout in tenths of a second | Increase for slow networks |
retrans=2 | Number of retries | Adjust for reliability |
_netdev | Wait for network | Required for auto-mount |
NFS Version Selection
# NFSv4 (recommended)
nfs-server:/export/webpdf-files /mnt/webpdf-shared nfs4 defaults,_netdev 0 0
# NFSv3 (older, more compatible)
nfs-server:/export/webpdf-files /mnt/webpdf-shared nfs nfsvers=3,defaults,_netdev 0 0
NFSv4 offers better performance, security, and firewall-friendliness. Use NFSv3 only if NFSv4 is not available.
Security Considerations
Authentication and Authorization
Kerberos Security
For enhanced security, use NFS with Kerberos:
# /etc/exports with Kerberos
/export/webpdf-files gss/krb5p(rw,sync,no_subtree_check)
# Mount with Kerberos
nfs-server:/export/webpdf-files /mnt/webpdf-shared nfs4 sec=krb5p,_netdev 0 0
Security levels:
krb5– Kerberos authenticationkrb5i– Kerberos with integrity checkingkrb5p– Kerberos with privacy (encryption)
UID/GID Mapping
Ensure consistent user IDs across cluster:
# Check webPDF process user UID
id webpdf-user
# Ensure same UID/GID on all nodes
# Or use all_squash with anonuid/anongid
NFS export with user mapping:
# /etc/exports - map all users to specific UID
/export/webpdf-files 192.168.1.0/24(rw,sync,all_squash,anonuid=1001,anongid=1001)
Network Security
- Firewall Rules – Restrict NFS ports to cluster nodes only
- Private Network – Use dedicated network for NFS traffic
- VPN/IPSec – Encrypt NFS traffic over untrusted networks
- Export Restrictions – Limit exports to specific IPs/subnets
Required NFS ports:
# NFSv4 (single port)
TCP/UDP 2049
# NFSv3 (multiple ports)
TCP/UDP 111 (portmapper)
TCP/UDP 2049 (nfs)
TCP/UDP 20048 (mountd)
High Availability
NFS Server HA Options
- DRBD + Pacemaker – Active-passive failover
- Clustered NFS – Multiple NFS servers with shared storage
- NAS HA Appliances – Hardware-based redundancy
- Cloud NFS – Managed NFS services (AWS EFS, Azure Files NFS)
Client-Side HA
Configure mount for resilience:
# High availability mount options
nfs-server:/export/webpdf-files /mnt/webpdf-shared nfs hard,intr,retrans=5,timeo=600,_netdev 0 0
Monitoring
Monitor NFS health:
# Check NFS mounts
mount | grep nfs
# Monitor NFS performance
nfsstat
# Check NFS server exports
showmount -e nfs-server.example.com
# Test NFS access
timeout 5 ls /mnt/webpdf-shared
Performance Tuning
NFS Server Tuning
Increase NFS threads:
# /etc/nfs.conf
[nfsd]
threads=128
# Or start with more threads
sudo systemctl restart nfs-server
Network Tuning
Enable jumbo frames for better throughput:
# Set MTU to 9000 on NFS network interfaces
sudo ip link set eth1 mtu 9000
# Verify
ip link show eth1
Client-Side Caching
Use NFS attribute caching:
# Mount with aggressive caching
nfs-server:/export/webpdf-files /mnt/webpdf-shared nfs ac,actimeo=60,_netdev 0 0
ac– Enable attribute cachingactimeo=60– Cache attributes for 60 seconds
Aggressive caching improves performance but may cause stale data in multi-node scenarios. Balance performance vs. consistency.
Troubleshooting
Mount Issues
NFS Mount Fails
Symptoms: Cannot mount NFS share
Check:
# Test NFS server connectivity
ping nfs-server.example.com
# Check NFS exports
showmount -e nfs-server.example.com
# Verify firewall (NFSv4)
telnet nfs-server.example.com 2049
# Check NFS service
sudo systemctl status nfs-server # On server
Stale File Handle
Symptoms: "Stale file handle" errors
Solutions:
# Unmount and remount
sudo umount -f /mnt/webpdf-shared
sudo mount /mnt/webpdf-shared
# Or restart NFS client services
sudo systemctl restart nfs-client.target
Permission Issues
Permission Denied
Symptoms: Cannot write to NFS share
Check:
# Verify mount permissions
ls -la /mnt/webpdf-shared
# Check NFS export options
sudo exportfs -v
# Test write as webPDF user
sudo -u webpdf-user touch /mnt/webpdf-shared/test.txt
# Review UID/GID mapping
id webpdf-user
Performance Issues
Slow NFS Performance
Check:
# Monitor NFS stats
nfsstat -c # Client stats
nfsstat -s # Server stats
# Check network latency
ping nfs-server.example.com
# Test throughput
dd if=/dev/zero of=/mnt/webpdf-shared/test bs=1M count=1000
rm /mnt/webpdf-shared/test
# Review mount options
mount | grep webpdf-shared
Optimize:
- Increase
rsizeandwsize - Enable jumbo frames
- Use NFSv4 instead of NFSv3
- Add more NFS server threads
webPDF Configuration Issues
Folder Not Found
Error: Folder '/mnt/webpdf-shared' does not exist
Solution:
- Verify NFS is mounted:
mount | grep webpdf-shared - Check path in config matches mount point exactly
- Ensure mount survives reboots (check
/etc/fstab)
Folder Not Writable
Error: Folder '/mnt/webpdf-shared' is not writeable
Solution:
- Check folder permissions:
ls -la /mnt/webpdf-shared - Verify webPDF user can write:
sudo -u webpdf-user touch /mnt/webpdf-shared/test - Review NFS export options (check
no_root_squashor UID mapping)
Comparison: NFS vs. Other Providers
| Feature | NFS | SMB | MinIO | Azure Blob |
|---|---|---|---|---|
| Protocol | NFS 3/4 | SMB 2/3 | S3 API | Azure API |
| Best For | Linux clusters | Windows clusters | Cloud-native | Azure cloud |
| Latency | Low | Medium | Low-Medium | Medium |
| Setup Complexity | Medium | Low | Medium | Low |
| Cost | Low (self-hosted) | Low (self-hosted) | Medium | Usage-based |
| POSIX Compliant | Yes | Limited | No | No |
Examples
Basic NFS Configuration
{
"url": "/mnt/webpdf-shared",
"sharedUsage": true
}
Production NFS Configuration
{
"url": "/mnt/nfs/webpdf-prod",
"sharedUsage": true,
"settings": {
"note": "NFS v4 mount at /mnt/nfs/webpdf-prod from nfs-prod.example.com"
}
}
Cluster Setup Example
Coordinator Node:
cluster.json:
{
"mode": "CLUSTER",
"role": "COORDINATOR",
"name": "webpdf-prod",
"nodeName": "coordinator-1",
"secretKey": "4f0a2c8efb1a0f9c79c4b0f5a81e6d5b4a7c8d9e2f0a1b2c3d4e5f60718293ab"
}
provider.json:
{
"documentStorage": {"name": "REDIS"},
"fileStorage": {"name": "LOCAL", "checks": {"enabled": true, "interval": 15000}},
"sessionStorage": {"name": "REDIS"}
}
provider-local.json:
{
"url": "/mnt/webpdf-shared",
"sharedUsage": true
}