Skip to content
7 changes: 6 additions & 1 deletion 07.reference/01.cli/default.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,12 @@ All commands are run with `dune` (or `deno task dune`).
| `dune serve --root my-site` | Serve a site in a subdirectory without `cd`-ing into it first. |
| `dune dev --env-file` | Load `.env` from the site root into the process environment before plugins/config are read. |
| `dune dev --env-file=path/to/file` | Same, from an explicit path (relative to the site root, or absolute). |
| `dune ps` | List dune dev/serve instances currently running on this machine — PID, mode, site title, root, and the port(s) actually listening. Scans the process table; works retroactively on anything already running. macOS/Linux only. |
| `dune ps` | List your dune dev/serve instances currently running on this machine — PID, mode, version, site title, root, the port(s) actually listening, and the command line. Mostly read-only: it scans the process table, so it works retroactively on anything already running, and it sends a `GET /health/live` to each listening instance (this appears in the instance's access log). Finds servers started through the generated `main.ts`, the `dune` CLI itself (`cli.ts dev`, the global shim, `jsr:@dune/core/cli`) and `deno task dev|serve`; a server's wrapper, re-exec child and esbuild workers are reported as one instance. Instances also record themselves in `~/.dune/instances/` (`DUNE_REGISTRY_DIR` overrides), so one started in an unusual way is still listed. A process that is running but holds no port is shown as **not listening**. A listening instance that fails three health probes in a row (about 10 seconds) is shown as **NOT RESPONDING**: a blocked event loop accepts the connection but never answers. It probes the port the instance registered, else every listening port, counting only dune's own answer. A process that matches dune only by its command line, with no `config/site.yaml` at the root that command line points to, is listed but marked unconfirmed. Only your own processes are shown. It needs permission to run `ps` and `lsof` (`--allow-run`, or `-A`) and says so rather than reporting no instances. macOS/Linux only. |
| `dune stop <pid>` | Stop one instance, with its **whole process tree** (including any other tool a `deno task` wrapper started). The pid can be any process `dune ps` shows for it, including an unconfirmed one (with a warning). The prompt shows each instance's full command line. Sends SIGTERM and waits up to 10 seconds for a server to drain; a process that ignores it is reported, not killed. Each pid's start time is re-checked immediately before it is signalled, so a pid that exited and was reused while the prompt was open is never hit. Asks first; `--yes` skips the prompt, and without a terminal it refuses unless `--yes` is given. It never signals itself or its parent processes. Exit code 1 if the pid matches no instance or something would not stop. |
| `dune stop --port <n>` | Stop the instance listening on that port. |
| `dune stop --idle` | Stop only **confirmed** instances that aren't serving: running but **not listening**, or listening but **not responding**, for at least 2 minutes (younger ones may still be starting, for example indexing a large site). Leaves live servers alone. An instance whose port state is unknown (no `lsof`) is never treated as idle. |
| `dune stop --all` | Stop every **confirmed** instance `dune ps` lists. An instance is confirmed when its own command line points at a dune site (the directory of the `main.ts` it runs, its `--root`, or the dune CLI's working directory, each holding a `config/site.yaml`) or when it registered itself in the instance registry. Merely running from inside a site directory confirms nothing, so another Deno project's `main.ts serve` is left out and reported; name it by pid if you mean it. A target is always required — a bare `dune stop` only prints usage (exit 2) — so stopping everything has to be asked for by name. |
| `dune stop … --force` | Also SIGKILL processes that ignore SIGTERM after the grace period, naming them. Opt-in: killing a wrapper process can leave its child running. A server stuck in a loop can't handle SIGTERM at all, so this is how to end a hung one. |

`--env-file` is off by default — nothing auto-loads secrets from disk on a plain `dune dev`/`serve`. It parses simple `KEY=VALUE` lines (blank lines and `#` comments skipped, surrounding quotes stripped); a key already set in the environment always wins over the file. An explicitly-requested file that doesn't exist is a hard error, not a silent no-op. Also accepted by `dune serve`.

Expand Down
Loading