DEV Community

Volyte
Volyte

Posted on Originally published at volyte.com

How to Install WordPress on a VPS (Nginx + PHP + MariaDB + Free SSL)

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
Enter fullscreen mode Exit fullscreen mode

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/
Enter fullscreen mode Exit fullscreen mode

You should see php8.3-fpm.sock.

2. Open the firewall

sudo ufw allow 'Nginx Full'
sudo ufw status
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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

sudo mariadb
Enter fullscreen mode Exit fullscreen mode
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;
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Now tell Nginx about the site:

sudo nano /etc/nginx/sites-available/example.com
Enter fullscreen mode Exit fullscreen mode
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; }
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode
sudo systemctl restart php8.3-fpm
Enter fullscreen mode Exit fullscreen mode

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 fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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.

Top comments (0)