EnderDashEnderDash
How-To Guides

Install an Agent

Install or reinstall the correct EnderDash agent for a server, proxy, or standalone host.

Use this guide when

Use this page when you need to:

  • install EnderDash on a new runtime
  • reinstall after rotating an agent key
  • move a server record to a different runtime

Just trying EnderDash first?

Use demo mode to see the product structure and explore the interface before you install anything. Demo mode is fully mocked, so it is useful for evaluation, not for real setup.

Before you begin

You need:

  • an active subscription on the organization
  • a server record in Servers
  • owner or admin access, because Downloads and agent-key management are admin-only

Pick the correct download

Open Downloads, select the server record, and choose the build that matches the runtime:

RuntimeDownload
Bukkit, Spigot, Paper, Purpur, FoliaEnderDash-Bukkit.jar
VelocityEnderDash-Velocity.jar
BungeeCord, WaterfallEnderDash-Bungeecord.jar
HytaleEnderDash-Hytale.jar
Standalone hostEnderDash-Standalone.jar or the standalone artifact shown in Downloads
Docker or Podman hostghcr.io/enderdash-com/enderdash-agent:latest
Kubernetes clusterghcr.io/enderdash-com/enderdash-agent:latest

Do not reuse a Bukkit build on a proxy or a standalone host. The runtime must match the artifact.

Container platform support

EnderDash supports common operational workflows for Docker-compatible hosts and Kubernetes clusters. It is not a replacement for every native platform tool.

PlatformFirst-class supportCompatibility scope
DockerContainers, logs, stats, exec, images, volumes, networks, daemon details, events, Compose-labeled containers, Compose project actions, Swarm services, Swarm nodes, Swarm tasks, and Minecraft server presets.Compose projects are discovered from Docker Compose labels. When the Compose CLI is available on the agent host, EnderDash can run up, down, build, pull, and config for discovered projects.
PodmanContainers, logs, stats, exec, images, volumes, networks, and Minecraft server presets through the Docker-compatible Podman API socket.This is compatibility support through the Podman API socket, not native Podman project management. Podman pods, Quadlet lifecycle management, Buildah flows, and podman kube workflows stay outside EnderDash. Rootless sockets only expose that user's containers.
KubernetesCluster info, pods, deployments, services, nodes, events, logs, diagnostics, exec, port-forward, debug containers, StatefulSets, DaemonSets, ReplicaSets, Jobs, CronJobs, Ingresses, PVCs, PVs, HPAs, ConfigMaps, Secrets, namespaces, ServiceAccounts, RBAC resources, NetworkPolicies, StorageClasses, custom resources, CRD discovery, rollout status, resource metrics, YAML dry-run, YAML diff, YAML apply, YAML delete, and Minecraft server presets.EnderDash supports common operational workflows, not the whole Kubernetes API surface. YAML diff requires kubectl on the agent host. Resource metrics require the Kubernetes metrics API, usually metrics-server. Helm release management is not implemented as a native panel.

For Kubernetes custom resources, use the CRD browser or enter the API group, version, and plural resource name in the dashboard. The agent uses those values to list and inspect matching objects, but your cluster RBAC must already grant get and list for that API group and resource plural.

For a detailed feature and RBAC reference, see Container Platforms.

Install the runtime package

Plugin and proxy runtimes

  1. Drop the downloaded jar into the runtime's plugins/ directory.
  2. Restart the runtime so it loads the plugin and exposes the enderdash console command. Without this restart the command does not exist yet.
  3. Run enderdash install <agentKey> in the console. The agent connects immediately, no second restart needed.

Standalone runtimes

  1. Place the standalone artifact in the directory where it will run.
  2. Save the agent key in ~/.enderdash/config.yml.
  3. Start the standalone runtime.

Docker hosts

Run the standalone agent image and mount the Docker socket only on hosts where EnderDash should inspect or manage local containers:

docker run -d --name enderdash-agent \
  --restart unless-stopped \
  --group-add "$(stat -c '%g' /var/run/docker.sock)" \
  -e ENDERDASH_AGENT_KEY='<agentKey>' \
  -v enderdash-agent-data:/enderdash/data \
  -v /var/run/docker.sock:/var/run/docker.sock \
  ghcr.io/enderdash-com/enderdash-agent:latest

