External Storage Mount Guide for XNAT Docker Deployment
Overview
This guide provides instructions for mounting external SFTP/SSH-based storage to serve as the archive directory for an XNAT Docker deployment. This approach enables cost-effective long-term storage while maintaining local VPS resources for temporary processing operations.
Prerequisites
- Root/sudo access to your XNAT host server
- External storage service with SSH/SFTP access enabled
- XNAT deployed via Docker Compose
- Required packages:
sshfs,cifs-utils
Architecture Decision
Storage Location Strategy
Mount to External Storage:
archive/– Permanent DICOM storage (high volume, infrequent access)
Keep on Local VPS:
prearchive/– Temporary staging during uploadbuild/– Processing workspacecache/– Temporary files during operationslogs/– Application logs
Rationale: External network storage introduces latency. Keeping high-frequency read/write operations local maximizes performance while offloading long-term storage to external infrastructure.
Installation Steps
1. Install Required Packages
apt-get update
apt-get install -y sshfs cifs-utils
2. Create Mount Point
mkdir -p /mnt/external-storage
3. Establish Initial Mount
Replace placeholders with your actual credentials:
sudo sshfs [email protected]:/ /mnt/external-storage
-o allow_other,default_permissions,uid=0,gid=0
Parameters explained:
allow_other– Allows non-root users (including Docker containers) to access the mountdefault_permissions– Enables kernel permission checkinguid=0,gid=0– Sets ownership to root for consistency
Authentication: You will be prompted for the storage password.
4. Verify Mount
df -h | grep external-storage
ls -la /mnt/external-storage/
Expected output should show the mount point with available storage capacity.
5. Create XNAT Directory Structure
sudo mkdir -p /mnt/external-storage/xnat-archive
sudo mkdir -p /mnt/external-storage/xnat-archive/.catalog
The .catalog directory is required by XNAT for metadata indexing.
6. Set Permissions
sudo chown -R root:root /mnt/external-storage/xnat-archive
sudo chmod -R 755 /mnt/external-storage/xnat-archive
7. Update XNAT Environment Configuration
Edit your .env file:
nano .env
Modify the archive path variable:
# Before:
XNAT_ARCHIVE_PATH=./xnat/data/archive
# After:
XNAT_ARCHIVE_PATH=/mnt/external-storage/xnat-archive
# Keep these local for performance:
XNAT_PREARCHIVE_PATH=./xnat/data/prearchive
XNAT_BUILD_PATH=./xnat/data/build
XNAT_CACHE_PATH=./xnat/data/cache
XNAT_LOGS_PATH=./xnat/data/home/logs
8. Restart XNAT Services
docker-compose down
docker-compose up -d
9. Verification
# Verify Docker container can access the mount
docker exec xnat-web ls -la /data/xnat/archive
# Test write permissions
docker exec xnat-web touch /data/xnat/archive/connectivity-test.txt
# Verify file appears on external storage
ls -la /mnt/external-storage/xnat-archive/connectivity-test.txt
# Monitor XNAT logs for errors
docker logs xnat-web --tail 50
Persistence Configuration
Create Remount Script
Since password-based SSHFS mounts don’t persist across reboots, create an automation script:
sudo nano /usr/local/bin/mount-external-storage.sh
Add the following content (replace with your credentials):
#!/bin/bash
if ! mountpoint -q /mnt/external-storage; then
echo "your-password-here" | sshfs [email protected]:/ /mnt/external-storage
-o allow_other,default_permissions,uid=0,gid=0,password_stdin
echo "External storage mounted"
else
echo "External storage already mounted"
fi
Make executable:
sudo chmod +x /usr/local/bin/mount-external-storage.sh
Add to System Startup
sudo nano /etc/rc.local
Add before the exit 0 line:
/usr/local/bin/mount-external-storage.sh
If /etc/rc.local doesn’t exist, create it:
#!/bin/bash
/usr/local/bin/mount-external-storage.sh
exit 0
Make it executable:
sudo chmod +x /etc/rc.local
Post-Upload Verification
After uploading DICOM data to XNAT:
# List project directories on external storage
ls -lah /mnt/external-storage/xnat-archive/
# View DICOM files for a specific project
find /mnt/external-storage/xnat-archive/PROJECT_NAME/ -name "*.dcm" | head -10
# Check storage utilization
du -sh /mnt/external-storage/xnat-archive/PROJECT_NAME/
# Verify growth is on external storage, not local VPS
df -h | grep external-storage
Troubleshooting
Mount Not Accessible from Docker Container
Symptoms: XNAT displays “Archive files do not exist” error.
Solution:
docker-compose restart xnat-web
docker exec xnat-web ls -la /data/xnat/archive
Permission Denied Errors
Cause: Incorrect mount options or ownership.
Solution:
sudo umount /mnt/external-storage
sudo sshfs [email protected]:/ /mnt/external-storage
-o allow_other,default_permissions,uid=0,gid=0
sudo chown -R root:root /mnt/external-storage/xnat-archive
Mount Disappears After Reboot
Cause: SSHFS mounts with password authentication don’t auto-mount.
Solution: Verify remount script is properly configured in /etc/rc.local or set up SSH key authentication (see Advanced Configuration).
Slow Upload Performance
Cause: Network latency between VPS and external storage.
Mitigation:
- Ensure
prearchive,build, andcacheremain on local storage - Check network bandwidth between host and storage provider
- Consider SSH compression: add
-o compression=yesto mount options
Advanced Configuration
SSH Key Authentication (Recommended)
For automatic mounting without password exposure:
# Generate SSH key pair
sudo ssh-keygen -t rsa -b 4096 -f /root/.ssh/external_storage -N ""
# Display public key
sudo cat /root/.ssh/external_storage.pub
Add the public key to your external storage service’s authorized keys (method varies by provider).
Update mount command:
sudo sshfs [email protected]:/ /mnt/external-storage
-o allow_other,default_permissions,uid=0,gid=0,IdentityFile=/root/.ssh/external_storage,reconnect,ServerAliveInterval=15,ServerAliveCountMax=3
Add to /etc/fstab for automatic mounting:
[email protected]:/ /mnt/external-storage fuse.sshfs noauto,x-systemd.automount,_netdev,allow_other,default_permissions,uid=0,gid=0,IdentityFile=/root/.ssh/external_storage,reconnect,ServerAliveInterval=15,ServerAliveCountMax=3 0 0
Test fstab entry:
sudo umount /mnt/external-storage
sudo mount /mnt/external-storage
Security Considerations
- Credential Storage: If using password authentication, ensure the remount script has restricted permissions (
chmod 700) - Network Security: Use SSH key authentication when possible
- Backup Strategy: Verify external storage provider offers snapshots or backup mechanisms
- Access Control: Limit SSH access to the storage service to your XNAT host IP if possible
Maintenance
Regular Health Checks
# Verify mount status
df -h | grep external-storage
# Check for connection issues
dmesg | grep -i fuse | tail -20
# Monitor storage capacity
du -sh /mnt/external-storage/xnat-archive/
Data Migration (Optional)
To migrate existing local archive data to external storage:
sudo rsync -av ./xnat/data/archive/ /mnt/external-storage/xnat-archive/
Verify integrity before removing local copies:
# Compare file counts
find ./xnat/data/archive/ -type f | wc -l
find /mnt/external-storage/xnat-archive/ -type f | wc -l
Performance Expectations
- Initial Upload: Speed limited by network bandwidth between VPS and storage provider
- Archive Access: Minimal impact as archived data is accessed infrequently
- Processing Operations: No degradation since prearchive/build/cache remain local
Conclusion
This configuration provides a scalable storage solution for XNAT deployments, separating high-performance temporary operations from cost-effective long-term archive storage. Regular monitoring of mount health and storage capacity ensures reliable operation.







