Azure Clean IP Registered Account How to Install and Configure Nginx on Azure VM

Azure Account / 2026-05-20 14:31:53

{ "description": "This article walks you through installing and configuring Nginx on an Azure Virtual Machine, from provisioning the VM to hardening basic security and getting your first “it works” webpage. You’ll learn how to install Nginx on common Linux distributions, open the right firewall ports in Azure, create a server block for your site, enable HTTPS with Let’s Encrypt, and verify everything behaves as expected. Along the way, it includes practical troubleshooting tips for common issues like 403/404 errors, misrouted traffic, and Nginx service startup problems.", "content": "

How to Install and Configure Nginx on Azure VM

\n\n

So you want Nginx on an Azure Virtual Machine. Excellent choice. Nginx is fast, flexible, and has the kind of configuration file structure that makes you feel powerful—until you accidentally put a semicolon in the wrong place and suddenly your server starts acting like it’s on strike. Don’t worry. This guide will get you from “brand-new Azure VM” to a working web server with clean configuration, sensible security, and HTTPS that doesn’t require you to chant IT incantations.

\n\n

We’ll cover:

\n\n
    \n
  • Creating an Azure VM and getting basic connectivity
  • \n
  • Installing Nginx on popular Linux distributions
  • \n
  • Opening ports in Azure (because Azure firewall rules are not psychic)
  • \n
  • Configuring Nginx server blocks (sites) properly
  • \n
  • Enabling HTTPS with Let’s Encrypt
  • \n
  • Basic hardening and useful performance settings
  • \n
  • Troubleshooting the usual suspects
  • \n
\n\n

1) Prerequisites: What You Need Before You Start

\n\n

Before touching Nginx, make sure you have the boring essentials handled:

\n\n
    \n
  • An Azure subscription
  • \n
  • An Azure VM running Linux (Ubuntu, Debian, etc.)
  • \n
  • SSH access to the VM (you can use your key or password depending on how you created it)
  • \n
  • A domain name (recommended for HTTPS); if you don’t have one, we can still set up HTTP and later add HTTPS
  • \n
  • Basic familiarity with terminal commands (no need to be a wizard, just don’t spill coffee on your keyboard)
  • \n
\n\n

Also, decide early whether you want:

\n\n
    \n
  • A simple default site (fast, minimal changes)
  • \n
  • A custom site with server blocks (more typical and more scalable)
  • \n
\n\n

This article will guide you through the “custom server block” route because it’s the version you’ll be glad you did later.

\n\n

2) Provision the Azure VM (Networking and Access)

\n\n

When creating the VM in Azure, choose a Linux image (for example, Ubuntu 22.04 LTS). You’ll also need:

\n\n
    \n
  • A resource group
  • \n
  • Networking configuration (usually a Virtual Network and Subnet)
  • \n
  • Security rules: inbound ports for SSH and later HTTP/HTTPS
  • \n
\n\n

After the VM is created, confirm you can connect via SSH:

\n\n

From your local machine:

\n\n
ssh azureuser@<VM_PUBLIC_IP>
\n\n

If that fails, don’t blame Nginx yet. The problem is almost certainly earlier in the chain: VM networking, SSH keys, NSG rules, or basic connectivity.

\n\n

Open the right inbound ports in Azure

\n\n

Azure traffic flow often includes:

\n\n
    \n
  • Azure Network Security Group (NSG) inbound rules
  • \n
  • OS-level firewall rules (if you use UFW or firewalld)
  • \n
  • Nginx listening ports and firewall inside the VM (yes, both layers matter)
  • \n
\n\n

You must allow inbound traffic to port 80 (HTTP) and port 443 (HTTPS) if you want web access. You’ll also need port 22 (SSH) to administer the server.

\n\n

In the Azure portal:

\n\n
    \n
  • Go to your VM or its associated NSG
  • \n
  • Add inbound security rules for:
  • \n
  • - TCP 22 (SSH), ideally restricted to your IP
  • \n
  • - TCP 80 (HTTP), ideally restricted or open depending on your use case
  • \n
  • - TCP 443 (HTTPS), ideally restricted or open depending on your use case
  • \n
\n\n

Quick tip: If you open ports in Azure but your OS firewall blocks them, you’ll still get no traffic. Similarly, if you allow them at the OS level but not in Azure, Azure will politely ignore the packets. It’s like trying to ring someone’s doorbell through a wall.

\n\n

3) Install Nginx on the Azure VM

\n\n

Linux distributions differ slightly, but the process is usually: update package list, install Nginx, enable it, start it, verify it’s listening.

\n\n

Ubuntu / Debian installation

\n\n

Run:

\n\n
sudo apt update\nsudo apt install -y nginx
\n\n

Then start and enable it:

\n\n
sudo systemctl start nginx\nsudo systemctl enable nginx
\n\n

Verify service status:

\n\n
sudo systemctl status nginx --no-pager
\n\n

You should see “active (running)”. If not, scroll carefully—Linux logs are dramatic, and they will tell you exactly what’s wrong once you read them.

\n\n

Azure Clean IP Registered Account RHEL / CentOS / AlmaLinux / Rocky installation

\n\n

If your VM uses an RPM-based distro, you may use:

\n\n
sudo dnf install -y nginx\nsudo systemctl enable --now nginx
\n\n

Then verify status similarly with systemctl.

\n\n

4) Confirm Nginx is Working (Before Configuration)

\n\n

At this stage, Nginx should be serving the default page. Test it using your VM’s public IP:

\n\n

From your browser: open:

\n\n

http://<VM_PUBLIC_IP>

\n\n

If you see the default Nginx welcome page, congratulations—you’ve successfully defeated the “it’s not working” boss at level 1.

\n\n

If you don’t, check:

\n\n
    \n
  • Azure NSG inbound rules for port 80
  • \n
  • OS firewall (UFW or firewalld)
  • \n
  • Nginx is running:
    sudo systemctl status nginx --no-pager
  • \n
  • Nginx is listening on port 80:
    sudo ss -ltnp | grep :80
  • \n
  • Logs:
    sudo tail -n 200 /var/log/nginx/error.log
  • \n
\n\n

5) Understand Nginx File Locations (So You Don’t Lose Your Mind)

\n\n

Nginx uses a configuration layout that can be surprisingly neat. On Ubuntu/Debian, common locations are:

\n\n
    \n
  • Main config: /etc/nginx/nginx.conf
  • \n
  • Site configs: /etc/nginx/sites-available/ and /etc/nginx/sites-enabled/
  • \n
  • Default server block: often /etc/nginx/sites-available/default
  • \n
  • Web root (for the default site): /var/www/html
  • \n
  • Logs: /var/log/nginx/access.log and /var/log/nginx/error.log
  • \n
\n\n

On many systems, /etc/nginx/sites-enabled contains symlinks to the actual config files in sites-available. This is convenient, because you can “enable” a site by creating a link.

\n\n

6) Configure a Server Block for Your Site

\n\n

Server blocks (similar to virtual hosts in Apache) define how Nginx responds to different domains or paths. Even if you’re serving one site, using a server block is best practice.

\n\n

Create a directory for your website

\n\n

Create a directory under /var/www. Example: create a site folder named example.com (swap as needed):

\n\n
sudo mkdir -p /var/www/example.com\nsudo chown -R $USER:$USER /var/www/example.com\n
\n\n

Create a test file:

\n\n
echo "<h1>Hello from Nginx on Azure VM!</h1>" > /var/www/example.com/index.html\n
\n\n

Then ensure permissions allow Nginx to read the files. On many systems, Nginx runs as www-data, not your user, so we should set permissions:

\n\n
sudo chown -R www-data:www-data /var/www/example.com\n
\n\n

Create the Nginx server block

\n\n

