Technology Encyclopedia Home >How to Install and Configure Nginx on a Cloud Server — The Setup I Use for Every Project

How to Install and Configure Nginx on a Cloud Server — The Setup I Use for Every Project

Honestly, the first few times I set up a web server I just threw Apache on and called it a day. It worked. But once I started running multiple sites on the same server, I kept running into the same problem: Apache felt heavy for what I was doing, and the config syntax made my eyes glaze over.

Someone in a forum told me to just try Nginx. I resisted for a while — yet another thing to learn — but eventually gave in on a Sunday afternoon when I had nothing else to do.

That was a couple of years ago, and now Nginx is the first thing I install on any server. Whether I'm running a single website or five apps behind a reverse proxy, it handles everything cleanly. Getting comfortable with Nginx genuinely changed how I think about self-hosting.

This guide covers everything from installation to production-ready config: serving a static site, virtual hosts for multiple domains, and HTTPS with Let's Encrypt.

I run this on Tencent Cloud Lighthouse with Ubuntu 22.04 LTS. A few things that matter specifically for Nginx setups: Lighthouse instances provision with a clean Ubuntu image (no pre-installed web server conflict to work around), the console-level firewall means you can open ports 80 and 443 from the control panel without touching UFW, and the bandwidth packages (starting at 200GB/month on basic plans) are predictable — no surprise bills if a post goes viral. If you haven't done initial server setup yet, start with the initial setup guide first.


Table of Contents

  1. Why Nginx?
  2. Part 1 — Install Nginx
  3. Part 2 — Understand the Directory Structure
  4. Part 3 — Serve Your First Static Site
  5. Part 4 — Set Up Multiple Sites with Server Blocks
  6. Part 5 — Configure HTTPS with Let's Encrypt
  7. Part 6 — Set Up Nginx as a Reverse Proxy
  8. Part 7 — Performance Tweaks Worth Making
  9. The Gotcha: Test Config Before Reloading
  10. Common Nginx Commands

Key Takeaways

  • Nginx handles HTTPS termination, static file serving, and reverse proxying
  • Always test config with sudo nginx -t before reloading
  • Virtual hosts let one server run multiple websites on different domains
  • Nginx's event-driven model uses less memory than Apache at comparable traffic
  • Use sudo nginx -s reload for zero-downtime config updates

