Deployment
Install
Section titled “Install”The installer downloads the signed binary for your platform, verifies its checksum (and optional cosign signature), creates a service user and data directory, and installs a hardened systemd unit.
curl -fsSL https://get.cogworks.dev | sh
# Optionscurl -fsSL https://get.cogworks.dev | sh -s -- --version v0.1.0curl -fsSL https://get.cogworks.dev | sh -s -- --port 9000 --no-startcurl -fsSL https://get.cogworks.dev | sh -s -- --verify-sig # cosign keylessRe-running the installer performs an in-place upgrade and preserves your data, secret, and admins. It’s Linux only; on other platforms grab a prebuilt binary from the GitHub releases or build your own.
systemd
Section titled “systemd”The installed unit runs as the cogworks user, reads
/etc/cogworks/cogworks.env, and applies heavy sandboxing
(ProtectSystem=strict, NoNewPrivileges, empty capability set,
ReadWritePaths=/var/lib/cogworks).
systemctl status cogworkssystemctl restart cogworksjournalctl -u cogworks -f
# edit config, then restartsudoedit /etc/cogworks/cogworks.envReverse proxy
Section titled “Reverse proxy”Cogworks serves plain HTTP on one port and does not compress or terminate TLS — put nginx or Caddy in front.
The realtime endpoints need special handling: WebSocket upgrade on /realtime and un-buffered SSE
on /api/realtime.
api.example.com { encode gzip zstd @ws path /realtime @sse path /api/realtime reverse_proxy @sse localhost:8091 { flush_interval -1 } reverse_proxy @ws localhost:8091 reverse_proxy localhost:8091}nginx equivalents: proxy_read_timeout 86400s on the WebSocket location and
proxy_buffering off on the SSE location. Sample nginx and Caddy configs ship in
deploy/.
Serving a static site {#deploy-static}
Section titled “Serving a static site {#deploy-static}”Point COGWORKS_PUBLIC_DIR at a folder and Cogworks serves it as a static site —
handy for a marketing page, docs, or a compiled SPA sharing the same origin as
your API (no CORS, one deploy). It’s opt-in: with no COGWORKS_PUBLIC_DIR,
nothing is served and / stays a 404.
COGWORKS_PUBLIC_DIR=/var/www/site cogworksStatic files are the lowest-priority handler — a request only falls through
to a file after it fails to match every API, admin (/_/), auth, realtime, and
custom route, and those reserved prefixes keep
their JSON 404s. Resolution for /foo:
- exact file —
public/foo - extensionless →
.html—public/foo.html - directory index —
public/foo/index.html
/ and trailing-slash paths serve the directory index.html. Paths are
resolved inside the root — traversal (../) is rejected. HTML is sent
Cache-Control: no-cache; other assets get a short max-age.
For a client-routed SPA, set COGWORKS_PUBLIC_SPA=1 so any unmatched
extensionless path serves the root index.html (letting the router take over);
asset requests (with an extension) still 404 when missing.
Building the binary
Section titled “Building the binary”Build a self-contained executable (bundles the admin UI):
bun run build # → ./cogworksbun run build:all # all cross-compile targets → releases/Targets: linux-x64, linux-arm64, linux-x64-musl (Alpine),
darwin-x64, darwin-arm64, windows-x64. A
docker-compose.web.yml for the landing/docs site lives at the repo root.