Create a new config file in sites-available:

\n\n
sudo nano /etc/nginx/sites-available/example.com
\n\n

Paste the following HTTP-only server block (replace example.com with your domain):

\n\n
server {\n    listen 80;\n    listen [::]:80;\n\n    server_name example.com www.example.com;\n\n    root /var/www/example.com;\n    index index.html index.htm;\n\n    location / {\n        try_files $uri $uri/ =404;\n    }\n}\n
\n\n

Notice these essentials:

\n\n
    \n
  • listen 80; sets HTTP port
  • \n
  • server_name determines which Host header matches
  • \n
  • root points to your site directory
  • \n
  • location / handles requests and tries to serve files, returning 404 if not found
  • \n
\n\n

Enable the site

\n\n

Create a symlink from sites-available to sites-enabled:

\n\n
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
\n\n

Now you should have the site enabled. If your distribution includes the default site and it’s enabled, it might “steal” traffic if your server_name doesn’t match your request. To avoid confusion, you can disable the default site:

\n\n
sudo unlink /etc/nginx/sites-enabled/default
\n\n

If that command errors because the link doesn’t exist, no worries—your system may already be configured differently.

\n\n

Test Nginx configuration and reload

\n\n

Before reloading Nginx, run:

\n\n
sudo nginx -t
\n\n

If you see something like “syntax is ok” and “test is successful,” reload:

\n\n
sudo systemctl reload nginx
\n\n

Now go to http://<YOUR_DOMAIN_OR_IP> and verify you get your page.

\n\n

7) Add HTTPS with Let’s Encrypt (Because HTTP Is 1999-ish)

\n\n

Let’s Encrypt makes HTTPS accessible without paying for certificates. It’s like a security guard who doesn’t demand a coffee break. You’ll need:

\n\n
    \n
  • Your domain DNS to point to your VM’s public IP
  • \n
  • Port 80 open so the certificate validation can work (commonly used)
  • \n
  • Port 443 open for final HTTPS serving
  • \n
\n\n

Install Certbot

\n\n

On Ubuntu/Debian:

\n\n
sudo apt update\nsudo apt install -y certbot python3-certbot-nginx
\n\n

If you’re on a different distro, install Certbot via your package manager or the official installation instructions for your OS (the idea is the same; details vary).

\n\n

Request a certificate

\n\n

Run:

\n\n
sudo certbot --nginx -d example.com -d www.example.com
\n\n

Certbot will detect your server block and edit it to support HTTPS automatically. It usually asks questions about redirecting HTTP to HTTPS. Choose the option to redirect so you don’t end up with both HTTP and HTTPS versions of your site doing different things.

\n\n

If you prefer to be explicit, you can decide later, but redirecting is typically recommended.

\n\n

Verify auto-renewal

\n\n

Certbot generally sets up a systemd timer or cron job for renewal. Check:

\n\n
sudo systemctl list-timers | grep certbot\n
\n\n

Or do a dry run:

\n\n
sudo certbot renew --dry-run
\n\n

Azure Clean IP Registered Account If the dry run succeeds, your future self will be grateful.

\n\n

8) Improve Nginx Configuration (Performance and Sanity)

\n\n

Nginx defaults are good, but real-world usage benefits from a few tweaks. Be careful: Nginx configuration changes are powerful and occasionally dramatic. Test after edits.

\n\n

Recommended basic server settings

\n\n

Inside your server block, you can add some common improvements:

\n\n
    \n
  • Security headers
  • \n
  • Client size limits
  • \n
  • Better handling of caching for static files
  • \n
  • Compression (gzip/brotli depending on your setup)
  • \n
\n\n

Here’s an example of an upgraded server block for HTTPS (conceptually). Note: If Certbot already configured your HTTPS block, you can edit it, but keep it consistent and don’t fight Certbot’s managed sections.

\n\n

Example (HTTP to HTTPS redirection snippet):

