From your laptop
Give the container's daemon a token and your laptop's awaywork report, plan, skip, approve and run --unit run there, /away included. It's the CLI over HTTP, not an API: the daemon runs the same command with its own config and streams back its output. A box of your own without a container is simpler: over ssh.
Make a token (
openssl rand -hex 32), set it asAWAYWORK_REMOTE_TOKENin Coolify or.env, redeploy. Without it the daemon opens no port; under 32 characters it logsremote: AWAYWORK_REMOTE_TOKEN is shorter than 32 characters, so no port is open.Give it a domain. In Coolify's Domains field,
https://away.example.com:7480: the proxy gets the certificate and forwards to 7480, exposed to it, never published. On a VPS, publish it on localhost in acompose.override.yml(compose merges it; install never touches it) behind Caddy:yamlservices: awaywork: ports: - "127.0.0.1:7480:7480"away.example.com { reverse_proxy 127.0.0.1:7480 }In the image the daemon listens on every interface for Coolify's proxy; elsewhere,
watchwith the token in its env file listens on127.0.0.1:7480only (remote: serving the CLI on port 7480, 127.0.0.1 only).On the laptop, in
~/.config/awaywork/env(AWAYWORK_REMOTEtakeshttps://orhttp://with the token, orssh://without):shAWAYWORK_REMOTE=https://away.example.com AWAYWORK_REMOTE_TOKEN=<the same token>
Against the image on Colima, Caddy standing in for Coolify, a stand-in agent and a chores source:
$ awaywork run --unit CH-1
Queued CH-1 as run 20261104-220657; awaywork report 20261104-220657 shows it once it ends
$ awaywork skip chores:CH-1 --until 2030-01-01
skipped with awaywork skip chores:CH-1 until 2030-01-01
$ awaywork report 20261104-220657 --unit CH-1
1 CH-1 Write a hello report
status done
files /home/away/.local/state/awaywork/runs/20261104-220657/units/ch-1/1-plan/worker.log
[...]
Hello from the stand-in agent, as awayworkThe paths are the container's. Each request is a line in its log, never the token: remote: ["run","--unit","CH-1"]: exit 0.
Details:
- What goes there:
report,plan,stats,sources,doctor,schedule status,config path,skills list,skip,unskip,approveandrun --unit, with their flags here. The rest stays local:init,config schemaandedit,skills eject, a fullrun,schedule install,--help. - One of the twelve with a flag the daemon refuses fails rather than running locally (
AWAYWORK_REMOTE (http://127.0.0.1:7480): refused --dry-run); a value starting with--is written--reason=-- see thread. -c/--configmeans this machine. To run anything else here, blank it:AWAYWORK_REMOTE= awaywork report.run --unitstarts no process on the box: the daemon queues a one-off run, like the workflow'sunitinput.- The item must still match a rule unless
--skillpicks one; it runs after a failed attempt, present outside a window, away inside one, and waits for the worker in progress like a soon run.--detachchanges nothing. Failures say why and exit 1:no unit "CH-9" in the plan; awaywork plan --why CH-9 says why,CH-1 is running in run 20261104-220137. - Two commands at a time, a third turned away (
2 commands are running, try again), 2 minutes each. A silent command gets a{}line every 30 s to keep the proxy open; Ctrl-C stops it on the box. A queuedrun --unitis the daemon's by then. - A box that's down or a wrong token fails in one line:
can't reach AWAYWORK_REMOTE (http://127.0.0.1:8480): read ECONNRESET,AWAYWORK_REMOTE (http://127.0.0.1:7480) refused AWAYWORK_REMOTE_TOKEN. - Remove the two lines to go back to local runs. A laptop daemon opens no port while
AWAYWORK_REMOTEis set. A leaked token and rotation: Safety.
Over ssh
awaywork on a box of its own, a VPS under systemd from schedule install, a home server, a Mac mini: you can ssh in, so use that. No proxy, TLS or token on the laptop:
AWAYWORK_REMOTE=ssh://box # or ssh://you@host:2222The host is whatever ssh takes, aliases included. The same calls go through the box's daemon: the laptop runs ssh -T -o BatchMode=yes box env AWAYWORK_REMOTE=http://127.0.0.1:7480 awaywork --from-ssh WyJzc2g6Ly9ib3giLCJwbGFuIl0, the call (["ssh://box","plan"]) as one base64url word no login shell reads into, csh included, and the box forwards it to its daemon. The box needs:
- The same awaywork or newer: an older one says
error: unknown option '--from-ssh'. Install the versionawaywork --versionprints on the laptop. watchwith a token:echo "AWAYWORK_REMOTE_TOKEN=$(openssl rand -hex 32)" >> ~/.config/awaywork/env, then restart it. The token never leaves the box: ssh is the lock.- awaywork and node on ssh's command
PATH, not your login shell's (nvm's usually isn't).ssh box env awaywork --versionchecks it as the laptop's calls do; exit 127 (env: 'awaywork': No such file or directory, ornode) means install them system-wide, orsudo ln -s "$(command -v node)" "$(command -v awaywork)" /usr/local/bin/from an interactive shell there. - Key auth:
BatchModenever asks for a password or a host key, either of which would hang the/awaypane. ssh in once by hand to know the host key.
Exit codes are the box's and stdout and stderr stay apart, so awaywork plan --json | jq works. Shell characters in arguments arrive as text (--reason "it's done; \$(rm -rf ~)" is just a reason). There's no Ctrl-C without a terminal; the box's awaywork leaves when the laptop's ssh goes, and the daemon stops the command (remote: ["plan"]: stopped, the client left). Errors name the remote and the box's side:
$ awaywork report
can't reach AWAYWORK_REMOTE (ssh://dev@127.0.0.1:2222): Host key verification failed.
$ awaywork report
AWAYWORK_REMOTE (ssh://box): awaywork isn't on the box's PATH for non-interactive ssh; install it and node system-wide there, or link both into /usr/local/bin
$ awaywork run --unit CH-1
AWAYWORK_REMOTE (ssh://box): the box's daemon isn't serving, the box's /home/dev/.config/awaywork/env has no AWAYWORK_REMOTE_TOKEN; add one there and restart awaywork watch
$ awaywork report --list
AWAYWORK_REMOTE (ssh://box): the box's daemon runs with another AWAYWORK_REMOTE_TOKEN than its env file; restart awaywork watch thereA call over ssh never runs on the box outside its daemon, so a box without a token refuses rather than running run --unit itself. The container is the exception: its port goes to the proxy, not the host, so Coolify and compose use HTTP.