HxHippy

WordPress Configuration

Optimized Nginx configuration for WordPress sites.

Last updated: 2025-01-15

Basic WordPress Config

server {
    listen 80;
    server_name example.com www.example.com;
    root /var/www/wordpress;
    index index.php;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_pass unix:/var/run/php/php-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_intercept_errors on;
    }

    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
        expires 30d;
        access_log off;
    }
}

Production WordPress

# Redirect HTTP to HTTPS
server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://example.com$request_uri;
}

# Main server
server {
    listen 443 ssl http2;
    server_name example.com;

    # SSL
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    include snippets/ssl-params.conf;

    root /var/www/wordpress;
    index index.php;

    # Security headers
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;

    # Gzip
    gzip on;
    gzip_types text/plain text/css application/json application/javascript;

    # WordPress permalinks
    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    # PHP handling
    location ~ \.php$ {
        try_files $uri =404;
        include fastcgi_params;
        fastcgi_pass unix:/var/run/php/php-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_intercept_errors on;
        fastcgi_buffer_size 16k;
        fastcgi_buffers 4 16k;
    }

    # Static files
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
        expires 30d;
        access_log off;
        add_header Cache-Control "public, immutable";
    }

    # Block access to sensitive files
    location ~ /\. {
        deny all;
    }

    location ~* /(?:uploads|files)/.*\.php$ {
        deny all;
    }

    location ~* /(wp-config\.php|readme\.html|license\.txt) {
        deny all;
    }

    # Disable xmlrpc (common attack vector)
    location = /xmlrpc.php {
        deny all;
    }

    # Block wp-includes scripts
    location ~* /wp-includes/.*\.php$ {
        deny all;
    }

    # Allow wp-includes for CSS/JS
    location ~* /wp-includes/.*\.(css|js)$ {
        expires 30d;
    }
}

WordPress Multisite

# Subdomain multisite
server {
    listen 443 ssl http2;
    server_name example.com *.example.com;

    root /var/www/wordpress;
    index index.php;

    # Multisite rules
    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_pass unix:/var/run/php/php-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}

# Subdirectory multisite
server {
    listen 443 ssl http2;
    server_name example.com;

    root /var/www/wordpress;
    index index.php;

    # Rewrite for multisite
    if (!-e $request_filename) {
        rewrite /wp-admin$ $scheme://$host$uri/ permanent;
        rewrite ^(/[^/]+)?(/wp-.*) $2 last;
        rewrite ^(/[^/]+)?(/.*\.php) $2 last;
    }

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_pass unix:/var/run/php/php-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}

WordPress with FastCGI Cache

# Cache zone
fastcgi_cache_path /var/cache/nginx/wordpress levels=1:2
                   keys_zone=WORDPRESS:100m inactive=60m;

# Skip cache variable
map $request_uri $skip_cache {
    default 0;
    ~*/wp-admin/ 1;
    ~*/wp-login.php 1;
    ~*preview=true 1;
}

map $http_cookie $skip_cache_cookie {
    default 0;
    ~*wordpress_logged_in 1;
    ~*comment_author 1;
}

server {
    listen 443 ssl http2;
    server_name example.com;

    root /var/www/wordpress;

    set $skip_cache 0;

    if ($skip_cache_cookie) {
        set $skip_cache 1;
    }

    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_pass unix:/var/run/php/php-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

        # Cache settings
        fastcgi_cache WORDPRESS;
        fastcgi_cache_valid 200 60m;
        fastcgi_cache_bypass $skip_cache;
        fastcgi_no_cache $skip_cache;

        add_header X-FastCGI-Cache $upstream_cache_status;
    }
}
intermediate Recipes Updated 2025-01-15
  • nginx
  • wordpress
  • php
  • cms
  • blog