Why Nginx? {#why-nginx}

Nginx is a high-performance web server and reverse proxy. On a cloud server, it typically plays one of two roles:

  • Web server — serves static files (HTML, CSS, images) directly to browsers
  • Reverse proxy — receives incoming requests and forwards them to a backend application (Node.js, Python, PHP-FPM, etc.)

Running applications behind Nginx rather than exposing them directly gives you:

  • SSL termination in one place — apps don't need to handle HTTPS themselves
  • Static file serving at full speed — Nginx serves files directly without involving your app
  • Multiple apps on one server — route different domains/paths to different backend services
  • Gzip compression and caching headers — configured once, applies to all sites

Part 1 — Install Nginx {#part-1}

sudo apt update
sudo apt install -y nginx

# Start Nginx and enable it to start on boot
sudo systemctl start nginx
sudo systemctl enable nginx

# Verify it's running
sudo systemctl status nginx

Allow HTTP and HTTPS through the firewall:

sudo ufw allow 'Nginx Full'
# This is equivalent to: sudo ufw allow 80 && sudo ufw allow 443

Visit http://YOUR_SERVER_IP in a browser. You should see the Nginx welcome page.


Part 2 — Understand the Directory Structure {#part-2}

Before touching any config files, here's where things live:

Path What it is
/etc/nginx/nginx.conf Main config file — global settings
/etc/nginx/sites-available/ Config files for individual sites (inactive until linked)
/etc/nginx/sites-enabled/ Symlinks to active site configs
/var/www/html/ Default web root
/var/log/nginx/access.log Request logs
/var/log/nginx/error.log Error logs

The workflow for adding a site:

  1. Create a config file in sites-available/
  2. Symlink it to sites-enabled/
  3. Test the config: sudo nginx -t
  4. Reload Nginx: sudo systemctl reload nginx

Part 3 — Serve Your First Static Site {#part-3}

Create the web root

# Create a directory for your site
sudo mkdir -p /var/www/mysite

# Create a simple HTML file to test with
sudo nano /var/www/mysite/index.html
<!DOCTYPE html>
<html>
<head><title>My Site</title></head>
<body>
  <h1>Nginx is working.</h1>
  <p>Running on Tencent Cloud Lighthouse.</p>
</body>
</html>
# Set ownership
sudo chown -R www-data:www-data /var/www/mysite

Create a server block

sudo nano /etc/nginx/sites-available/mysite
server {
    listen 80;
    listen [::]:80;

    server_name yourdomain.com www.yourdomain.com;

    root /var/www/mysite;
    index index.html index.htm;

    location / {
        try_files $uri $uri/ =404;
    }

    # Logging
    access_log /var/log/nginx/mysite_access.log;
    error_log  /var/log/nginx/mysite_error.log;
}
# Enable the site
sudo ln -s /etc/nginx/sites-available/mysite /etc/nginx/sites-enabled/

# Remove the default site (optional but clean)
sudo rm /etc/nginx/sites-enabled/default

# Test and reload
sudo nginx -t
sudo systemctl reload nginx

Visit http://yourdomain.com — your page is live.


Part 4 — Set Up Multiple Sites with Server Blocks {#part-4}

One server can host multiple websites, each with its own domain. Create a separate config file for each:

sudo nano /etc/nginx/sites-available/secondsite
server {
    listen 80;
    server_name secondsite.com www.secondsite.com;

    root /var/www/secondsite;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}
sudo mkdir -p /var/www/secondsite
# Add content to /var/www/secondsite/index.html

sudo ln -s /etc/nginx/sites-available/secondsite /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx

Nginx routes requests to the right site based on the Host header (which matches server_name).


Part 5 — Configure HTTPS with Let's Encrypt {#part-5}

Once your domain's DNS A record points to the server:

# Install Certbot
sudo apt install -y certbot python3-certbot-nginx

# Obtain and install certificate
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com

Certbot automatically:

  • Obtains a certificate from Let's Encrypt
  • Modifies your Nginx config to handle HTTPS
  • Sets up an HTTP → HTTPS redirect
  • Creates a cron job for auto-renewal

Verify renewal works:

sudo certbot renew --dry-run

Part 6 — Set Up Nginx as a Reverse Proxy {#part-6}

This is how I run most apps: the application (Node.js, Python, etc.) listens on a local port, and Nginx proxies public traffic to it.

sudo nano /etc/nginx/sites-available/myapp
server {
    listen 80;
    server_name app.yourdomain.com;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;

        # Required for WebSocket support
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_cache_bypass $http_upgrade;
        proxy_read_timeout 86400s;
    }
}

After enabling and reloading, run certbot --nginx -d app.yourdomain.com to add HTTPS.


Part 7 — Performance Tweaks Worth Making {#part-7}

Gzip compression

Add to /etc/nginx/nginx.conf inside the http {} block:

gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_proxied expired no-cache no-store private auth;
gzip_types
    text/plain
    text/css
    text/xml
    text/javascript
    application/x-javascript
    application/xml
    application/json;

Browser caching for static assets

Add inside your server {} block:

location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2)$ {
    expires 30d;
    add_header Cache-Control "public, no-transform";
}

Worker processes

In /etc/nginx/nginx.conf, set worker processes to match your CPU count:

worker_processes auto;  # "auto" detects CPU count automatically

After any change to nginx.conf:

sudo nginx -t && sudo systemctl reload nginx

The Gotcha: Test Config Before Reloading {#gotcha}

The most common Nginx mistake: editing a config file with a syntax error, reloading, and taking down all sites on the server.

Always run sudo nginx -t before sudo systemctl reload nginx. If the test fails, Nginx shows you exactly where the error is:

nginx: [emerg] unexpected "}" in /etc/nginx/sites-available/mysite:15
nginx: configuration file /etc/nginx/nginx.conf test failed

Fix the error, test again, then reload. Never skip the test step.

A second common issue: enabling a site config but forgetting to reload Nginx. The symlink exists in sites-enabled/ but Nginx is still serving the old config. Always reload after making changes.


Common Nginx Commands {#commands}

sudo nginx -t                    # Test configuration syntax
sudo systemctl reload nginx      # Apply config changes (no downtime)
sudo systemctl restart nginx     # Full restart (brief downtime)
sudo systemctl status nginx      # Check service status
sudo tail -f /var/log/nginx/error.log   # Watch error log live
sudo tail -f /var/log/nginx/access.log  # Watch access log live

# Enable a site
sudo ln -s /etc/nginx/sites-available/SITE /etc/nginx/sites-enabled/

# Disable a site
sudo rm /etc/nginx/sites-enabled/SITE

# Check which sites are active
ls -la /etc/nginx/sites-enabled/

Troubleshooting {#troubleshooting}

Issue Likely Cause Fix
Connection refused Service not running or wrong port Check systemctl status SERVICE and verify firewall rules
Permission denied Wrong file ownership or permissions Check file ownership with ls -la and use chown/chmod to fix
502 Bad Gateway Backend service not running Restart the backend service; check logs with journalctl -u SERVICE
SSL certificate error Certificate expired or domain mismatch Run sudo certbot renew and verify domain DNS points to server IP
Service not starting Config error or missing dependency Check logs with journalctl -u SERVICE -n 50 for specific error
Out of disk space Logs or data accumulation Run df -h to identify usage; clean logs or attach CBS storage
High memory usage Too many processes or memory leak Check with htop; consider upgrading instance plan if consistently high
Firewall blocking traffic Port not open in UFW or Lighthouse console Open port in Lighthouse console firewall AND sudo ufw allow PORT

Frequently Asked Questions {#faq}

What is Nginx used for on a cloud server?
Nginx serves static files, reverse-proxies backend applications, and terminates SSL/TLS for HTTPS. Most setups use it as the public-facing entry point.

Where are Nginx config files located?
Main config: /etc/nginx/nginx.conf. Sites: create in /etc/nginx/sites-available/, symlink to /etc/nginx/sites-enabled/ to activate.

How do I reload Nginx after config changes?
Run sudo nginx -t to test, then sudo nginx -s reload for a graceful reload without downtime.

Can Nginx host multiple websites on one server?
Yes — virtual hosts (server blocks) route requests by server_name.

What is the difference between nginx -s reload and systemctl restart nginx?
nginx -s reload finishes in-flight requests gracefully. systemctl restart immediately terminates all connections. Use reload for production.


Set up your cloud server today:
👉 Tencent Cloud Lighthouse — Ubuntu VPS, ready in minutes
👉 View current pricing and promotions
👉 Explore all active deals and offers