docker-compose.observability.yml adds three services beside ReachCrew:
Errors are the lines on stderr: ReachCrew writes
console.error and console.warn there.
What you need
- A Docker Compose install (Docker Compose) with the repository’s
docker/observability/folder besidedocker-compose.yml, or a clone of the repository. - About 1 GB of RAM to spare.
1. The read-only database role
The outreach and health panels read the database throughgrafana_reader, which can see states, types, timestamps and organization names only: no lead details, no message text, no rendered invitations, no webhook bodies. Each query is cut off after 10 seconds.
Replace CHANGEME-grafana-reader-password in docker/observability/grafana-reader.sql with a password (openssl rand -hex 16), then run it once:
psql "$DATABASE_URL" -f docker/observability/grafana-reader.sql as the database owner. Running it again is safe.
2. Turn it on
Add to.env:
COMPOSE_FILE=docker-compose.yml:docker-compose.https.yml:docker-compose.observability.yml. Then docker compose up -d.
3. Open Grafana
Grafana listens on127.0.0.1:3001 only, because it shows delivery data for every organization. From your computer:
admin with GRAFANA_ADMIN_PASSWORD. Anonymous access and sign-up are off.
To give it its own domain instead (for example grafana.example.com), route that name to grafana:3000 in your proxy, set GRAFANA_ROOT_URL=https://grafana.example.com, and keep a strong admin password.
Settings
On Dokploy
Create a separate Compose service in Dokploy from this repository withdocker-compose.observability.yml as its file, and set the variables above under Environment. GRAFANA_DB_HOST must name the database (the Dokploy PostgreSQL service’s internal host and port). Alloy reads the Docker socket, so it collects the ReachCrew app’s log however Dokploy runs it. Set LOG_CONTAINERS to your app’s container name pattern if the server runs other things. Add a domain for the grafana service, port 3000, under Domains.
Alerts
Grafana can alert on the same queries. A good first set, each sent to your on-call channel (Grafana → Alerting → Contact points):- Minutes since LinkedIn engine tick above 10.
- Stuck LinkedIn actions above 0 for 10 minutes.
- Webhooks given up (dead) above 0.
- Oldest unconfirmed above 24 hours.
- Errors above your normal rate.
/api/health from outside the server: if the server itself goes down, Grafana goes down with it.