Running WordPress on your own VPS gives you full control: your own PHP settings, no "resource limit reached" emails, and room to grow. This guide installs it the fast, modern way, on what's called a LEMP stack: Linux, Nginx ("engine-x"), MariaDB (a drop-in MySQL) and PHP, plus a free SSL certificate. It takes about 20 minutes.

What you need

In every command and file below, replace example.com with your own domain.

1. Install Nginx, PHP and MariaDB

sudo apt update sudo apt install -y nginx mariadb-server php-fpm php-mysql php-curl php-gd php-intl php-mbstring php-xml php-zip php-imagick unzip 

Ubuntu 24.04 installs PHP 8.3. Check the version and the PHP-FPM socket name, because you need it in step 4:

php -v ls /run/php/ 

You should see php8.3-fpm.sock.

2. Open the firewall

sudo ufw allow 'Nginx Full' sudo ufw status 

This opens ports 80 and 443. Port 80 is needed for the free certificate in step 6.

3. Create the database

First run the security script: press Enter for the current root password (there is none), then answer Y to the questions that remove test users and the test database.

sudo mariadb-secure-installation 

Then create a database and a user just for WordPress. Choose your own strong password:

sudo mariadb 
CREATE DATABASE wordpress DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE USER 'wpuser'@'localhost' IDENTIFIED BY 'Use-A-Strong-Password-Here'; GRANT ALL PRIVILEGES ON wordpress.* TO 'wpuser'@'localhost'; FLUSH PRIVILEGES; EXIT; 

WordPress gets its own user with access to only its own database, so a problem in one site can't touch anything else.

4. Download WordPress and set up Nginx

cd /tmp curl -O https://wordpress.org/latest.tar.gz tar xzf latest.tar.gz sudo mv wordpress /var/www/example.com sudo chown -R www-data:www-data /var/www/example.com 

Now tell Nginx about the site:

sudo nano /etc/nginx/sites-available/example.com 
server { listen 80; server_name example.com www.example.com; root /var/www/example.com; index index.php index.html; 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 ~ /\. { deny all; } } 

Enable it, switch off the default page, test and reload:

sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/ sudo rm /etc/nginx/sites-enabled/default sudo nginx -t sudo systemctl reload nginx 

What the important lines do:

  • try_files … /index.php?$args makes WordPress "pretty" links (like /about-us/) work. Without it they show 404.
  • client_max_body_size 64M lets you upload themes, plugins and images up to 64 MB.
  • xmlrpc.php is blocked because bots use it for password-guessing attacks, and most sites don't need it. If you use the Jetpack plugin or the WordPress mobile app, remove that line.

5. Raise PHP's upload and memory limits

PHP's defaults (2 MB uploads) are too small for WordPress. Open the settings file:

sudo nano /etc/php/8.3/fpm/php.ini 

Find and change these lines (in nano, Ctrl+W searches):

upload_max_filesize = 64M post_max_size = 64M memory_limit = 256M max_execution_time = 120 
sudo systemctl restart php8.3-fpm 

6. Get a free SSL certificate

sudo apt install -y certbot python3-certbot-nginx sudo certbot --nginx -d example.com -d www.example.com 

Enter your email and agree to the terms. Certbot gets a free Let's Encrypt certificate, adds HTTPS to your Nginx file and redirects HTTP to HTTPS. Certificates renew automatically; check renewal works with:

sudo certbot renew --dry-run 

7. Run the WordPress installer

Open https://example.com. Choose your language, then enter:

  • Database name: wordpress
  • Username: wpuser
  • Password: the one you chose in step 3
  • Database host: localhost
  • Table prefix: keep wp_, or change it to something like v7k_

Then set your site title and admin account. Don't use "admin" as the username; bots try it first. Use a long password.

8. Five things to do right after

  1. Permalinks: Settings → Permalinks → Post name. Clean URLs are better for visitors and Google.
  2. Block file editing in the dashboard, so a stolen password can't be used to change PHP code. Add this line to /var/www/example.com/wp-config.php, above "That's all, stop editing": define('DISALLOW_FILE_EDIT', true);
  3. Updates: keep WordPress, themes and plugins up to date, and delete the ones you don't use. Outdated plugins are the most common way WordPress sites get hacked.
  4. Backups: turn on server snapshots, and add a backup plugin that copies your files and database off the server (for example to Google Drive).
  5. Caching: install a caching plugin to make pages load faster and use less CPU.

Common problems

Problem Usual fix
502 Bad Gateway The PHP socket name in your Nginx file doesn't match. Run ls /run/php/, fix the fastcgi_pass line, then sudo nginx -t && sudo systemctl reload nginx.
Error establishing a database connection Wrong database name, user or password in wp-config.php, or MariaDB is stopped: sudo systemctl status mariadb.
Pages other than the home page show 404 The try_files line is missing from the Nginx file.
"The uploaded file exceeds the upload_max_filesize" Raise both PHP's limits (step 5) and Nginx's client_max_body_size, then restart PHP-FPM and reload Nginx.
WordPress asks for FTP details to install plugins File ownership is wrong. Run sudo chown -R www-data:www-data /var/www/example.com.
Certbot fails The domain doesn't point to the server yet, or port 80 is closed. Check with dig +short example.com and sudo ufw status.

Originally published on the Volyte blog. Rather not manage the server yourself? Our WordPress hosting runs on NVMe with free SSL and weekly backups, same price at renewal.