Let's consider a system with two mounted drives:
/dev/sda1 mounted on / (drive A) /dev/sdb1 mounted on /mnt/drive_b (drive B)
Currently, all files under /var/www
and its subdirectories (including /var/www/upload
) are stored on drive A. We want to redirect only /var/www/upload
to store files on drive B while keeping the rest on drive A.
Linux provides a powerful feature called "bind mounts" that allows mounting a directory to another location in the filesystem hierarchy. Here's how to implement it:
# Step 1: Create the target directory on drive B sudo mkdir -p /mnt/drive_b/uploads # Step 2: Move existing uploads (if any) to the new location sudo mv /var/www/upload/* /mnt/drive_b/uploads/ # Step 3: Remove the original directory (it will be replaced by the mount) sudo rmdir /var/www/upload # Step 4: Create the bind mount sudo mount --bind /mnt/drive_b/uploads /var/www/upload
To ensure the mount persists after reboots, add this line to /etc/fstab
:
/mnt/drive_b/uploads /var/www/upload none bind 0 0
After setting up, verify the mount points with:
mount | grep /var/www/upload
You should see output similar to:
/mnt/drive_b/uploads on /var/www/upload type none (rw,bind)
While bind mounts are the proper solution, some might consider symbolic links. However, this approach has limitations:
# Not recommended for this use case: sudo ln -s /mnt/drive_b/uploads /var/www/upload
The limitation is that some applications might not follow symlinks correctly, and permissions can become more complex to manage.
Ensure the web server (e.g., Apache or Nginx) has proper permissions on the new location:
sudo chown -R www-data:www-data /mnt/drive_b/uploads sudo chmod -R 755 /mnt/drive_b/uploads
For more complex setups, you might consider mounting drive B directly to /var/www/upload
:
# In /etc/fstab: /dev/sdb1 /var/www/upload ext4 defaults 0 2
This approach skips the bind mount but requires the partition to be dedicated to this single purpose.
When working with web servers in Linux, we often need to separate high-traffic directories like upload folders onto different physical drives. Consider this common setup:
Drive A (root): /var/ /var/www/ /var/www/index.html Drive B (mounted separately): (empty)
Currently, all files including uploads go to Drive A. This creates performance bottlenecks when upload directory grows.
The most effective way is using a bind mount. Here's how to implement it:
# Step 1: Create mount point on Drive B sudo mkdir -p /mnt/driveb/uploads # Step 2: Move existing uploads (if any) sudo mv /var/www/upload/* /mnt/driveb/uploads/ # Step 3: Create bind mount entry in fstab echo "/mnt/driveb/uploads /var/www/upload none bind 0 0" | sudo tee -a /etc/fstab # Step 4: Apply changes sudo mount -a
To confirm the setup works correctly:
# Create test files sudo touch /var/www/testfile sudo touch /var/www/upload/testupload # Check storage locations lsblk -o NAME,MOUNTPOINT | grep -A 5 "sd[b]" df -h /var/www /var/www/upload
While less robust than bind mounts, symlinks can work for simpler cases:
# First move the directory sudo mv /var/www/upload /mnt/driveb/ # Then create symlink sudo ln -s /mnt/driveb/upload /var/www/upload
Note: Some applications may not follow symlinks properly, especially with strict security policies.
Ensure proper permissions after mounting:
sudo chown -R www-data:www-data /mnt/driveb/uploads sudo chmod -R 755 /mnt/driveb/uploads
If uploads fail after setup:
- Check
mount | grep upload
to verify mounting - Verify SELinux contexts match:
ls -Z /var/www/ /var/www/upload
- Test with simple file operations as root first
For high-traffic servers, consider these additional steps:
# Mount with noatime option in /etc/fstab: UUID=xxxx-xxxx /mnt/driveb ext4 defaults,noatime,bind 0 0
This reduces write operations for frequently accessed upload directories.