Self-Hosting Monit with Docker Compose
What Is Monit?
Monit is a lightweight process and system monitoring tool that can automatically restart failed services, monitor resource usage, and alert you when thresholds are breached. It replaces the need for manual process babysitting and expensive monitoring SaaS. Monit runs as a daemon, checking services at configurable intervals, and provides a simple web UI for status visibility.
Prerequisites
- A Linux server (Ubuntu 22.04+ recommended)
- Docker and Docker Compose installed (guide)
- 512 MB of free RAM (minimum)
- 1 GB of free disk space
- A domain name (optional, for remote access)
Docker Compose Configuration
Monit does not have an official Docker image. The best community option is the lightweight Alpine-based image. Create a project directory and the following files.
Create a docker-compose.yml file:
services:
monit:
image: kijart/monit:5.34.2
container_name: monit
restart: unless-stopped
ports:
- "2812:2812" # Monit web UI
volumes:
- ./monitrc:/etc/monit/monitrc:ro # Main config file
- ./conf.d:/etc/monit/conf.d:ro # Additional service monitors
- monit-state:/var/lib/monit # Persistent state
- /var/run/docker.sock:/var/run/docker.sock:ro # Monitor Docker containers
- /proc:/host/proc:ro # Host process info
networks:
- monitoring
networks:
monitoring:
driver: bridge
volumes:
monit-state:
Create a monitrc configuration file:
# /monitrc - Monit main configuration
# This file MUST have permissions 0700 (chmod 700 monitrc)
# Check services every 30 seconds
set daemon 30
# Enable web interface
set httpd port 2812 and
use address 0.0.0.0
allow admin:changeme # CHANGE THIS PASSWORD
# Log to stdout for Docker
set log syslog
# State file for persistence
set statefile /var/lib/monit/monit.state
# Mail server for alerts (optional - configure your SMTP)
# set mailserver smtp.example.com port 587
# username "[email protected]"
# password "your-smtp-password"
# using tlsv13
# Alert recipient
# set alert [email protected]
# System monitoring
check system $HOST
if loadavg (1min) per core > 2 for 5 cycles then alert
if loadavg (5min) per core > 1.5 for 10 cycles then alert
if cpu usage > 90% for 5 cycles then alert
if memory usage > 85% then alert
if swap usage > 25% then alert
# Include additional service monitors
include /etc/monit/conf.d/*
Create a conf.d/ directory with example service monitors:
mkdir -p conf.d
Example conf.d/docker.conf for monitoring a Docker container:
# Monitor a Docker container by name
check program nginx-container with path "/bin/sh -c 'docker inspect --format={{.State.Running}} nginx 2>/dev/null | grep true'"
if status != 0 for 3 cycles then alert
group docker
Set correct permissions and start:
chmod 700 monitrc
docker compose up -d
Initial Setup
- Open
http://your-server-ip:2812in your browser - Log in with the credentials from
monitrc(default:admin/changeme) - The dashboard shows all monitored services and system metrics
- Change the default password immediately by editing
monitrc
| Default Setting | Value |
|---|---|
| Web UI port | 2812 |
| Username | admin |
| Password | changeme |
| Check interval | 30 seconds |
Configuration
Adding Service Monitors
Monit uses a declarative config syntax. Add files to conf.d/ for each service:
Monitor a network service:
# conf.d/ssh.conf
check process sshd with pidfile /var/run/sshd.pid
start program = "/usr/sbin/service ssh start"
stop program = "/usr/sbin/service ssh stop"
if failed port 22 protocol ssh then restart
if 5 restarts within 5 cycles then alert
Monitor disk space:
# conf.d/disk.conf
check filesystem rootfs with path /
if space usage > 80% then alert
if space usage > 95% then exec "/bin/sh -c 'docker system prune -f'"
Monitor a Docker container health:
# conf.d/nextcloud.conf
check program nextcloud with path "/bin/sh -c 'docker inspect --format={{.State.Health.Status}} nextcloud 2>/dev/null | grep healthy'"
if status != 0 for 5 cycles then alert
group docker
Alert Configuration
Configure email alerts by uncommenting the mail server section in monitrc:
set mailserver smtp.gmail.com port 587
username "[email protected]"
password "app-specific-password"
using tlsv13
set alert [email protected] not on { instance, pid, ppid }
Advanced Configuration (Optional)
M/Monit Integration
M/Monit is the commercial companion that aggregates data from multiple Monit instances. Add to monitrc:
set mmonit http://user:[email protected]:8080/collector
Custom Event Handlers
Monit can execute arbitrary scripts when conditions are met:
check process myapp matching "myapp"
if failed port 8080 protocol http then exec "/usr/local/bin/restart-myapp.sh"
if memory > 500 MB for 5 cycles then exec "/usr/local/bin/alert-slack.sh"
Reverse Proxy
To access Monit behind a reverse proxy with SSL:
Nginx Proxy Manager: Create a proxy host pointing to monit:2812. For detailed reverse proxy setup, see our Reverse Proxy Setup guide.
Caddy:
monit.example.com {
reverse_proxy monit:2812
}
Backup
Back up the Monit configuration:
# Back up config files
cp -r monitrc conf.d/ /path/to/backup/
# State is recreated on restart — no backup needed
For a comprehensive backup strategy, see our Backup Strategy guide.
Troubleshooting
Monit refuses to start — “Permission denied”
Symptom: Container exits immediately with a permissions error.
Fix: The monitrc file must have chmod 700 permissions:
chmod 700 monitrc
docker compose restart monit
Web UI not accessible
Symptom: Cannot reach the web interface on port 2812.
Fix: Ensure monitrc has use address 0.0.0.0 (not localhost). Localhost binding prevents external access from outside the container.
Docker socket monitoring not working
Symptom: Docker container checks always fail. Fix: Verify the Docker socket is mounted and the container user has access:
docker compose exec monit ls -la /var/run/docker.sock
Alerts not sending
Symptom: Conditions trigger but no email arrives. Fix: Test SMTP connectivity from inside the container. Check that your mail server accepts connections from Docker’s network range. Use app-specific passwords for Gmail.
Resource Requirements
| Resource | Requirement |
|---|---|
| RAM | ~20 MB idle, ~50 MB under load |
| CPU | Very low — lightweight C daemon |
| Disk | ~10 MB for application + state |
Monit is one of the lightest monitoring tools available. It runs comfortably on a Raspberry Pi.
Verdict
Monit is the right choice when you need process supervision and automatic restarts — not dashboards or metrics history. It excels at keeping services alive and alerting on basic system thresholds with almost zero resource overhead. If you want pretty graphs and long-term metrics, use Grafana + Prometheus. If you want simple uptime monitoring, use Uptime Kuma. But if you want a tiny daemon that watches your processes and restarts them when they die, Monit is hard to beat.
For a richer monitoring experience with a web dashboard, consider Netdata (real-time metrics) or Beszel (lightweight server monitoring).
Related
Get self-hosting tips in your inbox
Get the Docker Compose configs, hardware picks, and setup shortcuts we don't put in articles. Weekly. No spam.
Comments