Operations platform migration¶
This runbook moves the homelab from notification-led response to OneUptime incident management without replacing the existing monitoring stack.
The target architecture is documented in operations and incident platform.
Safety rules¶
- Prometheus and the Loki ruler remain alert evaluators.
- Alertmanager remains the routing, inhibition, and silence authority.
- Existing Discord and ntfy delivery stays active through the shadow and pilot stages.
- OneUptime does not receive production alerts before its restore drill passes.
- No remediation action receives an arbitrary command, SSH key, Docker socket, or runner operator credential.
- Disruptive actions require GitHub protected-environment approval.
- Stop and roll back a stage if duplicate incidents, lost recovery events, or notification regressions appear.
Stage 0: foundation¶
Deliver:
- architecture and state-ownership decision;
- operational alert contract;
- Prometheus and Alertmanager semantic CI;
- corrections for known rule and inhibition defects.
Gate:
uv run python scripts/lint-alert-schema.py
uv run python -m unittest discover -s tests -v
uv run python scripts/lint-markdown.py
promtool check config monitoring/prometheus/prometheus.yml
promtool check rules monitoring/prometheus/alerts/*.yml
promtool test rules monitoring/prometheus/tests/*.yml
amtool check-config /path/to/rendered-alertmanager.yml
Rollback: revert the foundation PR. It does not change live notification routing.
Stage 1: capacity¶
- Measure
infra-servicesCPU, memory, filesystem, and Docker usage. - Measure Proxmox RAM and
local-lvmthin-pool headroom. - Agree the target VM allocation and maintenance window with the owner.
- Resize VM 123 and verify the guest sees the new allocation.
- Update inventory and generated artifacts after the live change.
Gate:
- at least 20 percent disk free after pulling OneUptime images;
- at least 6 GiB
MemAvailablebefore OneUptime starts; - swap remains enabled;
- existing stacks are healthy;
- no
InfraServices*capacity alert fires for 15 minutes.
Rollback: CPU and memory can return to the previous allocation after shutdown if required. Disk expansion is not treated as reversible; follow the existing capacity runbook and never improvise a shrink.
Stage 2: shadow deployment¶
Deploy the five-service core:
- OneUptime application;
- OneUptime ingress;
- PostgreSQL;
- Redis;
- ClickHouse.
The probe and AI agent remain disabled. Duplicate telemetry ingestion remains disabled.
Gate:
- all containers are healthy within the documented startup window;
- Authentik protects the browser route;
- OneUptime local authentication is enabled;
- direct backend access does not bypass authorization;
- no host ports are published;
- WebSockets, redirects, cookies, and forwarded HTTPS headers work;
- the application runs within the approved memory and disk budget for 24 hours.
Rollback: stop the stack and remove its Traefik route. Do not delete volumes until backup/restore testing and owner approval establish whether state is disposable.
Stage 3: data protection¶
- Create a sample incident and workflow run.
- Take logical PostgreSQL and consistent ClickHouse backups.
- Restore into isolated volumes.
- Start the exact pinned OneUptime release against the restored data.
- Verify the incident, timeline, workflow history, users, and encrypted variables.
- Copy the backup through the tier-1 restic path.
Gate: the isolated restore passes. Production Alertmanager delivery remains blocked until it does.
Rollback: keep the shadow stack stopped and repair the backup procedure.
Stage 4: GitHub runner pilot¶
Forward only standardized warning and critical GitHub runner alerts.
Alertmanager routing is additive:
send_resolved: true;continue: true;- existing Discord delivery unchanged;
- existing critical patching ntfy delivery unchanged.
Synthetic lifecycle:
- Send one firing runner alert.
- Confirm one OneUptime incident appears.
- Repeat the same payload.
- Send two concurrent copies.
- Confirm the incident count remains one.
- Add a second fingerprint to the same correlation.
- Resolve one fingerprint and confirm the incident remains open.
- Resolve the final fingerprint and confirm the same incident resolves.
- Restart OneUptime and verify the timeline remains.
Rollback: remove or disable only the OneUptime child route and reload Alertmanager. Direct receivers continue.
Stage 5: domain rollout¶
Migrate one alert domain per reviewable change:
- node and host availability;
- containers and infra-services capacity;
- backup and restore;
- patching and Komodo;
- TLS and service health;
- monitoring-platform health.
For each domain:
- complete alert schema labels and annotations;
- add rule behavior tests;
- prove firing, repeat, and resolution;
- inspect correlation keys;
- verify direct notifications did not change;
- add the domain to the operations dashboard.
Rollback: remove the domain matcher from the OneUptime route. Do not remove the Prometheus rule or direct notification route.
Stage 6: runner remediation¶
The end-to-end example uses the existing runner-fleet dispatch workflow:
- A runner-pool alert creates an incident.
- The operator acknowledges it in OneUptime.
- The operator dispatches exact-runner diagnostics.
- GitHub records output as structured artifacts.
- The OneUptime timeline receives the workflow-run link and result.
- The operator previews drain/remediate/resume.
- A protected environment approves disruptive execution.
- Prometheus confirms recovery and Alertmanager sends the resolved event.
- OneUptime resolves and retains the incident.
Gate:
- the selected target is not the management runner;
- Apps, protected environments, and maintenance runner variables are configured;
- every target exists in
infra/github-runners/fleet.yml; - actions time out and reject arbitrary commands or unknown targets;
- early failures still emit an auditable result.
Rollback: disable the OneUptime dispatch credential or workflow action. Existing manual workflow dispatch remains available.
Stage 7: notification cutover¶
- Send OneUptime lifecycle messages to separate pilot Discord and ntfy destinations.
- Compare delivery, links, recovery behavior, and noise for at least one week.
- Move standardized domain lifecycle messages to the production destinations.
- Retain direct Alertmanager delivery for watchdog, OneUptime failure, and other agreed emergency alerts.
- Remove permanent duplicate routes only after owner approval.
Rollback: disable OneUptime notification workflows and restore the previous Alertmanager matcher. Incident ingestion can remain active.
Stage 8: closeout¶
Confirm:
- operations and platform-health dashboards are provisioned;
- noisy, stale, frequent, long-running, and flapping alerts are visible;
- platform health, database health, queue health, webhook delivery, backup freshness, disk, and certificates are monitored;
- the dead-man path is outside the Prometheus/Alertmanager failure domain;
- operator, restore, upgrade, rollback, and synthetic-test docs match reality;
- a project journal entry records the milestone and remaining gaps.
OneUptime becomes canonical incident state only after every prior gate passes.