Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

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

AltStyle γ«γ‚ˆγ£γ¦ε€‰ζ›γ•γ‚ŒγŸγƒšγƒΌγ‚Έ (->γ‚ͺγƒͺγ‚ΈγƒŠγƒ«) /