Files
Hanzo Devandzeekay 6055a14e34 k8s(lux-mainnet): expose rpc.{hanzo,zoo}.network for the two primary-network-validating L2s (#30)
* fix(lux-build): roll lux.build to 0.1.14 + decomplect to one route

lux.build was 503 crash-looping: the live deployment ran the OLD Prisma-based
image ghcr.io/luxfi/build:0.1.9 which SIGSEGV/heap-OOM'd on a missing
DATABASE_URL (62 restarts). The dashboard was rewritten Prisma-free (a
self-contained Next standalone server) and already built natively on the
lux-build ARC pool as 0.1.14 (HEAD 916863d) — it was simply never rolled.

- k8s/lux-mainnet/lux-build.yaml: image 0.1.6 -> 0.1.14 (canonical, live),
  replicas 1 -> 2 (flagship availability), liveness/readiness / -> /v1/health
  (the app's purpose-built health route). Validated in-cluster: starts clean,
  / + /quickstart + /v1/health all 200; rolled 2/2 Running, 0 restarts.

Decomplect to exactly ONE lux.build route (the canonical lux-mainnet/lux-build):
- k8s/lux-explorer/lux-build.yaml: DELETED — a dead duplicate (image 0.1.0,
  no live resources) whose IngressRoute also claimed Host(`lux.build`).
- k8s/lux-explorer/build-wl.yaml: removed the dead build-lux stanzas
  (ConfigMap/Deployment/Service/IngressRoute). Its build-lux IngressRoute
  claimed Host(`lux.build`) with a dead backend (svc had no endpoints),
  causing non-deterministic 503s when edge pods resolved the host to it.

lux.exchange: header doc clarified. The apex is healthy (in-cluster HTTP 200 +
valid TLS, CN=lux.exchange) served by the single class=ingress Ingress on
hanzoai/ingress with the cert-manager lux-exchange-tls secret. External apex
failures are safebrowse-style client-network content filtering of the
crypto-exchange domain (NOT an origin/ingress/cert fault) — the unfiltered
.network aliases serve 200.

Note: build-{zoo,hanzo,pars} in build-wl.yaml are also dead (other-brand
surfaces, out of scope) — flagged for those teams, left untouched.

* k8s(lux-mainnet): expose rpc.{hanzo,zoo}.network for the two L2s

Hanzo (chainId 36963) and Zoo (chainId 200200) are primary-network-
validating L2s — their blockchains already live on the Lux P-Chain
(hanzo bc RHuUsLWW..., zoo bc 4HBM17cz...) and are validated by the
existing Lux Primary Network validator set (platform.validatedBy ->
netID 1111...LpoYY, same as C-Chain). No separate validator set.

- rpc-brand-ingress.yaml: IngressRoute rpc-brand-root-mainnet adds
  bare-root JSON-RPC for rpc.{hanzo,zoo}.network at Path(/) priority
  10000, using the existing lux-system rpc-rewrite-{hanzo,zoo}
  middlewares (replacePath -> /ext/bc/{hanzo,zoo}/rpc). Mirrors the
  api-brand-root-mainnet pattern; full /ext/* surface already served by
  the shared api-mainnet IngressRoute. (A plain k8s Ingress is shadowed
  by api-mainnet@kubernetescrd, so IngressRoute is the one way here.)
- chains/chain-{hanzo,zoo}.yaml: lux.cloud/v1 Chain CRs (alias, networkRef
  luxd, vm evm) so the bootnode/lux.cloud fleet dashboard lists both L2s.
- chain-aliases.yaml: reconcile stale git blockchainIDs to the live
  on-chain P-Chain values (+ add osage).

Verified: rpc.hanzo.network eth_chainId 0x9063 (36963), rpc.zoo.network
0x30e08 (200200), both via the public Cloudflare endpoint.

---------

Co-authored-by: zeekay <[email protected]>
2026-07-26 15:46:01 -07:00

379 lines
10 KiB
YAML

# White-label Builder Hub deployments
# Same image (ghcr.io/hanzoai/lux-build:0.1.0), different ConfigMaps per brand
# Each brand gets its own hostname via IngressRoute
---
# ============================================================================
# ConfigMaps — per-brand environment
# ============================================================================
# NOTE: build-brand-lux / build-lux removed — lux.build is owned solely by the
# canonical lux-mainnet/lux-build (k8s/lux-mainnet/lux-build.yaml, the rewritten
# builders dashboard at ghcr.io/luxfi/build). This white-label hub kept a stale
# build-lux IngressRoute claiming Host(`lux.build`) with a dead backend, which
# conflicted with the canonical route (non-deterministic 503s across edge pods).
# Removed so there is exactly ONE lux.build route.
apiVersion: v1
kind: ConfigMap
metadata:
name: build-brand-zoo
namespace: lux-explorer
data:
NEXT_PUBLIC_SITE_NAME: "Zoo Build"
NEXT_PUBLIC_SITE_URL: "https://build.zoo.network"
NEXT_PUBLIC_SITE_DESCRIPTION: "Build decentralized AI research applications on Zoo Network — a Lux L2 for DeAI and DeSci."
NEXT_PUBLIC_NETWORK_NAME: "Zoo"
NEXT_PUBLIC_NETWORK_SHORT_NAME: "ZOO"
NEXT_PUBLIC_CHAIN_ID: "200200"
NEXT_PUBLIC_EXPLORER_URL: "https://explore-zoo.lux.network"
NEXT_PUBLIC_FAUCET_URL: "https://faucet.zoo.network"
NEXT_PUBLIC_DOCS_URL: "https://docs.zoo.network"
NEXT_PUBLIC_TWITTER_URL: "https://twitter.com/zoolabs"
NEXT_PUBLIC_DISCORD_URL: "https://discord.gg/zoolabs"
NEXT_PUBLIC_GITHUB_URL: "https://github.com/zoo-labs"
NEXT_PUBLIC_SITE_LOGO: "/zoo-logo.png"
NEXT_PUBLIC_SITE_OG_IMAGE: "/zoo-logo.png"
---
apiVersion: v1
kind: ConfigMap
metadata:
name: build-brand-hanzo
namespace: lux-explorer
data:
NEXT_PUBLIC_SITE_NAME: "Hanzo Build"
NEXT_PUBLIC_SITE_URL: "https://build.hanzo.ai"
NEXT_PUBLIC_SITE_DESCRIPTION: "Build AI compute infrastructure on Hanzo Network — a Lux L2 for LLM inference and agent frameworks."
NEXT_PUBLIC_NETWORK_NAME: "Hanzo"
NEXT_PUBLIC_NETWORK_SHORT_NAME: "AI"
NEXT_PUBLIC_CHAIN_ID: "36963"
NEXT_PUBLIC_EXPLORER_URL: "https://explore-hanzo.lux.network"
NEXT_PUBLIC_FAUCET_URL: "https://faucet.hanzo.ai"
NEXT_PUBLIC_DOCS_URL: "https://docs.hanzo.ai"
NEXT_PUBLIC_TWITTER_URL: "https://twitter.com/hanaboratory"
NEXT_PUBLIC_DISCORD_URL: "https://discord.gg/hanzoai"
NEXT_PUBLIC_GITHUB_URL: "https://github.com/hanzo-ai"
NEXT_PUBLIC_SITE_LOGO: "/hanzo-logo.png"
NEXT_PUBLIC_SITE_OG_IMAGE: "/hanzo-logo.png"
---
apiVersion: v1
kind: ConfigMap
metadata:
name: build-brand-pars
namespace: lux-explorer
data:
NEXT_PUBLIC_SITE_NAME: "Pars Build"
NEXT_PUBLIC_SITE_URL: "https://build.pars.network"
NEXT_PUBLIC_SITE_DESCRIPTION: "Build applications on Pars Network — a Lux L2 for general purpose EVM smart contracts."
NEXT_PUBLIC_NETWORK_NAME: "Pars"
NEXT_PUBLIC_NETWORK_SHORT_NAME: "PARS"
NEXT_PUBLIC_CHAIN_ID: "494949"
NEXT_PUBLIC_EXPLORER_URL: "https://explore-pars.lux.network"
NEXT_PUBLIC_FAUCET_URL: "https://faucet.pars.network"
NEXT_PUBLIC_DOCS_URL: "https://docs.pars.network"
NEXT_PUBLIC_TWITTER_URL: ""
NEXT_PUBLIC_DISCORD_URL: ""
NEXT_PUBLIC_GITHUB_URL: "https://github.com/pars"
NEXT_PUBLIC_SITE_LOGO: "/pars-logo.png"
NEXT_PUBLIC_SITE_OG_IMAGE: "/pars-logo.png"
---
apiVersion: v1
kind: ConfigMap
metadata:
name: build-brand-spc
namespace: lux-explorer
data:
NEXT_PUBLIC_SITE_NAME: "SPC Build"
NEXT_PUBLIC_SITE_URL: "https://build.sparklepony.club"
NEXT_PUBLIC_SITE_DESCRIPTION: "Build on SPC Network — a Lux L2."
NEXT_PUBLIC_NETWORK_NAME: "SPC"
NEXT_PUBLIC_NETWORK_SHORT_NAME: "SPC"
NEXT_PUBLIC_CHAIN_ID: "36911"
NEXT_PUBLIC_EXPLORER_URL: "https://explore-spc.lux.network"
NEXT_PUBLIC_FAUCET_URL: ""
NEXT_PUBLIC_DOCS_URL: ""
NEXT_PUBLIC_TWITTER_URL: ""
NEXT_PUBLIC_DISCORD_URL: ""
NEXT_PUBLIC_GITHUB_URL: ""
NEXT_PUBLIC_SITE_LOGO: "/spc-logo.png"
NEXT_PUBLIC_SITE_OG_IMAGE: "/spc-logo.png"
---
# ============================================================================
# Deployments — one per brand, same image, different ConfigMap
# ============================================================================
apiVersion: apps/v1
kind: Deployment
metadata:
name: build-zoo
namespace: lux-explorer
labels:
app: lux-build
brand: zoo
spec:
replicas: 1
selector:
matchLabels:
app: lux-build
brand: zoo
template:
metadata:
labels:
app: lux-build
brand: zoo
spec:
imagePullSecrets:
- name: ghcr-luxfi
containers:
- name: web
image: ghcr.io/hanzoai/lux-build:0.1.0
imagePullPolicy: Always
ports:
- name: http
containerPort: 3000
envFrom:
- configMapRef:
name: build-brand-zoo
env:
- name: NODE_ENV
value: "production"
resources:
requests:
cpu: "100m"
memory: "256Mi"
limits:
cpu: "500m"
memory: "512Mi"
livenessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 10
periodSeconds: 15
readinessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 5
periodSeconds: 5
securityContext:
runAsNonRoot: true
runAsUser: 1001
allowPrivilegeEscalation: false
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: build-hanzo
namespace: lux-explorer
labels:
app: lux-build
brand: hanzo
spec:
replicas: 1
selector:
matchLabels:
app: lux-build
brand: hanzo
template:
metadata:
labels:
app: lux-build
brand: hanzo
spec:
imagePullSecrets:
- name: ghcr-luxfi
containers:
- name: web
image: ghcr.io/hanzoai/lux-build:0.1.0
imagePullPolicy: Always
ports:
- name: http
containerPort: 3000
envFrom:
- configMapRef:
name: build-brand-hanzo
env:
- name: NODE_ENV
value: "production"
resources:
requests:
cpu: "100m"
memory: "256Mi"
limits:
cpu: "500m"
memory: "512Mi"
livenessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 10
periodSeconds: 15
readinessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 5
periodSeconds: 5
securityContext:
runAsNonRoot: true
runAsUser: 1001
allowPrivilegeEscalation: false
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: build-pars
namespace: lux-explorer
labels:
app: lux-build
brand: pars
spec:
replicas: 1
selector:
matchLabels:
app: lux-build
brand: pars
template:
metadata:
labels:
app: lux-build
brand: pars
spec:
imagePullSecrets:
- name: ghcr-luxfi
containers:
- name: web
image: ghcr.io/hanzoai/lux-build:0.1.0
imagePullPolicy: Always
ports:
- name: http
containerPort: 3000
envFrom:
- configMapRef:
name: build-brand-pars
env:
- name: NODE_ENV
value: "production"
resources:
requests:
cpu: "100m"
memory: "256Mi"
limits:
cpu: "500m"
memory: "512Mi"
livenessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 10
periodSeconds: 15
readinessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 5
periodSeconds: 5
securityContext:
runAsNonRoot: true
runAsUser: 1001
allowPrivilegeEscalation: false
---
# ============================================================================
# Services — one per brand
# ============================================================================
apiVersion: v1
kind: Service
metadata:
name: build-zoo
namespace: lux-explorer
spec:
type: ClusterIP
ports:
- name: http
port: 80
targetPort: http
selector:
app: lux-build
brand: zoo
---
apiVersion: v1
kind: Service
metadata:
name: build-hanzo
namespace: lux-explorer
spec:
type: ClusterIP
ports:
- name: http
port: 80
targetPort: http
selector:
app: lux-build
brand: hanzo
---
apiVersion: v1
kind: Service
metadata:
name: build-pars
namespace: lux-explorer
spec:
type: ClusterIP
ports:
- name: http
port: 80
targetPort: http
selector:
app: lux-build
brand: pars
---
# ============================================================================
# IngressRoutes — hostname-based routing
# ============================================================================
apiVersion: hanzo.ai/v1alpha1
kind: IngressRoute
metadata:
name: build-zoo
namespace: lux-explorer
spec:
entryPoints:
- websecure
routes:
- match: Host(`build.zoo.network`) || Host(`build.zoo.ngo`)
kind: Rule
services:
- name: build-zoo
port: 80
tls:
certResolver: letsencrypt
---
apiVersion: hanzo.ai/v1alpha1
kind: IngressRoute
metadata:
name: build-hanzo
namespace: lux-explorer
spec:
entryPoints:
- websecure
routes:
- match: Host(`build.hanzo.ai`) || Host(`build.hanzo.network`)
kind: Rule
services:
- name: build-hanzo
port: 80
tls:
certResolver: letsencrypt
---
apiVersion: hanzo.ai/v1alpha1
kind: IngressRoute
metadata:
name: build-pars
namespace: lux-explorer
spec:
entryPoints:
- websecure
routes:
- match: Host(`build.pars.network`)
kind: Rule
services:
- name: build-pars
port: 80
tls:
certResolver: letsencrypt