# Website Monitor A comprehensive website monitoring application built with ReasonML, OCaml, and server-reason-react. Monitor multiple websites for HTTP status deviations and receive alerts via email or webhooks. ## Features - **Real-time Monitoring**: Continuously monitor websites for HTTP 200 status deviations - **Alert System**: Send alerts via email or webhooks when websites go down or recover - **Admin Dashboard**: Beautiful, responsive web interface for managing websites and alerts - **REST API**: Full CRUD API for programmatic access - **History Tracking**: Keep detailed history of all website checks - **Docker Support**: Fully containerized with Docker and Docker Compose - **Resource-Constrained Builds**: Docker builds limited to 1 CPU core ## Technology Stack - **Language**: OCaml 5.0+ with ReasonML - **Web Framework**: Dream (OCaml web framework) - **Frontend**: server-reason-react (server-side React with ReasonML) - **Database**: PostgreSQL with Caqti (OCaml database interface) - **Async**: Lwt (OCaml's cooperative threading library) - **Container**: Docker & Docker Compose ## Quick Start ### Prerequisites - Docker 20.10+ - Docker Compose 2.0+ ### Installation 1. Clone the repository: ```bash git clone cd test3 ``` 2. Create environment file: ```bash cp .env.example .env ``` 3. Edit `.env` with your configuration (especially SMTP settings for alerts) 4. Start the application: ```bash docker-compose up -d ``` 5. Access the dashboard at http://localhost:8080 ## Configuration ### Environment Variables | Variable | Description | Default | |----------|-------------|---------| | `DB_PASSWORD` | PostgreSQL database password | `changeme` | | `SMTP_HOST` | SMTP server hostname | `smtp.gmail.com` | | `SMTP_PORT` | SMTP server port | `587` | | `SMTP_USER` | SMTP username | - | | `SMTP_PASSWORD` | SMTP password | - | | `ADMIN_EMAIL` | Email to receive all alerts | `admin@example.com` | | `SECRET_KEY` | Secret key for sessions | - | | `ENVIRONMENT` | Environment (`development`/`production`) | `production` | ## API Documentation ### Websites #### List all websites ``` GET /api/websites ``` #### Get website by ID ``` GET /api/websites/:id ``` #### Create website ``` POST /api/websites Content-Type: application/json { "name": "Example Site", "url": "https://example.com", "expected_status": 200, "timeout": 30, "check_interval": 300 } ``` #### Update website ``` PUT /api/websites/:id Content-Type: application/json { "name": "Updated Name", "active": true } ``` #### Delete website ``` DELETE /api/websites/:id ``` #### Check website now ``` POST /api/websites/:id/check ``` #### Get website history ``` GET /api/websites/:id/history?limit=100 ``` #### Get website status ``` GET /api/websites/:id/status ``` ### Alerts #### List all alerts ``` GET /api/alerts ``` #### Get alert by ID ``` GET /api/alerts/:id ``` #### Create alert ``` POST /api/alerts Content-Type: application/json { "website_id": 1, "alert_type": "email", "config": { "to_email": "admin@example.com", "cc_email": "client@example.com", "subject_prefix": "[Monitor]" } } ``` #### Update alert ``` PUT /api/alerts/:id Content-Type: application/json { "enabled": true } ``` #### Delete alert ``` DELETE /api/alerts/:id ``` ### Stats #### Get summary statistics ``` GET /api/stats/summary ``` ## Alert Types ### Email Alerts Configuration: ```json { "to_email": "recipient@example.com", "cc_email": "cc@example.com", // optional "subject_prefix": "[Monitor]" // optional } ``` ### Webhook Alerts Configuration: ```json { "url": "https://hooks.slack.com/services/...", "method": "POST", "headers": { "Content-Type": "application/json" }, "body_template": "" } ``` ## Development ### Local Development 1. Install dependencies: ```bash opam install . --deps-only ``` 2. Build the project: ```bash dune build ``` 3. Run tests: ```bash dune test ``` 4. Run the application: ```bash dune exec bin/main.exe ``` ### Docker Development Build with CPU constraint (1 core): ```bash docker build --build-arg BUILDKIT_INLINE_CACHE=1 -t website_monitor . ``` Run with Docker Compose: ```bash docker-compose up ``` ## Project Structure ``` test3/ ├── bin/ │ ├── dune # Binary build configuration │ └── main.ml # Application entry point ├── lib/ │ ├── dune # Library build configuration │ ├── database.ml # Database models and queries │ ├── monitor.ml # Website monitoring logic │ ├── alert.ml # Alerting system │ ├── api.ml # REST API handlers │ ├── ui.ml # Server-side React UI │ └── scheduler.ml # Background monitoring scheduler ├── docker/ │ └── Dockerfile ├── docker-compose.yml ├── dune-project ├── website_monitor.opam ├── .env.example └── README.md ``` ## Monitoring Behavior - Websites are checked at their configured `check_interval` (default: 5 minutes) - Failed checks trigger alerts to configured endpoints - Recovery alerts are sent when a website returns to normal - Check history is retained for 30 days (configurable) - The scheduler runs every minute to check due websites ## CPU Constraints The Docker build is configured to use only 1 CPU core: ```dockerfile ENV OPAMJOBS=1 ``` In docker-compose.yml: ```yaml cpus: '1.0' cpuset: '0' ``` ## Security Considerations 1. **Environment Variables**: Never commit `.env` files to version control 2. **Secrets**: Use strong random strings for `SECRET_KEY` 3. **SMTP**: Use app-specific passwords, not your main password 4. **Database**: Change default passwords in production 5. **HTTPS**: Use a reverse proxy (nginx, Traefik) for HTTPS ## Troubleshooting ### Database Connection Issues ```bash docker-compose logs postgres ``` ### SMTP Issues - Check SMTP credentials in `.env` - Verify SMTP host and port - Use app-specific passwords for Gmail ### High CPU Usage - Increase `check_interval` for less frequent checks - Reduce number of active websites - The build is already limited to 1 CPU core ## License MIT License - see LICENSE file for details ## Contributing 1. Fork the repository 2. Create a feature branch 3. Make your changes 4. Write tests 5. Submit a pull request ## Support For issues and questions, please open an issue on the GitHub repository.