π Professional WAN IP monitoring with multi-platform notifications
Monitor your WAN IPv4 and IPv6 addresses and receive instant notifications via Discord, Telegram, and Email when they change.
Perfect for homelabs, remote access, dynamic DNS monitoring, and more! π
Features β’ Quick Start β’ Configuration β’ Documentation β’ Upgrading
- π Automatic IP Change Detection - Monitors both IPv4 and IPv6
- π± Multi-Platform Notifications - Discord, Telegram, or Email (or all simultaneously)
- π Notification Retry Logic - Automatic retry with exponential backoff (v1.4.0)
- β Configuration Validation - Validates settings before startup (v1.4.0)
- ποΈ Explicit Enable/Disable Flags - Full control over notification platforms
- πΌοΈ Configurable Discord Avatars - Use webhook's avatar or custom URL
- π Geographic Information - Optional location data via ipinfo.io
- π³ Docker Optimized - Lightweight, continuous monitoring
- πΎ Persistent Storage - Survives container restarts
- π¦ Multi-Architecture - Supports AMD64 and ARM64 via automated builds
- β‘ Resource Efficient - ~50-60MB RAM usage
- π‘οΈ Error Handling - Automatic recovery and error notifications
- π§ͺ Tested & Validated - 109+ unit tests with CI/CD pipeline (v1.4.0)
- π Type Hints - Full type annotations for better code quality (v1.4.0)
- β Python 3.14 - Latest Python with JIT compiler for better performance
- β Code Quality Improvements - Fixed 65+ linting issues, standardized formatting
- β Security Enhancements - Resolved 8 CodeQL security alerts, added workflow permissions
- β CI/CD Improvements - All checks passing (Black, isort, MyPy with type stubs)
- β Smaller Docker Image - Optimized from 51MB to 49MB
- β Enhanced Testing - Now testing across Python 3.10, 3.11, 3.12, 3.13, and 3.14
- β Configuration Validator - Comprehensive validation before startup with clear error messages
- β Notification Retry Logic - Automatic retry with exponential backoff (3 attempts: 1s, 2s, 4s)
- β Enhanced IPv6 Validation - Proper format checking, filters special-use addresses
- β Unit Test Suite - 109+ test cases with pytest and coverage reporting
- β Type Hints - Full type annotations throughout codebase
- β Multi-Architecture - Automated AMD64 and ARM64 Docker builds
See CHANGELOG.md for full version history.
Choose at least one notification platform:
Option 1: Discord (Webhook)
- Go to Discord Server Settings β Integrations β Webhooks
- Create New Webhook
- Configure avatar (optional - in webhook settings)
- Copy the Webhook URL
Option 2: Telegram (Bot)
- Open Telegram and message @BotFather
- Send
/newbotand follow the instructions - Save your bot token (e.g.,
123456789:ABCdefGHIjklMNOpqrsTUVwxyz) - Message @userinfobot to get your Chat ID
- Start a chat with your new bot (send
/start)
Option 3: Email (SMTP)
- Configure your SMTP server details
- Enable "less secure apps" or use app-specific password if required
Optional: Get free ipinfo.io token from ipinfo.io/signup
-
Download docker-compose.yml:
curl -O https://raw.githubusercontent.com/noxied/wanwatcher/main/docker-compose.yml
-
Edit configuration:
nano docker-compose.yml
Configure your notification settings:
environment: # Discord Configuration DISCORD_ENABLED: "true" # NEW in v1.3.1 - Must be "true" to enable DISCORD_WEBHOOK_URL: "https://discord.com/api/webhooks/..." DISCORD_AVATAR_URL: "" # Optional custom avatar URL # Telegram Configuration TELEGRAM_ENABLED: "false" # Set to "true" to enable TELEGRAM_BOT_TOKEN: "" TELEGRAM_CHAT_ID: "" # Email Configuration EMAIL_ENABLED: "false" # Set to "true" to enable EMAIL_SMTP_HOST: "" EMAIL_SMTP_PORT: "587" # General Settings SERVER_NAME: "My Server" CHECK_INTERVAL: "900"
-
Start the container:
docker-compose up -d
-
Check logs:
docker-compose logs -f
You should see:
Notification Status: Discord: Configured β Telegram: Not enabled Email: Not enabled
Discord notifications:
docker run -d \
--name wanwatcher \
--restart unless-stopped \
-e DISCORD_ENABLED="true" \
-e DISCORD_WEBHOOK_URL="your_discord_webhook_url" \
-e SERVER_NAME="My Server" \
-e CHECK_INTERVAL="900" \
-v $(pwd)/data:/data \
-v $(pwd)/logs:/logs \
noxied/wanwatcher:latestFor Telegram, add:
-e TELEGRAM_ENABLED="true" \
-e TELEGRAM_BOT_TOKEN="your_telegram_bot_token" \
-e TELEGRAM_CHAT_ID="your_telegram_chat_id" \For Email, add:
-e EMAIL_ENABLED="true" \
-e EMAIL_SMTP_HOST="smtp.gmail.com" \
-e EMAIL_SMTP_PORT="587" \
-e EMAIL_SMTP_USER="your_email@gmail.com" \
-e EMAIL_SMTP_PASSWORD="your_app_password" \
-e EMAIL_FROM="your_email@gmail.com" \
-e EMAIL_TO="recipient@example.com" \- CHANGELOG.md - Version history and changes
- UPGRADING.md - How to upgrade between versions
- Troubleshooting - Common issues and solutions
See UPGRADING.md for detailed instructions on upgrading from previous versions.
DISCORD_ENABLED="true" to enable Discord notifications.
| Variable | Required | Default | Description |
|---|---|---|---|
| Discord Settings | |||
DISCORD_ENABLED |
No | false |
Enable/disable Discord notifications (NEW in v1.3.1) |
DISCORD_WEBHOOK_URL |
No* | - | Discord webhook URL for notifications |
DISCORD_AVATAR_URL |
No | - | Custom avatar URL (optional, uses webhook's avatar by default) |
| Telegram Settings | |||
TELEGRAM_ENABLED |
No | false |
Enable Telegram notifications |
TELEGRAM_BOT_TOKEN |
No* | - | Telegram bot token from @BotFather |
TELEGRAM_CHAT_ID |
No* | - | Your Telegram chat ID |
TELEGRAM_PARSE_MODE |
No | HTML |
Message format: HTML or Markdown |
| Email Settings | |||
EMAIL_ENABLED |
No | false |
Enable email notifications |
EMAIL_SMTP_HOST |
No* | - | SMTP server address (e.g., smtp.gmail.com) |
EMAIL_SMTP_PORT |
No | 587 |
SMTP server port |
EMAIL_USE_TLS |
No | true |
Use TLS encryption |
EMAIL_SMTP_USER |
No* | - | SMTP username |
EMAIL_SMTP_PASSWORD |
No* | - | SMTP password or app-specific password |
EMAIL_FROM |
No* | - | Sender email address |
EMAIL_TO |
No* | - | Recipient email address |
| General Settings | |||
SERVER_NAME |
No | WANwatcher Docker |
Server name for identification |
BOT_NAME |
No | WANwatcher |
Bot display name |
CHECK_INTERVAL |
No | 900 |
Check interval in seconds (15 min) |
IPINFO_TOKEN |
No | - | ipinfo.io token for geographic data |
MONITOR_IPV4 |
No | true |
Enable IPv4 monitoring |
MONITOR_IPV6 |
No | true |
Enable IPv6 monitoring |
* Required only if the corresponding platform is enabled. At least one notification platform must be enabled.
1. Discord Only:
environment:
DISCORD_ENABLED: "true"
DISCORD_WEBHOOK_URL: "https://discord.com/api/webhooks/..."
TELEGRAM_ENABLED: "false"
EMAIL_ENABLED: "false"2. Telegram Only:
environment:
DISCORD_ENABLED: "false"
TELEGRAM_ENABLED: "true"
TELEGRAM_BOT_TOKEN: "123456789:ABC..."
TELEGRAM_CHAT_ID: "123456789"
EMAIL_ENABLED: "false"3. Email Only:
environment:
DISCORD_ENABLED: "false"
TELEGRAM_ENABLED: "false"
EMAIL_ENABLED: "true"
EMAIL_SMTP_HOST: "smtp.gmail.com"
EMAIL_SMTP_USER: "your_email@gmail.com"
EMAIL_SMTP_PASSWORD: "your_app_password"
EMAIL_FROM: "your_email@gmail.com"
EMAIL_TO: "recipient@example.com"4. All Platforms (Recommended for redundancy):
environment:
DISCORD_ENABLED: "true"
DISCORD_WEBHOOK_URL: "https://discord.com/api/webhooks/..."
TELEGRAM_ENABLED: "true"
TELEGRAM_BOT_TOKEN: "123456789:ABC..."
TELEGRAM_CHAT_ID: "123456789"
EMAIL_ENABLED: "true"
EMAIL_SMTP_HOST: "smtp.gmail.com"
EMAIL_SMTP_USER: "your_email@gmail.com"
EMAIL_SMTP_PASSWORD: "your_app_password"
EMAIL_FROM: "your_email@gmail.com"
EMAIL_TO: "recipient@example.com"WANwatcher validates your configuration on startup. Check logs for:
Notification Status:
Discord: Configured β
Telegram: Not enabled
Email: Configured β
If you see errors, verify:
- Platform
*_ENABLEDflags are set to"true"(with quotes) - All required credentials are provided for enabled platforms
- URLs and tokens are valid and not expired
To enable Discord notifications:
- Set
DISCORD_ENABLED="true" - Provide your
DISCORD_WEBHOOK_URL - (Optional) Configure avatar (see below)
Example:
environment:
DISCORD_ENABLED: "true"
DISCORD_WEBHOOK_URL: "https://discord.com/api/webhooks/YOUR_ID/YOUR_TOKEN"Option 1: Use Webhook's Avatar (Recommended)
- Go to Discord Server Settings > Integrations > Webhooks
- Edit your webhook
- Set an avatar image
- Leave
DISCORD_AVATAR_URLempty in your config - WANwatcher will use the webhook's avatar automatically
Option 2: Use Custom Avatar URL
environment:
DISCORD_AVATAR_URL: "https://example.com/your-avatar.png"Custom avatar requirements:
- Must be publicly accessible URL
- Must use
http://orhttps://scheme - Must be a valid image file (PNG, JPG, GIF)
- Must be under 2048 characters
Note: Discord will use your webhook's configured avatar by default if DISCORD_AVATAR_URL is not provided. This is the recommended approach as it's simpler and more reliable.
-
Enable 2-Factor Authentication (if not already enabled)
-
Generate App Password:
- Go to Google Account Settings
- Click on "2-Step Verification"
- Scroll to "App passwords"
- Generate a new app password for "Mail"
-
Configure WANwatcher:
EMAIL_ENABLED: "true" EMAIL_SMTP_HOST: "smtp.gmail.com" EMAIL_SMTP_PORT: "587" EMAIL_SMTP_USER: "your_email@gmail.com" EMAIL_SMTP_PASSWORD: "your_16_char_app_password" EMAIL_FROM: "your_email@gmail.com" EMAIL_TO: "recipient@example.com"
Outlook/Hotmail:
EMAIL_SMTP_HOST: "smtp-mail.outlook.com"
EMAIL_SMTP_PORT: "587"Yahoo Mail:
EMAIL_SMTP_HOST: "smtp.mail.yahoo.com"
EMAIL_SMTP_PORT: "587"Custom SMTP:
EMAIL_SMTP_HOST: "mail.example.com"
EMAIL_SMTP_PORT: "587"
EMAIL_USE_TLS: "true"-
Create the bot:
Open Telegram β Search for @BotFather Send: /newbot Follow the instructions Save your bot token -
Get your Chat ID:
Search for @userinfobot Send: /start Copy your Chat ID -
Start your bot:
Search for your bot Send: /start -
Configure WANwatcher:
TELEGRAM_ENABLED: "true" TELEGRAM_BOT_TOKEN: "123456789:ABCdefGHIjklMNOpqrsTUVwxyz" TELEGRAM_CHAT_ID: "123456789"
| Path | Purpose |
|---|---|
/data |
IP database storage (survives restarts) |
/logs |
Log file storage |
Example:
volumes:
- ./data:/data # Database persists here
- ./logs:/logs # Logs stored here# Real-time logs
docker logs -f wanwatcher
# Last 50 lines
docker logs --tail 50 wanwatcher
# With docker-compose
docker-compose logs -f wanwatcher# Container status
docker ps | grep wanwatcher
# Resource usage
docker stats wanwatcher
# With docker-compose
docker-compose ps# Remove database to trigger first-run notification
docker exec wanwatcher rm /data/ipinfo.db
docker restart wanwatcher
# With docker-compose
docker-compose exec wanwatcher rm /data/ipinfo.db
docker-compose restart wanwatcher-
Check logs for configuration validation:
docker logs wanwatcher | grep "Notification Status"
-
Verify platform is enabled:
docker exec wanwatcher env | grep DISCORD_ENABLED # Should show: DISCORD_ENABLED=true
-
Test Discord webhook:
curl -X POST -H "Content-Type: application/json" \ -d '{"content":"Test"}' "YOUR_DISCORD_WEBHOOK_URL"
-
Test Telegram bot:
curl "https://api.telegram.org/botYOUR_BOT_TOKEN/getMe"
If you upgraded from v1.3.0 or earlier and notifications stopped:
-
Check if DISCORD_ENABLED is set:
docker logs wanwatcher | grep "Discord"
-
Add the required flag:
environment: DISCORD_ENABLED: "true" # Required in v1.3.1+ DISCORD_WEBHOOK_URL: "https://..."
-
Restart container:
docker-compose down docker-compose up -d
See UPGRADING.md for more details on v1.3.1 changes.
Option 1 (Recommended): Configure in Discord
- Go to Discord Server Settings > Integrations > Webhooks
- Edit webhook and set avatar
- Leave
DISCORD_AVATAR_URLempty
Option 2: Use custom URL
DISCORD_AVATAR_URL: "https://example.com/avatar.png"For more troubleshooting, see docs/TROUBLESHOOTING.md
-
Never commit secrets to version control
- Use environment variables
- Add
.envto.gitignore
-
Keep tokens private
- Webhook URLs and bot tokens are sensitive
- Rotate tokens periodically
-
Use app-specific passwords
- For email, use app passwords instead of main password
- Enable 2FA on your email account
- Memory: ~50-60MB
- CPU: <1% idle, ~2-5% during checks
- Disk: <100MB (image + logs)
- Network: Minimal (only during IP checks and notifications)
WANwatcher includes a comprehensive test suite:
# Install development dependencies
pip install -r requirements-dev.txt
# Run all tests with coverage
pytest tests/ -v --cov
# Run specific test file
pytest tests/test_config_validator.py -v
# Run with HTML coverage report
pytest tests/ --cov --cov-report=html
open htmlcov/index.htmlTest your configuration before deployment:
# Export your environment variables
export DISCORD_ENABLED=true
export DISCORD_WEBHOOK_URL="your_webhook_url"
# ... other variables ...
# Run validator
python config_validator.py# Format code
black *.py
isort *.py
# Lint
flake8 *.py
pylint *.py
# Type checking
mypy *.py --ignore-missing-importsThe CI/CD pipeline automatically builds for AMD64 and ARM64:
- Triggered on git tags (e.g.,
v1.4.0) - Automated via GitHub Actions
- Published to Docker Hub
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Write tests for your changes
- Ensure all tests pass:
pytest tests/ -v - Submit a Pull Request
The CI/CD pipeline will automatically:
- Run linting (Black, Flake8, Pylint)
- Run security scans (Bandit, Safety)
- Run all tests on Python 3.10, 3.11, 3.12
- Build Docker images for AMD64 and ARM64
MIT License - see LICENSE file for details.
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Documentation: CHANGELOG.md | UPGRADING.md
See CHANGELOG.md for complete version history.
Made with β€οΈ for homelab enthusiasts
