VPS.TC
| $
Server Status
Turkey Istanbul, Türkiye
Active
USA New York, USA
Active
Cart Total:
View Cart
How to Install WordPress on a VPS: Step-by-Step Guide
CMSs

How to Install WordPress on a VPS: Step-by-Step Guide

Avatar of Defne Defne 15 min read 0 Comments
Share:

Quick Summary – Installing WordPress on a VPS

A dependable WordPress VPS setup starts with DNS and SSH, then adds the web stack, database, HTTPS, updates, monitoring, and tested backups.

  • Check requirements — Verify the Ubuntu release, available RAM, disk space, PHP support, and DNS records before installing packages.
  • Secure access — Use a separate sudo user, SSH keys, a firewall, current packages, and login monitoring.
  • Build the stack — Install Nginx, PHP-FPM, MariaDB, and the modules required by WordPress and your plugins.
  • Limit privileges — Give WordPress its own MariaDB database and user instead of using the database root account.
  • Enable HTTPS — Complete the HTTP setup, request a Let's Encrypt certificate, and test the renewal process.
  • Test recovery — Copy database and site files to another destination and perform a real restore test.

A safe WordPress VPS installation is a chain of small checks: confirm DNS and SSH, build Nginx, PHP-FPM, and MariaDB, use a restricted database account, set sane permissions, and finish with HTTPS and a tested backup. If you test each layer as you add it, a broken page usually points to a specific configuration rather than a mystery inside WordPress.

What should you prepare before installing WordPress on a VPS?

A WordPress installation can fail before WordPress is even involved. DNS may point to the wrong address, Nginx may use the wrong PHP-FPM socket, or the database account may have one character wrong in its password. I prefer to prepare each layer separately and test it before moving on.

The commands below assume Ubuntu 24.04 LTS with Nginx, PHP-FPM, and MariaDB. I run them from a separate sudo-enabled user, not from a root shell. Check the package versions provided by your distribution and by the plugins you plan to use.

🚀 Boost Your Speed with VPS Server!

Speed up your projects with high-performance SSD storage and 99.9% uptime guarantee.

Get VPS Hosting

WordPress currently lists PHP 7.4 or newer and either MySQL 8.0 or newer or MariaDB 10.6 or newer among its requirements. That does not mean every plugin supports every available PHP release, so check the plugin documentation before choosing the newest package blindly.

HTTPS protects administrator passwords and session cookies in transit. It is more than a padlock in a browser.

DNS and server preparation

Point the domain’s A record to the VPS IPv4 address. Add an AAAA record only when IPv6 is correctly configured on the VPS, firewall, and web server. An abandoned AAAA record can send some visitors toward an unreachable address while IPv4 continues to work.

☁️ Gain Flexibility with Cloud Server!

Experience the power of cloud with scalable resources and instant backups.

Cloud Server Plans
dig +short example.com A
dig +short example.com AAAA
hostnamectl
free -h
df -hT

The dig +short output should show the addresses you expect. Check / and /var in the df -hT output. Disk space disappears quickly once media files, logs, backups, and package caches share a small VPS.

I also test SSH before changing the firewall. Create the administrative user, install your SSH key, and confirm that a second terminal can log in before touching UFW.

sudo adduser deploy
sudo usermod -aG sudo deploy
sudo apt update && sudo apt full-upgrade -y
sudo apt install -y ufw fail2ban curl unzip ca-certificates
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose

If SSH runs on a non-standard port, replace OpenSSH with a rule for the actual port. Changing the port is not a security strategy by itself. Strong authentication, current packages, and monitoring still matter.

Do not close your original session immediately after enabling UFW. Test the second connection first.

Caution

Do not enable UFW and immediately close your only SSH session. Test the actual SSH port from a second terminal first, or you may lock yourself out of the VPS.

Installing Nginx, PHP-FPM, and MariaDB

Nginx handles HTTP requests, PHP-FPM executes PHP code, and MariaDB stores WordPress data. Each service has a different failure mode, which is why I check them independently.

sudo apt install -y nginx mariadb-server mariadb-client \
  php-fpm php-mysql php-curl php-gd php-mbstring php-xml \
  php-zip php-intl php-imagick
sudo systemctl enable --now nginx mariadb
sudo systemctl status nginx mariadb --no-pager

Ubuntu 24.04 provides PHP 8.3 through its standard repositories at the time of writing, but use the version actually installed on your VPS rather than copying a socket name from a different system.

php -v
php -m | sort
systemctl list-units 'php*-fpm.service' --no-legend

A missing PHP module can look like a WordPress problem later. Image processing, plugin installation, and XML-related features may fail without making the missing package obvious in the browser.

Run the MariaDB hardening utility:

sudo mariadb-secure-installation

It normally asks about anonymous users, the test database, remote root access, and other basic settings. A WordPress site usually has no reason to expose MariaDB root access over the network.

Keep the WordPress database account local and limited to one database. The MariaDB account and privilege documentation is worth keeping nearby when you need to troubleshoot access errors.