The socket mount gives the agent broad control over the local Docker daemon. Use a dedicated host or a tightly controlled server record when you enable container management.

The --group-add flag gives the image's non-root enderdash user access to the mounted Docker socket. If your host uses a nonstandard socket path, pass the group id for that socket instead.

You can also start the same setup with the checked-in Compose file:

export ENDERDASH_AGENT_KEY='<agentKey>'
export DOCKER_SOCKET_GID="$(stat -c '%g' /var/run/docker.sock)"
docker compose -f deploy/agent/compose.yaml up -d

After the agent is connected, the Containers panel can create Minecraft server presets on the same Docker or Podman host. The preset uses itzg/minecraft-server, creates a persistent /data volume, publishes the Minecraft port, installs the EnderDash Modrinth plugin through MODRINTH_PROJECTS, and writes plugins/EnderDash/config.yml with the agent key you provide.

The same preset flow can target Docker Swarm. EnderDash creates a Swarm service with the Minecraft server image, published ports, persistent data volume, and EnderDash labels so the service is visible in Swarm inventory.

Podman hosts

Start the Podman API service first, then run the same agent image against the Podman socket:

systemctl --user enable --now podman.socket

podman run -d --name enderdash-agent \
  --replace \
  --restart unless-stopped \
  --group-add keep-groups \
  -e ENDERDASH_AGENT_KEY='<agentKey>' \
  -v enderdash-agent-data:/enderdash/data \
  -v "${XDG_RUNTIME_DIR}/podman/podman.sock:/run/podman/podman.sock" \
  -e DOCKER_HOST=unix:///run/podman/podman.sock \
  ghcr.io/enderdash-com/enderdash-agent:latest

Rootless Podman exposes only the containers owned by that user. --group-add keep-groups keeps the user's supplementary groups available to the container process so the mounted socket can be opened. Use a rootful socket only when the server record is allowed to manage system containers.

For a systemd-managed rootless Podman install, copy the files from deploy/agent/quadlet/ into ~/.config/containers/systemd/, set ENDERDASH_AGENT_KEY in the user service environment, then reload systemd:

systemctl --user daemon-reload
systemctl --user enable --now enderdash-agent.service

Kubernetes clusters

Create a secret for the agent key, bind read permissions for the resources EnderDash should display, and run the standalone agent image in the cluster:

apiVersion: v1
kind: Namespace
metadata:
  name: enderdash
---
apiVersion: v1
kind: Secret
metadata:
  name: enderdash-agent
  namespace: enderdash
