When a server goes down, an agent is the first to know
zyris-docker is a Zyris node that runs inside a container and connects it — and the Docker and Kubernetes infrastructure around it — to Attacca. It reads state, edits files and runs commands, and when something it watches goes down, it opens an agent session to diagnose and fix it.
Built for a containerised host rather than a machine with a display. To connect a desktop computer, use the Zyris desktop app.
services:
zyris-docker:
image: ghcr.io/attacca-cc/zyris-docker:latest
restart: on-failure:3
environment:
- ZYRIS_NODE_TOKEN_FILE=/run/secrets/zyris_token
- ZYRISD_WATCH_CONTAINERS=web,db
- ZYRISD_WATCH_PROCESSES=nginx
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./secrets/zyris_token:/run/secrets/zyris_token:ro
- ./data:/dataWhat it does
Monitoring
System snapshots, the process list, Docker container state and logs, and Kubernetes pod and node state — all through the monitor capability.
A self-healing loop
It samples the processes, containers and cluster you name, and when one is down it opens an agent session with the incident. It never blindly restarts things; the agent makes the call.
Fenced to its roots
File access and command execution stay inside the roots you configure, and every exec has a timeout and an output cap.
Tokens from a Secret
Mount a Kubernetes Secret or a docker secret through ZYRIS_NODE_TOKEN_FILE. It is re-read on every reconnect, so rotating the Secret needs no restart.
Docker and Kubernetes
Mount docker.sock to see Docker; give it a kubeconfig or an in-cluster service account to see Kubernetes.
Exit codes that mean something
Exit code 2 means a person has to act. Wire it into your restart policy so a node that needs a human does not loop forever, printing enrolment codes into a log nobody reads.
Deploy
Enrol once to get a znt_ node token, then mount it into the container as a file. Started without one, the node prints an eight-character enrolment code into the container log — in that case give ZYRIS_CONFIG_DIR a named volume, or every restart enrols again.
docker run --rm \
-e ZYRIS_NODE_TOKEN_FILE=/run/secrets/zyris_token \
-e ZYRISD_WATCH_CONTAINERS=web,db \
-v /var/run/docker.sock:/var/run/docker.sock \
-v "$PWD/secrets/zyris_token:/run/secrets/zyris_token:ro" \
ghcr.io/attacca-cc/zyris-docker:latestKubernetes
Set ZYRISD_WATCH_K8S=1 and mount a kubeconfig, or rely on an in-cluster service account. Mount the token from a Secret and point ZYRIS_NODE_TOKEN_FILE at it — and since a pod's hostname changes when it is recreated, give ZYRIS_NODE_NAME a stable value.
env:
- name: ZYRIS_NODE_NAME
value: prod-cluster
- name: ZYRIS_NODE_TOKEN_FILE
value: /run/secrets/zyris_token
- name: ZYRISD_WATCH_K8S
value: "1"Binary and source
git clone https://github.com/attacca-cc/zyris-docker.gitcd zyris-docker && cargo build --releaseRecovery stays with an agent that has judgement
zyris-docker does not restart a stopped service on its own. An agent uses this node's monitor and exec tools to find out why, does what is needed, and reports back. The image runs as the unprivileged zyris user, and files and commands stay inside the roots you set.