KBeezie

There's no place like ::1

Menu
  • Home
  • Start Here
  • Security Series
  • About

Installing WordPress 6.9.4 on Nginx

2026/05/11 in CMS Guides

Step 4: Directory protection and housekeeping

These are the same drop.conf rules that apply to any site — deny hidden files, backup files, and common config extensions:

# drop.conf

# Let's Encrypt renewal path
location ~ /.well-known/acme-challenge {
    root /usr/share/nginx/html;
    allow all;
}

# Deny hidden files
location ~ /\. {
    deny all;
    access_log off;
    log_not_found off;
}

# Deny backup files
location ~ ~$ {
    deny all;
    access_log off;
    log_not_found off;
}

# Deny sensitive extensions
location ~* \.(yml|yaml|env|bak|swp|dist|config)$ {
    deny all;
    access_log off;
    log_not_found off;
}

# Handle favicon.ico cleanly
location = /favicon.ico {
    access_log off;
    log_not_found off;
    try_files $uri =204;
}

# Handle robots.txt — WordPress generates this dynamically
location = /robots.txt {
    try_files $uri /index.php;
}

Step 5: Static file caching

WordPress themes and plugins ship a lot of static assets. Caching them aggressively at the Nginx level keeps PHP-FPM free for requests that actually need it:

# static_caching.conf

# Images and fonts — immutable, cache as long as possible
location ~* \.(png|jpg|jpeg|gif|ico|webp|woff2|woff|ttf)$ {
    try_files $uri =404;
    expires max;
    add_header Pragma public;
    add_header Cache-Control "public, no-transform";
}

# CSS, JS, SVG, text — cache aggressively but allow revalidation
location ~* \.(css|js|html|htm|txt|xml|svg)$ {
    gzip_static on;
    try_files $uri =404;
    expires max;
    add_header Pragma public;
    add_header Cache-Control "public, must-revalidate, proxy-revalidate";
}

try_files $uri =404; in both blocks ensures missing static files return a clean 404 instead of falling through to WordPress — saving a PHP-FPM worker and a database query for every broken asset reference.


Step 6: PHP handler and FastCGI tuning

WordPress benefits from PHP-FPM tuning at both the Nginx and pool levels:

# php.conf
location ~ \.php$ {
    try_files $uri =404;
    fastcgi_intercept_errors on;
    fastcgi_ignore_client_abort on;

    include fastcgi_params;
    fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
}

At the nginx.conf http { } level, these FastCGI directives optimize how Nginx talks to PHP-FPM for a WordPress workload:

# In http { } — applies to all PHP locations
fastcgi_intercept_errors on;
fastcgi_ignore_client_abort on;
fastcgi_max_temp_file_size 0;
fastcgi_buffers 512 4k;
fastcgi_read_timeout 180;

fastcgi_intercept_errors on — Lets Nginx serve its own error pages instead of passing PHP error responses through. Cleaner 404s and 50x pages without involving WordPress.

fastcgi_ignore_client_abort on — PHP-FPM finishes processing even if the visitor closes their browser. Critical for wp-cron and scheduled tasks that are triggered by page loads — without it, a user who navigates away mid-request cancels the backend work.

fastcgi_max_temp_file_size 0 — Disables buffering PHP responses to disk. Keeps everything in memory and avoids I/O bottlenecks on busy sites. Only safe if your PHP responses fit within your buffer configuration (which they will for normal WordPress pages).

fastcgi_buffers 512 4k — 512 buffers of 4KB each (2MB total). Tuned for WordPress page responses that can be larger than Nginx's default buffer allocation — the admin area, plugin pages, and certain themes push more markup than a typical PHP app.

fastcgi_read_timeout 180 — 180-second timeout for PHP responses. Accommodates slow WordPress admin operations like plugin updates, media processing, and backup generation that can take well over the default 60 seconds.

On the PHP-FPM side, make sure cgi.fix_pathinfo = 0 in your php.ini. When enabled, PHP tries to guess which file you meant if the requested path doesn't exist. When disabled, it only executes the exact file requested — defense in depth alongside try_files $uri =404;.

  • ← Previous
  • 1
  • 2
  • 3
  • 4
  • Next →
Tags: wordpress, nginx, php-fpm, caching, wp-config, hardening
©2026 KBeezie | Disclaimer | Privacy Notice