Creating a dedicated WordPress database

Give WordPress its own database and user. Using the MariaDB root account would increase the damage a compromised plugin or stolen configuration could cause.

sudo mariadb
CREATE DATABASE wp_site CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'wp_user'@'localhost' IDENTIFIED BY 'Put-a-long-random-password-here';
GRANT ALL PRIVILEGES ON wp_site.* TO 'wp_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;

utf8mb4 handles Turkish characters and four-byte Unicode characters. Generate the password locally and store it in a password manager, not in chat or an unencrypted note.

openssl rand -base64 32

Test the account before WordPress creates any tables:

mariadb -u wp_user -p -h localhost wp_site -e 'SELECT VERSION();'

You should get the MariaDB version. If the result is Access denied, check the username, database name, password, and host value before changing privileges.

Putting the WordPress files on the VPS

For this example, the site lives at /var/www/example.com. Replace the domain with yours. Download WordPress from the official distribution site, and record the version you deploy instead of treating latest.tar.gz as a permanent version reference.

sudo mkdir -p /var/www/example.com
cd /tmp
curl -O https://wordpress.org/latest.tar.gz
sudo tar -xzf latest.tar.gz -C /var/www/example.com --strip-components=1
sudo chown -R www-data:www-data /var/www/example.com
sudo find /var/www/example.com -type d -exec chmod 755 {} \;
sudo find /var/www/example.com -type f -exec chmod 644 {} \;

The web server needs to read the files. WordPress may need narrowly controlled write access for uploads or caching, but chmod 777 across the whole tree is not a fix. It only renames the problem.

Create the configuration file:

cd /var/www/example.com
sudo -u www-data cp wp-config-sample.php wp-config.php
sudo -u www-data vim wp-config.php

Replace DB_NAME, DB_USER, DB_PASSWORD, and DB_HOST with the values you created. Replace the sample salts with fresh values from the official WordPress salt generator. Never leave sample salts on a production site.

Making Nginx route WordPress requests

Nginx needs a server block that maps the domain to the WordPress directory. Static files can be served directly; requests that do not match a real file go through index.php.

sudo vim /etc/nginx/sites-available/example.com
server {
    listen 80;
    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 ~* /\.(?!well-known) {
        deny all;
    }
}

The socket may have a different name on your VPS. Check it before saving the configuration:

ls -la /run/php/

Enable the site. Remove the default site only after confirming that no other application depends on it.

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

Wait for both syntax is ok and test is successful. A reload without a configuration test is a small gamble with a live service.

The try_files directive is what lets WordPress handle pretty permalinks. Without it, the front page may work while individual posts return 404. For related checks, see What Is a 404 Error and How to Fix It.

Tip

Check /run/php/ before writing the Nginx server block. The installed PHP version determines the socket name, and guessing it commonly produces a 502 response.

HTTPS and the first WordPress login

Open the domain over HTTP and complete the initial WordPress setup with the site title, administrator account, password, and email address. Avoid using admin as the username. It is an easy name for automated login attempts to guess.

Once HTTP works, request a Let’s Encrypt certificate with Certbot:

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

The dry run checks the renewal path without replacing the live certificate. A timer existing on the system does not prove that renewal will succeed; read the command output.

After HTTPS is active, verify in Settings, General that both the WordPress Address and Site Address begin with https://. If redirects loop, inspect the reverse-proxy headers, siteurl, and home together. For status-code details, see What Is a 301 Redirect? An SEO Implementation Guide.

Open https://example.com/wp-admin, choose a permalink structure, and save it. This is a good point to test one post, one image, and the logout flow.

Security work after the installation

The installation is only the beginning. WordPress core, plugins, themes, PHP, MariaDB, and Ubuntu all create separate update surfaces. Remove unused plugins and themes instead of leaving them disabled forever.

Use a unique administrator password, two-factor authentication, and an email address you actually monitor. If no integration needs XML-RPC, consider disabling it after checking the site’s real features.

To disable the built-in theme and plugin editor, add this to wp-config.php:

define('DISALLOW_FILE_EDIT', true);

This prevents dashboard editing of theme and plugin files. It does not disable uploads or updates, so do not mistake it for a complete application security policy.

Read the logs before restarting anything. Useful places include journalctl -u nginx, the Nginx access and error logs, and the PHP-FPM logs. If PHP-FPM fails upstream, How to Fix a 502 Bad Gateway Error has additional checks.

I learned the value of this during a night when an application had filled /var with unrotated logs. I found the culprit with ncdu, added the missing logrotate rule, and avoided a reboot that would not have fixed anything. Logs often explain the outage if I give them a chance.

Keep backups away from the VPS disk. Back up the database and wp-content, then perform a restore rather than merely checking that an archive exists.

From the field

I once found an application filling /var with unrotated logs. ncdu showed me the directory responsible, and a missing logrotate rule explained the growth. The lesson was simple: read the disk and service logs before reaching for a reboot.

Performance, caching, and backup choices

