Networking

Temps runs a built-in Pingora reverse proxy that handles TLS termination, routing, and load balancing for your deployments. This page covers container ports, internal networking, firewall rules, and the routing surfaces available for managed and unmanaged services.


Ports

Each deployed container exposes one primary port. Temps auto-detects it from your Dockerfile EXPOSE directive or framework defaults, or you can set it explicitly.

Auto-detected defaults by framework:

FrameworkDefault Port
Next.js / Node.js3000
Python (uvicorn)8000
Go8080
Ruby on Rails3000
Custom DockerFrom EXPOSE

To override, set the PORT environment variable in Project → Settings → Environment Variables.

Your app must bind to 0.0.0.0, not 127.0.0.1, or the proxy cannot reach it.


Internal networking

Services within the same Temps instance communicate over a private Docker network without exposing ports to the internet. Use the container's service name as the hostname.

If you have a project named api deployed alongside postgres:

postgresql://postgres:password@postgres:5432/mydb

Internal hostnames follow the pattern <service-name>.<project-name>.internal for cross-project references:

http://api.my-project.internal:3000

Internal DNS resolver

Each node runs a built-in DNS resolver (the temps-dns-resolver crate, a Hickory-based UDP/TCP server bound on the bridge gateway). Containers use it as their first nameserver, which makes the *.temps.local names that back HA database clusters resolve natively from inside any cluster member.

The resolver decides how to answer each query by where the name falls:

QueryHow it is answered
In the temps.local zone (temps.local or any *.temps.local, matched case-insensitively, trailing dot optional)Answered authoritatively from the node's synced zone snapshot.
In-zone name that does not existNXDOMAIN.
In-zone name that exists but not for the requested record typeNODATA (NoError with an empty answer) — so IPv4-only names don't break AAAA lookups in glibc/busybox.
Outside temps.localRecursively forwarded to the upstream public resolvers (see below).

Recursive forwarding for public domains

Because the internal resolver is the only nameserver your containers see, queries for public domains (package mirrors, third-party APIs, and so on) are recursively forwarded to a pool of upstream public resolvers. Without this, every outbound lookup like apt-get, wget, or an external API call would return NXDOMAIN.

The default upstream pool is hardcoded:

UpstreamAddressPort
Cloudflare1.1.1.153
Cloudflare1.0.0.153
Google8.8.8.853

Forwarded answers come back as non-authoritative with recursion-available set. An upstream NXDOMAIN/NODATA is passed through as a negative answer; a transport failure (timeout, unreachable upstream) is returned as SERVFAIL so the client can retry.

If the upstream list is configured empty, the forwarder is disabled — the resolver logs DNS recursive forwarder disabled (empty upstream list) instead of DNS recursive forwarder enabled, and out-of-zone queries fall through to NXDOMAIN (strict authoritative-only behavior).


Firewall rules

Temps manages ufw firewall rules automatically. By default:

  • Port 80 (HTTP) — open, redirects to HTTPS
  • Port 443 (HTTPS) — open
  • Port 22 (SSH) — open (for server access)
  • All other ports — closed

To expose an additional port (e.g. for a custom TCP service):

# On the server
sudo ufw allow 25565/tcp comment "custom-service"

For database ports, keep them closed to the internet and use SSH tunneling for local access:

ssh -L 5432:localhost:16432 user@your-server-ip
# Then connect to localhost:5432 locally

Reverse proxy configuration

The built-in Pingora proxy loads routes for Temps-managed projects automatically. You do not maintain a Caddyfile or Nginx configuration for deployed applications.

To publish a service that Temps does not deploy, create a first-class reverse proxy route. Routes support HTTP TLS termination and TLS SNI passthrough, validate upstream destinations, and protect managed hostnames from accidental overrides. See Reverse Proxy Routes for the command reference and safety rules.

WebSockets

WebSocket connections are proxied automatically. Ensure your application handles the Upgrade and Connection headers.

gRPC

For gRPC services, expose the application port through a normal Temps project and confirm that your application supports the proxy's HTTP/2 transport.


Load balancing

When you scale a project to multiple replicas, Temps load-balances incoming requests across them using round-robin with health-check exclusion. Unhealthy replicas are removed from rotation within 10 seconds of a failed health check.

Configure the health check endpoint under Project → Settings → Health Check:

Path:      /health
Interval:  10s
Timeout:   5s
Threshold: 2 failures

Your app should return 200 OK from that path. Any non-2xx response marks the replica unhealthy.


Private networking (Tailscale)

For multi-server setups or connecting your laptop directly to Temps services, Tailscale is the recommended approach:

# On the Temps server
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up

Services become reachable at their Tailscale IP (100.x.x.x) without any firewall changes. This is the safest way to expose database ports to developers without opening them to the internet.

Was this page helpful?