Skip to content

indiser/WatchDog

Repository files navigation

πŸ• WatchDog

Distributed Uptime Monitoring & Cold-Start Prevention System

Python Flask Celery Redis Docker PostgreSQL HTMX

A production-grade, containerized microservice architecture for preventing cold starts on free-tier hosting platforms

Features β€’ Architecture β€’ Tech Stack β€’ Quick Start β€’ API


πŸ“‹ Table of Contents


🎯 Overview

WatchDog is a sophisticated, distributed uptime monitoring system engineered to solve the cold-start problem inherent in free-tier PaaS platforms (Render, Railway, Fly.io). Built on a microservices architecture, it leverages asynchronous task queues, scheduled workers, and real-time UI updates to ensure your services remain warm and responsive 24/7.

Key Highlights

  • Distributed Task Processing: Celery workers with Redis message broker
  • Intelligent Scheduling: Cron-based task scheduling with configurable intervals
  • Real-time Dashboard: HTMX-powered reactive UI with zero JavaScript frameworks
  • Containerized Deployment: Multi-container Docker Compose orchestration
  • Production Database: PostgreSQL with SQLAlchemy ORM
  • HTTP/2 Support: curl-cffi for browser impersonation and TLS fingerprinting
  • Graceful Failure Handling: Exponential backoff retry mechanism

πŸ” Problem Statement

Free-tier hosting platforms (Render, Railway, Heroku) spin down inactive services after 15 minutes of inactivity, causing:

  • Cold Start Latency: 30-60 second response delays on first request
  • Poor UX: Users experience timeouts and failed requests
  • Lost Opportunities: Recruiters/clients abandon slow-loading portfolio sites

WatchDog solves this by periodically pinging your services at configurable intervals, keeping them perpetually warm and responsive.


πŸ—οΈ System Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                         WatchDog System                         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              β”‚         β”‚              β”‚         β”‚              β”‚
β”‚   Flask Web  │◄─────────    Redis     │────────►│Celery Worker β”‚
β”‚   Server     β”‚         β”‚   Message    β”‚         β”‚    Pool      β”‚
β”‚   (Port 5000)β”‚         β”‚   Broker     β”‚         β”‚  (Async)     β”‚
β”‚              β”‚         β”‚  (Port 6379) β”‚         β”‚              β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚                                                  β”‚
       β”‚                                                  β”‚
       β”‚                 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                β”‚
       β”‚                 β”‚              β”‚                β”‚
       └────────────────►│  PostgreSQL  β”‚β—„β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                         β”‚   Database   β”‚
                         β”‚   (Neon)     β”‚
                         β”‚              β”‚
                         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                β–²
                                β”‚
                         β”Œβ”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”
                         β”‚              β”‚
                         β”‚ Celery Beat  β”‚
                         β”‚  Scheduler   β”‚
                         β”‚ (Cron Jobs)  β”‚
                         β”‚              β”‚
                         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      Request Flow Diagram                       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

User Browser ──► Flask (HTMX) ──► PostgreSQL (Read/Write)
                    β”‚
                    └──► Redis ──► Celery Worker ──► HTTP Request
                                        β”‚                  β”‚
                                        β”‚                  β–Ό
                                        β”‚            Target Service
                                        β”‚                  β”‚
                                        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                           (Update Status)

Component Breakdown

Component Technology Purpose
Web Server Flask + Gunicorn REST API & UI rendering
Message Broker Redis Task queue & pub/sub
Task Workers Celery Async HTTP request execution
Scheduler Celery Beat Cron-based task scheduling
Database PostgreSQL (Neon) Persistent storage
Frontend HTMX + TailwindCSS Reactive SPA-like experience
Containerization Docker Compose Multi-service orchestration

✨ Features

🎨 Frontend

  • Zero-JavaScript Framework: Pure HTMX for reactive updates
  • Real-time Polling: Auto-refresh every 5 seconds without page reload
  • Responsive Design: Mobile-first TailwindCSS styling
  • Smooth Animations: CSS keyframe animations with staggered delays
  • Dark Theme: Custom dot-grid background with glassmorphism effects
  • HTTP Basic Auth: Password-protected admin dashboard