\n\n
server {\n    listen 80;\n    listen [::]:80;\n\n    server_name example.com www.example.com;\n\n    return 301 https://$host$request_uri;\n}\n
\n\n

Now HTTPS server block could include:

\n\n
server {\n    listen 443 ssl http2;\n    listen [::]:443 ssl http2;\n\n    server_name example.com www.example.com;\n\n    root /var/www/example.com;\n    index index.html index.htm;\n\n    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;\n    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;\n\n    add_header X-Content-Type-Options nosniff;\n    add_header X-Frame-Options SAMEORIGIN;\n    add_header Referrer-Policy strict-origin-when-cross-origin;\n\n    location / {\n        try_files $uri $uri/ =404;\n    }\n\n    location ~* \\.(css|js|png|jpg|jpeg|gif|ico|svg|woff2?)$ {\n        expires 30d;\n        access_log off;\n    }\n}\n
\n\n

Azure Clean IP Registered Account Important note: Certbot sometimes uses managed configuration blocks and includes “managed by Certbot” comments. If you remove or heavily modify those sections, Certbot may not renew correctly or may overwrite your changes. A safe approach is:

\n\n
    \n
  • Inspect the existing file that Certbot modified
  • \n
  • Add your settings outside Certbot’s managed areas if possible
  • \n
  • Re-run nginx -t after edits
  • \n
\n\n

Enable gzip compression (optional)

\n\n

To improve performance, gzip can reduce bandwidth usage. Many distros include basic gzip settings already, but if you want to add or verify it, you can edit /etc/nginx/nginx.conf or create an included file.

\n\n

Example in http block (in /etc/nginx/nginx.conf):

\n\n
gzip on;\ngzip_vary on;\ngzip_proxied any;\ngzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;\n
\n\n

Again: after changes, run:

\n\n
sudo nginx -t\nsudo systemctl reload nginx
\n\n

9) Configure the Azure VM Firewall (Optional but Worth It)

\n\n

If your VM has an OS firewall enabled, you must allow inbound traffic to Nginx ports. For Ubuntu, this often means UFW. Check status:

\n\n
sudo ufw status
\n\n

If it’s inactive, you can stop worrying about it. If it’s active, allow the required ports:

\n\n
sudo ufw allow 22/tcp\nsudo ufw allow 80/tcp\nsudo ufw allow 443/tcp\n
\n\n

Then verify:

\n\n
sudo ufw status
\n\n

Remember: Azure NSG and UFW (if enabled) both need the right rules. Think of them as two bouncers checking two different lists.

\n\n

10) Troubleshooting: When Things Don’t Work (And They Will, Eventually)

\n\n

Here’s a list of common issues and how to diagnose them without losing your afternoon.

\n\n

Problem: Browser shows “502 Bad Gateway”

\n\n

Most common when using an upstream application (like proxying to an app server) rather than serving static pages. But even with static pages, misconfigurations can cause unexpected behavior.

\n\n

Steps:

\n\n
    \n
  • Check Nginx error log:
    sudo tail -n 200 /var/log/nginx/error.log
  • \n
  • Confirm Nginx is running:
    sudo systemctl status nginx --no-pager
  • \n
  • Run config test:
    sudo nginx -t
  • \n
\n\n

If the error references upstream hosts or “connect() failed,” you’ll need to ensure the backend service is running and accessible from the VM (usually localhost or a private network address).

\n\n

Problem: “404 Not Found” despite correct domain

\n\n

Usually means:

\n\n
    \n
  • The root directory is wrong
  • \n
  • The index file name differs
  • \n
  • Permissions prevent Nginx from reading files
  • \n
\n\n

Check:

\n\n
    \n
  • Validate your root and index directives
  • \n
  • Azure Clean IP Registered Account Verify file exists:
    ls -la /var/www/example.com
  • \n
  • Verify permissions:
    sudo -u www-data ls -la /var/www/example.com
  • \n
  • Azure Clean IP Registered Account Look at error log for permission or file path issues
  • \n
