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 "alerts@example.com"
# password "your-smtp-password"
# using tlsv13
# Alert recipient
# set alert admin@example.com
# 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 "your-email@gmail.com"
password "app-specific-password"
using tlsv13
set alert admin@example.com 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:password@mmonit.example.com: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).
FAQ
How does Monit compare to Uptime Kuma?
Different tools for different jobs. Uptime Kuma monitors URLs and services from the outside — is it up or down? Monit monitors processes from the inside — is the PID running, is RAM usage too high, should I restart it? Use Uptime Kuma for uptime dashboards and status pages. Use Monit for automatic service recovery and process supervision.
Can Monit automatically restart Docker containers?
Yes, with some setup. Mount the Docker socket into the Monit container and use check program with docker inspect to verify container health. Configure the exec action to run docker restart <container> when checks fail. This requires the Docker CLI inside the Monit container.
Is M/Monit required?
No. M/Monit is the commercial web dashboard that aggregates data from multiple Monit instances. The free Monit daemon works standalone with its built-in web UI. M/Monit adds centralized monitoring across multiple servers, historical data, and better alerting — useful for managing 5+ servers.
Can Monit replace Prometheus and Grafana?
No. Monit is a process supervisor with basic threshold alerting — it watches services and restarts them. Prometheus + Grafana provide time-series metrics, dashboards, and complex alerting rules. Monit is 20 MB; Prometheus + Grafana is 1+ GB. Use Monit for automatic recovery; use Prometheus/Grafana for metrics visualization.
How do I monitor host processes from inside Docker?
Mount /proc and /var/run/docker.sock as read-only volumes into the Monit container. Use check program with shell commands that inspect host-level data through these mounts. For full host monitoring, running Monit directly on the host (not in Docker) is simpler.
What alerting options does Monit support?
Email alerts via SMTP (built-in), custom script execution on any event (pipe to Slack, PagerDuty, webhooks), and M/Monit for centralized alerting. The exec action can run any script, so you can integrate with any notification service.
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