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,gdorimagick,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/wpmkdir -p /var/www/example.com && chown www-data:www-data /var/www/example.comcd /var/www/example.com && sudo -u www-data wp core downloadsudo -u www-data wp config create --dbname=wp --dbuser=wpuser --dbpass=strong-password --dbhost=localhostHere 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_passwordOr 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>&1Performance 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_filesizeandpost_max_sizeto matchclient_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_filesline 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.comand the same forsiteurl. - 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.