\n\n

Problem: Site loads default page instead of your page

\n\n

That’s typically server block matching. Ensure your server_name matches the Host header you’re using. If you’re testing with IP address, but your server block only matches example.com, Nginx might route to the default server.

\n\n

Fix options:

\n\n
    \n
  • Add the IP as server_name (not always ideal)
  • \n
  • Create a server block for the default server to serve your content
  • \n
  • Test using the domain name that matches your server_name
  • \n
\n\n

Also check that the default site is disabled if you don’t want it to catch traffic.

\n\n

Problem: Nginx won’t start after configuration changes

\n\n

This is the classic “typo with confidence” moment. Nginx won’t start if config is invalid. Always run:

\n\n
sudo nginx -t
\n\n

It will tell you exactly which line has an error. Fix it, then reload.

\n\n

Problem: Certbot fails to get certificates

\n\n

Let’s Encrypt commonly fails due to:

\n\n
    \n
  • DNS not pointing to the VM IP
  • \n
  • Port 80 not reachable from the internet
  • \n
  • Existing Nginx server blocks conflicting
  • \n
\n\n

Azure Clean IP Registered Account Check:

\n\n
    \n
  • DNS A/AAAA records for example.com and www.example.com
  • \n
  • Azure NSG allows inbound port 80
  • \n
  • Nginx is serving content on port 80
  • \n
\n\n

If you used a different server block name or server_name, ensure Certbot’s discovery matches your config.

\n\n

11) Going Further: Common Nginx Patterns for Azure Apps

\n\n

You might be installing Nginx just for static hosting, but many Azure VM setups eventually proxy to an app running on the VM. That’s where Nginx shines.

\n\n

For example, you could run:

\n\n
    \n
  • A Node.js app on localhost:3000
  • \n
  • A Python app using Gunicorn on localhost:8000
  • \n
  • A Java app behind an internal port
  • \n
\n\n

If you want, we can extend this guide with a section on reverse proxy configuration, WebSocket support, caching rules, and rate limiting. For now, we’ll keep it focused on installation and baseline configuration.

\n\n

Azure Clean IP Registered Account 12) Quick Checklist: Did You Do Everything?

\n\n

Here’s a “don’t miss anything” checklist. If you can tick most of these, you’re in great shape:

\n\n
    \n
  • Nginx installed successfully
  • \n
  • Nginx service is running: systemctl status shows active
  • \n
  • Azure Clean IP Registered Account Azure NSG allows inbound 80 and 443
  • \n
  • OS firewall (if enabled) allows 80 and 443
  • \n
  • Your Nginx server block exists under sites-available
  • \n
  • Your server block is enabled in sites-enabled
  • \n
  • nginx -t passes with no errors
  • \n
  • You tested the site via domain or public IP
  • \n
  • You enabled HTTPS with Certbot (and renewal works)
  • \n
\n\n

13) Conclusion

\n\n

Installing and configuring Nginx on an Azure VM is absolutely doable, even if you’ve never met the Nginx configuration file before. The main things that trip people up are usually not Nginx itself—it’s the layered nature of cloud networking and the fact that both Azure and the VM OS may have their own firewall rules.

\n\n

Once you’ve got your server block working, you’re standing on a foundation that supports everything from static websites to reverse-proxied applications and production-grade setups. Next up, you might want to:

\n\n
    \n
  • Add caching and compression tuning
  • \n
  • Set up a proper health check endpoint
  • \n
  • Harden headers and limit request sizes
  • \n
  • Log to a central system if you’re using monitoring tools
  • \n
\n\n

But for today, your Nginx is installed, configured, and hopefully serving a friendly “Hello” page to the outside world. If it isn’t, don’t panic—check logs first. Nginx is usually very honest; it just expects you to read its diary.

" }
TelegramContact Us
CS ID
@cloudcup
TelegramSupport
CS ID
@yanhuacloud