October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix NowOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk19 min

NGINX Subdomain Tutorial & Subdomain Setup Guide

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

NGINX can serve mulle subdomains from the same server by matching each request’s hostname to the right server block. With the right DNS records and configuration, names like app.example.com, blog.example.com, and api.example.com can each point to a different document root, upstream application, or redirect rule.

This guide walks through the practical setup process: creating DNS records, adding NGINX server blocks, serving static content or proxying apps, enabling HTTPS with Let’s Encrypt, and confirming that each subdomain resolves and routes correctly. It also covers common errors such as mismatched server_name values, stale DNS, certificate issues, and configuration reload failures.

As an Amazon Associate I earn from qualifying purchases.

How NGINX Handles Subdomains

NGINX serves subdomains by matching the hostname in the incoming HTTP request to a configured server block. A request for www.example.com, api.example.com, and admin.example.com can all arrive at the same server IP address, but NGINX decides what to do with each request by reading the Host header and comparing it with the server_name values in its configuration.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For example, a server can have one block for example.com, another for blog.example.com, and another for app.example.com. Each block can point to a different document root, reverse proxy to a different backend application, use a different TLS certificate, or apply different redirects and access rules. This is what allows one NGINX instance to host mulle sites and applications under separate subdomains.

#1 Best Overall
Sale
NETGEAR 5-Port Gigabit Ethernet Unmanaged Network Switch (GS305) | Home Network Hub, Office Ethernet Splitter, Plug-and-Play, Silent Operation, Desktop or Wall Mount, Essentials Model
  • GIGABIT ETHERNET PORTS: Features 5 x 1.0Gbps Ethernet ports for high-speed connectivity. Auto-negotiating ports detect the optimal speed for connected devices and work with existing Cat5e or Cat6 Ethernet cables.
  • PLUG-AND-PLAY UNMANAGED NETWORK SWITCH: Simple plug-and-play setup with no software to install or configuration required.
  • FLEXIBLE MOUNTING OPTIONS: Compact metal design supports desktop or wall-mount placement for versatile installation.
  • SILENT & ENERGY-EFFICIENT OPERATION: Fanless design ensures silent performance, while IEEE 802.3az Energy Efficient Ethernet reduces power consumption without compromising high-speed network performance.
  • REGIONAL COMPATIBILITY: Made for use in U.S. & CA only

Server name matching

The most common subdomain setup uses exact hostname matching. In an NGINX server block, the server_name directive tells NGINX which domain names belong to that block:

  • example.com can serve the main website.
  • www.example.com can redirect to the main domain or serve the same content.
  • api.example.com can proxy requests to an application running on a local port.
  • docs.example.com can serve static files from its own directory.

NGINX can also match wildcard names such as *.example.com, which is useful when many subdomains should share the same behavior. However, exact names are usually better for a first setup because they are clearer, safer, and easier to troubleshoot. If both an exact name and a wildcard could match, NGINX gives priority to the more specific match.

Ports, IP addresses, and default blocks

Subdomains are not separate servers by themselves. DNS points each subdomain to an IP address, and NGINX listens on ports such as 80 for HTTP and 443 for HTTPS. Mulle subdomains can resolve to the same IP and share the same listening ports. The separation happens inside NGINX through the server block selection process.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

If NGINX receives a request for a hostname that does not match any configured server_name, it falls back to the default server for that IP address and port. This default may be the first server block loaded for that listener, or one explicitly marked with default_server. A clear default block helps prevent unexpected content from appearing when someone visits an unconfigured subdomain or reaches the server by IP address.

Static files versus proxied applications

After NGINX selects the matching server block, it follows the directives inside that block. For a static subdomain, it may read files from a directory with root and serve an index.html file. For an application subdomain, it may use proxy_pass to forward traffic to a backend process such as Node.js, Python, PHP-FPM, Go, or another service listening on 127.0.0.1.

TLS configuration is also tied to the selected server block. When HTTPS is enabled, NGINX must present a certificate that covers the requested subdomain. A certificate for example.com alone does not automatically cover api.example.com unless the certificate includes that name or uses a valid wildcard such as *.example.com. This is DNS, server blocks, and certificates need to line up for every subdomain you plan to serve.

