anonpenguin23 e3b2f08a0a fix(gateway): plumb ntfy_base_url into gateway config so push fan-out activates (#858)
The ntfy fan-out (publish each push to every active push node so a
round-robin-DNS-pinned subscriber receives it) was coded but INERT: the
gateway's cfg.NtfyBaseURL was never populated, so the fan-out resolver was
never built and pushes went single-host (the ~87% loss the bug describes).
The orchestrator already derives https://push.<dnsZone> for the ntfy server +
Caddy reverse-proxy but never put it in node.yaml's http_gateway. Same
regression class as the v0.122.42 secrets_encryption_key fix (consumer
landed; template + parse field + node->gateway mapping were missed).

Plumb it through all four layers: render it under http_gateway (derived as
push.<dnsZone>, matching the ntfy host), parse it in HTTPGatewayConfig, map
it onto gateway.Config. Rolling-upgrade safe: Phase 4 regen runs under the
new binary (post-swap), so an old binary never reads a node.yaml with the new
field. DecodeStrict regression guard added (mirrors secrets_encryption_key).
2026-06-15 23:08:39 +03:00

126 lines
4.1 KiB
YAML

node:
id: "{{.NodeID}}"
listen_addresses:
- "/ip4/0.0.0.0/tcp/{{.P2PPort}}"
data_dir: "{{.DataDir}}"
max_connections: 50
domain: "{{.Domain}}"
{{- if .SSHUser}}
ssh_user: "{{.SSHUser}}"
{{- end}}
{{- if .Environment}}
environment: "{{.Environment}}"
{{- end}}
{{- if .OperatorWallet}}
operator_wallet: "{{.OperatorWallet}}"
{{- end}}
# Stealth TURN-over-443 SNI router (feat-124). When enabled, the node runs
# orama-sni-router on :443 and Caddy is moved to :8443; default-OFF so existing
# nodes are byte-identical until an operator opts in. This block is preserved
# across config regeneration (GenerateNodeConfig carries forward an existing
# sni_router.enabled: true).
sni_router:
enabled: {{if .SNIRouterEnabled}}true{{else}}false{{end}}
database:
data_dir: "{{.DataDir}}/rqlite"
replication_factor: 3
shard_count: 16
max_database_size: 1073741824
backup_interval: "24h"
rqlite_port: {{.RQLiteHTTPPort}}
rqlite_raft_port: {{.RQLiteRaftInternalPort}}
rqlite_join_address: "{{.RQLiteJoinAddress}}"
{{if .NodeCert}}# Node-to-node TLS encryption for Raft communication (direct RQLite TLS on port 7002)
node_cert: "{{.NodeCert}}"
node_key: "{{.NodeKey}}"
{{if .NodeCACert}}node_ca_cert: "{{.NodeCACert}}"
{{end}}{{if .NodeNoVerify}}node_no_verify: true
{{end}}{{end}}cluster_sync_interval: "30s"
peer_inactivity_limit: "24h"
min_cluster_size: {{if .MinClusterSize}}{{.MinClusterSize}}{{else}}1{{end}}
ipfs:
cluster_api_url: "http://localhost:{{.ClusterAPIPort}}"
api_url: "http://localhost:{{.IPFSAPIPort}}"
timeout: "60s"
replication_factor: 3
enable_encryption: true
discovery:
bootstrap_peers:
{{range .BootstrapPeers}} - "{{.}}"
{{end}}
discovery_interval: "15s"
bootstrap_port: {{.P2PPort}}
http_adv_address: "{{.HTTPAdvAddress}}"
raft_adv_address: "{{.RaftAdvAddress}}"
node_namespace: "default"
security:
enable_tls: false
logging:
level: "info"
format: "console"
http_gateway:
enabled: true
listen_addr: ":{{.UnifiedGatewayPort}}"
node_name: "{{.NodeID}}"
base_domain: "{{.BaseDomain}}"
{{if .EnableHTTPS}}https:
enabled: true
domain: "{{.Domain}}"
auto_cert: true
cache_dir: "{{.TLSCacheDir}}"
http_port: {{.HTTPPort}}
https_port: {{.HTTPSPort}}
email: "admin@{{.Domain}}"
{{end}}
# SNI gateway disabled - Caddy handles TLS termination for external traffic
# Internal service-to-service communication uses plain TCP
# Full gateway configuration (for API, auth, pubsub, and internal service routing)
client_namespace: "default"
rqlite_dsn: "http://localhost:{{.RQLiteHTTPPort}}"
olric_servers:
{{- if .WGIP}}
- "{{.WGIP}}:3320"
{{- else}}
- "127.0.0.1:3320"
{{- end}}
olric_timeout: "10s"
ipfs_cluster_api_url: "http://localhost:{{.ClusterAPIPort}}"
ipfs_api_url: "http://localhost:{{.IPFSAPIPort}}"
ipfs_timeout: "60s"
{{- if .SecretsEncryptionKey}}
# Serverless function secrets encryption key (AES-256, hex). Must be
# identical on every namespace-gateway node and stable across restarts
# (bugboard #837). Sourced from ~/.orama/secrets/secrets-encryption-key.
secrets_encryption_key: "{{.SecretsEncryptionKey}}"
{{- end}}
{{- if .NtfyBaseURL}}
# Shared self-hosted ntfy base URL (bugboard #858). Same push.<dnsZone> host
# the ntfy server + Caddy reverse-proxy use, so the gateway's push provider
# fans each publish out to every active push node (each node runs an
# independent ntfy with no shared store; without fan-out a subscriber pinned
# to a different instance than the publish lands on misses it ~87% of the time).
ntfy_base_url: "{{.NtfyBaseURL}}"
{{- end}}
{{- if .TURNSecret}}
# WebRTC/TURN config (feat-124 #913). turn_secret is sourced from
# ~/.orama/secrets/turn-secret so it survives config regeneration;
# turn_domain/sfu_port are carried forward from the previous node.yaml.
webrtc:
enabled: true
sfu_port: {{.SFUPort}}
turn_domain: "{{.TURNDomain}}"
turn_secret: "{{.TURNSecret}}"
{{- end}}
# Routes for internal service reverse proxy (kept for backwards compatibility but not used by full gateway)
routes: {}