How to Install WordPress on a Hostperl VPS in 2026

Start with the VPS, not the website
If you want to install WordPress on a VPS cleanly, start with access, updates, and a non-root admin user. That gives you a safer setup now and makes future maintenance easier. If you want full control from SSH to SSL, a Hostperl VPS is a solid place to begin.
This guide walks you from first login to a working WordPress site with Nginx, PHP-FPM, MariaDB, and Let’s Encrypt. It also includes the checks you should run before the site goes live.
Assumptions and placeholders: SERVER_IP is your VPS address, for example 203.0.113.10. DOMAIN_NAME is the hostname you will point at the server, for example example.com. ADMIN_USER is the sudo account you create, for example wpadmin. APP_DIR is your website root, for example /var/www/example.com.
Connect over SSH and check the operating system
On your local computer, connect as root or as the default provider account if Hostperl gave you one.
ssh root@SERVER_IPIf your VPS uses a non-root default login, use that account instead:
ssh ubuntu@SERVER_IPOnce you are on the server, identify the OS before you install packages.
cat /etc/os-releaseYou should see Ubuntu, Debian, AlmaLinux, or Rocky Linux details. The package and firewall commands below are split by family so you do not mix them up.
Create a non-root sudo user
Keep the root session open. Open a second terminal after the new account is ready, and only then consider disabling root login later.
Ubuntu and Debian
On the VPS as root, create the admin account, set a password, and add it to sudo.
adduser ADMIN_USER
usermod -aG sudo ADMIN_USERCopy your SSH key into the account. Replace the public key path with your own file.
mkdir -p /home/ADMIN_USER/.ssh
chmod 700 /home/ADMIN_USER/.ssh
cp /root/.ssh/authorized_keys /home/ADMIN_USER/.ssh/authorized_keys
chown -R ADMIN_USER:ADMIN_USER /home/ADMIN_USER/.ssh
chmod 600 /home/ADMIN_USER/.ssh/authorized_keysOn the VPS as the non-root sudo user, test the login in a second terminal.
ssh ADMIN_USER@SERVER_IP
sudo -vA successful sudo -v prompt confirms the account is ready.
AlmaLinux and Rocky Linux
On the VPS as root, create the user, set a password, and add it to wheel.
useradd -m ADMIN_USER
passwd ADMIN_USER
usermod -aG wheel ADMIN_USERMove the SSH key into place with the correct ownership and permissions.
mkdir -p /home/ADMIN_USER/.ssh
chmod 700 /home/ADMIN_USER/.ssh
cp /root/.ssh/authorized_keys /home/ADMIN_USER/.ssh/authorized_keys
chown -R ADMIN_USER:ADMIN_USER /home/ADMIN_USER/.ssh
chmod 600 /home/ADMIN_USER/.ssh/authorized_keysThen test the login from another terminal.
ssh ADMIN_USER@SERVER_IP
sudo -vUpdate packages, time sync, and the basic firewall
WordPress hosts fail in boring ways when updates and time sync are skipped. Fix those first. If you want background reading on the trade-off between shared hosting and a VPS, Hostperl’s shared hosting to VPS guide explains why this setup gives you more control and more responsibility.
Ubuntu and Debian
On the VPS as the non-root sudo user, update the package index, install time sync, and enable UFW.
sudo apt update
sudo apt -y upgrade
sudo apt -y install chrony ufw unzip curl gnupg2 ca-certificates lsb-release
sudo systemctl enable --now chrony
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verboseYou should see OpenSSH, HTTP, and HTTPS allowed. Do not close your current SSH session until the new user works.
AlmaLinux and Rocky Linux
On the VPS as the non-root sudo user, update the system, enable time sync, and open ports with firewalld.
sudo dnf -y update
sudo dnf -y install chrony firewalld unzip curl policycoreutils-python-utils
sudo systemctl enable --now chronyd
sudo systemctl enable --now firewalld
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
sudo firewall-cmd --list-allIf SELinux is enforcing, keep it that way. We will label the web root correctly instead of weakening the system.
Install Nginx, PHP-FPM, and MariaDB
WordPress needs a web server, PHP, and a database. Nginx handles static files well, PHP-FPM runs WordPress, and MariaDB stores content, users, and settings. For a quick comparison of control panels if you later move this site into a managed workflow, see how to compare cPanel, Plesk, and DirectAdmin.
Ubuntu and Debian
On the VPS as the non-root sudo user, install the stack.
sudo apt -y install nginx mariadb-server php-fpm php-mysql php-cli php-curl php-xml php-mbstring php-zip php-gd php-intl php-bcmath php-imagickCheck the service names and versions.
nginx -v
php -v
mariadb --version
sudo systemctl enable --now nginx php8.3-fpm mariadbThe PHP-FPM version may differ by distro release; use the version your system installed, such as php8.3-fpm.
AlmaLinux and Rocky Linux
On the VPS as the non-root sudo user, install the same components with DNF.
sudo dnf -y install nginx mariadb-server php php-fpm php-mysqlnd php-cli php-curl php-xml php-mbstring php-zip php-gd php-intl php-bcmath php-imagickCheck the versions and enable services.
nginx -v
php -v
mariadb --version
sudo systemctl enable --now nginx php-fpm mariadbSecure MariaDB for WordPress
Set a real database password, remove anonymous access, and drop the test database. This is enough for a single-site WordPress install and also reflects the support steps we use when helping customers move off shared plans.
On the VPS as the non-root sudo user, run the hardening script.
sudo mariadb-secure-installationAnswer the prompts to set the root password, remove anonymous users, disable remote root login, and remove the test database. Then create the database and application user.
sudo mariadbInside the MariaDB prompt, run the SQL below. Replace StrongDBPassHere with a long password.
CREATE DATABASE wordpress CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'wpuser'@'localhost' IDENTIFIED BY 'StrongDBPassHere';
GRANT ALL PRIVILEGES ON wordpress.* TO 'wpuser'@'localhost';
FLUSH PRIVILEGES;
EXIT;Confirm the database exists.
sudo mariadb -e "SHOW DATABASES LIKE 'wordpress';"Download WordPress and set the file ownership
Create the site directory, download the latest WordPress release, and place it in the document root. This keeps the structure clean for future backups and migrations.
sudo mkdir -p /var/www/DOMAIN_NAME
cd /tmp
curl -LO https://wordpress.org/latest.tar.gz
sudo tar -xzf latest.tar.gz
sudo rsync -a wordpress/ /var/www/DOMAIN_NAME/
sudo chown -R www-data:www-data /var/www/DOMAIN_NAMEOn AlmaLinux and Rocky Linux, the web user is usually nginx or apache depending on the stack. If PHP-FPM runs as nginx, use that account consistently when you set ownership. Check your pool file before you guess.
Replace DOMAIN_NAME with your actual domain. A successful copy leaves the WordPress files under your site directory, including wp-admin, wp-includes, and wp-content.
Create wp-config.php
Copy the sample config and fill in the database values. This is the file that connects WordPress to MariaDB.
cd /var/www/DOMAIN_NAME
sudo cp wp-config-sample.php wp-config.php
sudo nano wp-config.phpReplace the database settings with your values:
define( 'DB_NAME', 'wordpress' );
define( 'DB_USER', 'wpuser' );
define( 'DB_PASSWORD', 'StrongDBPassHere' );
define( 'DB_HOST', 'localhost' );
define( 'DB_CHARSET', 'utf8mb4' );
define( 'DB_COLLATE', '' );Save and exit the editor. Then add fresh security salts from WordPress.org and verify the file is readable by the web server.
curl -s https://api.wordpress.org/secret-key/1.1/salt/
sudo chmod 640 wp-config.php
sudo chown root:www-data wp-config.phpThe salt output should be pasted into the config file in place of the sample keys. The permission check should show a restricted file, not world-readable access.
Configure Nginx for the site
The next step is a server block that points to your WordPress files and passes PHP requests to PHP-FPM. Test the file before you reload Nginx.
Ubuntu and Debian
On the VPS as the non-root sudo user, create the site config.
sudo nano /etc/nginx/sites-available/DOMAIN_NAMEUse this full config:
server {
listen 80;
server_name DOMAIN_NAME www.DOMAIN_NAME;
root /var/www/DOMAIN_NAME;
index index.php index.html;
access_log /var/log/nginx/DOMAIN_NAME.access.log;
error_log /var/log/nginx/DOMAIN_NAME.error.log;
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 ~* /(wp-config.php|readme.html|license.txt) {
deny all;
}
}
Enable the site and test syntax.
sudo ln -s /etc/nginx/sites-available/DOMAIN_NAME /etc/nginx/sites-enabled/
sudo nginx -tIf the test reports syntax is ok and test is successful, reload Nginx.
sudo systemctl reload nginxAlmaLinux and Rocky Linux
On the VPS as the non-root sudo user, create the server block.
sudo nano /etc/nginx/conf.d/DOMAIN_NAME.confUse this config, and update the PHP-FPM socket path if your system uses a different version.
server {
listen 80;
server_name DOMAIN_NAME www.DOMAIN_NAME;
root /var/www/DOMAIN_NAME;
index index.php index.html;
access_log /var/log/nginx/DOMAIN_NAME.access.log;
error_log /var/log/nginx/DOMAIN_NAME.error.log;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php-fpm/www.sock;
}
location ~* /(wp-config.php|readme.html|license.txt) {
deny all;
}
}
Check syntax and reload safely.
sudo nginx -t
sudo systemctl reload nginxSet up PHP-FPM and SELinux where needed
On Ubuntu and Debian, the defaults usually work after the Nginx socket path matches the installed PHP version. On AlmaLinux and Rocky Linux, SELinux commonly blocks Nginx from reaching the WordPress files if you skip the label change.
On AlmaLinux and Rocky Linux as the non-root sudo user, label the web root for HTTP access.
sudo semanage fcontext -a -t httpd_sys_content_t "/var/www/DOMAIN_NAME(/.*)?"
sudo restorecon -Rv /var/www/DOMAIN_NAMEIf PHP-FPM needs write access to uploads, allow that separately and only where needed. Keep the scope tight.
Check PHP-FPM status on your distro and restart it if you changed pool settings.
sudo systemctl status php-fpm --no-pager
sudo systemctl restart php-fpmFinish the WordPress browser install
Open http://DOMAIN_NAME in your browser. You should see the WordPress setup screen. Enter the site title, admin username, strong password, and email address, then complete the install.
After that, log in to /wp-admin and confirm the dashboard loads. If the front page works but admin pages fail, check PHP errors and Nginx logs.
sudo tail -n 50 /var/log/nginx/DOMAIN_NAME.error.log
sudo journalctl -u php-fpm -n 50 --no-pagerOn Ubuntu and Debian, the PHP-FPM unit might be versioned, such as php8.3-fpm. Use the exact unit name from systemctl list-units | grep fpm if needed.
Issue SSL, then redirect HTTP to HTTPS
Once the site loads on HTTP, request a certificate with Let’s Encrypt. This is the right moment to add TLS because the domain already points at the server and Nginx is responding.
On Ubuntu and Debian, install Certbot and the Nginx plugin if they are not already present.
sudo apt -y install certbot python3-certbot-nginx
sudo certbot --nginx -d DOMAIN_NAME -d www.DOMAIN_NAMEOn AlmaLinux and Rocky Linux, install the packages and issue the certificate.
sudo dnf -y install certbot python3-certbot-nginx
sudo certbot --nginx -d DOMAIN_NAME -d www.DOMAIN_NAMEChoose the option that redirects HTTP to HTTPS. Then test renewal before you leave the server.
sudo certbot renew --dry-runIf you handle DNS and email for the same domain, Hostperl’s DNS and SSL setup guide is a useful follow-up, especially when you need SPF, DKIM, and DMARC to support mail deliverability.
Final checks from the server and from your browser
On the VPS as the non-root sudo user, confirm services are active and listening.
sudo systemctl status nginx mariadb --no-pager
sudo systemctl status php8.3-fpm --no-pager 2>/dev/null || sudo systemctl status php-fpm --no-pager
sudo ss -tulpn | grep -E ':80|:443|:3306'You should see Nginx on ports 80 and 443, MariaDB bound locally, and PHP-FPM running. Then run a functional test page.
echo "/dev/null
curl -I https://DOMAIN_NAME/info.php
sudo rm /var/www/DOMAIN_NAME/info.phpThe curl -I call should return 200 OK or a redirect to HTTPS, depending on your cert setup. Remove the test file immediately after checking it.
From your local computer, sign in to https://DOMAIN_NAME/wp-admin, create a test post, upload one image, and confirm the permalink opens in a private browser window. That proves PHP, the database, media uploads, and rewrite rules are all working.
Common problems and the command that shows them
Blank white page or 502 error: check the PHP-FPM socket and logs.
sudo systemctl status php8.3-fpm --no-pager 2>/dev/null || sudo systemctl status php-fpm --no-pager
sudo tail -n 50 /var/log/nginx/DOMAIN_NAME.error.logIf the socket path is wrong, fix it in the Nginx config and run nginx -t again before reloading.
Permission denied on uploads: check ownership and SELinux labels.
ls -ld /var/www/DOMAIN_NAME /var/www/DOMAIN_NAME/wp-content/uploads
sudo restorecon -Rv /var/www/DOMAIN_NAMESSL certificate request fails: confirm DNS points to the server and ports 80/443 are open.
dig +short DOMAIN_NAME
sudo ufw status verbose 2>/dev/null || sudo firewall-cmd --list-allKeep it recoverable
Before you hand the site over, take a backup of the database and files, then test the restore into a staging directory or a spare VPS. That is the difference between a site that merely runs and one you can safely migrate later.
If you expect the site to grow, a safe migration plan from shared hosting to VPS helps you avoid downtime during launch week. For a hands-on restore mindset, the VPS backup testing guide is a good next step.
If you want this WordPress setup on a server you can actually control, Hostperl VPS hosting gives you room to tune PHP, Nginx, and MariaDB without shared hosting limits getting in the way. For agencies, ecommerce sites, and client migrations, that flexibility matters when you need to troubleshoot, restore, or scale.
Explore Hostperl VPS and review Hostperl shared hosting if you are still deciding whether you need full server control or a simpler starting point.
FAQ
Can I use Apache instead of Nginx?
Yes. The install flow changes, but the WordPress files, database, and SSL steps stay similar.
Why does WordPress ask for file credentials?
That usually means ownership or permissions are wrong. Check the web root owner and the wp-config.php mode.
Do I need Redis for one site?
Not at launch. Add caching after the site is stable and you know where the bottlenecks are.
Which PHP version should I use?
Use the supported version provided by your OS repositories or your PHP stream, then keep it patched.
Should I disable root SSH login now?
Only after the sudo user works in a second terminal and you have confirmed passwordless key access.