Prerequisites and DNS Record Setup

Before creating NGINX server blocks, make sure the server and domain are ready. You need a Linux server with a public IP address, NGINX installed, shell access with sudo privileges, and a registered domain name managed through a DNS provider. Common providers include Cloudflare, Route 53, DigitalOcean DNS, Namecheap, and Google Cloud DNS. You should also know which subdomains you want to serve, such as www.example.com, api.example.com, app.example.com, or blog.example.com.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Start by finding your server’s public IP address. On many cloud dashboards, this appears as the instance’s public IPv4 address. From the server itself, you can also run a network lookup command such as curl ifconfig.me. Use the IPv4 address for an A record. If your server also has IPv6 configured, use the IPv6 address for an AAAA record. Do not point DNS records to a private address such as 10.x.x.x, 172.16.x.x, or 192.168.x.x, because those addresses are not reachable from the public internet.

Create DNS Records for Each Subdomain

In your DNS provider’s control panel, create one record per subdomain. Each record maps a hostname to the server that will receive the request. For example, if NGINX will serve both a website and an API from the same machine, both subdomains can point to the same IP address. NGINX will later decide which site or application receives the request based on the Host header.

Hostname Record Type Value Purpose
www.example.com A 203.0.113.10 Main website subdomain
api.example.com A 203.0.113.10 Backend API routed by NGINX
blog.example.com A 203.0.113.10 Static or CMS-powered blog
app.example.com CNAME www.example.com Alias to another hostname

Use an A record when you want the subdomain to point directly to an IPv4 address. Use an AAAA record for IPv6. Use a CNAME record when one hostname should alias another hostname, such as pointing app.example.com to www.example.com. Avoid creating a CNAME at the root domain, such as example.com, unless your DNS provider supports CNAME flattening or an equivalent feature.

Check Propagation Before Editing NGINX

After saving DNS records, allow time for propagation. Some changes resolve within minutes, while others may take longer depending on the record’s TTL and DNS provider behavior. You can test resolution from your workstation with tools such as dig or nslookup. For example, checking api.example.com should return the public IP address of your NGINX server. If it returns an old address, no address, or a proxy provider address, confirm that you edited the authoritative DNS zone for the domain.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Confirm the domain uses the nameservers shown in your DNS provider account.
  • Create records for every subdomain NGINX will serve.
  • Verify each subdomain resolves to the expected public IP address.
  • Make sure firewall rules allow inbound traffic on ports 80 and 443.
  • If using a DNS proxy such as Cloudflare, decide whether the record should be proxied or DNS-only during setup.

Once each subdomain resolves correctly and the server accepts web traffic, you can configure NGINX with matching server_name values. DNS gets the request to your server; the NGINX server block then determines which document root, reverse proxy target, redirect, or TLS certificate should handle that subdomain.

Creating an NGINX Server Block for a Subdomain

After DNS points the subdomain to your server, NGINX needs a matching server block so it knows how to handle requests for that hostname. A server block is NGINX’s virtual host configuration: it matches the incoming Host header, such as blog.example.com or app.example.com, then serves files from a document root or forwards the request to an application.

On most Ubuntu and Debian servers, site configurations are stored in /etc/nginx/sites-available/ and enabled with symbolic links in /etc/nginx/sites-enabled/. For a static subdomain such as blog.example.com, create a dedicated document root first:

sudo mkdir -p /var/www/blog.example.com/public
sudo chown -R www-data:www-data /var/www/blog.example.com
sudo chmod -R 755 /var/www/blog.example.com

