OC
OpenClaw
Dashboard

openclaw-dashboard-deploy.md

/home/ubuntu/.openclaw/workspace/docs/openclaw-dashboard-deploy.md

openclaw-dashboard — current deploy/runtime setup

Last updated: 2026-04-14 (UTC)

Goal

Run the OpenClaw Dashboard (Next.js) on the EC2 host without building on the server (builds were timing out, eating RAM/swap, and sometimes hitting disk pressure).

How it detects changes (trigger) + restarts

There is no change detection on the EC2 host anymore.

  • A push to main on GitHub triggers GitHub Actions.
  • The workflow SSHes into EC2, deploys the new tarball, then runs:
    • sudo systemctl restart openclaw-dashboard.service
  • systemd starts whatever code the /opt/openclaw-dashboard/current symlink points to.

High-level design

  • CI builds the app on every push to main (GitHub Actions)
  • CI packages a Next.js “standalone” artifact (.next/standalone + static + public) into a tarball
  • CI copies the tarball to EC2, unpacks into a versioned release dir, and flips a symlink
  • systemd runs the standalone server via node server.js

Repos / paths

  • Repo: /home/ubuntu/projects/openclaw-dashboard
  • Deployed runtime root: /opt/openclaw-dashboard
    • Releases: /opt/openclaw-dashboard/releases/<git-sha>/
    • Current symlink: /opt/openclaw-dashboard/current/opt/openclaw-dashboard/releases/<git-sha>

Runtime service (systemd)

Unit: /etc/systemd/system/openclaw-dashboard.service

  • Runs as user: ubuntu
  • WorkingDirectory: /opt/openclaw-dashboard/current
  • Listens on: 127.0.0.1:3579
  • Start command:
    • node /opt/openclaw-dashboard/current/server.js

Check status/logs:

sudo systemctl status openclaw-dashboard.service
sudo journalctl -u openclaw-dashboard.service -n 200 --no-pager
ss -ltnp | grep ':3579'

Build packaging

next.config.ts:

  • output: "standalone"

Packaging script:

  • scripts/package-standalone.sh
  • Produces: dist/openclaw-dashboard-standalone.tgz (local only; ignored by git)

The tarball includes:

  • .next/standalone/** (contains server.js + minimal node_modules)
  • .next/static/**
  • public/**

CI deploy (GitHub Actions)

Workflow:

  • .github/workflows/deploy-ec2.yml
  • Trigger: push to main

Secrets required in the GitHub repo:

  • EC2_HOST — EC2 hostname/IP
  • EC2_USERubuntu
  • EC2_SSH_KEY — private key allowed to SSH into the EC2 host as ubuntu

Deploy steps (on EC2):

  1. Upload artifact to /tmp/openclaw-dashboard-standalone-<sha>.tgz
  2. Untar to /opt/openclaw-dashboard/releases/<sha>/
  3. Update symlink /opt/openclaw-dashboard/current
  4. sudo systemctl restart openclaw-dashboard.service

Runtime GitHub token (optional)

If the dashboard needs to call the GitHub API at runtime, provide a token via a root-owned env file (avoid baking secrets into the unit file or the repo).

  1. Create /etc/openclaw-dashboard.env:
sudo sh -c 'umask 077 && cat > /etc/openclaw-dashboard.env'
# paste a single line, then Ctrl+D
# GITHUB_TOKEN=github_pat_...
  1. Add to the systemd service:
EnvironmentFile=/etc/openclaw-dashboard.env

(Use sudo systemctl edit openclaw-dashboard.service to add it as an override, or edit the unit file directly.)

  1. Reload + restart:
sudo systemctl daemon-reload
sudo systemctl restart openclaw-dashboard.service

Previous mechanism (disabled)

The old “pull + rebuild on server” updater is now disabled:

  • openclaw-dashboard-update.timer (disabled)
  • openclaw-dashboard-update.service (static helper unit)

This is intentionally disabled to avoid conflicting deployment mechanisms.

Rollback

If a bad deploy happens, roll back by repointing the current symlink to a previous release and restarting:

ls -la /opt/openclaw-dashboard/releases
sudo ln -sfn /opt/openclaw-dashboard/releases/<good-sha> /opt/openclaw-dashboard/current
sudo systemctl restart openclaw-dashboard.service

Notes / gotchas

  • EC2 root disk is small; avoid committing build artifacts or building repeatedly on-host.
  • If disk fills up, check df -h and consider cleaning caches (apt, npm cache) before attempting any local builds.