Point the subdomain’s DNS record at the Nginx server, then choose the behavior you actually need. Use proxy_pass when visitors must keep seeing app.example.com while Nginx retrieves the application from another IP and port. Use return 301 when the browser should move to a different hostname or URL. DNS itself cannot send web traffic to an arbitrary port.
Need a server to try this on? Antihost offers Linux VPS plans with NVMe storage, full root access and a 14-day free trial.
Redirect or reverse proxy: the decision that determines your configuration
“Redirecting a subdomain to another IP and port” can describe two different operations. They produce different browser behavior, require different Nginx directives, and have different security and TLS implications.
As an Amazon Associate I earn from qualifying purchases.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →| Requirement | Use | What the client sees | Where the request is handled |
|---|---|---|---|
| Move visitors to another hostname or URL | return 301 (use 302 while testing) |
The address bar changes to the destination URL | The client makes a new request directly to the destination |
| Keep the public subdomain while serving an application elsewhere | proxy_pass in an HTTP location |
The address bar remains app.example.com |
Nginx connects to the configured upstream IP and port |
| Forward a non-HTTP TCP or UDP service | stream { ... proxy_pass ...; } |
There is no HTTP URL redirect | Nginx relays the connection at the transport layer |
Nginx’s return directive immediately stops request processing and sends the chosen status and rewritten URL to the client. A reverse proxy does not send a redirect response; it fetches the upstream response and returns it through the original virtual host.
How the traffic should be arranged
The normal layout is:
- DNS:
app.example.comresolves to the public IP address of the Nginx host. - Public listener: the Nginx host accepts TCP 80 for HTTP and, when enabled, TCP 443 for HTTPS.
- Upstream: Nginx reaches the application at an address such as
192.0.2.10:8080. - Application: the upstream service listens on the destination port and accepts requests from the Nginx host or its network.
Do not point the public DNS record at a private upstream address that Internet clients cannot reach. Conversely, do not expose the upstream port publicly merely because Nginx needs to use it; a firewall or security group can allow that port only from the Nginx host’s address.
#1 Best Overall
Prerequisites before editing Nginx
- Control of the DNS zone for the subdomain.
- The public IPv4 or IPv6 address of the Nginx server.
- The destination IP or hostname and port, for example
192.0.2.10:8080. - Network reachability from the Nginx server to the destination. Test from that host, not from your laptop.
- Firewall and cloud security-group rules allowing public 80/443 as appropriate and allowing Nginx to reach the upstream port.
- An Nginx installation with the HTTP proxy module for HTTP applications. Raw TCP or UDP forwarding requires the stream module.
- A certificate and private key if the subdomain will serve HTTPS.
Point DNS at Nginx, not at the application port
Create the record
Create an A record for app.example.com that contains the Nginx server’s public IPv4 address. If the server is reachable over IPv6, create an AAAA record as well. DNS records map names to addresses; they do not encode an HTTP destination such as port 8080.
After the record is published, verify it from an external resolver. The answer should be the Nginx address. If it returns the upstream address instead, the request will bypass Nginx and none of its virtual-host or proxy settings can take effect. DNS caching means a change can remain invisible to some clients until their resolver cache expires.
Recommended Free Tools
Open only the listeners you intend to use
For an HTTP site, permit inbound TCP 80 to Nginx. For an HTTPS site, permit TCP 443 and either redirect or separately serve HTTP on 80. The upstream port, such as 8080, normally needs to be reachable from Nginx but does not need to be open to the entire Internet.
Keep the subdomain in the browser with an HTTP reverse proxy
Create a server block
Use a dedicated virtual server whose server_name matches the subdomain. Nginx uses that name to select the virtual server; exact and wildcard names are supported, with Nginx applying its defined name-matching order.
server {
listen 80;
server_name app.example.com;
location / {
proxy_pass http://192.0.2.10:8080;
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;
}
}
Here, a request for http://app.example.com/orders is sent by Nginx to the upstream at port 8080. The public URI remains /orders; the browser never sees the upstream IP or port. The address in proxy_pass can be an IP address or hostname and can include a port.
Rank #2
Understand the forwarded headers
The header directives tell the application what the original request looked like. Host preserves the public host name, X-Real-IP supplies the immediate client address, and X-Forwarded-For maintains the proxy chain. X-Forwarded-Proto records whether the client used HTTP or HTTPS at Nginx. These are common deployment settings, not universal requirements: adjust them if the application has a documented proxy-header policy or if another trusted proxy is already in front of Nginx.
Free tools Windows power users keep installed
One-click scans. No signup required.
Only trust forwarded headers from proxies you control. An application that accepts arbitrary client-supplied forwarding headers can log a false address or make incorrect security decisions. Configure the application to trust Nginx as its proxy rather than treating every Internet request as trusted.
Test the configuration and reload
- Save the server block in the configuration location used by your Nginx installation and ensure it is included by the main configuration.
- Run
nginx -t. Fix every syntax or include-file error before reloading. - Reload Nginx with the service command used by your platform, commonly
systemctl reload nginx. A reload applies the new workers without needlessly dropping existing connections. - From a network outside the Nginx host, request the site and confirm that the response is generated by the application while the URL remains
app.example.com.
Send the browser to another URL with a redirect
Use a redirect when the destination should be visible to the client. A dedicated server block is the clearest arrangement:
server {
listen 80;
server_name app.example.com;
return 301 https://new.example.com$request_uri;
}
$request_uri preserves the original path and query string. For example, a request for /download?id=42 is redirected to the same path and query on new.example.com. The destination host must be prepared to serve that request; Nginx is not proxying it.
Use a temporary response while experimenting
Browsers and intermediary caches can retain a permanent redirect. During a migration or while checking a hostname, use a temporary response first:
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errorsserver {
listen 80;
server_name app.example.com;
return 302 https://new.example.com$request_uri;
}
Change the status to 301 only after the destination, certificate, paths, and application behavior are stable. A 301 is appropriate for a permanent move; it is not a mechanism for forwarding an otherwise private service port.
Serve the subdomain over HTTPS
Terminate TLS at Nginx
For a public HTTPS endpoint, create an HTTPS server block with the same server_name, listen 443 ssl, and certificate directives. The certificate must cover app.example.com.
server {
listen 443 ssl;
server_name app.example.com;
ssl_certificate /etc/nginx/certs/app.example.com/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/app.example.com/privkey.pem;
location / {
proxy_pass http://192.0.2.10:8080;
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;
}
}
The paths above are an example layout; use the actual certificate and key paths on your server and protect the private key from unprivileged users. Nginx decrypts the client connection, then makes an HTTP connection to the upstream in this example.
Redirect HTTP to HTTPS
Keep a separate port-80 block that sends clients to HTTPS while preserving the requested URI:
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallserver {
listen 80;
server_name app.example.com;
return 301 https://app.example.com$request_uri;
}
Test this with a temporary 302 if you are still changing hostnames or certificates. Once the HTTPS endpoint is confirmed, the permanent redirect prevents accidental plain-HTTP use.
Rank #4
Proxy to an HTTPS upstream
If the application itself speaks HTTPS, change the upstream scheme:
location / {
proxy_pass https://192.0.2.10:8443;
proxy_set_header Host upstream.example.internal;
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;
}
Upstream certificate validation and Server Name Indication can require more than changing http to https. When the upstream certificate is issued to a hostname rather than its IP, configure the appropriate upstream name and proxy_ssl_name, and use a matching Host header when the application expects one. Decide explicitly whether Nginx should validate the upstream certificate; disabling validation can hide a mistaken destination or a man-in-the-middle condition.
Trailing slashes and path rewriting in proxy_pass
The URI portion of proxy_pass changes how Nginx constructs the upstream request. When a URI is included, Nginx replaces the part of the request URI that matched the location. A whole-subdomain pass-through should therefore begin with the no-URI form:
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →location / {
proxy_pass http://192.0.2.10:8080;
}
With this form, /assets/app.css is passed through as /assets/app.css. Add a URI only when the application is mounted beneath a different path, and treat the trailing slash as significant:
location /service/ {
proxy_pass http://192.0.2.10:8080/;
}
In that example, the matching /service/ prefix is replaced by /, so a public request for /service/status reaches the upstream as /status. If the upstream must receive /service/status, omit the URI in proxy_pass or use a location and rewrite strategy designed for that application. Test both the root path and a nested path before deploying a permanent redirect or changing a production mount point.
Forward raw TCP or UDP with the stream module
An HTTP server block and an HTTP-context proxy_pass are for HTTP-family traffic. Databases, game protocols, mail protocols, and other raw TCP or UDP services need Nginx’s stream module instead.
stream {
server {
listen 12345;
proxy_pass 192.0.2.10:12345;
}
}
This configuration listens on port 12345 and relays the TCP connection to the destination address and port. Place the stream block in the configuration context supported by your Nginx build; it is not nested inside an HTTP server block. For UDP, configure the stream listener and the UDP behavior required by the module and your protocol. There is no HTTP status code, URI, browser redirect, or Host header in a raw transport proxy.
Choose the approach with this checklist
| Question | If the answer is yes | Configuration direction |
|---|---|---|
| Should the address bar change to another hostname? | Yes | Use return 302 while testing, then return 301. |
| Must users continue to see the original subdomain? | Yes | Use an HTTP location with proxy_pass. |
| Is the payload HTTP or HTTPS? | Yes | Use an HTTP server block; terminate TLS at Nginx or proxy to an HTTPS upstream. |
| Is the payload raw TCP or UDP? | Yes | Use the stream module with a listener and destination port. |
| Does the application need to remain private? | Yes | Keep DNS pointed at Nginx and restrict the upstream firewall to Nginx’s network. |
| Does the public path differ from the upstream path? | Yes | Use a deliberate URI in proxy_pass and test trailing-slash behavior. |
Validate from the outside and from Nginx
- Resolve the name and confirm it returns the Nginx public address, not the upstream address.
- Run
nginx -twith the same configuration path and include files used by the running service. - Reload Nginx and confirm that the reload succeeds.
- For HTTP, run
curl -I http://app.example.com/from an external vantage point. - For HTTPS, run
curl -vkI https://app.example.com/. Check the certificate name, handshake, status, and any redirect location. - Request a nested path and a query string to verify URI preservation or intentional rewriting.
- From the Nginx host, test reachability to the upstream IP and port. A successful DNS lookup does not prove that a firewall permits the connection.
- Inspect Nginx access and error logs while making a request, then inspect the upstream application’s logs for the received host, path, and client-address headers.
Troubleshoot the common failure modes
The request reaches the wrong site
Check the DNS answer first. If the record points directly to the application or to a different Nginx host, the intended server_name block cannot receive the request. If DNS is correct, check for another server block with a more specific name, a duplicate configuration, or a default server catching the request.
Nginx returns 502 Bad Gateway or a connection-refused error
Verify that the application is listening on the configured destination address and port, that the address is reachable from Nginx, and that host-level and cloud firewalls allow the connection. A service bound only to 127.0.0.1 on a different machine, an incorrect port, or a security group that allows clients but not Nginx will all produce this symptom. The Nginx error log normally identifies connection refusal, timeout, or name-resolution details.
The page loads but redirects to an internal host or wrong scheme
The application may be unaware that it is behind a proxy. Check the Host and X-Forwarded-Proto values reaching the application and enable its documented proxy-awareness setting. Also check whether the application emits an absolute redirect containing its internal hostname or HTTP scheme.
Static files or routes return 404 after adding a path prefix
Compare the public URI with the URI sent upstream. A URI in proxy_pass replaces the matching location prefix; a missing or extra trailing slash commonly changes the result. Temporarily use location / { proxy_pass http://IP:PORT; } to establish that the service works without rewriting, then add a prefix only when the application requires it.
HTTPS fails before the application responds
Confirm that TCP 443 is open, the certificate covers the requested subdomain, and the certificate and key match. For an HTTPS upstream, inspect the upstream certificate name and SNI requirements. Configure the upstream TLS name and validation policy deliberately instead of assuming an IP address will satisfy a hostname certificate.
A permanent redirect keeps appearing after you removed it
Browsers and intermediary caches can retain a 301. Test with a fresh client or a cache that does not contain the old response, and use a temporary 302 while making future changes. Verify the current response with curl so you are testing the server rather than a browser’s cached decision.
Quick Recap
Operational and security considerations
- Keep the upstream service off the public Internet when Nginx is the intended gateway; restrict its listener with firewall rules.
- Use HTTPS for credentials, session cookies, and other sensitive traffic. If TLS terminates at Nginx, protect the certificate key and decide whether the Nginx-to-upstream leg also requires encryption.
- Preserve the original host and forwarding information only when the application is configured to trust Nginx. Do not blindly trust forwarding headers from untrusted clients.
- Monitor both Nginx and upstream logs. Nginx can show a healthy client connection while the upstream is timing out or returning application errors.
- Make one change at a time, run
nginx -t, reload, and test externally. Keep a known-good configuration so a failed path rewrite or certificate change can be reverted quickly.
A minimal deployment sequence
- Create
Aand, if needed,AAAArecords for the subdomain pointing to Nginx. - Confirm the upstream service and firewall permit Nginx-to-destination traffic.
- Choose
proxy_passfor a stable public URL,return 301for a visible move, or the stream module for raw TCP/UDP. - Write the matching Nginx server or stream configuration, paying attention to the port and any path URI.
- Run
nginx -t, reload Nginx, and test with externalcurlrequests. - Read the logs, fix name selection, connectivity, headers, TLS, or path handling as indicated, and only then make permanent redirects or tighten access rules.
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.