Add a simple test file so you can confirm that NGINX is serving the correct directory:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #2
Sale
TP-Link TL-SG105, 5 Port Gigabit Unmanaged Ethernet Switch, Network Hub, Ethernet Splitter, Plug & Play, Fanless Metal Design, Shielded Ports, Traffic Optimization
  • 𝗢𝗻𝗲 𝗦𝘄𝗶𝘁𝗰𝗵 𝗠𝗮𝗱𝗲 𝘁𝗼 𝗘𝘅𝗽𝗮𝗻𝗱 𝗡𝗲𝘁𝘄𝗼𝗿𝗸: 5× 10/100/1000Mbps RJ45 Ports supporting Auto Negotiation and Auto MDI/MDIX.
  • 𝗚𝗶𝗴𝗮𝗯𝗶𝘁 𝘁𝗵𝗮𝘁 𝗦𝗮𝘃𝗲𝘀 𝗘𝗻𝗲𝗿𝗴𝘆: Latest innovative energy-efficient technology greatly expands your network capacity with much less power consumption and helps save money.
  • 𝗥𝗲𝗹𝗶𝗮𝗯𝗹𝗲 𝗮𝗻𝗱 𝗤𝘂𝗶𝗲𝘁: IEEE 802.3X flow control provides reliable data transfer and Fanless design ensures quiet operation.
  • 𝗣𝗹𝘂𝗴 𝗮𝗻𝗱 𝗣𝗹𝗮𝘆: Easy setup with no software installation or configuration needed.
  • 𝗔𝗱𝘃𝗮𝗻𝗰𝗲𝗱 𝗦𝗼𝗳𝘁𝘄𝗮𝗿𝗲 𝗙𝗲𝗮𝘁𝘂𝗿𝗲𝘀: Prioritize your traffic and guarantee high quality of video or voice data transmission with Port-based 802.1p/DSCP QoS and IGMP Snooping.

echo '<h1>blog.example.com is working</h1>' | sudo tee /var/www/blog.example.com/public/index.html

Next, create a new server block file for the subdomain:

sudo nano /etc/nginx/sites-available/blog.example.com

Use a configuration like this for a basic static site:

server {
listen 80;
listen [::]:80;

server_name blog.example.com;

root /var/www/blog.example.com/public;
index index.html index.htm;

access_log /var/log/nginx/blog.example.com.access.log;
error_log /var/log/nginx/blog.example.com.error.log;

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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

The server_name value must match the subdomain exactly. The root directive tells NGINX where to look for files, while try_files checks whether the requested file or directory exists before returning a 404 response. Separate log files are optional, but they make troubleshooting much easier when one server hosts mulle subdomains.

Enable the site by linking it into sites-enabled:

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

Before reloading NGINX, test the configuration syntax:

sudo nginx -t

If the test succeeds, reload NGINX without interrupting active connections:

sudo systemctl reload nginx

Adding Mulle Subdomains

Repeat the same pattern for each subdomain you want to serve. For example, docs.example.com can use its own file, root directory, and logs:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

server {
listen 80;
listen [::]:80;

server_name docs.example.com;

root /var/www/docs.example.com/public;
index index.html;

access_log /var/log/nginx/docs.example.com.access.log;
error_log /var/log/nginx/docs.example.com.error.log;

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

You can also place mulle hostnames in one server block when they should serve the same content:

server_name www.example.com example.com;

For separate applications or separate websites, use separate server blocks. This keeps routing clear, avoids accidental content sharing, and makes later HTTPS setup easier because each hostname can be included explicitly in the certificate request.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Serving Static Sites or Proxying Apps from Subdomains

After the server block matches a subdomain with server_name, NGINX needs to know what to serve. Most subdomain configurations fall into one of two patterns: serving files directly from a document root, or forwarding requests to an application running on a local port or upstream host. For example, docs.example.com might serve static HTML from /var/www/docs, while app.example.com might proxy traffic to a Node.js, Python, Ruby, or Go application listening on 127.0.0.1:3000.

Serving a static site from a subdomain

For a static site, set a dedicated root for the subdomain and use try_files to control how requests are resolved. This keeps each subdomain isolated from the main site and from other subdomains. A typical static configuration looks like this:

server {
listen 80;
server_name docs.example.com;

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

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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

access_log /var/log/nginx/docs.access.log;
error_log /var/log/nginx/docs.error.log;
}

Create the document root if it does not exist, add your files, and make sure NGINX can read them. On many Linux systems, the files can be owned by your deployment user while remaining readable by the web server process:

Rank #3
Sale
NETGEAR 8-Port Gigabit Ethernet Unmanaged Network Switch (GS308)
  • GIGABIT ETHERNET PORTS: Features 8 x 1.0Gbps Ethernet ports for high-speed connectivity. Auto-negotiating ports detect the optimal speed for connected devices and work with existing Cat5e or Cat6 Ethernet cables.
  • PLUG-AND-PLAY UNMANAGED NETWORK SWITCH: Simple plug-and-play setup with no software to install or configuration required.
  • FLEXIBLE MOUNTING OPTIONS: Compact metal design supports desktop or wall-mount placement for versatile installation.
  • SILENT & ENERGY-EFFICIENT OPERATION: Fanless design ensures silent performance, while IEEE 802.3az Energy Efficient Ethernet reduces power consumption without compromising high-speed network performance.
  • REGIONAL COMPATIBILITY: Made for use in U.S. & CA only

sudo mkdir -p /var/www/docs
echo "Docs site" | sudo tee /var/www/docs/index.html
sudo chown -R www-data:www-data /var/www/docs
sudo find /var/www/docs -type d -exec chmod 755 {} \;
sudo find /var/www/docs -type f -exec chmod 644 {} \;

If the static site is a single-page application, such as a React, Vue, or Angular build, direct deep links like /dashboard/settings may need to fall back to index.html. In that case, replace the location block with:

location / {
try_files $uri $uri/ /index.html;
}

Proxying a subdomain to an application

For an application server, use proxy_pass instead of root. NGINX accepts public traffic for the subdomain, then passes it to the backend application. The app should usually bind to 127.0.0.1 rather than a public interface, leaving NGINX as the public entry point:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

server {
listen 80;
server_name app.example.com;

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

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;
}

access_log /var/log/nginx/app.access.log;
error_log /var/log/nginx/app.error.log;
}

The forwarded headers help the application generate correct URLs, log real client IP addresses, and detect whether the original request used HTTP or HTTPS. This is especially useful after TLS is enabled at the NGINX layer, because the backend may still receive plain HTTP from 127.0.0.1.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Supporting WebSockets and long-running requests

If the application uses WebSockets, server-sent events, or long-lived HTTP connections, add upgrade headers and increase proxy timeouts. A common WebSocket-ready location block is:

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

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_read_timeout 300;
proxy_send_timeout 300;
}