A larger VPS is not always the first answer to a slow WordPress site. Unnecessary plugins, large images, slow queries, and uncached PHP requests can consume resources quickly.

Start with htop, Nginx logs, and query timings. I still use htop because my fingers remember its function keys, although btop is certainly prettier.

Set pm.max_children according to available RAM and the memory usage of your actual PHP workers. A value of 50 copied from another server can push a small VPS into swap. For swap planning, see How to Create Swap Space on a VPS for Linux Memory Management.

For media, consider WebP or AVIF conversion, browser cache headers, and page caching. Before debating TTFB by the millisecond, check whether the page cache is serving the request at all.

A simple local backup example is:

sudo install -d -m 700 /var/backups/wordpress
sudo mariadb-dump --single-transaction wp_site | \
  gzip | sudo tee /var/backups/wordpress/wp_site-$(date +%F).sql.gz > /dev/null
sudo tar -czf /var/backups/wordpress/wp-content-$(date +%F).tar.gz \
  -C /var/www/example.com wp-content

These archives are useful for a quick rollback, but they will not protect you from VPS loss or disk failure. I use rsync for copying to a remote target and Borg for versioned, encrypted backups. Schedule a restore test at least monthly.

When the new site does not load

Do not restart the VPS as your first diagnostic step. Separate DNS, network, Nginx, PHP-FPM, MariaDB, and WordPress problems one at a time.

  • Run dig +short example.com to check the resolved address.
  • Run curl -I https://example.com to inspect the status and redirect.
  • Run sudo nginx -t to test the configuration syntax.
  • Check services with systemctl status php8.3-fpm nginx mariadb.
  • Read journalctl -u nginx -n 100 --no-pager and the PHP-FPM logs.
  • Watch new Nginx errors with sudo tail -f /var/log/nginx/error.log.

A 403 often points to permissions or an Nginx rule. A 404 commonly involves try_files or permalink handling. A 502 usually means that Nginx cannot reach the expected PHP-FPM service or socket.

For a database connection error, compare the values in wp-config.php with the MariaDB user’s database and host privileges. Repeat the request with curl, then match its timestamp with the log entry. That is usually quicker than a reboot based on a guess.

Example

A 404 on individual posts usually points toward permalink routing, while a 502 after a PHP package change points toward the PHP-FPM service or socket. Use the status code to choose the next log instead of treating it as a reason to restart the VPS.

Check These Before Calling the Installation Finished

  • Verify the A and AAAA records from the VPS and from an external network.
  • Create a separate sudo user and test a second SSH session.
  • Install and verify Nginx, PHP-FPM, MariaDB, and the required PHP modules.
  • Create a restricted WordPress database and user, then test the credentials.
  • Set file ownership and permissions without using chmod 777.
  • Run nginx -t before every reload and confirm the PHP-FPM socket.
  • Obtain the HTTPS certificate, test renewal, and perform a real backup restore.

Once WordPress is serving HTTPS, perform the first restore test before installing a pile of plugins. That quiet test tells you more about your VPS readiness than another dashboard setting.

Explore VPS plans

Frequently Asked Questions

How much RAM does a WordPress VPS need?

A small blog may run with 1 GB of RAM, but that is a starting point rather than a guarantee. PHP workers, plugins, MariaDB, web traffic, and background jobs all share memory. Measure usage with free -h and htop, then tune PHP-FPM instead of choosing an arbitrary worker count.

Should I install WordPress as root?

No. Use a separate sudo-enabled administrator for server work and give the web server only the ownership and write access it needs. WordPress should also use a dedicated MariaDB account restricted to its own database. Running every command and the application as root increases the consequences of a compromised plugin or mistaken command.

Why does WordPress show a 502 Bad Gateway error after installation?

Nginx usually returns 502 when it cannot communicate with PHP-FPM. Check the PHP-FPM service status, inspect /run/php/ for the real socket name, compare it with fastcgi_pass, and read the Nginx error log. A stopped service, wrong socket path, or exhausted PHP-FPM pool can all produce the same browser error.

Do I need an AAAA record for my WordPress VPS?

Only create an AAAA record when IPv6 is configured and reachable on the VPS, firewall, and web server. An incorrect AAAA record can make IPv6-capable visitors try an unusable address even while IPv4 works. Check both records with dig +short example.com A and dig +short example.com AAAA before publishing the site.

Is chmod 777 safe for WordPress?

No. It grants read, write, and execute permissions broadly and hides the underlying ownership or application-write problem. Start with directories at 755 and files at 644, owned by the account that serves the site, then grant narrowly targeted write access only where WordPress requires it, such as uploads or a controlled cache directory.

How should I back up a WordPress VPS?

Back up both the database and the files, especially wp-content, to a destination separate from the VPS disk. A local archive helps with a quick rollback but will not protect against disk failure or VPS loss. Use a remote copy or versioned backup system, encrypt sensitive data, and perform a restore test regularly; an untested archive is only a hopeful file.

Sources

Avatar of Defne
Author

Defne