tutorial

Monitoring Your Self-Hosted Appwrite Backend with Vigilmon

Appwrite bundles auth, databases, storage, and functions into one self-hosted BaaS. Learn how to monitor each service endpoint, detect partial failures, and get alerted before your app breaks.

Monitoring Your Self-Hosted Appwrite Backend with Vigilmon

Appwrite gives you a full backend in a single Docker deployment — authentication, databases, file storage, cloud functions, and realtime subscriptions. It's the self-hosted alternative to Firebase and Supabase that keeps your data on your own infrastructure.

That self-hosted advantage comes with a responsibility: no one else is watching your uptime. When Appwrite goes down, every app that depends on it stops working. This guide shows you how to set up proper monitoring using Vigilmon so you know about failures before your users do.


What makes Appwrite monitoring distinct

Appwrite is not a single process — it's a set of microservices running as Docker containers:

  • appwrite — the core API
  • appwrite-worker-* — background workers for functions, mails, webhooks, etc.
  • appwrite-executor — runs cloud functions
  • mariadb — the primary database
  • redis — caching and queues
  • influxdb — usage metrics
  • traefik — the reverse proxy that routes traffic

A partial failure — say, the functions executor crashes while the core API stays up — looks like "Appwrite is running" from the outside but silently breaks cloud function invocations. You need service-level monitoring, not just a single ping.


Step 1: Explore Appwrite's health API

Appwrite exposes a comprehensive health API at /v1/health. You don't need to write any code — it's built in.

Overall health check

curl https://your-appwrite.com/v1/health

Response when healthy:

{
  "ping": 128,
  "status": "pass"
}

This confirms the Appwrite API process is alive and responding.

Per-service health endpoints

Appwrite provides granular health checks for each internal service:

# Database (MariaDB)
curl https://your-appwrite.com/v1/health/db

# Cache (Redis)
curl https://your-appwrite.com/v1/health/cache

# Queue (Redis-backed)
curl https://your-appwrite.com/v1/health/queue

# Storage filesystem
curl https://your-appwrite.com/v1/health/storage/local

# Certificate renewal queue
curl https://your-appwrite.com/v1/health/certificate

# Functions execution queue depth
curl https://your-appwrite.com/v1/health/queue/functions

Each returns the same shape:

{ "ping": 45, "status": "pass" }

Or on failure:

{ "ping": 0, "status": "fail" }

Authentication requirement

The /v1/health endpoints require an API key with the health.read scope. Create one:

  1. Appwrite console → Settings → API Keys → Add API Key
  2. Name it "monitoring" and enable the health.read permission
  3. Copy the key

You'll pass this in the X-Appwrite-Key header.


Step 2: Set up Vigilmon monitors for each service

With the health API explored, set up a monitor per critical service in Vigilmon:

  1. Sign up at vigilmon.online — free tier, no credit card
  2. New Monitor → HTTP

For monitors that require authentication headers, use Vigilmon's custom headers:

| Monitor name | URL | Custom header | |---|---|---| | Appwrite API | /v1/health | X-Appwrite-Key: your-key | | Database | /v1/health/db | X-Appwrite-Key: your-key | | Cache | /v1/health/cache | X-Appwrite-Key: your-key | | Storage | /v1/health/storage/local | X-Appwrite-Key: your-key | | Queue | /v1/health/queue | X-Appwrite-Key: your-key |

Add keyword monitors for status assertion

HTTP status alone isn't enough — you want to assert that the response body says "status":"pass", not just that the server returned 200.

For each service monitor, set the Keyword to "status":"pass". If Appwrite returns a 200 but the body says "status":"fail", Vigilmon treats it as an outage.


Step 3: Monitor cloud functions with heartbeats

HTTP endpoint checks confirm Appwrite is running. They won't tell you if a cloud function that runs on a schedule has silently stopped executing.

The heartbeat pattern: your function pings Vigilmon at the end of each successful run. If Vigilmon stops receiving pings within the expected interval, it fires an alert.

Example: Node.js cloud function with heartbeat

// functions/nightly-sync/src/index.js
import { Client, Databases } from 'node-appwrite';
import https from 'https';

