Configuring Nginx virtual hosts (server blocks) on a Linux server or VPS is fundamental for hosting multiple websites or applications. This guide will walk you through the basics, from adding a virtual host to enabling PHP support, setting up image hotlink protection, and configuring WordPress permalink rules.
Prerequisites
This guide assumes you have Nginx installed. If not, refer to your Linux distribution's official documentation or use a one-click installation package like the LNMP stack to set up your environment quickly.
Adding an Nginx Virtual Host
The main steps to configure a virtual host are:
- Create a configuration file: Navigate to your Nginx configuration directory (commonly
/etc/nginx/conf.dor/usr/local/nginx/conf/vhost) and create a file named after your domain, e.g.,demo.example.com.conf. - Write the server block: Add a
serverblock to define core parameters like the listening port, domain name, and website root directory. - Include the configuration: In the main
nginx.conffile, within thehttpblock, use anincludedirective to load your virtual host configuration file(s). - Restart Nginx: Apply the changes.
Here is a basic virtual host configuration example:
server {
listen 80;
server_name demo.example.com;
index index.html index.htm index.php;
root /var/www/demo_example_com;
access_log /var/log/nginx/demo.example.com.access.log;
error_log /var/log/nginx/demo.example.com.error.log;
}
In your main nginx.conf file, within the http block, add:
include /etc/nginx/conf.d/*.conf;
After configuration, restart Nginx:
# For systemd systems
sudo systemctl restart nginx
# For systems using service
sudo service nginx restart
Enabling PHP Support for the Virtual Host
To run PHP applications (like WordPress), you need to add a location block within the server block to process PHP files, typically via PHP-FPM (FastCGI Process Manager).
Updated configuration example:
server {
listen 80;
server_name demo.example.com;
index index.html index.htm index.php;
root /var/www/demo_example_com;
location ~ \.php$ {
fastcgi_pass unix:/run/php/php8.2-fpm.sock; # Adjust for your PHP version and socket path
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
access_log /var/log/nginx/demo.example.com.access.log;
error_log /var/log/nginx/demo.example.com.error.log;
}
Important: The fastcgi_pass value must match your PHP-FPM configuration. Modern Linux distributions often use a socket path like /run/php/php[version]-fpm.sock.
Configuring Image Hotlink Protection
To prevent other websites from directly linking to (hotlinking) your images and consuming your bandwidth, you can check the Referer header in HTTP requests.
Add this configuration within your server block:
location ~ \.(ico|jpg|jpeg|png|gif|webp)$ {
expires 1y; # Set browser cache for 1 year
add_header Cache-Control "public, immutable";
# Define valid referrers
valid_referers none blocked demo.example.com *.google.com *.baidu.com;
# If referrer is invalid, return 403 or 404
if ($invalid_referer) {
return 403;
# or return 404;
}
}
Explanation: The valid_referers directive lists domains allowed to access images. none means the request has no Referer header (e.g., direct browser access), blocked means the Referer exists but was removed by a firewall or proxy. Add your own domain or permitted third-party sites as needed.
WordPress Permalink (Pretty URL) Configuration
When WordPress uses "Pretty Permalinks" (like /%postname%/), Nginx must rewrite these URLs to WordPress's index.php front controller.
Recommended configuration for WordPress:
server {
listen 80;
server_name demo.example.com;
root /var/www/demo_example_com;
index index.php index.html index.htm;
# WordPress permalink rule (core)
location / {
try_files $uri $uri/ /index.php?$args;
}
# Handle PHP files
location ~ \.php$ {
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# Redirect /wp-admin to /wp-admin/
rewrite ^/wp-admin$ $scheme://$host$uri/ permanent;
# Security: Block access to sensitive files
location ~* /\.(htaccess|htpasswd|git|svn)$ {
deny all;
}
location ~* /(wp-config\.php|readme\.html|license\.txt)$ {
deny all;
}
access_log /var/log/nginx/demo.example.com.access.log;
error_log /var/log/nginx/demo.example.com.error.log;
}
Core Rule: try_files $uri $uri/ /index.php?$args; is the essential rule for WordPress. It checks: 1) if the requested file exists, 2) if the requested directory exists, 3) if neither exists, it forwards the request to index.php with all query arguments ($args).
If you use the LNMP one-click install package, it often includes an optimized WordPress config file (e.g., wordpress.conf) which you can include:
include wordpress.conf;
Troubleshooting: WordPress Admin 404 Error
If you get a 404 error when accessing the WordPress admin (/wp-admin), it's often due to a missing trailing slash. The rewrite rule in the configuration above automatically redirects /wp-admin to /wp-admin/ to fix this.
Summary
Following these steps, you can configure an Nginx virtual host from basic to advanced. Key points are: 1) correctly setting up the server block, 2) processing PHP via PHP-FPM, and 3) using the try_files directive for WordPress permalinks. Always test your configuration with nginx -t before restarting the service.