Deploy with a Node.js backend
Node.js services — Express, Fastify, NestJS, or anything on the Node runtime —
pair with the sidecar as a separate process or container. There’s no npm
package to install and nothing to require(): your application code and
package.json don’t change.
This guide assumes you have a
config bundle or a hand-written
sidecar.yaml + token.
Docker Compose
Section titled “Docker Compose”services: app: image: acme/acme-api:latest # your Node image ports: - "3000:3000" environment: NODE_ENV: production
ringzero-sidecar: image: ghcr.io/ringzero/sidecar:1 restart: unless-stopped ports: - "7301:7301" # challenge listener — reachable at every (re)registration volumes: - ./ringzero-sidecar-config:/etc/ringzero:roKubernetes
Section titled “Kubernetes”The per-pod sidecar (when each pod has its own reachable address):
apiVersion: apps/v1kind: Deploymentmetadata: name: acme-apispec: replicas: 1 selector: matchLabels: { app: acme-api } template: metadata: labels: { app: acme-api } spec: initContainers: - name: ringzero-sidecar image: ghcr.io/ringzero/sidecar:1 restartPolicy: Always # native sidecar (K8s 1.29+) ports: - containerPort: 7301 volumeMounts: - name: ringzero-config mountPath: /etc/ringzero readOnly: true resources: requests: { cpu: 10m, memory: 16Mi } limits: { memory: 64Mi } containers: - name: app image: acme/acme-api:latest ports: - containerPort: 3000 volumes: - name: ringzero-config secret: secretName: ringzero-sidecar# identical, but the sidecar goes under `containers` instead of# `initContainers` (drop restartPolicy).containers: - name: app image: acme/acme-api:latest - name: ringzero-sidecar image: ghcr.io/ringzero/sidecar:1 ports: - containerPort: 7301 volumeMounts: - name: ringzero-config mountPath: /etc/ringzero readOnly: trueCreate the ringzero-sidecar Secret from your bundle as shown in
Automated setup.
VMs with PM2 or systemd
Section titled “VMs with PM2 or systemd”If your Node app runs under PM2 on a VM, run the sidecar as a system service rather than a PM2 app — PM2 restarts and deploys shouldn’t cycle your host registration. Install the binary and use the systemd unit (it’s stack-independent):
pm2 start dist/server.js --name acme-api # your app, as usualsudo systemctl enable --now ringzero-sidecar # the sidecar, as a system unitOne sidecar per host covers every Node process on it, cluster-mode workers included.
Verify
Section titled “Verify”Sidecar logs show host registered; Settings → Hosts lists the host as
active (see the host lifecycle);
the health probe reports
"registered": true. Troubleshooting:
manual setup.