EspoCRM is a modern, lightweight open-source CRM platform (PHP/JavaScript, GPL-3.0) designed for teams that need clean architecture, extensive REST API coverage, and a fast, self-hostable alternative to heavier CRM suites. With over 200 extensions available and active community development, EspoCRM is a popular choice for small-to-medium teams and VPS deployments where resource efficiency matters.
When you self-host EspoCRM, you take on full operational responsibility. This tutorial walks you through setting up comprehensive monitoring for a self-hosted EspoCRM installation using Vigilmon — so you catch outages, API failures, and background job stoppages before your team does.
Why monitoring EspoCRM matters
EspoCRM is a multi-layer PHP application with a REST API backend, a JavaScript SPA frontend, and a daemon-based background job runner. Each layer can fail independently:
- Web server / PHP failure — Apache or Nginx stops serving requests; users get 502 or a blank page
- Database connectivity loss — EspoCRM's PHP backend can't connect to MySQL/MariaDB; API calls return 500 errors
- REST API routing failure — the API path is misconfigured or PHP-FPM exhausted; integrations lose connectivity
- Background job runner stoppage —
daemon.phpstops processing jobs; email fetching, workflow triggers, and reminders silently queue up - SPA loading failure — a bad deployment or nginx misconfiguration causes the JavaScript frontend to fail to load
External monitoring from Vigilmon checks each layer from the outside — the same perspective as your users and integrated tools.
What you'll need
- A running self-hosted EspoCRM instance (Linux/Apache, Nginx, or Docker)
- A free Vigilmon account — no credit card required
- Your EspoCRM public URL (e.g.
https://crm.yourdomain.com)
Step 1: Monitor the EspoCRM web UI
The web UI check confirms that your web server is serving the EspoCRM frontend at all.
- Log in to vigilmon.online and go to Monitors → New Monitor
- Choose HTTP / HTTPS
- Set the URL to:
https://crm.yourdomain.com/ - Check interval: 1 minute
- Expected status code:
200 - (Optional) Response body contains:
EspoCRM - Save the monitor
A successful 200 response confirms that nginx or Apache is running and the SPA entry point is being served.
Step 2: Monitor the REST API health endpoint (unauthenticated)
EspoCRM exposes an unauthenticated API health endpoint that returns version and application status information. This is the ideal lightweight health probe.
- Create a new HTTP / HTTPS monitor
- URL:
https://crm.yourdomain.com/api/v1/App/about - Check interval: 1 minute
- Expected status code:
200 - (Optional) Response body contains:
version - Save the monitor
This endpoint returns a JSON payload like {"version":"8.x.x","coreVersion":"..."}. It is unauthenticated and fast, making it the best primary uptime check for EspoCRM's API layer. If the PHP runtime, routing, or JSON serialization stack is broken, this will fail.
Step 3: Monitor authenticated API connectivity (database check)
The /api/v1/App/user endpoint returns authenticated user information and requires a valid session or API key. Adding this check verifies not just the API layer, but also database connectivity — because EspoCRM must query the database to return user data.
- Create a new HTTP / HTTPS monitor
- URL:
https://crm.yourdomain.com/api/v1/App/user - Method:
GET - Add HTTP headers:
X-Api-Key: YOUR_ESPOCRM_API_KEY - Check interval: 2 minutes
- Expected status code:
200 - (Optional) Response body contains:
userName - Save the monitor
To create a dedicated API key for monitoring:
- In EspoCRM, go to Administration → API Users
- Create a new API User with read-only access
- Copy the generated API key and paste it into the Vigilmon monitor header
This check catches database connection failures that the unauthenticated /App/about endpoint might not reveal.
Step 4: Monitor SSL certificate expiry
An expired TLS certificate locks out every user and API integration simultaneously — with no warning to end users except a browser error.
- Create a new SSL Certificate monitor in Vigilmon
- Domain:
crm.yourdomain.com - Alert thresholds:
- Warning: 30 days before expiry
- Critical: 7 days before expiry
- Save the monitor
If you're using Let's Encrypt with certbot or acme.sh, this monitor acts as a safety net if auto-renewal fails silently.
Step 5: Monitor EspoCRM background job runner with a heartbeat
EspoCRM's background job runner (daemon.php) is responsible for fetching emails via IMAP, processing workflow triggers, sending reminder notifications, and running scheduled jobs. If the daemon stops — due to a PHP crash, memory exhaustion, or a deployment error — these operations queue up silently with no visible indicator in the UI.
Create a Vigilmon heartbeat monitor
- In Vigilmon, go to Monitors → New Monitor
- Choose Heartbeat / Cron Job
- Name it
EspoCRM Background Job Runner - Set the expected interval to 5 minutes
- Copy the generated heartbeat URL:
https://vigilmon.online/heartbeat/YOUR_TOKEN - Save the monitor
Configure the EspoCRM cron job to ping Vigilmon
EspoCRM uses a cron job to drive its background processing. Modify /etc/cron.d/espocrm or the web server user's crontab:
* * * * * www-data /usr/bin/php /var/www/html/espocrm/cron.php > /dev/null 2>&1 && curl -fsS --retry 3 https://vigilmon.online/heartbeat/YOUR_TOKEN > /dev/null
If you're running the daemon mode instead:
# /etc/systemd/system/espocrm-daemon.service
[Unit]
Description=EspoCRM Daemon
After=network.target
[Service]
Type=simple
User=www-data
WorkingDirectory=/var/www/html/espocrm
ExecStart=/usr/bin/php daemon.php
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
For daemon mode, add a periodic health ping from a wrapper script or use the /api/v1/App/about heartbeat check instead — if the daemon is processing jobs, the API remains responsive:
*/5 * * * * www-data curl -fsS --retry 3 https://crm.yourdomain.com/api/v1/App/about > /dev/null && curl -fsS --retry 3 https://vigilmon.online/heartbeat/YOUR_TOKEN > /dev/null
Step 6: Configure alert channels
- In Vigilmon, go to Alert Channels → Add Channel
- Add your preferred notification channels:
- Slack — route alerts to
#operationsor#crm-alerts - Email — notify the EspoCRM administrator
- Webhook — forward to PagerDuty, OpsGenie, or a custom endpoint
- Slack — route alerts to
Recommended alert tiers:
| Tier | Trigger | Channel |
|------|---------|---------|
| Immediate | /App/about API unavailable | Slack + email + pager |
| Immediate | Authenticated API failure (DB down) | Slack + email |
| Warning | Background job heartbeat missed | Slack + email |
| Maintenance | SSL expiry within 30 days | Email |
Step 7: Docker Compose deployment with health checks
If you're running EspoCRM with Docker, add health checks to detect container-level failures:
version: "3.9"
services:
espocrm:
image: espocrm/espocrm:latest
ports:
- "80:80"
environment:
ESPOCRM_DATABASE_HOST: mariadb
ESPOCRM_DATABASE_NAME: espocrm
ESPOCRM_DATABASE_USER: espocrm
ESPOCRM_DATABASE_PASSWORD: ${DB_PASSWORD}
ESPOCRM_ADMIN_USERNAME: admin
ESPOCRM_ADMIN_PASSWORD: ${ADMIN_PASSWORD}
depends_on:
mariadb:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/api/v1/App/about"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
restart: unless-stopped
espocrm-daemon:
image: espocrm/espocrm:latest
command: ["daemon.php"]
environment:
ESPOCRM_DATABASE_HOST: mariadb
ESPOCRM_DATABASE_NAME: espocrm
ESPOCRM_DATABASE_USER: espocrm
ESPOCRM_DATABASE_PASSWORD: ${DB_PASSWORD}
depends_on:
mariadb:
condition: service_healthy
restart: unless-stopped
mariadb:
image: mariadb:10.11
environment:
MARIADB_ROOT_PASSWORD: ${ROOT_PASSWORD}
MARIADB_DATABASE: espocrm
MARIADB_USER: espocrm
MARIADB_PASSWORD: ${DB_PASSWORD}
volumes:
- espocrm_db:/var/lib/mysql
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
volumes:
espocrm_db:
Complete monitor setup summary
| Monitor | Type | Target | Interval | Catches |
|---------|------|--------|----------|---------|
| Web UI | HTTP | / | 1 min | Web server / frontend crash |
| API health (unauth) | HTTP | /api/v1/App/about | 1 min | PHP, routing, JSON failure |
| API + DB (auth) | HTTP | /api/v1/App/user | 2 min | Database connectivity loss |
| Background job runner | Heartbeat | cron.php exit ping | 5 min | Daemon / cron stoppage |
| SSL certificate | SSL | crm.yourdomain.com | Daily | Certificate expiry |
Conclusion
EspoCRM's lightweight footprint and clean REST API make it excellent for VPS self-hosting — but that same lightness means there's no built-in monitoring dashboard watching for problems. A PHP crash, a database connection exhaustion, or a stopped daemon can silently break your team's workflows for hours.
With Vigilmon monitoring each layer of your EspoCRM installation, you get 60-second detection of every outage and the background job heartbeat means silent daemon failures don't go unnoticed either.
Start monitoring for free at vigilmon.online.