Skip to main content
Version: Next

Running Juno on Kubernetes

You can deploy Juno on Kubernetes using the official Helm chart. The chart deploys a Juno Starknet full node as a StatefulSet with persistent storage. Optionally, a staking validator service can be enabled alongside.

Prerequisites

  • A running Kubernetes cluster (v1.23+)
  • Helm v3 installed
  • kubectl configured for your cluster
  • An Ethereum node WebSocket endpoint (or use --disable-l1-verification for testing)

1. Add the Helm repository

helm repo add nethermind https://nethermindeth.github.io/helm-charts
helm repo update

2. Install the chart

helm install my-juno nethermind/juno

This installs the chart with the default configuration (Sepolia network). However, Juno requires either an Ethereum node endpoint or --disable-l1-verification to start successfully, which you configure via juno.extraArgs. The recommended way is to create a values.yaml file:

values.yaml
juno:
network: mainnet
image:
tag: "v0.15.19"
extraArgs:
- --eth-node=wss://mainnet.infura.io/ws/v3/<YOUR-PROJECT-ID>
persistence:
size: 1Ti
storageClassName: "your-storage-class"
resources:
requests:
cpu: "4"
memory: "8Gi"
limits:
cpu: "8"
memory: "16Gi"

Then install with your values:

helm install my-juno nethermind/juno -f values.yaml
caution

You must provide either --eth-node <WS endpoint> or --disable-l1-verification in juno.extraArgs. Without one of these, Juno will fail to start.

tip

You can use a snapshot to quickly synchronise your node with the network. Check out the Database Snapshots guide to get started. Use an init container to download the snapshot before Juno starts:

juno:
initContainers:
- name: download-snapshot
image: alpine:latest
command: ["sh", "-c", "wget -O- <SNAPSHOT_URL> | tar xf - -C /data"]
volumeMounts:
- name: data-juno
mountPath: /data

3. Verify the deployment

# Check pod status
kubectl get pods -l app.kubernetes.io/name=juno

# View logs
kubectl logs -f statefulset/my-juno-juno

# Test the RPC endpoint
kubectl port-forward svc/my-juno-juno 6060:6060
curl -s http://localhost:6060 \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"juno_version","params":[],"id":1}'

Configuration

Network selection

Set juno.network to one of: mainnet, sepolia, or sepolia-integration.

Ports

The chart exposes the following ports by default:

PortServiceDescription
6060RPCHTTP JSON-RPC endpoint
6061WSWebSocket endpoint
8080MetricsPrometheus metrics

Extra arguments

Pass additional CLI flags to Juno using juno.extraArgs:

juno:
extraArgs:
- --rpc-cors-enable
- --ws
- --ws-port=6061
- --readiness-block-tolerance=10

See the Configuring Juno guide for the full list of options.

Persistent storage

The chart creates a PersistentVolumeClaim for Juno's data directory. Configure the storage size and class:

juno:
persistence:
size: 1Ti
storageClassName: "gp3"
accessModes:
- ReadWriteOnce

Exposing the RPC endpoint

Ingress

Enable an Ingress resource to expose Juno externally. Each path defaults to the RPC port (6060). Set servicePort to route to a different port (e.g., 6061 for WebSocket):

ingress:
enabled: true
className: "nginx"
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
hosts:
- host: rpc.example.com
paths:
- path: /
pathType: Prefix
- host: ws.example.com
paths:
- path: /
pathType: Prefix
servicePort: 6061
tls:
- secretName: juno-tls
hosts:
- rpc.example.com
- ws.example.com

Gateway API (HTTPRoute)

If your cluster uses the Gateway API instead of Ingress:

httpRoute:
enabled: true
parentRefs:
- name: gateway
sectionName: http
hostnames:
- rpc.example.com
rules:
- matches:
- path:
type: PathPrefix
value: /

Enabling the staking service

The chart can deploy a staking validator alongside Juno. The staking service automatically connects to the Juno node via internal service DNS.

First, create a Kubernetes secret with your staking configuration:

kubectl create secret generic staking-config \
--from-file=config.json=path/to/your/config.json

Then enable the staking service:

staking:
enabled: true
config:
existingSecret: "staking-config"
resources:
requests:
cpu: "1"
memory: "4Gi"

Using inline config (dev/test only)

For development and testing, you can provide the config inline:

staking:
enabled: true
config:
data:
signer:
privateKey: "0x..."
operationalAddress: "0x..."
warning

Do not use inline config with private keys in production. Use existingSecret instead.

Monitoring

ServiceMonitor

If you have the Prometheus Operator installed, enable the ServiceMonitor to automatically scrape metrics from both Juno and the staking service:

serviceMonitor:
enabled: true
interval: "30s"
labels:
release: prometheus

The ServiceMonitor targets the metrics port on each enabled service at /metrics. For more details on monitoring, see the Monitoring Juno guide.

Upgrading

helm repo update
helm upgrade my-juno nethermind/juno -f values.yaml

Uninstalling

helm uninstall my-juno
caution

Uninstalling the chart does not delete the PersistentVolumeClaim. To fully remove the data, delete the PVC manually:

kubectl delete pvc -l app.kubernetes.io/name=juno,app.kubernetes.io/instance=my-juno
tip

For the full list of configurable values, see the chart README or run:

helm show values nethermind/juno