Documentation menu

Docker

Docker's own HEALTHCHECK runs inside the host. If the host, its network or the Docker daemon goes down, nothing reports it. Asniher watches from outside:

  • An HTTP monitor for services published to the internet.
  • A heartbeat monitor for job containers and for services on private networks that Asniher cannot reach.

You create monitors in the dashboard under Monitors → New monitor. The setups below only send pings or answer checks, so they need no API key.

Put the heartbeat URL in an .env file next to compose.yaml, which Compose reads automatically, and keep that file out of source control:

ASNIHER_HEARTBEAT_URL=https://app.asniher.com/api/heartbeat/<token>

Heartbeat: job containers

Add asniher-run to the job's image and make it the entrypoint. It pings /start, runs the command, then reports its exit status with the last 10 KB of output. The container exits with the command's exit status, as before.

FROM postgres:17-alpine
RUN apk add --no-cache curl \
 && curl -fsSL https://app.asniher.com/asniher-run.sh -o /usr/local/bin/asniher-run \
 && chmod +x /usr/local/bin/asniher-run
ENTRYPOINT ["asniher-run", "--"]
CMD ["sh", "-c", "pg_dump --format=custom --file=/backups/db-$(date +%F).dump"]

asniher-run needs sh and curl. On Debian-based images, install curl with apt-get update && apt-get install -y --no-install-recommends curl.

Run the job from the host's crontab with Compose. The jobs profile keeps it from starting with docker compose up:

services:
  backup:
    build: ./backup
    profiles: [jobs]
    environment:
      ASNIHER_HEARTBEAT_URL: ${ASNIHER_HEARTBEAT_URL}
      PGHOST: db
      PGUSER: app
      PGPASSWORD: ${POSTGRES_PASSWORD}
      PGDATABASE: app
    volumes:
      - ./backups:/backups
30 2 * * * cd /srv/app && docker compose run --rm backup

Use the cron expression 30 2 * * * with the host's time zone on the monitor. If the host is down, the cron daemon stops or the image fails to start, no ping arrives and the monitor alerts.

To ping from a job without changing its image, wrap docker run on the host instead:

30 2 * * * asniher-run -u https://app.asniher.com/api/heartbeat/<token> -- docker run --rm acme/report:latest

Heartbeat: internal services

A service with no public URL can still be monitored: let its health check ping Asniher. Each healthy check sends a ping, so the pings stop when the service is unhealthy, the container stops or the host goes down.

services:
  worker:
    image: acme/worker:latest
    environment:
      ASNIHER_HEARTBEAT_URL: ${ASNIHER_HEARTBEAT_URL}
    healthcheck:
      test: ["CMD-SHELL", "curl -fsS http://localhost:8080/healthz > /dev/null || exit 1; curl -fsS -m 10 -X POST \"$$ASNIHER_HEARTBEAT_URL\" > /dev/null || true"]
      interval: 1m
      timeout: 15s
      retries: 3
  • The first curl checks the service. If it fails, the health check fails and no ping is sent.
  • The second curl pings Asniher. || true keeps a network problem on the way to Asniher from marking the container unhealthy.
  • $$ stops Compose from replacing the variable; the shell in the container reads it.

Set the monitor to a fixed period equal to your plan's minimum interval and a grace period of 2 minutes. Pinging more often than the period is fine.

The image needs curl. Replace the first command with whatever health check the service already uses.

HTTP monitor: published services

For a service behind a public domain, add a health endpoint to the app (see the Node.js, Python or ASP.NET Core examples) and create an HTTP monitor for it:

Setting Value
URL https://app.example.com/healthz
Method GET
Expected status 200
Interval Your plan's minimum

Asniher checks from outside your network, so the monitor also catches problems with DNS, TLS certificates, the reverse proxy and the host itself. Monitors can only reach public addresses; for anything on a private network, use the heartbeat setup above.

Check that it works

docker compose run --rm backup

The monitor's ping log shows a start ping, then the exit status and output of the run.

Questions about this page? Email support@asniher.com.