βš™οΈ Backend

  • Asynchronous Task Queue: Celery with Redis broker
  • Intelligent Scheduling: Per-target configurable ping intervals
  • Retry Logic: Exponential backoff (3 retries, 15s delay)
  • Browser Impersonation: curl-cffi for bypassing bot detection
  • ORM Layer: SQLAlchemy for database abstraction
  • Environment Variables: python-dotenv for configuration management

🐳 DevOps

  • Multi-Stage Dockerfile: Optimized Python 3.13 image
  • Docker Compose: 4-service orchestration (web, worker, beat, redis)
  • Health Checks: Container dependency management
  • Volume Persistence: Redis data persistence
  • Network Isolation: Internal Docker network

πŸ› οΈ Tech Stack

Backend Framework

Flask 3.0          # Lightweight WSGI web framework
Flask-SQLAlchemy   # ORM integration
python-dotenv      # Environment variable management

Task Queue & Scheduling

Celery 5.3         # Distributed task queue
Redis 7.0          # Message broker & result backend
celery-beat        # Periodic task scheduler

Database

PostgreSQL 16      # Production-grade RDBMS
psycopg2-binary    # PostgreSQL adapter
Neon Database      # Serverless Postgres hosting

HTTP Client

curl-cffi          # HTTP/2 client with browser impersonation
requests           # Fallback HTTP library

Frontend

HTMX 1.9           # Hypermedia-driven interactions
TailwindCSS 3.0    # Utility-first CSS framework
Idiomorph          # DOM morphing for smooth updates

DevOps

Docker 24.0        # Containerization
Docker Compose 3.8 # Multi-container orchestration

πŸš€ Installation & Setup

Prerequisites

  • Docker & Docker Compose installed
  • Python 3.13+ (for local development)
  • PostgreSQL database (or use Neon free tier)
  • Redis server (or use Docker)

Option 1: Docker Compose (Recommended)

# Clone the repository
git clone https://github.com/indiser/WatchDog.git
cd WatchDog

# Create environment file
cat > .env << EOF
DATABASE_URL=postgresql://user:pass@host:5432/dbname
ADMIN_USER=admin
ADMIN_PASS=your_secure_password
CELERY_BROKER_URL=redis://redis:6379/0
EOF

# Build and start all services
docker-compose up --build -d

# View logs
docker-compose logs -f

# Access dashboard
open http://localhost:5000

Option 2: Local Development

# Create virtual environment
python -m venv env
source env/bin/activate  # Windows: env\Scripts\activate

# Install dependencies
pip install -r requirements.txt

# Set environment variables
export DATABASE_URL="postgresql://..."
export ADMIN_USER="admin"
export ADMIN_PASS="password"
export CELERY_BROKER_URL="redis://localhost:6379/0"

# Terminal 1: Start Flask
python app.py

# Terminal 2: Start Celery Worker
celery -A tasks.celery worker --pool=solo --loglevel=info

# Terminal 3: Start Celery Beat
celery -A tasks.celery beat --loglevel=info

βš™οΈ Configuration

Environment Variables

Variable Description Default
DATABASE_URL PostgreSQL connection string sqlite:///local_test.db
CELERY_BROKER_URL Redis connection URL redis://localhost:6379/0
ADMIN_USER Dashboard username admin
ADMIN_PASS Dashboard password super_secret_default

Docker Compose Services

services:
  redis:      # Message broker (port 6379)
  web:        # Flask application (port 5000)
  worker:     # Celery task executor
  beat:       # Celery scheduler

Database Schema

class TargetURL(db.Model):
    id                 # Primary key
    url                # Target URL to monitor
    interval_minutes   # Ping frequency (default: 5)
    is_active          # Enable/disable monitoring
    last_pinged_at     # Last successful ping timestamp

πŸ“– Usage

Adding a Target

  1. Navigate to http://localhost:5000
  2. Enter credentials (ADMIN_USER / ADMIN_PASS)
  3. Input target URL and interval (minutes)
  4. Click "Monitor"

Dashboard Features

  • Real-time Stats: Total/Active/Paused targets
  • Target Management: Toggle active status, delete targets
  • Live Updates: Auto-refresh every 5 seconds
  • Mobile Responsive: Card layout on small screens

Monitoring Behavior

# Celery Beat runs every minute
@celery.task
def queue_due_pings():
    # Check each active target
    # If (now - last_ping) >= interval:
    #     Queue ping_url.delay(url)
    #     Update last_pinged_at

