Single top-to-bottom runbook covering preflight, local build, server deploy,
first-agent dry run, test tier, full rollout, rollback, and ongoing ops.
Each step has a verification command. Ends with a Go/No-Go sign-off list.
Returns 200 with {status: ok, version, db: ok} when SQLite is reachable,
503 when the DB probe fails. Unauthenticated so external monitors can
poll without credentials.
Extended Server.Release with migrate/0 and rollback/2 so
'bin/server eval Server.Release.migrate' works from a released binary.
Removed the phx.gen.release-generated rel/overlays/bin/server wrapper
that hardcoded 'start' — it collided with the mix-release default
dispatcher, blocking 'server version', 'server eval', etc. The 'migrate'
overlay is kept (bin/migrate calls server eval under the hood).
Blocking bootstrap in dev meant you couldn't even run 'mix run' to
generate the initial hash. Now dev/test accept an optional env override
and boot without it; prod still raises when unset.
Application.start ran mark_all_offline unconditionally, which meant
every "mix run"/"mix ecto.migrate" invocation would flip all
connected hosts to offline. Gate the call on Phoenix.Endpoint.server?
so non-serving boots don't disturb live state.
Errors produced by Collectors.Host were keyword tuples {:tag, msg}, which
Jason cannot encode — metric push crashed the channel. Convert them to
plain maps with :tag and :message fields.
Reporter.handle_info/2 returned {:ok, socket}, which Slipstream rejects
(GenServer-style {:noreply, socket} is the only valid return for that
callback, unlike handle_connect/handle_join/handle_disconnect).