🌐 Domain Monitor
A powerful, self-hosted domain expiration monitoring system with multi-channel notifications
A modern PHP MVC application for monitoring domain expiration dates and sending notifications through multiple channels (Email, Telegram, Discord, Slack). Never lose a domain again with automated monitoring and timely alerts.
✨ Features
Core Features
- 📋 Domain Management - Add, edit, and monitor unlimited domains
- 🔍 Smart WHOIS/RDAP Lookup - Automatically fetches expiration dates and registrar information
- 🗂️ TLD Registry System - Built-in support for 1,400+ TLDs with IANA integration
- 🔔 Multi-Channel Notifications - Email, Telegram, Discord, and Slack support
- 👥 Notification Groups - Organize channels and assign domains flexibly
- ⚡ Real-time Dashboard - Overview of all domains and their status
- 📊 Notification Logs - Complete history of all sent notifications
- 🤖 Automated Monitoring - Cron-based checks with configurable intervals
- 🎨 Modern UI - Clean, responsive design with intuitive interface
Advanced Features
- 🔐 Secure by Default - Random passwords, session management, prepared statements
- 📈 Bulk Operations - Import, refresh, and manage multiple domains at once
- 🎯 Flexible Alerts - Customizable notification thresholds (60, 30, 21, 14, 7, 5, 3, 2, 1 days)
- 🔄 Auto WHOIS Refresh - Keep domain data up-to-date automatically
- 📱 Monitoring Controls - Enable/disable notifications per domain with alerts
- 🌍 RDAP Support - Modern protocol for faster, structured domain data
📋 Requirements
- PHP 8.1 or higher
- MySQL 5.7+ or MariaDB 10.3+
- Composer
- Apache/Nginx with mod_rewrite enabled
- Cron support for automated checks
- SMTP server for email notifications (optional)
🔐 Security
The application includes built-in authentication with secure practices:
- 🔑 Random Password Generation - Unique secure password created on installation
- 🛡️ Session Management - Secure session handling with httpOnly cookies
- 💉 SQL Injection Protection - All queries use prepared statements
- 🔒 One-time Credentials - Admin password shown only once during setup
⚠️ Important: Save your admin password during installation - it won't be shown again!
🚀 Quick Start
1. Clone the Repository
git clone https://github.com/Hosteroid/domain-monitor.git
cd domain-monitor
2. Install Dependencies
composer install
3. Configure Environment
Copy the example environment file:
# Linux/Mac
cp env.example.txt .env
# Windows
copy env.example.txt .env
Edit .env and configure your settings:
# Database
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=domain_monitor
DB_USERNAME=root
DB_PASSWORD=your_password
# Email (if using email notifications)
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=your_username
MAIL_PASSWORD=your_password
MAIL_FROM_ADDRESS=noreply@domainmonitor.com
4. Create Database
Create a MySQL database:
CREATE DATABASE domain_monitor CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
5. Run Migrations
php database/migrate.php
⚠️ IMPORTANT: The migration will generate a random admin password and display it only once:
🔑 Admin credentials (SAVE THESE!):
═══════════════════════════════════════
Username: admin
Password: 3f8a2b9c4d5e6f7a
═══════════════════════════════════════
⚠️ This password will not be shown again!
💾 Save it to a secure password manager.
Save this password immediately - you'll need it to access the dashboard!
6. Import TLD Registry Data (Optional but Recommended)
For enhanced WHOIS lookups with automatic server discovery:
php cron/import_tld_registry.php
This imports RDAP and WHOIS server data for 1,400+ TLDs from IANA.
7. Configure Web Server
Apache
Make sure .htaccess is enabled. Your virtual host should point to the public directory.
Example configuration:
<VirtualHost *:80>
ServerName domainmonitor.local
DocumentRoot "D:/Cursor/Domain Monitor/public"
<Directory "D:/Cursor/Domain Monitor/public">
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
PHP Built-in Server (Development)
php -S localhost:8000 -t public
Then visit: http://localhost:8000
🔧 Configuration
Notification Channels
Configure SMTP settings in .env:
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=your-email@gmail.com
MAIL_PASSWORD=your-app-password
MAIL_ENCRYPTION=tls
✈️ Telegram
- Create a bot using @BotFather
- Get your Chat ID using @userinfobot
- Add the channel in the notification group settings
💬 Discord
- Go to Server Settings → Integrations → Webhooks
- Create a new webhook
- Copy the webhook URL
- Add it in the notification group settings
💼 Slack
- Go to Slack App Settings
- Enable Incoming Webhooks
- Create a new webhook
- Copy the webhook URL
- Add it in the notification group settings
📅 Setting Up Cron Jobs
The application requires a cron job to check domains periodically.
Linux/Mac
crontab -e
Add this line to run daily at 9 AM:
0 9 * * * /usr/bin/php /path/to/project/cron/check_domains.php
Windows
Use Task Scheduler:
- Open Task Scheduler
- Create Basic Task
- Set trigger (e.g., Daily at 9:00 AM)
- Action: Start a program
- Program:
C:\php\php.exe - Arguments:
D:\Cursor\Domain Monitor\cron\check_domains.php
🧪 Testing Notifications
Before setting up the cron job, test your notification channels:
php cron/test_notification.php
Follow the prompts to test Email, Telegram, Discord, or Slack.
📖 Usage Guide
Adding Domains
- Navigate to Domains → Add Domain
- Enter the domain name (e.g.,
example.com) - Optionally assign to a notification group
- Click Add Domain
The system will automatically fetch WHOIS information.
Creating Notification Groups
- Navigate to Notification Groups → Create Group
- Enter a name and description
- Click Create Group
- Add notification channels (Email, Telegram, Discord, Slack)
- Assign domains to the group
Monitoring
The Dashboard shows:
- Total domains and their status
- Domains expiring soon
- Recent notifications sent
Notification Schedule
By default, notifications are sent at these intervals before expiration:
- 60 days (2 months)
- 30 days (1 month)
- 21 days (3 weeks)
- 14 days (2 weeks)
- 7 days (1 week)
- 5 days
- 3 days
- 2 days
- 1 day (tomorrow!)
- When expired (immediate alert)
Configure this in .env:
NOTIFICATION_DAYS_BEFORE=60,30,21,14,7,5,3,2,1
Customization Examples:
# Minimal alerts
NOTIFICATION_DAYS_BEFORE=30,7,1
# More frequent alerts
NOTIFICATION_DAYS_BEFORE=90,60,45,30,21,14,10,7,5,3,2,1
# Business-focused (weekday planning)
NOTIFICATION_DAYS_BEFORE=60,30,14,7,3,1
📁 Project Structure
Domain Monitor/
├── app/
│ ├── Controllers/ # Application controllers
│ ├── Models/ # Database models
│ ├── Services/ # Business logic & services
│ │ └── Channels/ # Notification channel implementations
│ └── Views/ # HTML views
├── core/ # Core MVC framework
├── cron/ # Cron job scripts
├── database/
│ └── migrations/ # Database migrations
├── public/ # Web root (index.php, assets)
├── routes/ # Route definitions
├── vendor/ # Composer dependencies
└── .env # Environment configuration
🔐 Security Considerations
- Never commit
.env- Contains sensitive credentials - Secure your web server - Point only the
publicdirectory to the web - Use strong database passwords
- Enable HTTPS in production
- Protect cron endpoints - Ensure cron scripts aren't web-accessible
- Regular updates - Keep dependencies updated
🐛 Troubleshooting
WHOIS Lookup Fails
- Some domain TLDs may not be supported
- Check if the domain is valid and registered
- Verify your server can make outbound connections
Notifications Not Sending
- Check logs:
logs/cron.log - Verify notification channel configuration
- Test using:
php cron/test_notification.php - Check SMTP/API credentials
Database Connection Error
- Verify database credentials in
.env - Ensure MySQL service is running
- Check if database exists
Cron Job Not Running
- Verify cron syntax and paths
- Check server logs
- Test manually:
php cron/check_domains.php
🐛 Bug Reports & Feature Requests
We welcome bug reports and feature requests! Please use GitHub Issues:
🐞 Report a Bug
Found a bug? Open an issue with:
- Clear description of the issue
- Steps to reproduce
- Expected vs actual behavior
- Environment details (PHP version, OS, etc.)
💡 Request a Feature
Have an idea? Submit a feature request with:
- Clear description of the feature
- Use case and benefits
- Any implementation ideas
🤝 Contributing
Contributions are welcome and appreciated! Here's how you can help:
How to Contribute
- Fork the repository
- Create a feature branch (
git checkout -b feature/AmazingFeature) - Make your changes
- Test thoroughly
- Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
Development Guidelines
- Follow PSR-12 coding standards
- Write clear commit messages
- Add comments for complex logic
- Test your changes before submitting
- Update documentation as needed
Areas for Contribution
- 🐛 Bug fixes
- ✨ New features
- 📝 Documentation improvements
- 🌍 Translations
- 🎨 UI/UX enhancements
- ⚡ Performance optimizations
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
TL;DR: Free to use for personal and commercial projects. Attribution appreciated but not required.
📧 Support & Community
- 💬 Discussions: GitHub Discussions
- 🐛 Issues: Bug Tracker
- 📖 Documentation: Wiki
- ⭐ Star the project if you find it useful!
💼 Created & Sponsored By
Hosteroid - Premium Hosting Solutions
This project is proudly created and maintained by Hosteroid, a leading provider of premium hosting solutions.
Services: Web Hosting • VPS • Dedicated Servers • Domain Registration
🌐 Website: hosteroid.uk
📧 Contact: support@hosteroid.uk
🙏 Acknowledgments
📊 Project Stats
Made with ❤️ by Hosteroid