export default async ({ req, res, log, error }) => {
  try {
    const client = new Client()
      .setEndpoint(process.env.APPWRITE_FUNCTION_API_ENDPOINT)
      .setProject(process.env.APPWRITE_FUNCTION_PROJECT_ID)
      .setKey(req.headers['x-appwrite-key']);

    const databases = new Databases(client);

    // Your actual business logic
    const items = await databases.listDocuments('main', 'sync-queue');
    log(`Processing ${items.total} items`);
    // ... process items ...

    // Ping heartbeat only on success
    const heartbeatUrl = process.env.SYNC_HEARTBEAT_URL;
    if (heartbeatUrl) {
      await new Promise((resolve, reject) => {
        https.get(heartbeatUrl, resolve).on('error', reject);
      });
      log('Heartbeat pinged');
    }

    return res.json({ ok: true, processed: items.total });
  } catch (err) {
    error(err.message);
    // Do NOT ping on failure — the missed ping is the alert
    return res.json({ ok: false, error: err.message }, 500);
  }
};

Set the environment variable in Appwrite's function settings:

SYNC_HEARTBEAT_URL = https://vigilmon.online/api/heartbeat/your-unique-token

In Vigilmon:

  1. New Monitor → Heartbeat
  2. Set the expected interval (e.g., 25 hours for a nightly function)
  3. Copy the ping URL and add it to your function's env vars

Now if the function crashes, the Appwrite executor goes down, or the function is accidentally deleted, Vigilmon alerts you within one missed interval.


Step 4: Monitor the Appwrite console

The Appwrite web console is separate from the API. Monitor it independently — a broken Traefik configuration or a failed SSL certificate renewal can take down the console while leaving the API accessible.

Add a simple HTTP monitor:

  • URL: https://your-appwrite.com (the console root)
  • Expected status: 200
  • Keyword: Appwrite (to confirm the right page is loading)

Step 5: Configure alerts

Set up alert channels in Vigilmon so the right people are notified immediately.

Slack:

  1. Create an incoming webhook in your Slack workspace
  2. Vigilmon: Notifications → New Channel → Slack
  3. Paste the webhook URL and enable it on all your Appwrite monitors

PagerDuty or on-call rotation: For production Appwrite deployments, wire Vigilmon into your on-call tool via webhook:

  1. Vigilmon: Notifications → New Channel → Webhook
  2. Enter your PagerDuty Events API or on-call webhook URL

When the database goes down:

🔴 DOWN: your-appwrite.com/v1/health/db
Keyword "status":"pass" not found
Regions: US-East, EU-West
Started: 4 minutes ago

When it recovers:

✅ RECOVERED: your-appwrite.com/v1/health/db is back UP
Total downtime: 12 minutes

Step 6: Docker Compose health checks

If you manage Appwrite via Docker Compose (the standard self-hosted setup), add container-level health checks to the core service:

# docker-compose.yml (add to the appwrite service)
services:
  appwrite:
    # ... existing config ...
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost/v1/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 90s

This makes Docker aware of Appwrite's health state and restarts the container automatically on repeated failures. Vigilmon handles the external alert; Docker handles the self-healing.


Step 7: Set up a public status page

If you're offering Appwrite as a backend to other developers or teams, give them visibility into service health.

In Vigilmon:

  1. Status Pages → New Status Page
  2. Name it (e.g. "Backend Services")
  3. Add monitors grouped by service:
    • API — the core /v1/health monitor
    • Database — the /v1/health/db monitor
    • Storage — the /v1/health/storage/local monitor
  4. Save and share the public URL

What you've built

| What | How | |---|---| | API health monitoring | Vigilmon HTTP monitor on /v1/health | | Per-service health | Separate monitors for DB, cache, queue, storage | | Keyword assertion | Verify "status":"pass" in response body | | Cloud function monitoring | Heartbeat ping after each successful execution | | Console monitoring | HTTP monitor on the Appwrite console URL | | Instant alerts | Slack/webhook notifications on down + recovery | | Container self-healing | Docker Compose healthcheck + restart policy | | Public status page | Vigilmon status page for API consumers |

Appwrite's built-in /v1/health API does most of the heavy lifting. The key is checking each service independently — a database failure that keeps the API process alive is invisible to a single top-level monitor but immediately visible when you watch /v1/health/db separately.


Get started free at vigilmon.online — your first monitor is running in under a minute.

Monitor your app with Vigilmon

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

Start free →