tutorial

How to Monitor NervesHub with Vigilmon

Monitor your NervesHub OTA deployment platform and Nerves device fleet with Vigilmon — catch deployment pipeline failures, API outages, and device connectivity issues before they stall your embedded Linux rollouts.

How to Monitor NervesHub with Vigilmon

NervesHub is the OTA (over-the-air) firmware update platform for Nerves-based embedded Linux devices. It handles deployment pipelines, firmware signing, device health reporting, and audit trails for your entire fleet. When NervesHub goes down — or when your self-hosted instance develops a fault — firmware updates stall silently, devices fall behind on patches, and you may not know for hours.

Vigilmon closes that gap with HTTP uptime checks, heartbeat monitoring, and instant alerts so your OTA pipeline stays healthy and your fleet stays current.

This tutorial covers:

  • HTTP monitoring for NervesHub's public API
  • Heartbeat monitoring from within Nerves firmware
  • Monitoring your self-hosted NervesHub instance
  • Alerts for deployment failures and device connectivity drops

What to Monitor in a NervesHub Deployment

NervesHub has two layers worth monitoring:

| Layer | What it is | How to monitor | |---|---|---| | NervesHub server | The web app / API that manages devices and deployments | HTTP uptime check | | Device connectivity | Individual devices' ability to reach NervesHub | Heartbeat from firmware | | Deployment pipeline | Whether new firmware is actually reaching devices | Custom heartbeat after deployment |


Step 1: Monitor the NervesHub API endpoint

If you use the hosted NervesHub service (nerveshub.org), monitor their API:

  1. Sign in at vigilmon.online and click Add Monitor.
  2. Choose HTTP monitor type.
  3. Use https://nerveshub.org as the URL (or your self-hosted domain).
  4. Set check interval to 60 seconds.
  5. Expected status: 200.

For self-hosted NervesHub, monitor your own domain plus the internal health endpoint if one is exposed.


Step 2: Monitor a self-hosted NervesHub instance

NervesHub is an open-source Phoenix application. Add a lightweight health plug:

# In your self-hosted NervesHub fork, add to router.ex
scope "/health", NervesHubWeb do
  pipe_through :api
  get "/", HealthController, :index
end
# lib/nerves_hub_web/controllers/health_controller.ex
defmodule NervesHubWeb.HealthController do
  use NervesHubWeb, :controller

  def index(conn, _params) do
    checks = %{
      database: check_db(),
      ssl_certs: :ok   # extend with actual cert expiry logic
    }

    status = if Enum.all?(checks, fn {_, v} -> v == :ok end), do: 200, else: 503

    conn
    |> put_status(status)
    |> json(%{status: status_text(status), checks: checks})
  end

  defp check_db do
    case NervesHub.Repo.query("SELECT 1", []) do
      {:ok, _} -> :ok
      _ -> :error
    end
  end

  defp status_text(200), do: "ok"
  defp status_text(_), do: "degraded"
end

Point your Vigilmon HTTP monitor at https://your-nerveshub.example.com/health.


Step 3: Add heartbeat monitoring from Nerves firmware

Devices that can reach NervesHub can also reach Vigilmon's heartbeat endpoint. Add a GenServer to your Nerves firmware that pings Vigilmon on each successful NervesHub connection:

# lib/my_firmware/heartbeat.ex
defmodule MyFirmware.Heartbeat do
  use GenServer
  require Logger

  @interval_ms 60_000

  def start_link(_opts), do: GenServer.start_link(__MODULE__, %{}, name: __MODULE__)

  @impl true
  def init(state) do
    schedule_ping()
    {:ok, state}
  end

  @impl true
  def handle_info(:ping, state) do
    ping_vigilmon()
    schedule_ping()
    {:noreply, state}
  end

  defp ping_vigilmon do
    case System.get_env("VIGILMON_HEARTBEAT_URL") do
      nil ->
        Logger.debug("VIGILMON_HEARTBEAT_URL not set, skipping heartbeat")

      url ->
        case :httpc.request(:get, {String.to_charlist(url), []}, [{:timeout, 5000}], []) do
          {:ok, _} -> Logger.debug("Vigilmon heartbeat sent")
          {:error, reason} -> Logger.warning("Vigilmon heartbeat failed: #{inspect(reason)}")
        end
    end
  end

  defp schedule_ping, do: Process.send_after(self(), :ping, @interval_ms)
