Blog / Linux/ Complete Guide to Nginx Virtual Host Configuration: From Basics to WordPress Permalinks

Complete Guide to Nginx Virtual Host Configuration: From Basics to WordPress Permalinks

Nginx 虚拟主机配置详解:从基础到 WordPress 伪静态

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:

  1. Create a configuration file: Navigate to your Nginx configuration directory (commonly /etc/nginx/conf.d or /usr/local/nginx/conf/vhost) and create a file named after your domain, e.g., demo.example.com.conf.
  2. Write the server block: Add a server block to define core parameters like the listening port, domain name, and website root directory.
  3. Include the configuration: In the main nginx.conf file, within the http block, use an include directive to load your virtual host configuration file(s).
  4. 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.

Post a Comment

Your email will not be published. Required fields are marked with *.