Skip to content

feat: add NITRIC_HOSTNAME env var for configurable local backend address#870

Open
tom-groves wants to merge 3 commits intonitrictech:mainfrom
tom-groves:feat/configurable-hostname
Open

feat: add NITRIC_HOSTNAME env var for configurable local backend address#870
tom-groves wants to merge 3 commits intonitrictech:mainfrom
tom-groves:feat/configurable-hostname

Conversation

@tom-groves
Copy link

Presigned storage URLs, gateway addresses, and website URLs are hardcoded to localhost, making them unresolvable when the backend runs in a Docker container addressed from another container.

For example, when calling PreSignUrl from a service in a separate container, the returned URL is:

http://localhost:54321/read/<token>

Which resolves to the calling container itself, not the Nitric backend.

Solution

Introduce a NITRIC_HOSTNAME environment variable (default: localhost) that controls the hostname used in all generated URLs. The value is resolved once at startup in cloud.New() and threaded through storage, gateway, and website service constructors.

Usage:

NITRIC_HOSTNAME=backend-container nitric start

Presigned URL with override:

http://backend-container:54321/read/<token>

Without override (default, no behavior change):

http://localhost:54321/read/<token>

Affected code paths

Location Before After
storage.go PreSignUrl http://localhost:{port}/read/... http://{NITRIC_HOSTNAME}:{port}/read/...
storage.go PreSignUrl http://localhost:{port}/write/... http://{NITRIC_HOSTNAME}:{port}/write/...
gateway.go GetTriggerAddress [::]localhost [::]{NITRIC_HOSTNAME}
gateway.go GetApiAddresses [::]localhost [::]{NITRIC_HOSTNAME}
gateway.go GetHttpWorkerAddresses [::]localhost [::]{NITRIC_HOSTNAME}
gateway.go GetWebsocketAddresses [::]localhost [::]{NITRIC_HOSTNAME}
websites.go register http://localhost:{port}/... http://{NITRIC_HOSTNAME}:{port}/...

Additional hardening

  • IPv6 literal hostnames are automatically bracketed for valid URL construction per RFC 3986 (e.g. fe80::1[fe80::1])
  • Hostnames containing URL-unsafe characters (/?#, newlines, whitespace) are rejected at startup with a clear error
  • Added comment clarifying why connectionStringHost (for Postgres) is intentionally separate from NITRIC_HOSTNAME

Note on connectionStringHost

The SQL connectionStringHost in cloud.go is deliberately not changed to use NITRIC_HOSTNAME. It controls how application services reach the Postgres container (a separate container with host-mapped ports), which is a different network path from how callers reach the Nitric backend. The existing RunMode/StartMode logic with host.docker.internal already handles this correctly.

Presigned storage URLs, gateway addresses, and website URLs were
hardcoded to localhost, making them unresolvable when the backend
runs in a Docker container addressed by other containers. Introduce
NITRIC_HOSTNAME (default: "localhost") so all generated URLs use a
configurable host, resolved once in cloud.New() and threaded through
storage, gateway, and website services.
- Move env import to correct alphabetical position
- Wrap IPv6 literal hostnames in brackets for valid URL construction
- Add comment explaining why connectionStringHost is separate from
  NITRIC_HOSTNAME
- Move env import to correct alphabetical position (between batch
  and gateway)
- Reject NITRIC_HOSTNAME values containing URL-unsafe characters
  (/?#, newlines, whitespace) at startup to prevent malformed URLs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant