How to setup WordPress on LEMP with Redis and WP CLI on Debian 11

This is the fastest, most secure, and most resource-efficient way to self-host WordPress in 2025. We’ll use a proper LEMP stack (Linux + Nginx + MySQL/MariaDB + PHP-FPM) with per-site PHP isolation, Redis object caching, automatic SSL, and WP-CLI — everything tuned for speed and security.

5 months ago   •   4 min read

By Aquasp
Table of contents

Introduction

This is the fastest, most secure, and most resource-efficient way to self-host WordPress in 2025.
We’ll use a proper LEMP stack (Linux + Nginx + MySQL/MariaDB + PHP-FPM) with per-site PHP isolation, Redis object caching, automatic SSL, and WP-CLI — everything tuned for speed and security.

Let’s go.

Step 0: Secure & Update Your VPS

(If you haven’t already, follow a VPS hardening guide first — SSH keys only, firewall, fail2ban, etc.)

apt update && apt upgrade -y
apt autoremove --purge
reboot

Step 1: Install the Core Stack

# Nginx
apt install nginx -y
systemctl enable nginx

# MariaDB (better than MySQL on Debian)
apt install mariadb-server -y
systemctl enable mariadb

# PHP 8.3 + all needed extensions (using ondrej/sury repo)
apt install ca-certificates apt-transport-https lsb-release -y
wget -qO- https://packages.sury.org/php/apt.gpg | gpg --dearmor > /usr/share/keyrings/sury-php.gpg
echo "deb [signed-by=/usr/share/keyrings/sury-php.gpg] https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/sury-php.list
apt update
apt install 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-imagick php8.3-redis -y
systemctl enable php8.3-fpm

# Redis
curl -fsSL https://packages.redis.io/gpg | gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" > /etc/apt/sources.list.d/redis.list
apt update && apt install redis-server -y
systemctl enable redis-server

# Certbot + WP-CLI
apt install python3-certbot-nginx -y
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
chmod +x wp-cli.phar && mv wp-cli.phar /usr/local/bin/wp

Step 2: Secure MariaDB & Create Database

mysql_secure_installation
mysql -u root -p
CREATE DATABASE wp_yoursite;
CREATE USER 'wp_yoursite'@'localhost' IDENTIFIED BY 'strongpassword';
GRANT ALL ON wp_yoursite.* TO 'wp_yoursite'@'localhost';
FLUSH PRIVILEGES;
EXIT;

Step 3: Isolate PHP-FPM Per Site (Security + Stability)

cd /etc/php/8.3/fpm/pool.d/
cp www.conf yoursite.conf
nano yoursite.conf

Replace:

  • [www] → [yoursite]
  • user = www-data → user = yoursiteuser (we’ll create this user soon)
  • group = www-data → group = yoursiteuser
  • listen = /run/php/php8.3-fpm.sock → listen = /run/php/php8.3-fpm-yoursite.sock
  • Change process manager from dynamic → ondemand (saves RAM)
systemctl restart php8.3-fpm

(It will fail until the user exists — that’s fine.)

Step 4: Optimize PHP & Enable OPcache

sed -i "s/memory_limit = .*/memory_limit = 1024M/" /etc/php/8.3/fpm/php.ini
sed -i "s/upload_max_filesize = .*/upload_max_filesize = 10240M/" /etc/php/8.3/fpm/php.ini
sed -i "s/post_max_size = .*/post_max_size = 10240M/" /etc/php/8.3/fpm/php.ini
sed -i "s/max_execution_time = .*/max_execution_time = 600/" /etc/php/8.3/fpm/php.ini
sed -i "s/;opcache.enable=1/opcache.enable=1/" /etc/php/8.3/fpm/php.ini
sed -i "s/;opcache.memory_consumption=.*/opcache.memory_consumption=512/" /etc/php/8.3/fpm/php.ini
sed -i "s/;opcache.max_accelerated_files=.*/opcache.max_accelerated_files=20000/" /etc/php/8.3/fpm/php.ini
sed -i "s/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/" /etc/php/8.3/fpm/php.ini

Step 5: Create System User & Site Directory

adduser yoursiteuser --shell /bin/bash
su yoursiteuser
mkdir ~/public_html && cd ~/public_html
echo "cd ~/public_html" >> ~/.bashrc
exit

Step 6: Nginx Config (Fast & Secure)

nano /etc/nginx/sites-available/yoursite.conf
upstream php-yoursite {
    server unix:/run/php/php8.3-fpm-yoursite.sock;
}

server {
    listen 80;
    listen [::]:80;
    server_name yourdomain.com www.yourdomain.com;
    root /home/yoursiteuser/public_html;
    index index.php index.html;

    client_max_body_size 10G;

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

    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_pass php-yoursite;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }

    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff2?|ttf|eot)$ {
        expires max;
        log_not_found off;
    }
}
ln -s /etc/nginx/sites-available/yoursite.conf /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx

Step 7: Install WordPress via WP-CLI (as the site user)

su yoursiteuser
cd ~/public_html

wp core download
wp config create --dbname=wp_yoursite --dbuser=wp_yoursite --dbpass='strongpassword' --locale=en_US
wp core install --url=https://yourdomain.com --title="Your Site" --admin_user=admin --admin_password='strongpass' --admin_email=you@domain.com

Step 8: SSL with Let’s Encrypt (Auto-renew)

certbot --nginx -d yourdomain.com -d www.yourdomain.com
# Choose redirect to HTTPS when asked

Add auto-renew cron:

crontab -e
# Add:
0 0 * * 0 certbot renew --quiet

Step 9: Enable Redis Object Cache

# As root
usermod -aG redis yoursiteuser
chmod 770 /var/run/redis/redis-server.sock

# Optimize Redis config
sed -i 's/port 6379/port 0/' /etc/redis/redis.conf
sed -i 's|# unixsocket /run/redis/redis-server.sock|unixsocket /var/run/redis/redis-server.sock|' /etc/redis/redis.conf
sed -i 's/# unixsocketperm 700/unixsocketperm 770/' /etc/redis/redis.conf
sed -i 's/# maxmemory .*/maxmemory 1024mb/' /etc/redis/redis.conf
systemctl restart redis-server
# As yoursiteuser
cd ~/public_html
wp plugin install redis-cache --activate
wp config set WP_REDIS_SCHEME unix
wp config set WP_REDIS_PATH '/var/run/redis/redis-server.sock'
wp redis enable

Done!

You now have:

  • Fully isolated PHP-FPM pool (1 user = 1 site = no cross-site damage)
  • Redis object caching over Unix socket
  • OPcache + huge upload limits
  • Automatic SSL renewal
  • Fastest possible Nginx routing
  • WP-CLI ready

Your wp-admin will feel instant, and the site will handle traffic like a champ — even on a $5/month VPS.

Next steps:

  • Install a page cache plugin (any free one is ok)
  • Set up Cloudflare (optional but recommended)
  • Regular backups

Enjoy your blazing-fast, private WordPress setup!

If this guide helped, share it or subscribe to The Self Hosting Art. Thanks for reading! 😊

Spread the word

Keep reading