feat!(helm): Allow full customization of urls and ingress, move network settings under networking - #7034
feat!(helm): Allow full customization of urls and ingress, move network settings under networking#7034corneliusroemer wants to merge 21 commits into
Conversation
…rt and group `publicHosts`, `ingressHosts`, `subdomainSeparator`, `enforceHTTPS`, and `traefikVersion` under this common group for improved flexibility.
…ng.subdomainSeparator
…when values are not set and improve URL construction
…tually contains the websiteUrl that end-users will interact with
- revert `$.Values.host` -> `.Values.hos` changes - Remove redundant `| default ""` fallbacks in URL construction (except for ingressroute.yaml `hasPrefix` guard)
…g.publicHosts` keys
Keep the `networking` block where the former top-level `enforceHTTPS` and `traefikVersion` keys lived, and leave `enableServiceMonitor` in its original position instead of shifting it below the new block. This is a pure key-ordering change: `helm template` output is byte-identical before and after, and it reduces the values.yaml diff against main from 10 to 7 changed lines with no unrelated entries moved. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ad of a parallel ingressHosts map
…sts as override; fix keycloak redirectUris schemes
…rceHTTPS is off; drop bogus host default from schema
…nt the three config layers Also fail loudly when a publicHosts URL carries a path prefix in the server environment, where the Ingress routes a whole hostname at /.
…rule exists; drop minio/docs ingress host overrides
There was a problem hiding this comment.
Pull request overview
This PR introduces a breaking Helm values re-organization by grouping all networking-related configuration under networking, and updates Helm templates to derive Ingress hostnames from the configured public URLs (with optional per-service overrides). This addresses previously inconsistent behavior where “public” URLs affected only advertised URLs but not actual Ingress routing.
Changes:
- Move
host,subdomainSeparator,enforceHTTPS,traefikVersion, andpublic.*intonetworking.*and document the 3-layer resolution model invalues.schema.json. - Update Ingress and service config templates to use
networking.publicHosts/networking.ingressHostsand shared URL helpers. - Build Keycloak
redirectUrisfrom the website URL and make thewww.website rule conditional.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| kubernetes/loculus/values.yaml | Moves networking settings under networking in the default chart values. |
| kubernetes/loculus/values.schema.json | Defines the new networking block schema (public/ingress host layering) and removes old root keys. |
| kubernetes/loculus/values_e2e_and_dev.yaml | Migrates dev/e2e values to networking.host. |
| kubernetes/loculus/templates/lapis-ingress.yaml | Derives LAPIS ingress host via networking.ingressHosts or URL-derived hostname. |
| kubernetes/loculus/templates/keycloak-config-map.yaml | Derives Keycloak redirect URIs from the website URL and gates plaintext redirect URIs on enforceHTTPS. |
| kubernetes/loculus/templates/ingressroute.yaml | Derives website/backend/keycloak ingress hosts from URLs and makes the www. rule conditional. |
| kubernetes/loculus/templates/ingest-config.yaml | Switches backend URL derivation to the shared loculus.backendUrl helper. |
| kubernetes/loculus/templates/ena-submission-config.yaml | Switches backend URL derivation to the shared loculus.backendUrl helper. |
| kubernetes/loculus/templates/docs-preview.yaml | Moves docs preview hostname derivation to networking.*. |
| kubernetes/loculus/templates/autoapprove-config.yaml | Switches backend URL derivation to the shared loculus.backendUrl helper. |
| kubernetes/loculus/templates/_urls.tpl | Centralizes URL construction under networking.publicHosts and adds helpers for ingress hostname + routability assertion. |
| kubernetes/loculus/templates/_common-metadata.tpl | Uses the shared LAPIS URL template helper for runtime config generation. |
| docs/src/content/docs/for-administrators/setup-with-k3d-and-nginx.mdx | Updates admin setup docs to the new networking.publicHosts structure. |
| deploy.py | Updates deployment helper flags to set networking.host and networking.publicHosts. |
Suppressed comments (2)
kubernetes/loculus/values.schema.json:1503
- The schema/docstring says
networking.publicHosts.lapisUrlTemplate“must contain%organism%as a placeholder”, but the schema doesn’t enforce that. If a user sets a URL without%organism%,generateExternalLapisUrlswill silently produce the same URL for every organism. Add a pattern that allows empty string or requires%organism%when set.
"enableSubmissionNavigationItem": {
"groups": ["website"],
"type": "boolean",
"default": true,
"description": "Whether the website should show \"Submit\" link in the top navigation bar."
},
kubernetes/loculus/values.schema.json:1510
- The
networking.ingressHostsdescription says “Only services with a networking.publicHosts URL can be overridden here”, but the chart logic allows overriding ingress hosts even when using convention-derived defaults (i.e. without settingpublicHosts). This sentence is misleading and should be removed or rephrased to match the actual behavior.
"type": "boolean",
"default": true,
"description": "Whether to completely disable submission related pages. Setting this to false is useful when hosting Loculus for analysis-only purposes."
}
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…ar in the chart config reference
…te and clarify the ingressHosts docs
…mplate and correct the networking schema descriptions
|
Preview is broken - not sure if we can test preview before making changes to another repo that apply to all previews. Full argo error: DetailsUpdate: Hacked around this by hardcoding |
|
Thanks @corneliusroemer for the substantial effort in this! This implementation looks to be a lot cleaner and easier than my earlier approach, especially the inheritance here is a lot more predictable in the long run. tl;dr this looks great to me! |
feat!(deployment): group networking values under
networkingand derive Ingress hostnames from the public URLsFeature requested by @florianzwagemaker who also did initial implementation in #6699. This PR builds on his work there.
Rename in your values files:
public.backendUrlnetworking.publicHosts.backendUrlpublic.websiteUrlnetworking.publicHosts.websiteUrlpublic.keycloakUrlnetworking.publicHosts.keycloakUrlpublic.lapisUrlTemplatenetworking.publicHosts.lapisUrlTemplate, append/%organism%path if not presenthostnetworking.hostsubdomainSeparatornetworking.subdomainSeparatorenforceHTTPSnetworking.enforceHTTPStraefikVersionnetworking.traefikVersionWhy
<service>-<host>subdomain layout was limited and partially broken.values.yaml—host,subdomainSeparator,enforceHTTPS,traefikVersion,public— with no indication that theybelong together.
<prefix><subdomainSeparator><host>in five differenttemplates. A deployment whose services do not live on sibling subdomains of one base domain (e.g.
loculus.x.y.com+api.loculus.x.y.com+auth.loculus.x.y.com) could not be expressed at all.public.backendUrl/websiteUrl/keycloakUrl/lapisUrlTemplatechanged only whatthe applications advertise, never what the Ingress routes. Setting them produced a deployment
that hands out URLs no Ingress rule answers — with no error.
ingest,ena-submissionandautoapproveeach re-derived the backend URL ashttps://backend<sep><host>rather than using the shared helper, sopublic.backendUrlneverreached those configs.
What this changes
All networking configuration now lives in one block with an explicit three-layer model, documented
in the schema:
Inheritance runs in exactly one direction:
networking.hostand you get today's behaviour, unchanged.publicHostsURL and both the advertised URL and that service's Ingress rule (and itsTLS SAN) follow it.
ingressHostsentry only for the rare case where cluster routing must differ from thepublic URL — a CDN or external reverse proxy that terminates the public name. This changes routing
only; advertised URLs are untouched.
Overrideable:
website,backend,keycloak,lapis.Further behaviour changes beyond the renames
redirectUrisare built from the website URL instead ofhttps://<host>+http://<host>, so they are correct when the website is not athttps://<host>. The plaintexthttp://variant of the public host is now emitted only whennetworking.enforceHTTPSisfalse.
www.website rule is now conditional. It is emitted only when the website is still onnetworking.hostand that host does not already start withwww.; theredirect-www-middlewareis attached only when the rule exists. Previously
www.<host>was emitted unconditionally, sohost: www.example.orgproduced an unvalidatablewww.www.example.orgTLS SAN — and with acustom website hostname, a
www.SAN with no DNS record would fail the ACME order and take thewhole TLS secret, including the working host, down with it.
Verification (by Claude)
ingressroute,lapis-ingress,keycloak-config-map,loculus-website-config,docs-preview,ingest-config,autoapprove-configandena-submission-configfor bothenvironment=serverandenvironment=localis byte-identical tomain, apart from the intendedredirectUrischange.publicHostsonly → website / backend / keycloak / lapis Ingress hostnames and TLS SANs allfollow;
www.rule correctly suppressed; KeycloakfrontendUrlandredirectUrisfollow.publicHosts+ingressHosts→ Ingress routes the internal hostnames while the advertised URLsand
redirectUriskeep the public ones.host: www.example.org→ nowww.www.rule or SAN.publicHostsURL → fails in server environment, renders fine in local.runDevelopmentS3=false(external S3 endpoint) → no failure from the MinIO hostname derivation.host/subdomainSeparator, and removedingressHosts.docs→ rejected by theschema.
values_e2e_and_dev.yamlrenders the same service URLs as before on the pathdeploy.py --for-e2eactually builds.
Manual testing
🚀 Preview: https://helm-url-flex-simplified.loculus.org