ProdCraft
Subscribe
Linux

Nginx Reverse Proxy on Ubuntu: HTTPS, Headers and FastAPI Example

Configure Nginx as an HTTPS reverse proxy for FastAPI on Ubuntu with TLS, headers, validation and debugging steps.

ProdCraft6 min read
ProdCraft featured image — Nginx Reverse Proxy on Ubuntu: HTTPS, Headers and FastAPI Example

Nginx Reverse Proxy on Ubuntu: HTTPS, Headers and FastAPI Example is a practical walkthrough for engineers who want to understand the reasoning behind a working setup—not only paste commands. Examples assume an authorized lab or server. Verify the operating-system version, back up important data and read commands before using them on production systems.

The practical problem

Running a web app on port 8000 is convenient for development, but it does not provide a complete public-facing setup. An Nginx reverse proxy can terminate HTTPS, route requests to your application, and centralize certain request limits. We’ll place a small FastAPI service behind Nginx on an Ubuntu host. The example assumes you control a domain pointing at your server and that DNS propagation has completed. For a public deployment, a certificate must be valid for the hostname users actually visit.

Prepare the host and plan a safe change

Install prerequisites with sudo apt update and sudo apt install nginx, then enable the service. Run the FastAPI app on 127.0.0.1:8000, not on every public interface, and verify curl http://127.0.0.1:8000/health returns a legitimate application response. Keep application process management separate using systemd or a container supervisor. Confirm ports 80 and 443 are permitted by your host firewall and cloud controls. Never assume opening 443 fixes an application that is not healthy behind the proxy.

Installation and configuration example

Create an Nginx server block for api.example.com with listen 80;, server_name api.example.com;, and a location mapping to proxy_pass http://127.0.0.1:8000;. Forward Host, X-Real-IP, X-Forwarded-For, and X-Forwarded-Proto using Nginx’s request variables. Trust forwarded headers in the application only when requests arrive from your controlled proxy; an arbitrary external header is not identity. Test the file with sudo nginx -t, then sudo systemctl reload nginx. A failed configuration test means stop rather than deploying blindly.

Verify the result before declaring success

Provision a TLS certificate with a supported ACME client such as Certbot following its distribution-specific Nginx instructions. Use the real hostname and confirm its A/AAAA records resolve correctly. Redirect plain HTTP to HTTPS after issuance, and check automatic renewal using the installed scheduler and a dry run where supported. For long-lived WebSocket connections, include the appropriate upgrade handling; it is not needed for ordinary JSON APIs. Set timeouts according to legitimate request duration instead of increasing every timeout to several minutes to hide application bottlenecks.

Troubleshooting and rollback

Validate with curl -I https://api.example.com/health, an authorized browser test, and the Nginx access and error logs. A 502 response often means the upstream is down, bound to a different address, or blocked by permissions. A 404 may mean the request never matched your intended server block or the application’s route path differs. A certificate mismatch usually points to the wrong hostname or virtual host. Debug layer by layer: DNS, listener, certificate, reverse proxy, upstream app. That sequence saves hours of random configuration changes.

Make it dependable in production

Production design requires rate limiting aligned to your users, a trusted request body size, security headers that do not break your application, and monitoring of Nginx 4xx/5xx rates. Keep TLS private keys readable only by their intended services. Use automated tests for proxy behavior after upgrades; do not rely on nginx -t alone, which checks syntax but not functional request routing. Record rollback steps and certificate renewal ownership. Where a cloud load balancer already terminates TLS, make the proxy trust boundary explicit rather than stacking headers unpredictably.

Operational example: from a lab change to a managed service

Imagine the same server moving from an individual’s test environment into a small team’s production fleet. The command that proved the idea still matters, but it is no longer the whole delivery plan. Assign a specific owner, record the intended configuration in version control, create a change ticket or deployment record, and test the behavior in staging before rolling it to every machine. Keep the old configuration or previous release available so you can restore service quickly if assumptions prove wrong. Most Linux incidents are not caused by one mysterious command; they grow from undocumented changes and missing verification.

For this topic, build a compact runbook with four things: the expected healthy state, the fastest read-only observation command, a low-risk diagnostic path, and an explicit rollback trigger. Pair logs with actual user-facing checks. If the main service says “active” but requests fail, the monitoring check should reveal that mismatch. A beginner can follow the commands in this guide to learn the mechanics, while an on-call engineer should be able to follow the runbook without guessing which changes are allowed during an outage.

Security and maintenance checklist

Apply least privilege, restrict unnecessary network exposure, and keep configuration and credentials separate. Review distribution security updates rather than freezing package versions forever; however, test major upgrades that can alter configuration defaults. Backups must include the data and metadata necessary to recreate a working service, and the restore procedure must be exercised. Record where logs appear and how to correlate them with incidents. Document any example-specific assumptions, such as a local hostname or account name, before colleagues reuse the steps. These operational details are what separate a tutorial that runs once from a deployment that survives the next six months.

FAQ

Can I run these commands on a production server directly?

Use a test host first and review the exact distribution and version. Commands that alter authentication, networking or filesystems can be disruptive. Confirm backup and console or rollback access before changing remote infrastructure.

How can I tell whether the setup is actually reliable?

Verify the expected behavior from another process or host, inspect relevant logs, and test a deliberate failure with a documented recovery procedure. A successful exit code from an installation command is only the beginning of validation.

Review the official reference for this component before deploying, particularly for version-dependent options. For a broader engineering perspective, explore ProdCraft’s self-hosted model operations guide and our security architecture checklist; the same principles of least privilege, observability and measured changes apply to AI infrastructure as well as traditional servers.

Mini lab: confirm proxy headers safely

Create a temporary API route that returns a request ID and the hostname the application believes it received, without returning credentials or all raw headers. Compare a direct request to http://127.0.0.1:8000 with a request to your Nginx hostname. The upstream should receive the expected host and scheme when the proxy is configured correctly. If your framework supports trusted proxy settings, restrict them to known Nginx addresses; do not trust arbitrary client-supplied forwarding headers. Capture the result of both requests as a regression test.

During TLS certificate renewal testing, verify the hostname, not just successful TCP connection. A proxy can serve a valid certificate for the wrong site. For the application service itself, use our systemd Python deployment tutorial, which covers ownership, startup and logs.

Share this article

Written by

ProdCraft

ProdCraft publishes practical engineering guides on DevOps, Kubernetes, Docker, Linux, databases, cloud and LLMs — written for engineers who ship.

227 articles View profile

The weekly ops & AI brief

One email a week with the best new guides, tools and incident write-ups. No spam, unsubscribe anytime.

Leave a Reply

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