πŸ”Œ API Reference

Authentication

All endpoints require HTTP Basic Auth.

Endpoints

GET /

Returns the main dashboard HTML.

POST /add_target_ui

Add a new monitoring target.

Form Data:

url: string (required)
interval_minutes: integer (default: 5)

GET /targets_partial

Returns HTMX-compatible table body HTML.

DELETE /delete_target/<id>

Removes a target from monitoring.

PATCH /toggle_target/<id>

Toggles target active/paused status.

GET /stats

Returns real-time statistics HTML fragment.


πŸ“Š Performance Metrics

Scalability

  • Concurrent Workers: Configurable Celery pool size
  • Request Throughput: 100+ pings/minute per worker
  • Database Connections: SQLAlchemy connection pooling
  • Memory Footprint: ~150MB per container

Reliability

  • Retry Mechanism: 3 attempts with 15s exponential backoff
  • Timeout Handling: 10s HTTP timeout per request
  • Graceful Degradation: Failed pings don't block queue

Monitoring

# Check Celery worker status
celery -A tasks.celery inspect active

# View Redis queue length
redis-cli LLEN celery

# Monitor container health
docker-compose ps

πŸ”’ Security

Implemented Measures

  • βœ… HTTP Basic Authentication: Password-protected dashboard
  • βœ… Environment Variables: Secrets stored in .env (gitignored)
  • βœ… SQL Injection Prevention: SQLAlchemy ORM parameterization
  • βœ… CSRF Protection: Form-based actions only
  • βœ… Docker Network Isolation: Internal service communication

Recommendations

  • Use strong passwords for ADMIN_PASS
  • Enable HTTPS with reverse proxy (Nginx/Caddy)
  • Rotate database credentials regularly
  • Implement rate limiting for production
  • Use secrets management (AWS Secrets Manager, Vault)

🚧 Future Enhancements

Planned Features

  • Webhook Notifications: Slack/Discord alerts on downtime
  • Prometheus Metrics: Grafana dashboard integration
  • Multi-User Support: Role-based access control
  • Response Time Tracking: Historical latency graphs
  • Status Page: Public uptime dashboard
  • API Key Authentication: RESTful API access
  • Kubernetes Deployment: Helm charts for K8s
  • Email Alerts: SMTP integration for notifications

Technical Debt

  • Implement comprehensive unit tests (pytest)
  • Add CI/CD pipeline (GitHub Actions)
  • Database migration system (Alembic)
  • API rate limiting (Flask-Limiter)
  • Logging aggregation (ELK stack)

πŸ“ Project Structure

WatchDog/
β”œβ”€β”€ app.py                 # Flask application & routes
β”œβ”€β”€ tasks.py               # Celery tasks & scheduling
β”œβ”€β”€ requirements.txt       # Python dependencies
β”œβ”€β”€ dockerfile             # Container image definition
β”œβ”€β”€ docker-compose.yml     # Multi-service orchestration
β”œβ”€β”€ .env                   # Environment variables (gitignored)
β”œβ”€β”€ static/
β”‚   └── style.css         # Custom CSS animations
β”œβ”€β”€ templates/
β”‚   β”œβ”€β”€ index.html        # Main dashboard
β”‚   β”œβ”€β”€ _stats_bar.html   # Stats component
β”‚   β”œβ”€β”€ _target_row.html  # Table row partial
β”‚   └── ...               # Other HTMX partials
└── README.md             # This file

🀝 Contributing

Contributions are welcome! Please follow these steps:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/AmazingFeature)
  3. Commit changes (git commit -m 'Add AmazingFeature')
  4. Push to branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.


πŸ‘¨β€πŸ’» Author

Indiser


πŸ™ Acknowledgments

  • Flask team for the excellent web framework
  • Celery project for distributed task processing
  • HTMX for revolutionizing frontend interactivity
  • TailwindCSS for rapid UI development
  • Neon for serverless PostgreSQL hosting

⭐ Star this repository if you find it useful!

Built with ❀️ using Flask, Celery, Redis, and Docker

About

Open-source distributed uptime monitoring | Flask + Celery + Redis + Docker | Asynchronous task processing | Celery Beat scheduler | PostgreSQL/SQLite | HTMX real-time UI | HTTP/2 support | Container orchestration | Prevent cold starts | Health check automation | Python 3.13

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors