WordPress

Install WordPress on a Linux VPS with Nginx (LEMP)

Install WordPress on your own VPS: PHP-FPM and extensions, a MariaDB database, WP-CLI download, an Nginx server block with security rules, SSL, real cron and caching.

IntermediateLinux VPS3 min read

On cPanel hosting, Softaculous installs WordPress in a minute. On an unmanaged server you set up everything yourself, which gives full control. This guide shows how to install WordPress on a VPS with Nginx using WP-CLI.

Before you start

  • An Ubuntu or Debian VPS with a LEMP stack (Nginx, MariaDB, PHP-FPM) and sudo access.
  • A domain pointing to the VPS.
  • PHP extensions: mysql, curl, gd or imagick, mbstring, xml, zip, intl, opcache.

Create the database

mysql -e "CREATE DATABASE wp CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE USER 'wpuser'@'localhost' IDENTIFIED BY 'strong-password'; GRANT ALL ON wp.* TO 'wpuser'@'localhost';"

Install WP-CLI and WordPress

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
mkdir -p /var/www/example.com && chown www-data:www-data /var/www/example.com
cd /var/www/example.com && sudo -u www-data wp core download
sudo -u www-data wp config create --dbname=wp --dbuser=wpuser --dbpass=strong-password --dbhost=localhost

Here the PHP user owns the files so WordPress can install updates and plugins itself; for tighter security a separate owner with only wp-content/uploads writable is possible, at the cost of manual updates.

Configure Nginx

server {
    server_name example.com www.example.com;
    root /var/www/example.com;
    index index.php;
    client_max_body_size 64m;

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

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.3-fpm.sock;
    }

    location = /xmlrpc.php { deny all; }
    location ~* /(?:uploads|files)/.*\.php$ { deny all; }
    location ~ /\.(?!well-known) { deny all; }

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

The rules block XML-RPC, PHP execution in uploads and hidden files. Enable the site, test with nginx -t and reload. Add SSL with certbot --nginx -d example.com -d www.example.com.

Finish the install

sudo -u www-data wp core install --url=https://example.com --title="My Site" --admin_user=siteadmin --admin_email=admin@example.com --prompt=admin_password

Or open the site in a browser and complete the installer.

Use a real cron

WordPress's built-in cron runs on page views. Disable it in wp-config.php with define('DISABLE_WP_CRON', true); and add a system cron for www-data:

*/5 * * * * cd /var/www/example.com && wp cron event run --due-now >/dev/null 2>&1

Performance and email

  • Install Redis and the Redis Object Cache plugin for an object cache.
  • Use a page cache plugin or Nginx FastCGI cache.
  • Configure SMTP (WP Mail SMTP or similar); a fresh VPS usually cannot deliver mail reliably by itself.
  • Set PHP upload_max_filesize and post_max_size to match client_max_body_size.

Backups

Dump the database (wp db export) and copy wp-content off the server daily. Test a restore occasionally.

Troubleshooting

  • Permalinks return 404: the try_files line is missing.
  • Asked for FTP credentials when updating plugins: the PHP user cannot write the files; fix ownership.
  • Redirect loop after enabling SSL: siteurl/home are http; run wp option update home https://example.com and the same for siteurl.
  • 413 Request Entity Too Large: raise client_max_body_size.

WordPress VPS FAQ

VPS or WordPress hosting?

Managed cPanel hosting with LiteSpeed is simpler and fast for most sites. A VPS makes sense for custom stacks, heavy traffic or full control.

Nginx or LiteSpeed for WordPress?

Both are fast. LiteSpeed with the LSCache plugin offers easy full-page caching; Nginx needs a cache plugin or FastCGI cache configuration.

Can I host several WordPress sites on one VPS?

Yes, with a separate database, folder and server block for each, ideally each with its own PHP-FPM pool and user.

Next steps

Was this guide helpful?

Still stuck?

Ask MdmHost AI for a quick answer, or open a ticket and our team will take a look. We are here 24/7.