Opsgenie and Grafana OnCall: two pillars fading out
Opsgenie was acquired by Atlassian in 2018 and gradually absorbed into the Jira suite. The end-of-life announcement was published on the official Atlassian status page: the service stops on April 5, 2027. Users have just over a year to migrate their on-call policies, integrations and incident history. Grafana OnCall OSS, the open source component of Grafana OnCall, was archived on GitHub on March 24, 2026. The Grafana Labs team stated that the cloud version remains available, but the self-hosted repository no longer receives patches or new features. Teams that had built their incident management infrastructure on this component are in the same position: they must migrate before unpatched security vulnerabilities become a real risk. The convergence of these two events in less than twelve months creates a migration window that teams would do well to plan now rather than waiting for pressure to build in the final weeks before the April 2027 deadline.
What an incident management solution must cover
- Receiving and deduplicating alerts from Prometheus, Grafana, Zabbix or any HTTP webhook
- Routing alerts to the right teams based on configurable rules (severity, service, schedule)
- Managing on-call schedules with weekly or custom rotations
- Automatic escalations if an alert is not acknowledged within a defined time window
- Multi-channel notifications: email, SMS, voice call, Slack, Microsoft Teams, PagerDuty webhooks
- Public status page to keep users informed in real time
- Searchable and exportable incident history for post-mortems
- REST API for integration into CI/CD pipelines and automation tools
OneUptime vs IncidentRelay vs PagerDuty
Scroll the table
| Criterion | OneUptime | IncidentRelay | PagerDuty (SaaS) |
|---|---|---|---|
| License | Apache 2.0 | MIT | Proprietary |
| Hosting | Self-hosted (Docker Compose) | Self-hosted (Docker Compose) | Cloud only |
| Tech stack | Node.js / TypeScript, PostgreSQL | Go, SQLite/PostgreSQL | Undisclosed |
| Minimum recommended RAM | 4 GB (light production), 8 GB advised | 512 MB (SQLite), 2 GB (PostgreSQL) | N/A |
| Built-in status page | Yes, public and customizable | Yes, basic | Yes, via Statuspage (paid separately) |
| Base price | Free (self-hosted) | Free (self-hosted) | From $21/user/month |
VPS requirements for OneUptime
OneUptime uses a multi-container architecture orchestrated by Docker Compose. For a team of fewer than twenty people with moderate alert volume (fewer than one thousand events per day), a VPS with 4 vCPU and 8 GB of RAM is a solid baseline. Below 4 GB of RAM, several containers compete at startup and cause repeated restarts. Storage should be on an SSD volume: OneUptime writes frequently to PostgreSQL and its internal event bus. Plan for at least 40 GB for logs and the database over six months. The server must expose ports 80 and 443; an nginx or Caddy reverse proxy can sit in front if the VPS already hosts other services. Docker Engine version 24 or later and Docker Compose version 2.20 or later are required. A fixed IP address and a domain name with a DNS A record are needed for the TLS certificate and so that incoming webhooks are reachable.
Deploy OneUptime on a VPS in 7 steps
Connect to the VPS via SSH and install Docker Engine and Docker Compose v2 from the official Docker repository:
curl -fsSL https://get.docker.com | sh, then verify withdocker compose version.Clone the OneUptime repository:
git clone https://github.com/OneUptime/oneuptime.gitthen enter the directorycd oneuptime.Copy the example configuration file:
cp .env.example .envthen open it in an editor. At a minimum setDOMAIN(your domain or subdomain),DISABLE_TELEMETRY=trueif you do not want to send usage metrics, and the SMTP variables (SMTP_HOST,SMTP_PORT,SMTP_USERNAME,SMTP_PASSWORD,SMTP_FROM_EMAIL) for email notifications.Start the containers in the background:
docker compose up -d. The first startup downloads images and runs database migrations; allow three to five minutes depending on bandwidth.Verify that all services are healthy:
docker compose ps. The containersoneuptime-app,oneuptime-worker,oneuptime-postgresandoneuptime-redisshould show staterunning. If a container errors, inspect its logs withdocker compose logs <container-name> --tail=100.Open a browser at
https://your-domainand create the initial admin account. Then go to *Settings → On-Call Duty → Policies* to create your first policy: define the team, time windows and notification channels.Enable automatic image updates with Watchtower or schedule a weekly
docker compose pull && docker compose up -dvia cron to pull security patches without extended downtime.
Configuring alerts: Prometheus webhook to OneUptime
OneUptime exposes an incoming webhook endpoint for each monitor or integration created. In the interface, go to *Integrations → Incoming Webhooks* and create a new integration of type Prometheus Alertmanager. The interface generates a URL in the form https://your-domain/api/v1/incoming-request/<uuid>. In the Prometheus Alertmanager configuration, add a receiver of type webhook pointing to this URL. The field send_resolved: true allows OneUptime to automatically close an incident when Alertmanager sends the resolution notification. For integration from Grafana, use the *Webhook* contact type and provide the same URL. OneUptime parses the incoming JSON and automatically extracts the title, severity and labels from the Prometheus alert. If you send alerts from a custom tool, the expected format is documented in the integration page: a title field and a description field are sufficient to create an incident.
Managing on-call schedules and escalations
On-Call Schedules in OneUptime define who is available, at what time and for which service. A schedule is associated with one or more layers: each layer represents a team rotation. The rotation can be daily, weekly or over a custom period. Each team member can set their notification preferences in their profile: immediate email, SMS after two minutes, voice call if the incident is not acknowledged after five minutes. Escalations are configured in Alert Policies: if the on-call person at level 1 does not respond within the configured window, the alert automatically escalates to level 2, which can be a different person, a different team or a shared Slack channel. This escalation chain is visible in the history of each incident, which makes post-mortem reviews straightforward.
Exposing the status page behind nginx
OneUptime generates a public status page accessible at a dedicated subdomain, for example status.your-domain.com. To expose it cleanly behind nginx as a reverse proxy, create a vhost that forwards requests to the internal port 3105 used by the status page container: proxy_pass http://127.0.0.1:3105;. Enable the X-Forwarded-Proto header so that OneUptime generates correct HTTPS links in notifications. The TLS certificate can be obtained via Certbot with the nginx plugin: certbot --nginx -d status.your-domain.com. The status page lets customers and users follow service status in real time without accessing the admin interface.
Troubleshooting — common startup errors
The most common issue at first startup is a PostgreSQL container that is not ready before the application container tries to connect. OneUptime includes healthcheck directives in its official docker-compose.yml; if you use a modified version, ensure the app service has a depends_on entry with condition service_healthy on the postgres service. A second frequent problem involves SMTP variables: if account verification emails are not sent, verify that SMTP_PORT is 587 (STARTTLS) and not 465 (direct SSL) if your SMTP provider requires it. To diagnose silent errors, watch the worker logs in real time with docker compose logs -f oneuptime-worker. Finally, if port 443 is already occupied by another service, OneUptime will start but be unreachable: change the port mapping in docker-compose.yml or stop the competing service before launching the stack.
Planning the Opsgenie to OneUptime migration before April 2027
Opsgenie allows exporting alert policies, on-call schedules and incident history as JSON or CSV from *Settings → Export*. These exports contain routing rules, team members and active integrations. Import into OneUptime is not automatic: policies must be recreated manually or via the OneUptime REST API using the exported data. Starting with critical integrations (Prometheus, Grafana, Datadog) and then moving to on-call schedules and finally secondary notifications is the recommended approach. Plan for a parallel-run period of at least two weeks: both systems receive the same alerts while teams validate the new policies. The April 5, 2027 deadline leaves enough time for a careful migration if it is started before January 2027. Waiting until the final weeks risks a forced cutover with no option to roll back if an integration is missing.