Installing Nginx on a VPS – A Step-by-Step Guide from A to Z for Beginners
- Published on

Introduction
Nginx is one of the most popular and powerful web servers in use today, powering major websites like Netflix, Dropbox, and WordPress.com. Thanks to its event-driven architecture, Nginx can handle thousands of concurrent connections with minimal resource consumption.
When you get a VPS (Virtual Private Server), the first thing to do is install and configure a web server. This guide walks you through every step from A to Z on how to install Nginx on a VPS running Ubuntu 22.04 or 24.04.
If you're new to Nginx, start with our article What is Nginx? A Comprehensive Guide. And if you don't have a VPS yet, check out What is VPS? Comparison with Shared Hosting.
Prerequisites
Before we begin, make sure you have:
Requirements
- A VPS running Ubuntu 22.04 or 24.04 (LTS).
- Root access or a user with
sudoprivileges. - SSH access to your VPS (use PuTTY on Windows or Terminal on macOS/Linux).
- A domain name pointing to your VPS IP (if you want to run a live website).
Connect via SSH
ssh user@your-server-ip
Replace user with your username and your-server-ip with your actual VPS IP address.
Update the System
Always update the package list before installing new software:
sudo apt update
sudo apt upgrade -y
This ensures you're installing the latest available versions.
Step 1: Install Nginx
1.1. Install from the Official Repository
Ubuntu includes Nginx in its default package repository:
sudo apt install nginx -y
Once installed, Nginx starts automatically. Verify:
sudo systemctl status nginx
You should see output similar to:
● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
Active: active (running) since ...
1.2. Configure the Firewall (UFW)
If UFW (Uncomplicated Firewall) is active, open the necessary ports:
sudo ufw allow 'Nginx Full'
Check the status:
sudo ufw status
Expected output:
Status: active
To Action From
-- ------ ----
Nginx Full ALLOW Anywhere
Nginx Full (v6) ALLOW Anywhere (v6)
Nginx Full opens both port 80 (HTTP) and 443 (HTTPS).
1.3. Verify Nginx Is Running
Open a browser and visit http://your-server-ip. If you see the "Welcome to nginx!" page, you've installed it successfully.
To find your VPS IP:
curl -4 icanhazip.com
1.4. Important Directory Structure
Familiarize yourself with these key Nginx paths:
| Path | Description |
|---|---|
/etc/nginx/nginx.conf | Main configuration file |
/etc/nginx/sites-available/ | Configuration files for each site (not yet active) |
/etc/nginx/sites-enabled/ | Symlinks to enabled sites |
/etc/nginx/conf.d/ | Additional configuration snippets |
/var/www/ | Root directory for website files |
/var/log/nginx/access.log | Access log |
/var/log/nginx/error.log | Error log |
Learn more: What is a Web Server?
Step 2: Configure Virtual Hosts (Server Blocks)
Virtual Hosts (called Server Blocks in Nginx) let you run multiple websites on a single VPS.
2.1. Create the Website Directory
sudo mkdir -p /var/www/example.com/html
sudo chown -R $USER:$USER /var/www/example.com/html
sudo chmod -R 755 /var/www/example.com
Create a sample index.html:
nano /var/www/example.com/html/index.html
Add some content:
<html>
<head>
<title>Welcome to example.com</title>
</head>
<body>
<h1>Nginx installed successfully!</h1>
<p>Your site is running on example.com</p>
</body>
</html>
2.2. Create a Server Block
Create the configuration file:
sudo nano /etc/nginx/sites-available/example.com
Add the following:
server {
listen 80;
listen [::]:80;
root /var/www/example.com/html;
index index.html index.htm index.nginx-debian.html;
server_name example.com www.example.com;
location / {
try_files $uri $uri/ =404;
}
}
2.3. Enable the Server Block
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
Test the configuration before reloading:
sudo nginx -t
If the output says test is successful, reload Nginx:
sudo systemctl reload nginx
2.4. Disable the Default Server Block
Nginx ships with a default server block. Remove it:
sudo rm /etc/nginx/sites-enabled/default
sudo systemctl reload nginx
Tip: Use
sudo unlink /etc/nginx/sites-enabled/defaultto preserve the original file.
Visit http://example.com — you should see your new site.
Step 3: Integrate PHP-FPM for WordPress
To run WordPress or any PHP-based CMS, you need PHP-FPM.
3.1. Install PHP-FPM
sudo apt install php-fpm php-mysql php-curl php-gd php-mbstring php-xml php-xmlrpc php-zip php-opcache -y
This installs PHP 8.3 (default on Ubuntu 24.04) along with essential extensions for WordPress.
3.2. Configure Nginx for PHP-FPM
Edit your server block:
sudo nano /etc/nginx/sites-available/example.com
Add the location ~ \.php$ block:
server {
listen 80;
listen [::]:80;
root /var/www/example.com/html;
index index.php index.html index.htm;
server_name example.com www.example.com;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}
Test and reload:
sudo nginx -t
sudo systemctl reload nginx
3.3. Verify PHP Is Working
Create a PHP test file:
echo "<?php phpinfo(); ?>" | sudo tee /var/www/example.com/html/info.php
Visit http://example.com/info.php. If you see the PHP info page, PHP-FPM is working.
Important: Delete
info.phpafter testing as it exposes sensitive information:sudo rm /var/www/example.com/html/info.php
Learn more about how to optimize WordPress hosting after completing this setup.
Step 4: Secure Nginx
4.1. Disable Server Version Information
By default, Nginx includes its version in HTTP headers. Disable it:
Open the main config:
sudo nano /etc/nginx/nginx.conf
Add this line inside the http block:
server_tokens off;
4.2. Add Security Headers
Include these headers in your server block:
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
4.3. Limit Upload Size
Nginx caps file uploads at 1MB by default. To increase it:
client_max_body_size 128M;
4.4. Prevent Brute Force and DDoS
Limit requests from a single IP:
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
server {
...
location / {
limit_req zone=mylimit burst=20 nodelay;
...
}
}
4.5. Block Access to Sensitive Files
location ~ /\.(?!well-known) {
deny all;
}
location = /wp-config.php {
deny all;
}
Test and reload after each change:
sudo nginx -t && sudo systemctl reload nginx
See also: Comprehensive website security guide.
Step 5: Install SSL with Let's Encrypt
HTTPS is mandatory for modern websites. Let's Encrypt provides free SSL certificates.
5.1. Install Certbot
sudo apt install certbot python3-certbot-nginx -y
5.2. Obtain an SSL Certificate
sudo certbot --nginx -d example.com -d www.example.com
Certbot will automatically:
- Verify domain ownership.
- Issue the SSL certificate.
- Update the Nginx configuration with HTTPS redirect.
5.3. Test Auto-Renewal
sudo certbot renew --dry-run
Let's Encrypt certificates are valid for 90 days. Certbot handles auto-renewal via a cron job.
Learn more: What is SSL? and What is HTTPS?
After SSL installation, your Nginx config will look like:
server {
listen 443 ssl;
server_name example.com www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
root /var/www/example.com/html;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
}
}
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$server_name$request_uri;
}
For a Cloudflare-based approach, see Install Free SSL Cloudflare.
Step 6: Optimize Nginx Performance
6.1. Configure Worker Processes
Edit /etc/nginx/nginx.conf:
worker_processes auto;
worker_connections 1024;
keepalive_timeout 65;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
worker_processes auto— matches the number of CPU cores.worker_connections— max connections per worker.sendfile— optimizes static file delivery.tcp_nopush/tcp_nodelay— TCP optimization.
6.2. Enable Gzip Compression
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml application/json application/javascript text/javascript image/svg+xml;
6.3. Cache Static Files
Inside your server block:
location ~* \.(jpg|jpeg|png|gif|ico|css|js|webp|avif|woff|woff2)$ {
expires 365d;
add_header Cache-Control "public, immutable";
}
6.4. WordPress-Specific Optimizations
If you're running WordPress, add these rules:
# Cache static files
location ~* \.(jpg|jpeg|png|gif|ico|css|js|webp|avif)$ {
expires 365d;
add_header Cache-Control "public, immutable";
}
# Deny access to dot files
location ~ /\.(?!well-known) {
deny all;
}
# Protect wp-login from brute force
location = /wp-login.php {
limit_req zone=login burst=3 nodelay;
}
# Block PHP execution in uploads
location ~* /uploads/.*\.php$ {
deny all;
}
See also: 26+ Tips to Optimize WordPress Website Speed.
6.5. Test Performance
Use these commands to verify:
# Check worker processes
ps aux | grep nginx
# Check active connections
sudo ss -tlnp | grep nginx
For external testing, use GTmetrix or PageSpeed Insights:
Step 7: Monitoring and Logging
7.1. View Nginx Logs
# Real-time access log
sudo tail -f /var/log/nginx/access.log
# Real-time error log
sudo tail -f /var/log/nginx/error.log
7.2. Analyze Logs with GoAccess
sudo apt install goaccess -y
sudo goaccess /var/log/nginx/access.log -o /var/www/example.com/html/report.html --log-format=COMBINED
7.3. Monitor with Netdata
bash <(curl -Ss https://my-netdata.io/kickstart.sh)
Netdata provides a real-time dashboard for CPU, RAM, disk, network, and Nginx metrics.
Step 8: Common Troubleshooting
8.1. "Port 80 already in use"
Apache is occupying port 80. Stop it:
sudo systemctl stop apache2
sudo systemctl disable apache2
sudo systemctl start nginx
8.2. "502 Bad Gateway"
PHP-FPM is not running or the socket path is incorrect:
sudo systemctl restart php8.3-fpm
sudo systemctl status php8.3-fpm
Verify the socket path:
ls /var/run/php/
8.3. "404 Not Found"
Check the root directive and verify files exist:
ls -la /var/www/example.com/html/
Make sure the index directive is correct:
index index.php index.html index.htm;
8.4. "413 Request Entity Too Large"
Increase client_max_body_size:
client_max_body_size 128M;
8.5. Always Test Before Reloading
sudo nginx -t
If there's a syntax error, Nginx will show the exact line.
| Error Code | Cause | Solution |
|---|---|---|
| 502 Bad Gateway | PHP-FPM not running or wrong socket path | Restart PHP-FPM, check socket path |
| 404 Not Found | Wrong root path or missing index file | Verify root and index directives |
| 413 Request Entity Too Large | Upload exceeds client_max_body_size | Increase client_max_body_size value |
| Permission Denied | Wrong owner/permissions on directory | Run chown -R www-data:www-data /var/www/ |
| Address already in use | Port 80/443 taken by Apache | Stop Apache, start Nginx |
Frequently Asked Questions
How is Nginx different from Apache?
Nginx uses an event-driven architecture, handling more connections with fewer resources than Apache. It's ideal for high-traffic websites and reverse proxy setups. See the comparison in What is Apache?.
Can I install WordPress on a VPS with Nginx?
Yes. After completing the steps above (especially PHP-FPM and MySQL), you can install WordPress. See our WordPress Complete Guide.
How do I know if Nginx is running well?
Run sudo systemctl status nginx to check the service status. Use htop for CPU/RAM monitoring, and GTmetrix for external speed tests.
Should I use Nginx or Apache for a new WordPress site?
Nginx paired with PHP-FPM delivers better performance than Apache, especially under high traffic. On shared hosting, the provider usually decides — but on a VPS, Nginx is the optimal choice.
Check out our Hostinger vs Namecheap comparison if you're choosing a VPS provider.
Summary
You've successfully installed Nginx on a VPS from A to Z:
- Connected and prepared your VPS.
- Installed Nginx and configured the firewall.
- Created virtual hosts for your websites.
- Integrated PHP-FPM for dynamic content.
- Secured the server with security headers and rate limiting. Read the Server Security Guide for more measures.
- Installed a free Let's Encrypt SSL certificate.
- Optimized performance with gzip, caching, and worker tuning.
- Set up monitoring and learned common troubleshooting.
VPS + Nginx provides a rock-solid foundation for any website — from a WordPress blog to complex web applications. By setting it up yourself, you gain full control and a deep understanding of your server.
If you need professional website design or hosting optimization, contact RiverLee for expert consultation.
Comments
0 Comment(s)
Loading...
Latest Posts

Why Choose NextJS Over WordPress for Complex Projects (2026)
An in-depth analysis of why NextJS outperforms WordPress for complex projects — covering performance, SEO, security, and scalability. Practical guidance from web design professionals.

Real Estate Website Design in Dak Lak: Growth Solutions for 2026
Professional real estate website design solutions for Dak Lak — covering local SEO, 7 essential features, real pricing, and client testimonials. Built for agents and investors looking to grow online in 2026.

Website Design in Buon Ma Thuot: Cost, Process & Key Considerations (2026)
A comprehensive guide to website design in Buon Ma Thuot — real pricing for 2026, a step-by-step process, common mistakes to avoid, and a 10-point checklist for choosing a reliable web design agency in Dak Lak.

What is Content Pillar? SEO Content Strategy Guide 2026
Discover what a Content Pillar is and how to build an effective SEO content strategy. A detailed guide covering pillar characteristics, structure, the creation process, and KPI tracking for your website in 2026.
Related Posts

Server Security Guide – Essential Hardening Measures for Linux 2026
A comprehensive Linux server security guide covering 10 essential hardening measures — SSH hardening, firewall configuration, fail2ban, automatic security updates, user management, service security, kernel hardening, intrusion detection, and log monitoring.

What is Cloud Hosting? Benefits, How It Works, and When to Use It — 2026 Guide
Cloud hosting uses a cluster of virtualized servers to host websites and applications. Learn about its benefits, how it works, how it compares to VPS, and when to make the switch.

Basic Linux Commands for Hosting Management — A Complete A-Z Guide for Beginners
A complete guide to basic Linux server commands for hosting management — from SSH and file management to permissions, systemctl, apt, and log inspection. Everything a beginner needs.

Hosting Price Comparison 2026 – Detailed Pricing of 15+ Local & International Providers
The most comprehensive hosting price comparison for 2026 — compare 15+ Vietnamese and international hosting providers including Hostinger, Bluehost, SiteGround, MatBao, PA Vietnam, VinaHost and more. Find the right hosting plan for your budget.

