Skip to content

AS213941 · Peering-20% on all VPS with code NVH20 · Delivered in 60 seconds

Linux VPSFrom 2,49 €/monthWindows VPSFrom 3,49 €/monthFiveM serverFrom 0,99 €/monthMinecraft serverFrom 1,99 €/month
VPS & Cloud

Ranges

Linux NVMe VPSRoot access, Debian, Ubuntu, Alma…Windows RDP VPSRemote desktop, licence includedDedicated serversIntel Xeon Gold, exclusive resourcesPterodactyl VPSGame panel preinstalled

Network and hosting

Anti-DDoSWeb hostingColocationIP transitVPN

Professionals

Reseller VPSReseller programme
Solutions

Bots and automation

AI agents VPSA server for your coding assistants and autonomous agentsTelegram bot VPSPython or Node.js, always reachableDiscord bot VPSMusic, moderation, tickets: no downtimen8n VPSWorkflows with no execution limitVPN VPSAn encrypted tunnel exiting in FranceWeb scraping VPSScheduled data collection, dedicated IP

Trading

Forex VPSYour robots manage positions overnightMetaTrader 4 VPSSeveral MT4 terminals on one machineMetaTrader 5 VPSForex, indices and stocks in MT5NinjaTrader VPSFutures and NinjaScript strategiesTrading bot VPSOpen-source crypto bots, protected API keys

Windows desktop

Windows 10 VPSFor software that requires Windows 10Windows 11 VPSA modern Windows desktop, reachable anywhereSEO VPSLarge-site crawls without tying up your PCStreaming VPSAn OBS studio streaming from the data centreWordPress VPSFast websites on NVMe disks
Marketplace

Intelligence artificielle

Claude CodeL'agent de code d'Anthropic, dans votre terminalCodex CLIL'agent de code d'OpenAI en ligne de commandeOllamaDes modèles de langage locaux, sans API externeOpen WebUIUne interface de discussion pour vos modèles Ollama

Automatisation

n8nVos automatisations, sans limite d'exécutions

Déploiement et conteneurs

DockerLe moteur de conteneurs et Docker ComposeCoolifyDéployez vos applications depuis Git, sur votre serveurPortainerGérez vos conteneurs Docker depuis le navigateur

Supervision

Uptime KumaSurveillez vos sites et serveurs, alertes comprises

Network and security

WireGuardVotre propre VPN chiffré, rapide et moderneVaultwardenUn gestionnaire de mots de passe auto-hébergé

Sites et cloud

NextcloudVotre cloud de fichiers, agenda et contactsWordPressLe CMS le plus utilisé, sur une pile Nginx rapide

Jeux

PterodactylLe panel pour héberger vos serveurs de jeux
Gaming

Game servers

FiveM servertxAdmin, ESX, QBCoreMinecraft serverJava, Bedrock, modpacksRust serverOxide, Carbon, wipesNova-Life serverNova-Life: Amboise RP

Protection and tools

FiveM Anti-DDoSFree tools
Resources

Learn

DocumentationBlog

Assistance

ContactSLA commitment
View plans Client area Peering · AS213941

Installation

Installing WordPress on a VPS with Nginx, MariaDB and PHP 8.3

By the NVHCloud team · 2026-09-18 · 5 min read

This guide installs WordPress on a fresh VPS with the best-performing stack for the resources: Nginx, PHP-FPM 8.3 and MariaDB. Allow about twenty minutes. The commands are written for Ubuntu 24.04 LTS, which ships PHP 8.3 by default; differences with Debian 12 are pointed out.

Prefer a graphical interface? Hosting with Plesk installs WordPress in one click: see our web hosting. And if you are unsure about the server size, first read which VPS to host WordPress (in French).

1. Prerequisites

  • A freshly installed VPS with at least 2 GB of RAM (4 GB recommended for a business site).
  • Root access over SSH. If you have not done so yet, follow first steps on your VPS.
  • A domain name whose A record points to the VPS IP address. See configuring DNS.

Throughout the guide, replace mysite.com with your domain.

2. Install Nginx, MariaDB and PHP 8.3

apt update && apt upgrade -y
apt install -y nginx mariadb-server \
  php8.3-fpm php8.3-mysql php8.3-curl php8.3-gd php8.3-intl \
  php8.3-mbstring php8.3-xml php8.3-zip php8.3-bcmath php-imagick

These extensions cover what WordPress asks for in its "Site Health" screen: intl for languages, gd and imagick for images, zip to install plugins from the admin panel.

💡 On Debian 12, the version shipped is PHP 8.2: replace php8.3 with php8.2 everywhere in this guide, or add Sury's repository to get PHP 8.3. WordPress recommends PHP 8.3 or newer.

Then secure MariaDB: this command removes anonymous accounts and the test database.

mariadb-secure-installation

Answer Y to every question. On Ubuntu, MariaDB's root account authenticates through the system: mariadb run as root asks for no password, and that is intended. To go further, see securing MariaDB.

3. Create the database

First generate a strong password, then create a database and a user dedicated to this site:

openssl rand -base64 24
mariadb
CREATE DATABASE mysite CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'mysite'@'localhost' IDENTIFIED BY 'THE_GENERATED_PASSWORD';
GRANT ALL PRIVILEGES ON mysite.* TO 'mysite'@'localhost';
FLUSH PRIVILEGES;
EXIT;

One user per site: if one site is compromised, the attacker cannot reach the other sites' databases.

4. Download and configure WordPress

cd /var/www
wget https://wordpress.org/latest.tar.gz
tar xzf latest.tar.gz && rm latest.tar.gz
mv wordpress mysite.com
cd mysite.com
cp wp-config-sample.php wp-config.php

Open wp-config.php and fill in DB_NAME, DB_USER and DB_PASSWORD. Then replace the block of security keys (the lines AUTH_KEY to NONCE_SALT) with unique values generated by the official service:

curl -s https://api.wordpress.org/secret-key/1.1/salt/

Also add these two lines above /* That's all, stop editing! */:

define('DISABLE_WP_CRON', true);   // replaced by a real cron, see step 8
define('DISALLOW_FILE_EDIT', true); // no code editor in the admin panel

Finally, give the files to the web server user:

chown -R www-data:www-data /var/www/mysite.com
find /var/www/mysite.com -type d -exec chmod 755 {} \;
find /var/www/mysite.com -type f -exec chmod 644 {} \;
chmod 640 /var/www/mysite.com/wp-config.php

5. Configure Nginx

Create the file /etc/nginx/sites-available/mysite.com:

server {
    listen 80;
    listen [::]:80;
    server_name mysite.com www.mysite.com;
    root /var/www/mysite.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;
    }
    # sensitive files
    location ~ /\.(?!well-known) { deny all; }
    location = /xmlrpc.php { deny all; }
    location ~* /(?:uploads|files)/.*\.php$ { deny all; }
    location ~* \.(?:css|js|jpe?g|png|gif|webp|avif|svg|ico|woff2?)$ {
        expires 30d;
        add_header Cache-Control "public";
        access_log off;
    }
}

Three rules deserve an explanation. The \. in \.php$ matters: without the backslash, the dot matches any character. Blocking xmlrpc.php closes an entry point widely used for brute-force attacks; only remove it if you use the WordPress mobile app or Jetpack. Finally, no PHP file must be able to run from the uploaded media folder.

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

6. Tune PHP

PHP's default limits block media uploads above 2 MB. Create an override file rather than editing php.ini: it survives updates.

cat > /etc/php/8.3/fpm/conf.d/99-wordpress.ini <<'EOF'
upload_max_filesize = 64M
post_max_size = 64M
memory_limit = 256M
max_execution_time = 120
EOF
systemctl restart php8.3-fpm

Keep upload_max_filesize in line with client_max_body_size in Nginx, otherwise the smaller of the two values applies.

7. Enable HTTPS

apt install -y certbot python3-certbot-nginx
certbot --nginx -d mysite.com -d www.mysite.com --redirect

Certbot gets the certificate, adds the HTTPS configuration and redirects HTTP. Renewal is automatic. Details and troubleshooting in Nginx and Let's Encrypt.

8. Finish the installation

Open https://mysite.com: the WordPress wizard asks for the site name and the administrator account. Choose a username other than admin and a long password.

Then set up the system cron declared in step 4. By default, WordPress runs its scheduled tasks during visits, which slows some pages down and does not run when the site has no traffic.

echo '*/5 * * * * www-data /usr/bin/php /var/www/mysite.com/wp-cron.php >/dev/null 2>&1' > /etc/cron.d/wordpress-mysite

Finally, in Settings → Permalinks, choose "Post name": readable addresses are better for SEO.

9. Secure and optimise

The site works. Here is what makes it last, in order of priority:

  1. Firewall: only the SSH, 80 and 443 ports open. See configuring UFW.
  2. Key-based SSH and root login disabled. See securing SSH.
  3. Fail2ban on SSH and on wp-login.php. See advanced Fail2ban.
  4. Daily off-server backups, files and database. See backups with Borg.
  5. Performance: OPcache, Nginx page cache and Redis. See optimising PHP-FPM and the Nginx cache.
💡 Moving an existing site rather than creating one? Follow our procedure migrating WordPress to a VPS with no downtime (in French) instead of steps 4 and 8.

Frequently asked questions

MySQL or MariaDB for WordPress?

Both work. WordPress recommends MySQL 8.0 or newer, or MariaDB 10.11 or newer. MariaDB is the default database on Debian and Ubuntu, it is compatible with WordPress without any change, and it is the simplest choice on a VPS.

Why Nginx rather than Apache?

Nginx uses less memory per connection and serves static files more efficiently, which matters on a small VPS. Apache remains a good choice if you depend on .htaccess files, which Nginx does not read: with Nginx, rewrite rules go in the server configuration.

How many WordPress sites can I install on a VPS?

As many as memory allows. Repeat steps 3 to 7 for each site, with a separate database, user, folder and Nginx file. A 4 GB VPS comfortably hosts several small sites with caching enabled.

How do I update WordPress on a VPS?

From the admin panel, as on any hosting, since the files belong to the web server user. Take a backup before every major update. To manage several sites from the command line, the WP-CLI tool updates everything with a single command.

Windows VPS

Remote desktop and licence included, from 3,49 €/month.