The two mains shared no history, so this is a per-file three-way merge:
for each file the 65 forge-only commits touched (by patch-id), the base is
the newest version both histories held. 105 files merged or took one side
cleanly, 48 were already identical, and the 45 true conflicts and 31
modify/delete pairs were resolved by what runs on the cluster:
- The forge wins where it is live: explorer 1.5.56 (digest 45db11ff) and
its archive readers, explore-fe-hanzo's ConfigMap env (AI coin,
/v1/indexer/hanzo, /v1/chain/hanzo/rpc), exchange-api reading
luxd-archive, and explore-fe-{lux,zoo}-testnet, pinned to what they run
(v2.8.5-lux / v2.8.4-lux).
- GitHub wins where it is live: explore-fe-lux v2.8.5-lux, explore-fe-zoo
v2.8.4-lux, bankd v1.0.18, lux-build's routes.
- The forge's retirement of workloads that run nowhere stands: lux-mainnet
dex, lux-hb2, lux-market, traffic, wallet-web; the lux-testnet frontends,
indexer, exchange and gateways; lux-operator. deploy/lux-testnet/luxd.yaml
stays, since roll_luxd.sh reads it.
- GitHub's deletions stand: lux-finance and lux-financial (static sites
now), the k8s/ operator manifests, .hanzo/workflows/cicd.yml.
- Paths are /v1/chain/C/rpc where the forge had written /v1/chain/c. All
four spellings answer; this one is the documented form. The forge's
/{network}/v1 doc lines are dropped: a network is a host, and the prefix
404s.
Dry-run against the running objects (server-side, as CD applies), the
merged explorer shows no change where GitHub's showed 152 lines, and no
other live workload moves further from what runs. Every deploy/*/*.yaml
renders with charts/app; price.yaml, which failed on GitHub, now renders.
Claude-Session: https://claude.ai/code/session_01TzirYkGmD88w4GipqivUtV
257 lines
7.4 KiB
YAML
257 lines
7.4 KiB
YAML
# Generated from the live explorer Deployment on lux-k8s by
|
|
# hack/live2values.py. Live is the source: a repo of hand-applied manifests has
|
|
# unknown currency, the running fleet does not.
|
|
#
|
|
# ⚠️ The ports/service block below is deliberate and load-bearing. This workload
|
|
# needs THREE service ports over TWO container ports, with the container port
|
|
# named differently from every service port:
|
|
#
|
|
# live Service http:80->8090, http-v2:8090->8090, ui:3000->3000
|
|
# live containers explorer[api:8090], explore[ui:3000]
|
|
#
|
|
# One `ports[]` entry cannot express that — it yields ONE container port and ONE
|
|
# service port from a single name. Two primitives were added to charts/app for
|
|
# exactly this shape:
|
|
#
|
|
# ports[].expose: false keeps `api` on the POD, where all three probes
|
|
# below reference it by name, and OFF the Service
|
|
# service.extraPorts Service ports with no container behind them
|
|
#
|
|
# Until 2026-07-31 this file declared a single entry named `http-v2`, and a sync
|
|
# would have broken the Application two ways:
|
|
#
|
|
# 1. The Service collapses to [80]. About 55 IngressRoutes and Ingresses
|
|
# across lux-devnet/mainnet/testnet target explorer:8090 BY NUMBER — every
|
|
# api-explore.* host and most explore.* hosts, across lux.network,
|
|
# hanzo.ai, hanzo.network, pars.network, zoo.network and osage.network —
|
|
# and exchange-api dials explorer.<ns>.svc:8090 for SUBGRAPH_URL. Port 3000
|
|
# (the `explore` UI sidecar) goes with it.
|
|
# 2. The pods stop becoming Ready. The probes say `api`; renaming the
|
|
# container port leaves them pointing at a port that is not declared, and
|
|
# kubelet fails `strconv.Atoi: parsing "api"` — the fault that held
|
|
# mpc-node NotReady for 14h.
|
|
#
|
|
# ⚠️ Requires charts/app >= 0.1.2 — `expose` and `service.extraPorts` are schema
|
|
# errors under the 0.1.0 lux-fleet used to pin. The fleet was repointed on
|
|
# 2026-07-31, so this is now safe to sync.
|
|
replicas: 1
|
|
selectorLabels:
|
|
app: explorer
|
|
network: devnet
|
|
image:
|
|
repository: ghcr.io/luxfi/explorer
|
|
tag: 1.5.10
|
|
# The tag is how a human says it; the digest is what the kubelet obeys. With
|
|
# pullPolicy: IfNotPresent a node that has seen a tag keeps those bytes, and
|
|
# ghcr tags are mutable, so the digest is the only exact identity. 1.3.4 was
|
|
# a floating tag here with no digest at all.
|
|
digest: sha256:a67cf7a88cf8f68c7cff6fb549d81dafb7ed80ab6c9fdb29a27889fe5edf6e28
|
|
pullPolicy: IfNotPresent
|
|
labels:
|
|
network: devnet
|
|
args:
|
|
- --config=/etc/explorer/chains.yaml
|
|
env:
|
|
- name: DATA_DIR
|
|
value: /data
|
|
- name: HTTP_ADDR
|
|
value: :8090
|
|
- name: EXPLORER_STATIC_DIR
|
|
value: /etc/explorer/static
|
|
resources:
|
|
limits:
|
|
cpu: '2'
|
|
memory: 4Gi
|
|
requests:
|
|
cpu: 250m
|
|
memory: 512Mi
|
|
volumeMounts:
|
|
- mountPath: /etc/explorer
|
|
name: config
|
|
readOnly: true
|
|
- mountPath: /etc/explorer/static
|
|
name: static
|
|
readOnly: true
|
|
- mountPath: /data
|
|
name: data
|
|
livenessProbe:
|
|
failureThreshold: 5
|
|
httpGet:
|
|
path: /health
|
|
port: api
|
|
scheme: HTTP
|
|
initialDelaySeconds: 30
|
|
periodSeconds: 30
|
|
successThreshold: 1
|
|
timeoutSeconds: 10
|
|
readinessProbe:
|
|
failureThreshold: 6
|
|
httpGet:
|
|
path: /health
|
|
port: api
|
|
scheme: HTTP
|
|
initialDelaySeconds: 5
|
|
periodSeconds: 10
|
|
successThreshold: 1
|
|
timeoutSeconds: 5
|
|
startupProbe:
|
|
failureThreshold: 30
|
|
httpGet:
|
|
path: /health
|
|
port: api
|
|
scheme: HTTP
|
|
initialDelaySeconds: 5
|
|
periodSeconds: 5
|
|
successThreshold: 1
|
|
timeoutSeconds: 5
|
|
securityContext:
|
|
runAsNonRoot: true
|
|
runAsUser: 65532
|
|
ports:
|
|
- name: api
|
|
containerPort: 8090
|
|
expose: false
|
|
service:
|
|
extraPorts:
|
|
- name: http
|
|
port: 80
|
|
targetPort: 8090
|
|
- name: http-v2
|
|
port: 8090
|
|
targetPort: 8090
|
|
- name: ui
|
|
port: 3000
|
|
targetPort: 3000
|
|
volumes:
|
|
- configMap:
|
|
name: explorer-chains
|
|
name: config
|
|
- configMap:
|
|
name: explorer-static
|
|
name: static
|
|
- name: data
|
|
persistentVolumeClaim:
|
|
claimName: explorer-data
|
|
imagePullSecrets:
|
|
- name: ghcr-luxfi
|
|
sidecars:
|
|
- env:
|
|
- name: PORT
|
|
value: '3000'
|
|
- name: ENVS_PRESET
|
|
value: none
|
|
- name: SKIP_ENVS_VALIDATION
|
|
value: 'true'
|
|
- name: NEXT_TELEMETRY_DISABLED
|
|
value: '1'
|
|
- name: NEXT_PUBLIC_NETWORK_ID
|
|
value: '96370'
|
|
- name: NEXT_PUBLIC_NETWORK_NAME
|
|
value: Lux Devnet
|
|
- name: NEXT_PUBLIC_NETWORK_SHORT_NAME
|
|
value: LUX
|
|
- name: NEXT_PUBLIC_NETWORK_CURRENCY_NAME
|
|
value: LUX
|
|
- name: NEXT_PUBLIC_NETWORK_CURRENCY_SYMBOL
|
|
value: LUX
|
|
- name: NEXT_PUBLIC_NETWORK_CURRENCY_DECIMALS
|
|
value: '18'
|
|
- name: NEXT_PUBLIC_NETWORK_RPC_URL
|
|
value: https://api.lux-dev.network/v1/chain/C/rpc
|
|
- name: NEXT_PUBLIC_NETWORK_LOGO
|
|
value: /logo.svg
|
|
- name: NEXT_PUBLIC_NETWORK_ICON
|
|
value: /icon.svg
|
|
- name: NEXT_PUBLIC_BRAND
|
|
value: lux
|
|
- name: NEXT_PUBLIC_IS_TESTNET
|
|
value: 'true'
|
|
- name: NEXT_PUBLIC_APP_HOST
|
|
value: explore.lux-dev.network
|
|
- name: NEXT_PUBLIC_APP_PROTOCOL
|
|
value: https
|
|
- name: NEXT_PUBLIC_API_HOST
|
|
value: api-explore.lux-dev.network
|
|
- name: NEXT_PUBLIC_API_PROTOCOL
|
|
value: https
|
|
- name: NEXT_PUBLIC_API_BASE_PATH
|
|
value: /v1/indexer/cchain
|
|
- name: NEXT_PUBLIC_API_WEBSOCKET_PROTOCOL
|
|
value: wss
|
|
- name: NEXT_PUBLIC_NETWORK_ORG_NAME
|
|
value: Lux Industries Inc.
|
|
- name: NEXT_PUBLIC_NETWORK_WEBSITE_URL
|
|
value: https://lux.network
|
|
- name: NEXT_PUBLIC_COLOR_THEME_DEFAULT
|
|
value: dark
|
|
- name: NEXT_PUBLIC_ACCOUNT_AUTH_PROVIDER
|
|
value: oidc
|
|
- name: NEXT_PUBLIC_OIDC_SERVER_URL
|
|
value: https://lux.id
|
|
- name: NEXT_PUBLIC_OIDC_CLIENT_ID
|
|
value: lux-explore-client-id
|
|
image: ghcr.io/luxfi/explore@sha256:ddb15bc28ff38c7619bc08df9337e02b32ef886c33b9993a9b9cb3c475ad75de
|
|
imagePullPolicy: IfNotPresent
|
|
livenessProbe:
|
|
failureThreshold: 5
|
|
httpGet:
|
|
path: /
|
|
port: ui
|
|
scheme: HTTP
|
|
initialDelaySeconds: 90
|
|
periodSeconds: 60
|
|
successThreshold: 1
|
|
timeoutSeconds: 10
|
|
name: explore
|
|
ports:
|
|
- containerPort: 3000
|
|
name: ui
|
|
protocol: TCP
|
|
readinessProbe:
|
|
failureThreshold: 6
|
|
httpGet:
|
|
path: /
|
|
port: ui
|
|
scheme: HTTP
|
|
initialDelaySeconds: 30
|
|
periodSeconds: 15
|
|
successThreshold: 1
|
|
timeoutSeconds: 10
|
|
resources:
|
|
limits:
|
|
cpu: '1'
|
|
memory: 2Gi
|
|
requests:
|
|
cpu: 100m
|
|
memory: 256Mi
|
|
startupProbe:
|
|
failureThreshold: 30
|
|
httpGet:
|
|
path: /
|
|
port: ui
|
|
scheme: HTTP
|
|
initialDelaySeconds: 15
|
|
periodSeconds: 10
|
|
successThreshold: 1
|
|
timeoutSeconds: 10
|
|
fsGroup: 65532
|
|
strategy: Recreate
|
|
topologySpread:
|
|
enabled: false
|
|
lifecycle: null
|
|
terminationGracePeriodSeconds: 60
|
|
|
|
# NOT SYNCABLE by this chart, and the reason is precise rather than a mystery.
|
|
# Live Service `explorer` publishes TWO ports over ONE container port:
|
|
# http 80 -> 8090 (browser, via the explore.* Ingresses)
|
|
# http-v2 8090 -> 8090 (dialed in-cluster as
|
|
# explorer.<ns>.svc:8090/v1/graph/... by exchange-api
|
|
# on mainnet, testnet AND devnet — the DEX subgraph)
|
|
# ui 3000 -> 3000
|
|
# A values `ports` entry is one container port AND one Service port with one
|
|
# shared name, so two Service ports over one container port cannot be expressed;
|
|
# declaring only `http` prunes port 8090 and takes the DEX subgraph down in three
|
|
# namespaces. Syncing this needs the chart to accept an explicit extra Service
|
|
# port, not a values edit. Left OutOfSync deliberately — a report is honest, a
|
|
# guess here is an outage.
|