type: Opaque
stringData:
  agentKey: "<agentKey>"
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: enderdash-agent
  namespace: enderdash
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: enderdash-agent-read
rules:
  - apiGroups: [""]
    resources: ["pods", "pods/log", "services", "nodes", "events", "configmaps", "secrets", "persistentvolumeclaims", "persistentvolumes", "namespaces", "serviceaccounts"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["pods/exec", "pods/portforward"]
    verbs: ["create"]
  - apiGroups: [""]
    resources: ["pods/ephemeralcontainers"]
    verbs: ["get", "patch", "update"]
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["delete"]
  - apiGroups: [""]
    resources: ["nodes"]
    verbs: ["get", "patch", "update"]
  - apiGroups: [""]
    resources: ["configmaps", "services", "secrets", "persistentvolumeclaims"]
    verbs: ["get", "list", "watch", "create", "delete", "patch", "update"]
  - apiGroups: ["apps"]
    resources: ["deployments", "replicasets", "statefulsets", "daemonsets"]
    verbs: ["get", "list", "watch"]
  - apiGroups: ["apps"]
    resources: ["deployments", "statefulsets", "daemonsets"]
    verbs: ["get", "list", "watch", "create", "delete", "patch", "update"]
  - apiGroups: ["batch"]
    resources: ["jobs", "cronjobs"]
    verbs: ["get", "list", "watch", "create", "delete", "patch", "update"]
  - apiGroups: ["networking.k8s.io"]
    resources: ["ingresses", "networkpolicies"]
    verbs: ["get", "list", "watch"]
  - apiGroups: ["autoscaling"]
    resources: ["horizontalpodautoscalers"]
    verbs: ["get", "list", "watch"]
  - apiGroups: ["rbac.authorization.k8s.io"]
    resources: ["roles", "rolebindings", "clusterroles", "clusterrolebindings"]
    verbs: ["get", "list", "watch"]
  - apiGroups: ["storage.k8s.io"]
    resources: ["storageclasses"]
    verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: enderdash-agent-read
subjects:
  - kind: ServiceAccount
    name: enderdash-agent
    namespace: enderdash
roleRef:
  kind: ClusterRole
  name: enderdash-agent-read
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: enderdash-agent
  namespace: enderdash
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: enderdash-agent
  template:
    metadata:
      labels:
        app.kubernetes.io/name: enderdash-agent
    spec:
      serviceAccountName: enderdash-agent
      securityContext:
        runAsNonRoot: true
        runAsUser: 1001
        runAsGroup: 1001
        fsGroup: 1001
        seccompProfile:
          type: RuntimeDefault
      containers:
        - name: agent
          image: ghcr.io/enderdash-com/enderdash-agent:latest
          imagePullPolicy: Always
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop:
                - ALL
          env:
            - name: ENDERDASH_AGENT_KEY
              valueFrom:
                secretKeyRef:
                  name: enderdash-agent
                  key: agentKey
          resources:
            requests:
              cpu: 100m
              memory: 256Mi
            limits:
              memory: 512Mi
          volumeMounts:
            - name: data
              mountPath: /enderdash/data
      volumes:
        - name: data
          emptyDir:
            sizeLimit: 1Gi

Apply the manifest after narrowing the RBAC rules if the agent should only see or modify specific namespaces. Write verbs are only needed for operator actions such as pod exec, port-forward, debug containers, workload restart or scale, CronJob actions, YAML apply or delete, selected deletes, node cordon or uncordon, and Kubernetes Minecraft presets. Keep the security context and resource requests unless your cluster policy requires different values.

For reusable Kubernetes installs, use the manifests in deploy/agent/:

kubectl create namespace enderdash
kubectl -n enderdash create secret generic enderdash-agent \
  --from-literal=agentKey='<agentKey>'

# Read-only inventory, logs, diagnostics, and resource views.
kubectl apply -k deploy/agent/kustomize/base

# Operator mode adds exec, port-forward, debug containers, restarts, scale, delete, and cron job actions.
kubectl apply -k deploy/agent/kustomize/operator

The Helm chart in deploy/agent/helm provides the same two RBAC modes:

helm upgrade --install enderdash-agent deploy/agent/helm \
  --namespace enderdash \
  --create-namespace \
  --set agentKeySecret.name=enderdash-agent \
  --set agentKeySecret.key=agentKey \
  --set rbac.mode=readonly

Use rbac.mode=operator only for clusters where EnderDash should run Kubernetes mutations such as rollout restarts, StatefulSet scaling, CronJob suspension, pod debug containers, pod exec, port-forward sessions, and YAML apply or delete actions.

Operator mode also enables Minecraft server presets for Kubernetes. A preset creates a Secret for the EnderDash plugin config, a PVC for /data, a Service for the Minecraft port, and a StatefulSet running itzg/minecraft-server with the EnderDash Modrinth plugin enabled.

The chart exposes production knobs for image pull secrets, pod labels and annotations, pod and container security contexts, resource requests and limits, persistence, node selectors, tolerations, and affinity. Enable persistence.enabled=true when the standalone agent needs state to survive pod replacement instead of using the default emptyDir volume.

Reinstall after a key rotation

If Downloads shows a fresh agent key, the previous key is no longer valid for that server record.

  • On runtimes with the command surface, run enderdash install <agentKey> again.
  • On standalone or manual setups, replace the old agentKey value in the config file and restart.

Manual fallback

If the runtime does not expose the enderdash console command, set the key manually in the local config:

agentKey: "<agentKey>"
signalingUrl: "wss://signaling.enderdash.com/ws"

Use signalingUrl only if you need to override the default signaling host.

Verify the result

The install is complete when:

  • the server shows Online
  • the server page opens without setup prompts
  • live panels begin loading data

If the runtime starts but EnderDash still shows the server as offline, continue with Recover an Offline Server.

Was this page helpful?

Send a quick note if anything is missing or unclear.

Last updated on

On this page