end

Add to your firmware supervision tree:

# lib/my_firmware/application.ex
children = [
  # ... existing children
  MyFirmware.Heartbeat
]

Set the heartbeat URL in your Nerves firmware config or via NervesHub's device environment variables:

# config/prod.exs
config :my_firmware, heartbeat_url: System.get_env("VIGILMON_HEARTBEAT_URL")

In Vigilmon:

  1. Open your monitor → Heartbeat tab.
  2. Copy the heartbeat URL.
  3. Set it as a NervesHub deployment variable so all devices in the deployment receive it.
  4. Set grace period to 3 minutes (three missed 1-minute pings = alert).

Step 4: Monitor deployment health with a post-deploy heartbeat

Wire a heartbeat ping into your CI/CD pipeline to confirm firmware actually deployed:

#!/bin/bash
# scripts/deploy.sh

# Push firmware to NervesHub
mix nerves_hub.firmware publish --product MyProduct --tag ${FIRMWARE_TAG}

# Start deployment
mix nerves_hub.deployment update --name production --tag ${FIRMWARE_TAG}

# Ping Vigilmon to confirm deploy was initiated
curl -s "${VIGILMON_DEPLOY_HEARTBEAT_URL}" > /dev/null

echo "Deployment started, Vigilmon heartbeat sent"

Create a separate Vigilmon heartbeat monitor for your deployment pipeline with a longer grace period (e.g., 24 hours) to catch cases where your CI/CD stops running entirely.


Step 5: Configure alerts

In Vigilmon go to Alerts and configure notification channels:

  • Slack (#ops or #firmware-deploys) — good for deployment events
  • Email — on-call engineer
  • PagerDuty — for fleets where stale firmware is a safety issue

Recommended alert policies for NervesHub:

| Monitor | Condition | Action | |---|---|---| | NervesHub API | HTTP non-200 or timeout | Alert on-call immediately | | Device heartbeat | Missed ≥ 3× | Alert device owner | | Deploy pipeline heartbeat | Missed ≥ 1× | Alert CI/CD team | | Response latency | > 3 s | Warning — possible DB slowdown |


Step 6: Status page for your fleet team

Create a Vigilmon Status Page that your firmware team and field teams can bookmark:

  1. Go to Status PagesNew Page.
  2. Add: NervesHub API monitor, any device fleet heartbeat monitors.
  3. Set visibility to Team (internal) or Public for partner visibility.

Key Metrics to Watch

| Metric | Threshold | Meaning | |---|---|---| | NervesHub API HTTP status | Must be 200 | Server reachable | | Device heartbeat | < 3 missed | Device connected to network | | Deploy heartbeat | < 1 missed per 24 h | CI/CD pipeline running | | API response time | < 2 s | No DB or backend bottleneck | | Self-hosted DB check | Must be ok | Postgres/Ecto healthy |


Why Monitor NervesHub?

NervesHub is infrastructure. When it's unhealthy:

  • Devices can't receive firmware updates — security patches, bug fixes, and new features stall
  • Device health reporting breaks — you lose visibility into your fleet
  • Deployment audit trails stop — compliance and debugging suffer

A 5-minute Vigilmon setup gives you early warning for all of these scenarios.


Conclusion

NervesHub keeps your Nerves fleet patched and healthy — and Vigilmon keeps NervesHub itself under watch. With HTTP monitoring on the NervesHub API, heartbeat checks from each device, and a deploy-pipeline heartbeat in your CI/CD, you have end-to-end observability from firmware build to device in the field.

Get started free at vigilmon.online.

Monitor your app with Vigilmon

Free plan — 5 monitors, no credit card required. Up and running in 60 seconds.

Start free →