Your FastAPI app is deployed and running at my-app-production-abc123.railway.app. It works. But you want users to reach it at api.myapp.com. This is where code ends and infrastructure begins, and it is the part AI handles worst, because there is nothing to code. It is all configuration in external systems.
How a request reaches your APIWhat is api?A set of rules that lets one program talk to another, usually over the internet, by sending requests and getting responses.
Before diving into configuration, understand what happens when someone visits api.myapp.com:
Browser → DNS Resolver → Platform Load Balancer → TLS Termination → Your App
↓ ↓ ↓ ↓ ↓
"api.myapp.com" "Where is that?" "Route to app" "Decrypt HTTPS" "Handle request"
→ 104.21.12.34- DNSWhat is dns?The system that translates human-readable domain names like google.com into the numerical IP addresses computers use to find each other. resolution: the browser asks "what IP addressWhat is ip address?A numerical label (e.g., 172.217.14.206) that identifies a device on a network - DNS translates domain names into IP addresses. is
api.myapp.com?" and gets an answer from DNS - TCP connection: the browser connects to that IP address
- TLSWhat is ssl/tls?Encryption protocols that secure the connection between a browser and a server, preventing eavesdropping on data in transit. handshakeWhat is handshake?The initial exchange between a client and server that establishes a connection and agrees on communication rules before data starts flowing.: HTTPSWhat is https?HTTP with encryption added, so data traveling between your browser and a server can't be read or tampered with by anyone in between. encryptionWhat is encryption?Scrambling data so only someone with the right key can read it, protecting information from being intercepted or stolen. is established (SSL certificate verification)
- HTTPWhat is http?The protocol browsers and servers use to exchange web pages, API data, and other resources, defining how requests and responses are formatted. request: the actual request reaches the platform's load balancerWhat is load balancer?A server that distributes incoming traffic across multiple backend servers so no single server gets overwhelmed.
- Routing: the platform routes the request to your specific app containerWhat is container?A lightweight, portable package that bundles your application code with all its dependencies so it runs identically on any machine.
- Your code: FastAPI receives the request and returns a response
DNSWhat is dns?The system that translates human-readable domain names like google.com into the numerical IP addresses computers use to find each other. records you need to know
You configure DNS records at your domain registrar (Namecheap, Cloudflare, Google Domains, etc.).
| Record type | Points to | When to use | Example |
|---|---|---|---|
| A | IP address | Root domain (myapp.com) | myapp.com → 104.21.12.34 |
| CNAME | Another domain | Subdomain (api.myapp.com) | api.myapp.com → my-app.railway.app |
| AAAA | IPv6 address | IPv6 support | myapp.com → 2606:4700::1 |
For most deployments, you need one CNAME record pointing your subdomainWhat is subdomain?A prefix to a domain (api.example.com, blog.example.com) that routes to a distinct service or section of a site. to the platform's domain.
# DNS record for Railway deployment
Type: CNAME
Name: api
Value: my-app-production.up.railway.app
TTL: 300myapp.com without a subdomain). Some DNS providers offer "CNAME flattening" or "ALIAS records" as a workaround. Cloudflare does this automatically. If your provider does not, use an A record with the platform's IP address.HTTPSWhat is https?HTTP with encryption added, so data traveling between your browser and a server can't be read or tampered with by anyone in between. and TLSWhat is ssl/tls?Encryption protocols that secure the connection between a browser and a server, preventing eavesdropping on data in transit. certificates
HTTPS encrypts the connection between the browser and your server. Without it, passwords and tokens travel in plain text.
The good news: in 2026, every deployment platform auto-provisions TLS certificates via Let's Encrypt. You do not need to buy certificates or configure them manually.
The flow:
- You add a custom domain in the platform's dashboard
- You configure DNSWhat is dns?The system that translates human-readable domain names like google.com into the numerical IP addresses computers use to find each other. to point to the platform
- The platform detects the DNS change and requests a Let's Encrypt certificate
- HTTPS works automatically (usually within minutes)
certbot, openssl commands, certificate files in the repo). For platform-hosted apps, this is unnecessary and wrong. The platform handles certificates. You only need manual cert management if you are running your own server on a VPS.Reverse proxies
A reverse proxyWhat is reverse proxy?A server that sits in front of your app and forwards incoming requests to it, often handling SSL, caching, or load balancing along the way. sits between the internet and your application. On managed platforms, this is handled for you. But understanding what it does helps you debug issues.
Internet → Reverse Proxy (platform) → Your Uvicorn Process
↓
- SSL termination (decrypts HTTPS)
- Load balancing (routes to healthy instances)
- Static file serving
- Rate limiting
- Request bufferingWhen you deploy on Railway or Fly.io, the platform's reverse proxy handles SSLWhat is ssl/tls?Encryption protocols that secure the connection between a browser and a server, preventing eavesdropping on data in transit. termination. Your app receives plain HTTPWhat is http?The protocol browsers and servers use to exchange web pages, API data, and other resources, defining how requests and responses are formatted. on its internal port. This is why your FastAPI app binds to 0.0.0.0:$PORT with no SSL configuration, the proxy already handled it.
Headers from the proxy
The reverse proxy adds headers that tell your app about the original request:
# These headers come from the reverse proxy, not the client
# X-Forwarded-For: 203.0.113.42 ← client's real IP
# X-Forwarded-Proto: https ← original protocol
# X-Request-ID: abc-123 ← request tracking
from fastapi import Request
@app.get("/debug")
async def debug(request: Request):
return {
"client_ip": request.headers.get("X-Forwarded-For"),
"protocol": request.headers.get("X-Forwarded-Proto"),
}--ssl-keyfile and --ssl-certfile flags to the uvicorn start command. Behind a reverse proxy, this causes double encryption (proxy encrypts, then uvicorn tries to encrypt again). Your app should listen on plain HTTP; the proxy handles HTTPS.Platform-specific domain setup
Railway
- Go to your service's Settings → Domains
- Click "Add Custom Domain"
- Add a CNAME record at your DNSWhat is dns?The system that translates human-readable domain names like google.com into the numerical IP addresses computers use to find each other. providerWhat is provider?A wrapper component that makes data available to all components nested inside it without passing props manually.
- Railway auto-provisions the certificate
Fly.io
fly certs create api.myapp.com
# Then add a CNAME record: api.myapp.com → my-app.fly.devRender
- Go to your service's Settings → Custom Domains
- Add your domain
- Add the CNAME record Render gives you
- Certificate is provisioned automatically
Quick reference
| Concept | What it is | Who manages it |
|---|---|---|
| DNS records | Maps domain names to IP addresses | You, at your registrar |
| TLS certificate | Enables HTTPS encryption | Platform (auto via Let's Encrypt) |
| Reverse proxy | Sits between internet and your app | Platform (managed) |
| SSL termination | Decrypts HTTPS before reaching your app | Reverse proxy |
| TTL | How long DNS records are cached | You set it; lower = faster changes |