How to Host a WordPress Site on a VPS: Step-by-Step Tutorial
This tutorial walks you through the entire process from a blank Ubuntu 22.04 VPS to a fully running, SSL-secured WordPress site. No prior server experience required.
Before You Begin
Make sure you have the following ready before starting:
Min: 1 GB RAM, 1 vCPU, 20 GB SSD
Pointed to your VPS IP via A record
Root or sudo user credentials
Update System & Install Nginx
⏱ ~3 min
Start with a clean, updated system. Then install Nginx — the web server that will handle all HTTP/HTTPS traffic to your WordPress site.
# Update packages $ apt update && apt upgrade -y # Install Nginx $ apt install nginx -y # Start and enable Nginx $ systemctl start nginx $ systemctl enable nginx # Allow HTTP/HTTPS through firewall $ ufw allow 'Nginx Full'
Verify Nginx is running by visiting your server’s IP address in a browser. You should see the default Nginx welcome page.
Install PHP 8.3
⏱ ~5 min
WordPress requires PHP. We’ll install PHP 8.3 along with the extensions WordPress depends on. We use php-fpm (FastCGI Process Manager) to integrate PHP with Nginx.
# Add PHP repository $ apt install software-properties-common -y $ add-apt-repository ppa:ondrej/php -y $ apt update # Install PHP 8.3 and required extensions $ apt install php8.3-fpm php8.3-mysql php8.3-curl \ php8.3-gd php8.3-mbstring php8.3-xml php8.3-zip \ php8.3-bcmath php8.3-imagick -y # Verify PHP version $ php -v
ondrej/php PPA is the most reliable source for up-to-date PHP versions on Ubuntu. It’s maintained by one of the official PHP package maintainers.Install MySQL & Create a Database
⏱ ~5 min
WordPress stores all its data — posts, settings, users — in a MySQL database. Install MySQL, secure it, then create a dedicated database and user for WordPress.
# Install MySQL $ apt install mysql-server -y # Run the security script $ mysql_secure_installation
Follow the prompts: set a root password, remove anonymous users, disallow remote root login, and remove the test database.
Now create the WordPress database and user:
$ mysql -u root -p -- Create the database CREATE DATABASE wordpress_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -- Create a dedicated user CREATE USER 'wp_user'@'localhost' IDENTIFIED BY 'StrongPassword123!'; -- Grant permissions GRANT ALL PRIVILEGES ON wordpress_db.* TO 'wp_user'@'localhost'; FLUSH PRIVILEGES; EXIT;
Download & Configure WordPress
⏱ ~4 min
Download the latest WordPress release directly from wordpress.org and place it in your web root directory.
# Download latest WordPress $ cd /tmp $ wget https://wordpress.org/latest.tar.gz $ tar -xzf latest.tar.gz # Move to web root $ mv wordpress /var/www/yourdomain.com # Create wp-config.php from the sample $ cp /var/www/yourdomain.com/wp-config-sample.php \ /var/www/yourdomain.com/wp-config.php
Edit the config file with your database credentials:
$ nano /var/www/yourdomain.com/wp-config.php
define( 'DB_NAME', 'wordpress_db' ); define( 'DB_USER', 'wp_user' ); define( 'DB_PASSWORD', 'StrongPassword123!' ); define( 'DB_HOST', 'localhost' );
Also update the secret keys by fetching fresh ones from https://api.wordpress.org/secret-key/1.1/salt/ and replacing the placeholder block in wp-config.php.
Configure Nginx for WordPress
⏱ ~5 min
Create an Nginx server block (virtual host) for your domain. This tells Nginx how to route requests to your WordPress installation.
$ nano /etc/nginx/sites-available/yourdomain.com
Paste the following configuration (replace yourdomain.com with your actual domain):
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
root /var/www/yourdomain.com;
index index.php index.html;
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 ~ /\.ht {
deny all;
}
# Cache static assets
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2)$ {
expires 30d;
add_header Cache-Control "public, no-transform";
}
}
# Enable site and test config $ ln -s /etc/nginx/sites-available/yourdomain.com \ /etc/nginx/sites-enabled/ $ nginx -t $ systemctl reload nginx
Set Correct File Permissions
⏱ ~2 min
WordPress needs specific file permissions to function securely. The web server user (www-data) must own the WordPress files so it can read them and write uploads.
# Set ownership $ chown -R www-data:www-data /var/www/yourdomain.com # Set directory permissions $ find /var/www/yourdomain.com -type d -exec chmod 755 {} \; # Set file permissions $ find /var/www/yourdomain.com -type f -exec chmod 644 {} \;
Install Free SSL with Certbot (Let’s Encrypt)
⏱ ~5 min
HTTPS is mandatory in 2025 — it affects both your Google rankings and user trust. Let’s Encrypt provides free, auto-renewing SSL certificates via Certbot.
# Install Certbot $ apt install certbot python3-certbot-nginx -y # Obtain and install SSL certificate $ certbot --nginx -d yourdomain.com -d www.yourdomain.com
Certbot will automatically edit your Nginx config to enable HTTPS and set up a redirect from HTTP. It also installs a cron job to auto-renew the certificate before it expires.
Test the auto-renewal:
$ certbot renew --dry-run
Complete WordPress Setup in the Browser
⏱ ~3 min
The technical setup is done. Now finish the WordPress installation through its web interface.
- Visit https://yourdomain.com in your browser
- Select your language and click Continue
- Enter your site title, admin username, a strong password, and your email
- Click Install WordPress
- Log in at https://yourdomain.com/wp-admin
Performance Tuning: Make WordPress Faster
⏱ Optional
With your VPS, you have tools unavailable on shared hosting. Here are three quick wins that significantly improve WordPress performance:
Enable PHP OPcache
OPcache stores compiled PHP code in memory, eliminating the need to recompile scripts on every request.
$ nano /etc/php/8.3/fpm/php.ini # Find and set: opcache.enable=1 opcache.memory_consumption=128 opcache.max_accelerated_files=10000 opcache.revalidate_freq=2
Install Redis Object Cache
Redis caches WordPress database queries in memory, dramatically reducing response times for dynamic pages.
$ apt install redis-server php8.3-redis -y $ systemctl enable redis-server
Then install the Redis Object Cache plugin in your WordPress dashboard and enable it.
Use Cloudflare (Free CDN + DDoS Protection)
Point your domain’s nameservers to Cloudflare. Their free plan provides global CDN caching, DDoS mitigation, and an extra SSL layer — all with zero additional cost.
Frequently Asked Questions
🚀 Your WordPress Site is Live on a VPS
You’ve gone from a blank server to a fully functional, SSL-secured WordPress site with a production-grade stack: Nginx, PHP 8.3, MySQL 8, and Let’s Encrypt. That’s the same setup used by professional developers and agencies around the world.Next steps: lock down your WordPress installation (limit login attempts, disable XML-RPC, add two-factor authentication for admin), install a caching plugin, and set up automated backups. Your site is now running on infrastructure you fully own and control.