When running several apps, give each subdomain its own server block and backend port, such as api.example.com to 127.0.0.1:4000 and admin.example.com to 127.0.0.1:5000. This makes routing explicit, simplifies log review, and prevents one subdomain from accidentally serving another application.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Enabling HTTPS for Subdomains with Let’s Encrypt

After the DNS record points to your server and the NGINX server block responds for the subdomain, the next step is to issue a TLS certificate. Let’s Encrypt provides free certificates that work well for individual subdomains such as app.example.com, blog.example.com, and api.example.com. The most common tool for requesting and installing these certificates with NGINX is Certbot.

Install Certbot and its NGINX plugin using your server’s package manager. On Ubuntu or Debian, the usual commands are:

sudo apt update
sudo apt install certbot python3-certbot-nginx

Before requesting a certificate, make sure the subdomain resolves publicly to the server and that ports 80 and 443 are open in your firewall. Let’s Encrypt must be able to reach the HTTP version of the subdomain during validation. If you are using UFW, allow NGINX traffic with:

sudo ufw allow 'Nginx Full'

To issue and install a certificate for a single subdomain, run Certbot with the --nginx option and the exact hostname from your server block:

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

sudo certbot --nginx -d app.example.com

Certbot reads your NGINX configuration, finds the matching server_name, requests the certificate, and can update the server block to include the required ssl_certificate and ssl_certificate_key directives. During the prompt, choose whether to redirect HTTP traffic to HTTPS. For most public websites and applications, selecting the redirect option is recommended so visitors always land on the encrypted version.

Issuing Certificates for Multiple Subdomains

If several subdomains should be covered by one certificate, include each name with a separate -d flag:

Rank #4
Sale
TP-Link LS1005G, Litewave 5 Port Gigabit Ethernet Unmanaged Switch | Desktop Ethernet Splitter, Unshielded Network Switch, Plug & Play, Fanless Quiet
  • 【One Switch Made to Expand Network】Features 5 RJ45 ports with 10/100/1000Mbps speeds, supporting Auto-Negotiation and Auto MDI/MDIX for hassle-free setup. Ideal for expanding your network, with 1 uplink (input) port and 4 output ports to split your Ethernet connection to multiple devices.
  • 【Gigabit that Saves Energy】Latest innovative energy-efficient technology greatly expands your network capacity with much less power consumption and helps save money
  • 【Reliable and Quiet】IEEE 802.3X flow control provides reliable data transfer and Fanless design ensures quiet operation
  • 【Plug and Play】Easy setup with no software installation or configuration needed
  • 【Ethernet Splitter】Connect to your router or modem for additional wired connections (laptop, gaming console, printer, etc)

sudo certbot --nginx -d example.com -d www.example.com -d blog.example.com -d app.example.com

This creates one certificate containing all listed names. Each name must already have a valid DNS record pointing to the server. For unrelated services with separate NGINX server blocks, you can also request separate certificates per subdomain, which can make renewal and troubleshooting more isolated.

Typical HTTPS Server Block Result

After Certbot finishes, your NGINX configuration usually contains a port 443 server block similar to this:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

server {
listen 443 ssl;
server_name app.example.com;

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

ssl_certificate /etc/letsencrypt/live/app.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/app.example.com/privkey.pem;
}

If you selected HTTP-to-HTTPS redirection, you may also see a separate port 80 block that redirects requests:

server {
listen 80;
server_name app.example.com;
return 301 https://$host$request_uri;
}

For proxied applications, Certbot’s TLS directives are added around your existing location proxy configuration. Your upstream app can still run on a local port such as 3000, while NGINX handles the public HTTPS connection.

Certificate Renewal

Let’s Encrypt certificates are valid for 90 days, but Certbot normally installs an automatic renewal timer. Check that renewal is configured with:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

systemctl list-timers | grep certbot

You can also run a safe renewal test:

sudo certbot renew --dry-run

If the dry run succeeds, Certbot can renew certificates automatically before they expire. After renewal, Certbot reloads NGINX so the updated certificate files are used without manually restarting the server.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Testing, Reloading, and Verifying the Configuration

After adding DNS records, creating server blocks, and enabling TLS, validate the NGINX configuration before you reload the service. This prevents a small syntax error from interrupting every site on the server. Run the configuration test first:

sudo nginx -t

A successful result should report that the syntax is OK and the test is successful. If NGINX prints an error, read the file path and line number carefully. Common causes include a missing semicolon, an unmatched brace, a duplicate server_name, or a certificate path that does not exist. Fix the referenced file, then run sudo nginx -t again until it passes.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Once the test succeeds, reload NGINX instead of restarting it whenever possible. A reload applies the new server block configuration without dropping active connections:

sudo systemctl reload nginx

If you are on a system without systemd, use sudo service nginx reload or sudo nginx -s reload. Then confirm that NGINX is still running with sudo systemctl status nginx. If the service fails to reload, inspect the recent logs with sudo journalctl -u nginx --since "10 minutes ago" or check /var/log/nginx/error.log.

Verify DNS Resolution

Before testing in a browser, confirm that each subdomain resolves to the expected server IP address. This helps separate DNS problems from NGINX routing problems:

  • dig app.example.com
  • dig www.example.com
  • dig api.example.com
  • nslookup app.example.com

The returned A record should match your server’s public IPv4 address. If you created an AAAA record, the IPv6 address should also match the server. If the result is stale, wait for DNS propagation or query a public resolver directly, such as dig @1.1.1.1 app.example.com.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Test Each Subdomain with curl

Use curl to verify that each hostname reaches the correct NGINX server block. The -I option fetches headers only, which is useful for checking status codes, redirects, and TLS behavior:

Best Value
Sale
TP-Link TL-SG108S-M2, 8-Port Multi-Gigabit 2.5G Unmanaged Ethernet Switch | Multi Gigabit Network Switch, Ethernet Splitter, Plug & Play, Desktop/Wall Mount, Silent Operation
  • 𝗘𝗶𝗴𝗵𝘁 𝟮.𝟱 𝗚𝗯𝗽𝘀 𝗣𝗼𝗿𝘁𝘀 𝗳𝗼𝗿 𝗦𝘂𝗽𝗲𝗿-𝗙𝗮𝘀𝘁 𝗖𝗼𝗻𝗻𝗲𝗰𝘁𝗶𝗼𝗻𝘀: 8× 2.5-Gigabit ports unlock the highest performance of your Multi-Gig bandwidth and devices, and provide up to 40 Gbps of switching capacity.
  • 𝗔𝘂𝘁𝗼-𝗡𝗲𝗴𝗼𝘁𝗶𝗮𝘁𝗶𝗼𝗻: Auto-negotiation intelligently senses the link speeds and adjusts between 3-speeds (100Mb/1G/2.5G) for compatibility and optimal performance for all your devices, including 2.5G WiFi 6 AP, 2.5G NAS, 2.5G PCIe Adapter, 2.5G Server, gaming computer, 4K video, and more.
  • 𝗜𝗱𝗲𝗮𝗹 𝗳𝗼𝗿 𝗩𝗮𝗿𝗶𝗼𝘂𝘀 𝗦𝗰𝗲𝗻𝗮𝗿𝗶𝗼𝘀: Built for LAN parties, home entertainment, small and home offices, and instant transfer for workstations.
  • 𝗛𝗮𝘀𝘀𝗹𝗲-𝗙𝗿𝗲𝗲 𝗖𝗮𝗯𝗹𝗶𝗻𝗴: Instantly upgrade to 2.5 Gbps without the need to upgrade to Cat6 wiring, reducing wiring costs and hassle. *
  • 𝗦𝗶𝗹𝗲𝗻𝘁 𝗢𝗽𝗲𝗿𝗮𝘁𝗶𝗼𝗻: Industry-leading fanless design ensures silent operation, ideal for any home or business.
  • curl -I http://app.example.com
  • curl -I https://app.example.com
  • curl -I https://www.example.com

For a static site, you should usually see 200 OK on the final HTTPS URL. If you configured an HTTP-to-HTTPS redirect, the HTTP request should return 301 or 308 with a Location header pointing to the HTTPS version. For a proxied application, a 502 Bad Gateway response usually means NGINX matched the right subdomain but cannot reach the upstream app process.

Confirm the Correct Site or Application Responds

Open each subdomain in a browser and check that it displays the intended site, not the default NGINX page or another virtual host. If mulle subdomains point to the same server, test them one by one. For static roots, add a temporary unique text string to each site’s index.html file. For proxied apps, expose a lightweight health endpoint such as /health and request it through the public subdomain.

Check Expected result
nginx -t Syntax test passes
DNS lookup Subdomain resolves to the server IP
HTTP request Redirects to HTTPS if configured
HTTPS request Returns the correct site or app response
Logs No repeated routing, TLS, or upstream errors

Common Subdomain Setup Errors and Troubleshooting

Most NGINX subdomain problems come from one of four places: DNS does not point to the server, the request reaches the wrong server block, the upstream application is unavailable, or HTTPS was issued for a different name than the one being requested. Work through the failure from the outside in: confirm DNS, confirm NGINX is matching the hostname, confirm the local site or app works, then check the TLS certificate and redirects.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

DNS resolves to the wrong IP address

If blog.example.com still opens an old server, parking page, or registrar default page, check the DNS record first. The subdomain should usually have an A record pointing to your server’s IPv4 address and, if used, an AAAA record pointing to its IPv6 address. If the subdomain uses a CNAME, make sure the target hostname ultimately resolves to the correct server. After changing DNS, allow for propagation based on the record’s TTL, but also test directly with a resolver:

  • dig blog.example.com should return the expected IP address.
  • dig @1.1.1.1 blog.example.com checks Cloudflare’s public resolver.
  • dig @8.8.8.8 blog.example.com checks Google’s public resolver.

NGINX serves the default site instead of the subdomain

When DNS is correct but the browser shows the wrong site, the server_name value is usually missing, misspelled, or not loaded. For example, a block for app.example.com will not match www.app.example.com unless both names are included. Check that the file is enabled, commonly by linking it from /etc/nginx/sites-available/ to /etc/nginx/sites-enabled/ on Debian and Ubuntu systems. Then run nginx -T to view the full active configuration and confirm the expected server_name appears in the loaded output.

