Linux Filesystem Hierarchy: Best Practices for /srv vs /var in Web Development Environments


2 views

Having worked across multiple Linux distributions (Fedora/RHEL vs Ubuntu/Debian), I've noticed significant differences in how they handle service data locations. Let's break down the technical rationale and modern best practices.

The Filesystem Hierarchy Standard (FHS) defines both directories:

/var - Variable data files (logs, spool files, transient/temporary files)
/srv - Data for services provided by the system (website content, FTP files)

Web Server Configurations

For Apache/Nginx on Ubuntu:

# Typical /srv structure
/srv/
├── http/          # or www/
│   ├── wordpress/
│   └── static-site/
└── ftp/
    └── public_uploads/

For RHEL-based systems:

# Traditional /var structure
/var/
├── www/html/
│   ├── wordpress -> /srv/wordpress/  # Symlink example
└── ftp/pub/

Samba Shares

Modern approach recommends:

/srv/samba/
├── department_shares/
│   ├── finance/
│   └── engineering/
└── public_share/

Web Applications

Best practice for complex apps:

# Physical location
/srv/applications/
├── wordpress/
│   ├── wp-content/
│   └── wp-config.php
└── custom-app/

# Symlink to web root
ln -s /srv/applications/wordpress /srv/http/wordpress
  • Security: /srv often has simpler permission structures
  • Backup: /srv contains pure data, while /var mixes data with operational files
  • Portability: /srv makes migration between systems cleaner

Moving from /var/www to /srv/http:

# 1. Create new structure
sudo mkdir -p /srv/http
sudo chown www-data:www-data /srv/http

# 2. Move content
sudo rsync -avz /var/www/html/ /srv/http/

# 3. Update web server config
# Apache example:
DocumentRoot "/srv/http"

# 4. Symlink legacy location (optional)
sudo ln -s /srv/http /var/www/html

For new deployments on any distribution:

  1. Use /srv for all service data (web, FTP, Samba)
  2. Reserve /var for transient/operational files
  3. Maintain symlinks only for backward compatibility

The Filesystem Hierarchy Standard (FHS) specifies that /var should contain "variable" data - files expected to grow during normal operation like logs, caches, and spools. Meanwhile, /srv is designated for "site-specific data served by the system" - a newer standard aiming to separate service data from system data.

Red Hat-based systems (RHEL/Fedora) traditionally use /var/www due to historical Apache conventions, while Debian-based systems (Ubuntu) adopted /srv earlier:

# RHEL default
DocumentRoot "/var/www/html"

# Ubuntu default
DocumentRoot "/srv/www/html"

Consider these factors when choosing:

  • Service Isolation: Use /srv/service_name for self-contained services (e.g., /srv/gitlab)
  • System Integration: Use /var for components tied to package management
  • Scaling Needs: /srv often works better for horizontal scaling scenarios

Web Applications:

# Preferred structure for multiple sites
/srv/
├── www/
│   ├── example.com/
│   │   ├── public_html/
│   │   └── logs/
│   └── app.example.com/
└── git/
    └── repos/

Samba Shares:

# /etc/samba/smb.conf
[department]
   path = /srv/samba/department
   read only = no
   guest ok = yes

For backward compatibility or specific application requirements:

# Symlink from legacy location
ln -s /srv/wordpress /var/www/wordpress

# Apache configuration example
<VirtualHost *:80>
    DocumentRoot /srv/www/example.com/public_html
    Alias /legacy /var/www/old_site
</VirtualHost>

Key differences in default permissions:

# Typical /var/www permissions (RHEL)
drwxr-xr-x. 2 root root 4096

# Recommended /srv permissions
drwxr-xr-x 2 www-data www-data 4096

Always set proper SELinux/AppArmor contexts when migrating between locations.

Modern deployments often use:

# Docker volume example
docker run -v /srv/app_data:/var/lib/app ...

This maintains host data in /srv while preserving application expectations.