Check server availability
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
maxpeterkaya d85cf284fe
All checks were successful
CI / build (push) Successful in 2m7s
fix: hopefully fix debian upload
2026-09-03 13:56:46 -04:00
.forgejo/workflows ci: add changelog 2026-09-03 10:29:04 -04:00
packaging/systemd fix(systemd): run outpost as a system service 2026-08-17 12:04:33 -04:00
.gitignore gitignore tmp files and folders 2026-09-03 13:23:43 -04:00
.goreleaser.yml fix: hopefully fix debian upload 2026-09-03 13:56:46 -04:00
actions.go feat: add outpost host health daemon 2026-08-17 12:05:19 -04:00
actions_linux.go feat: add outpost host health daemon 2026-08-17 12:05:19 -04:00
actions_other.go feat: add outpost host health daemon 2026-08-17 12:05:19 -04:00
auth.go feat: add outpost host health daemon 2026-08-17 12:05:19 -04:00
config.example.yaml docs: add prom metrics feat 2026-09-03 13:09:33 -04:00
config.go feat: add metrics route and config 2026-09-03 13:09:15 -04:00
events.go feat: add outpost host health daemon 2026-08-17 12:05:19 -04:00
go.mod deps: add prom 2026-09-03 13:08:39 -04:00
go.sum deps: add prom 2026-09-03 13:08:39 -04:00
LICENSE docs: add AGPL-3.0 license 2026-08-17 12:05:21 -04:00
main.go feat: add metrics route and config 2026-09-03 13:09:15 -04:00
main_test.go feat: add outpost host health daemon 2026-08-17 12:05:19 -04:00
metrics.go feat: create metrics 2026-09-03 13:09:02 -04:00
metrics_test.go feat: create metrics 2026-09-03 13:09:02 -04:00
prober.go feat: add outpost host health daemon 2026-08-17 12:05:19 -04:00
README.md docs: add prom metrics feat 2026-09-03 13:09:33 -04:00

Outpost

Outpost is a host health daemon. It polls external HTTP targets and exposes their status over a small HTTP API. It can also schedule a delayed, cancellable restart or shutdown of the host it runs on.

Why outpost

  • Single-host by design.
    • Most monitoring stacks watch many hosts and services. Outpost is for the one host nobody else is watching like a self-hosted server, a VM host, or an edge device.
  • Zero dependencies.
    • It is one static Go binary and a YAML config file. No database, no agents, no external services. It sits behind any reverse proxy or is reached directly.
  • Recovery primitive, not a platform.
    • The point is "is the thing I rely on still answering, and can I kick it". HTTP probing plus a delayed, cancellable restart and shutdown lets you rescue a wedged host from another device. Metrics are live gauges only; the daemon stores nothing.
  • Deliberately small scope.
    • No metrics storage, no alerting, no dashboards. It only exposes live state over /metrics for an existing Prometheus to scrape.

Features

  • Probes all targets concurrently on a fixed interval. Up means any 2xx or 3xx response.
  • JSON /status and /health endpoints, optionally public.
  • Prometheus /metrics endpoint, gated like /status.
  • Actions gated by an API key sent as an Authorization: Bearer header, minimum 32 characters.
  • Delayed, cancellable host restart and shutdown via systemctl.
  • Append-only JSONL event log of all scheduled and fired actions.

Install

Requires Go 1.26.

go build -o outpost .

Prebuilt binaries are published on releases and packaged for Arch Linux as the outpost AUR package.

Configuration

Copy config.example.yaml to /etc/outpost/config.yaml and edit it. By default outpost

  • listens on :8080,
  • probes every 30s with a 10s minimum,
  • keeps /status, /health and /metrics key-free since public_status defaults to true,
  • writes events to /var/log/outpost/events.jsonl.

The config path comes from the -config flag, falls back to $OUTPOST_CONFIG, and then to /etc/outpost/config.yaml.

API

Method Path Auth Notes
GET /health only with public_status: false Returns {"status":"ok"}.
GET /status only with public_status: false Probe snapshot. Reports up and total, per-target results, and an overall status of unknown, up, down, or degraded.
GET /metrics only with public_status: false Prometheus text format. Per-target outpost_probe_up and outpost_probe_last_check, overall outpost_probe_targets / outpost_probe_targets_up, plus Go runtime and process metrics.
POST /restart required Body {"reason":"..."} is optional. Returns HTTP 202 with the action name and its delay in seconds. Answers 409 when one is already pending.
POST /shutdown required Same as /restart.
POST /cancel required Body holds "action" set to "restart" or "shutdown". Answers 404 when nothing is pending.
GET /events required Event log entries, newest last. ?limit=N caps the count.

Example:

curl -H "Authorization: Bearer $(cat /etc/outpost/api_key)" \
  -d '{"reason":"updating packages"}' http://localhost:8080/restart

Auth

Actions require a Bearer token read from api_key_file. When the file is missing or the key is shorter than 32 characters, the action endpoints answer 503. The daemon keeps serving status, so a bad key is safe degradation rather than a startup failure.

Actions

On Linux, restart runs systemctl reboot and shutdown runs systemctl poweroff. Only one action of each kind may be pending at a time. The event is written to the log before the command fires, since a successful reboot or poweroff usually kills the process. On other platforms actions are unsupported and answer 503.

systemd

A unit file is included at packaging/systemd/outpost.service.

License

AGPL-3.0