Static files return 403 or 404

A 404 Not Found usually means the root path or requested filename does not match the actual document location. A 403 Forbidden often means NGINX can reach the directory but cannot serve an index file, or file permissions prevent access. Confirm that the directory exists, the index file is present, and the NGINX worker user can read the files. On many Linux distributions, that user is www-data or nginx. A static subdomain such as docs.example.com should have a valid root path, such as /var/www/docs.example.com/public, and an index file such as index.html.

Proxied applications show 502 Bad Gateway

A 502 Bad Gateway means NGINX matched the subdomain but could not get a valid response from the upstream application. Check that the app process is running and listening on the same host and port used in proxy_pass. For example, if NGINX proxies to http://127.0.0.1:3000, the application must be listening on port 3000 locally. Also confirm that no firewall, container network boundary, or service manager restart loop is blocking the connection. The NGINX error log will usually show messages such as connect() failed or connection refused, which point to an unavailable upstream.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

HTTPS certificate or redirect issues

If the browser reports a certificate name mismatch, the certificate may not include the requested subdomain. A certificate for example.com does not automatically cover api.example.com unless it is a wildcard certificate or the subdomain is listed as a subject alternative name. Re-run your certificate command with every required hostname, then reload NGINX. Redirect loops usually happen when both NGINX and an application or CDN are forcing HTTPS or canonical host redirects differently. Keep redirects consistent: choose one canonical hostname, such as https://www.example.com or https://app.example.com, and make every redirect point there only once.

Symptom Likely cause Check
Wrong site loads Incorrect server block match server_name and nginx -T
DNS points elsewhere Wrong A, AAAA, or CNAME record dig against multiple resolvers
403 or 404 Bad root path, missing index, or permissions Document root and file ownership
502 Bad Gateway Application port unavailable App process, port, and NGINX error log

Frequently Asked Questions

Do I need a separate NGINX server block for every subdomain?

Usually, yes. A separate server block for each subdomain keeps the document root, proxy target, logs, redirects, and TLS settings clear and easier to troubleshoot. You can use wildcard or shared server blocks for similar subdomains, but individual blocks are safer when each subdomain serves a different app or site.

How long does it take for a new subdomain DNS record to work?

Many DNS changes start working within a few minutes, but it can take longer depending on the record TTL and your DNS provider. You can check propagation with tools like dig, nslookup, or an online DNS checker. Make sure the subdomain has an A record pointing to your server’s IPv4 address or an AAAA record pointing to its IPv6 address.

Can one NGINX server host multiple subdomains on the same IP address?

Yes. NGINX uses the requested hostname from the HTTP Host header and matches it to the correct server_name in your server blocks. This lets app.example.com, blog.example.com, and api.example.com all run on the same server and IP address while serving different content or proxying to different backend ports.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

How do I point a subdomain to an app running on a local port?

Create a server block with the subdomain in server_name, then use proxy_pass to send traffic to the local app, such as http://127.0.0.1:3000. Include proxy headers like Host, X-Real-IP, and X-Forwarded-For so the application receives accurate request information. After saving the file, test with nginx -t and reload NGINX.

What should I check if my subdomain shows the wrong site or the default NGINX page?

First, confirm the DNS record points to the correct server IP address. Then check that your NGINX server block has the exact subdomain listed in server_name and that the file is enabled in the active NGINX configuration. Run nginx -T to inspect the loaded configuration, then reload NGINX after any changes.

Bottom Line

Setting up NGINX subdomains comes down to a reliable sequence: create the right DNS records, define separate server blocks, point each subdomain to the correct app or document root, then secure everything with TLS. Once that foundation is in place, redirects, reverse proxies, and mulle environments become much easier to manage.

Your next step is to test each subdomain end to end: confirm DNS resolution, run an NGINX config check, reload the service, verify HTTPS, and inspect logs if anything fails. Keep each server block clear and isolated so future subdomains can be added quickly without breaking existing sites.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.