WordPress Production Setup with Nginx, PHP-FPM, and Redis Cache
Web Infrastructure

WordPress Production Setup with Nginx, PHP-FPM, and Redis Cache

  • Author :Liam K.
  • Date :July 02, 2026
  • Time :30 minutes

WordPress powers over 40% of the web, but a default installation on shared hosting is far from production-ready. Running WordPress on your own Linux server with Nginx, PHP-FPM, MariaDB, and Redis gives you full control over performance, security, and scaling. This guide walks through a complete production stack — from database creation to Redis object caching, SSL, security hardening, and wp-cron optimization.

The target architecture handles thousands of daily visitors on a modest VPS (4 CPU, 8 GB RAM). Redis eliminates repeated database queries for options, transients, and post meta. Nginx serves static files directly and caches FastCGI responses for anonymous visitors. PHP-FPM is tuned to prevent memory exhaustion under traffic spikes.

Stack Overview

  • Nginx — reverse proxy, static file serving, FastCGI cache, TLS termination
  • PHP-FPM 8.3 — PHP process manager with tuned worker pool
  • MariaDB 11 — database with InnoDB buffer pool sizing
  • Valkey/Redis — persistent object cache via Redis Object Cache plugin
  • Certbot — Let's Encrypt SSL with auto-renewal

Prerequisites

  • Ubuntu 22.04+ or Debian 12 VPS with 4 GB+ RAM
  • Domain with DNS A record pointing to the server
  • SSH access with sudo privileges

Step 1: Install Nginx, PHP-FPM, and MariaDB

bash
sudo apt update
sudo apt install -y nginx mariadb-server \
  php8.3-fpm php8.3-mysql php8.3-curl php8.3-gd php8.3-mbstring \
  php8.3-xml php8.3-zip php8.3-intl php8.3-redis php8.3-imagick

sudo systemctl enable nginx mariadb php8.3-fpm
sudo mysql_secure_installation

Step 2: Create Database and User

bash
sudo mysql <<'SQL'
CREATE DATABASE wordpress CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'wp_user'@'localhost' IDENTIFIED BY 'REPLACE_STRONG_PASSWORD';
GRANT ALL PRIVILEGES ON wordpress.* TO 'wp_user'@'localhost';
FLUSH PRIVILEGES;
SQL

Step 3: Install WordPress

bash
sudo mkdir -p /var/www/wordpress
cd /tmp
curl -LO https://wordpress.org/latest.tar.gz
tar xzf latest.tar.gz
sudo cp -r wordpress/* /var/www/wordpress/
sudo chown -R www-data:www-data /var/www/wordpress
sudo find /var/www/wordpress -type d -exec chmod 755 {} \;
sudo find /var/www/wordpress -type f -exec chmod 644 {} \;

Step 4: Configure wp-config.php

php
sudo cp /var/www/wordpress/wp-config-sample.php /var/www/wordpress/wp-config.php
# Generate salts: https://api.wordpress.org/secret-key/1.1/salt/
# Add to wp-config.php:
define('DB_NAME', 'wordpress');
define('DB_USER', 'wp_user');
define('DB_PASSWORD', 'REPLACE_STRONG_PASSWORD');
define('DB_HOST', 'localhost');
define('DB_CHARSET', 'utf8mb4');
[...]
Command truncated. Copy to view full command.

Step 5: Nginx Virtual Host with FastCGI Cache

bash
sudo tee /etc/nginx/sites-available/wordpress.conf >/dev/null <<'EOF'
fastcgi_cache_path /var/cache/nginx/wordpress levels=1:2 keys_zone=WP:100m inactive=60m max_size=1g;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
server {
    listen 80;
    server_name blog.example.com;
    return 301 https://$host$request_uri;
}
[...]
Command truncated. Copy to view full command.

Step 6: Install Valkey and Redis Object Cache Plugin

bash
sudo apt install -y valkey
sudo systemctl enable --now valkey

# Install plugin via WP-CLI:
cd /var/www/wordpress
sudo -u www-data wp plugin install redis-cache --activate
sudo -u www-data wp redis enable

Step 7: Tune PHP-FPM for WordPress

bash
# /etc/php/8.3/fpm/pool.d/www.conf
pm = dynamic
pm.max_children = 30
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 10
pm.max_requests = 500
php_admin_value[memory_limit] = 256M
[...]
Command truncated. Copy to view full command.

Step 8: Replace wp-cron with System Cron

WordPress built-in cron runs on every page load, adding latency. Disable it in wp-config.php (done in Step 4) and schedule it via system cron instead.

bash
sudo tee /etc/cron.d/wordpress >/dev/null <<'EOF'
*/5 * * * * www-data curl -s https://blog.example.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1
EOF

Step 9: Security Hardening

  • Block xmlrpc.php — common DDoS and brute-force vector.
  • Rate-limit wp-login.php — max 5 requests per minute per IP.
  • Install Fail2ban or CrowdSec for automated IP banning.
  • Keep WordPress core, themes, and plugins updated via WP-CLI cron.
  • Disable file editing: define('DISALLOW_FILE_EDIT', true);
  • Use unique table prefix — not the default wp_.

Step 10: Verify Performance

bash
# Check Redis object cache:
sudo -u www-data wp redis status

# Check FastCGI cache headers:
curl -I https://blog.example.com/
# Look for X-FastCGI-Cache: HIT on second request

# Load test (from another machine):
ab -n 1000 -c 50 https://blog.example.com/

Production Checklist

  • Enable Redis object cache and verify hit rate above 90%.
  • Configure automated backups for database and /var/www/wordpress.
  • Set up Uptime Kuma or similar for availability monitoring.
  • Review Nginx and PHP slow logs weekly for performance regressions.
  • Test restore from backup quarterly.

"WordPress at scale is not about plugins — it is about caching layers, cron discipline, and a stack you control end to end."

Technical Author

Technical Author - Liam K.
Liam K.

System administrator and technical writer specializing in server infrastructure, security and deployment. Creating comprehensive guides to help you master server administration.