Self-hosted software often knows less about its public address than the proxy in front of it.
Inside a container, the server may see plain HTTP even though visitors use HTTPS. A reverse proxy may rewrite the host, remove a port, or add forwarded headers. If the application interprets those signals incorrectly, the dashboard can display a broken MCP URL, OAuth metadata can advertise the wrong scheme, audit logs can record the proxy instead of the operator, and rate limiting can trust an address supplied by the client.
Usertour v0.9.2 makes that boundary explicit and reliable.
Zero-config self-hosting now derives correct public URLs behind the bundled nginx and common TLS-terminating edges. A new TRUST_PROXY setting defines which proxies are allowed to speak for the client address, and startup errors terminate the process instead of leaving a container that appears alive but never listens.
Correct public URLs without extra configuration#
When API_URL is not configured, Usertour derives public URLs from the incoming request. That fallback now preserves the information that matters across the proxy chain:
- The original
X-Forwarded-Protoreaches the server instead of being replaced by nginx's internal scheme. - The client's
Hostheader keeps its port. - The real peer is appended correctly to
X-Forwarded-For. - Duplicate forwarded-protocol values such as
https, httpsare handled safely.
The result is one consistent public address across Settings → MCP, OAuth discovery metadata, authentication challenges, and the installation snippet.
For the stock Docker mapping, docker compose up can now produce a working URL such as http://localhost:8011/mcp instead of silently dropping the port. Behind Railway, Cloudflare, or another HTTPS edge, OAuth metadata uses https:// so MCP clients accept it.
Explicit configuration still wins. API_URL and MCP_SERVER_URL override derived values whenever an installation needs a fixed public address.
A proxy chain clients cannot spoof#
Forwarded headers influence more than links. They also determine the client IP used by rate limiting and the audit log.
v0.9.2 introduces TRUST_PROXY, accepting the same forms as Express: a hop count, address list, or false. The default trusts only the bundled nginx. A direct public, LAN, or Docker-network peer is treated as the client unless an operator explicitly declares another trusted proxy.
That prevents a caller from rotating a fake X-Forwarded-For prefix to create a fresh rate-limit bucket for every request.
When a real proxy sits in front of the container, configure the number or addresses of trusted hops. Usertour then resolves the actual client IP and records it as the actor IP in the audit log rather than storing the address of the ingress or edge proxy.
TRUST_PROXY=2
This is especially important for deployments that rely on the audit log during security reviews: the address now reflects the trust model the operator chose instead of whichever header happened to arrive.
Startup failures now fail fast#
A container that is running but not serving traffic is worse than a container that exits. Restart policies and orchestration health checks can recover from a clear failure; they cannot easily recover from a process that swallowed its bootstrap error.
Previously, an invalid TRUST_PROXY value—or another startup exception—could be logged while the process remained alive without listening. v0.9.2 sanitizes common configuration forms, names invalid values clearly, and exits with code 1 when startup cannot complete.
That turns misconfiguration into an observable deployment failure instead of a silent zombie container.
Fixes included in v0.9.2#
The release closes several related problems:
- Settings no longer shows an empty MCP Server URL when a self-hosted instance has no explicit
API_URL. - OAuth metadata no longer advertises HTTP behind a TLS-terminating edge.
- Derived URLs preserve non-default ports.
- The legacy WebSocket transport returns safe empty URL values when there is no HTTP request to derive from.
- Docker image workflows use their current Node-based GitHub Actions versions.
Regression tests now pin the URL-derivation contract and verify that forged forwarded-header prefixes still reach the same rate-limit bucket.
Who should pay attention to this release?#
Upgrade if your self-hosted Usertour runs behind:
- Railway or Cloudflare
- Kubernetes ingress
- A load balancer or reverse proxy outside the bundled nginx
- A non-default public port
- Any topology where client IPs matter for audit or rate limiting
Most installations using the bundled nginx need no additional setting. If another trusted edge is present, declare it with TRUST_PROXY and verify that audit entries resolve the expected client address.
Usertour Cloud customers receive these changes automatically.
Read the full v0.9.2 release notes. This release follows v0.9.1: Build Onboarding with AI, MCP, and API v2 and is followed by v0.9.3: Outbound Webhooks with Signed, Durable Delivery.



