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, Mattermost, Pushover, Webhook). Never lose a domain again with automated monitoring and timely alerts.
- ๐ 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, Slack, Mattermost, Pushover, and Webhook 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
- ๐ Secure by Default - Random passwords, database-backed sessions, prepared statements
- ๐ User Notifications System - In-app notification center with real-time updates
- ๐ฌ Smart Notifications - Welcome messages, upgrade alerts, domain warnings
- ๐ Advanced Session Management - View all active sessions with geolocation and device tracking
- ๐จ Remote Session Termination - Logout any device immediately from anywhere
- ๐ 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
- ๐ด Geolocation Tracking - See location, ISP, and device info for all sessions
- 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)
The application includes built-in authentication with secure practices:
- ๐ Random Password Generation - Unique secure password created on installation
- ๐ก๏ธ Database-Backed Sessions - True session management with immediate remote logout
- ๐ Session Tracking - Monitor all active sessions with location and device info
- ๐จ Remote Session Control - Terminate suspicious sessions from any device
- ๐ SQL Injection Protection - All queries use prepared statements
- ๐ One-time Credentials - Admin password shown only once during setup
- ๐ช Secure Remember Me - Cryptographically secure 30-day tokens linked to sessions
git clone https://github.com/Hosteroid/domain-monitor.git
cd domain-monitorcomposer installCopy the example environment file:
# Linux/Mac
cp env.example.txt .env
# Windows
copy env.example.txt .envEdit .env and configure your settings:
# Database
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=domain_monitor
DB_USERNAME=root
DB_PASSWORD=your_passwordNote:
- The encryption key (APP_ENCRYPTION_KEY) will be automatically generated during web installation
- Application name, URL, timezone, email settings, and monitoring schedules are configured through the web interface in Settings (not .env)
Create a MySQL database:
CREATE DATABASE domain_monitor CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;Configure your web server (see step 7 below), then visit your domain in a browser:
http://your-domain.com
You'll be automatically redirected to the installer.
php -S localhost:8000 -t publicThen visit: http://localhost:8000
The web installer will:
- โ Create all database tables
- โ
Generate encryption key and save to
.env - โ Let you set admin email and password
- โ Show credentials on completion (save them!)
After logging in, go to TLD Registry page and click "Import TLDs" to download RDAP and WHOIS server data for 1,400+ TLDs from IANA.
Alternatively, use the CLI:
php cron/import_tld_registry.phpMake sure .htaccess is enabled. Your virtual host should point to the public directory.
Example configuration:
<VirtualHost *:80>
ServerName domainmonitor.local
DocumentRoot "/path/to/domain-monitor/public"
<Directory "/path/to/domain-monitor/public">
AllowOverride All
Require all granted
</Directory>
</VirtualHost>php -S localhost:8000 -t publicThen visit: http://localhost:8000
All application and email settings are now managed through the Settings page in the web interface:
-
Navigate to Settings โ Application tab
- Set application name, URL, and timezone
-
Navigate to Settings โ Email tab
- Configure SMTP server (host, port, encryption)
- Set authentication credentials
- Configure from address and name
Example Email Settings:
- SMTP Host:
smtp.gmail.com - SMTP Port:
587 - Encryption:
TLS - Username:
your-email@gmail.com - Password:
your-app-password
- Create a bot using @BotFather
- Get your Chat ID using @userinfobot
- Add the channel in the notification group settings
- Go to Server Settings โ Integrations โ Webhooks
- Create a new webhook
- Copy the webhook URL
- Add it in the notification group settings
- Go to Slack App Settings
- Enable Incoming Webhooks
- Create a new webhook
- Copy the webhook URL
- Add it in the notification group settings
Send JSON payloads to any HTTP endpoint (e.g., n8n, Zapier, Make, your own API):
- Go to Notification Groups โ Edit โ Add Channel
- Choose "Webhook (Custom)"
- Paste your endpoint URL (HTTPS recommended)
- Click "Test Channel" to verify
Payload example sent on domain alerts:
{
"event": "domain_expiration_alert",
"message": "โ ๏ธ WARNING: Domain 'example.com' expires in 7 days (January 30, 2026)!\n\nRegistrar: Example Registrar\nPlease renew soon.",
"data": {
"domain": "example.com",
"domain_id": 123,
"days_left": 7,
"expiration_date": "2026-01-30",
"registrar": "Example Registrar"
},
"sent_at": "2025-10-17T12:34:56Z"
}Use this with n8n's "Webhook" trigger to start flows.
The application requires a cron job to check domains periodically.
๐ก Pro Tip: The cron path is automatically detected! Go to Settings โ System to copy the exact command for your installation.
crontab -eAdd this line (or copy from Settings โ System):
0 9 * * * /usr/bin/php /your/actual/path/cron/check_domains.phpUse 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: Copy from Settings โ System tab (auto-detected path)
Before setting up the cron job, test your notification channels through the web interface:
- Go to Settings โ Email tab
- Enter a test email address
- Click "Send Test Email" to verify SMTP configuration
- For Telegram/Discord/Slack, send a test from the notification group settings
- 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.
- 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
The Dashboard shows:
- Total domains and their status
- Domains expiring soon
- Recent notifications sent
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)
All system settings are managed through the Settings page (/settings) in your browser:
- Application Name: Customize the display name
- Application URL: Base URL for links in emails
- Timezone: Set your preferred timezone
- User Registration: Enable/disable new user signups
- Email Verification: Require email verification for new users
- SMTP Configuration: Host, port, encryption
- Authentication: Username and password
- From Address: Email sender details
-
Notification Schedule: Choose from presets or create custom
- Minimal: 30, 7, 1 days
- Standard: 60, 30, 21, 14, 7, 5, 3, 2, 1 days
- Frequent: 90, 60, 45, 30, 21, 14, 10, 7, 5, 3, 2, 1 days
- Business Focused: 60, 30, 14, 7, 3, 1 days
- Custom: Enter your own comma-separated days
-
Check Interval: How often to check domains
- Every 6 hours
- Every 12 hours
- Daily (24 hours)
- Every 2 days
- Weekly
- Auto-Detected Cron Path: Copy-paste ready cron commands with your actual installation path
- Log File Locations: Find logs for troubleshooting
Stay informed with the in-app notification system:
- Bell Icon: Top navigation shows unread count with animated indicator
- Dropdown Preview: Quick view of 5 most recent unread notifications
- Full Page:
/notificationswith complete history and management
- ๐ฌ Welcome - Sent when you create an account or system is installed
- โฌ๏ธ System Upgrade - Admins notified when system is updated (includes version & migration count)
- ๐ด Domain Expiring - Alerts based on your configured thresholds
โ ๏ธ Domain Expired - Critical alerts for expired domains- ๐ Domain Updated - WHOIS data changes detected
- ๐ New Login - Security alerts for new device logins
- โ WHOIS Failed - Lookup errors and issues
- Filter by Status: Unread, Read, or All
- Filter by Type: Domain, System, or Security notifications
- Date Ranges: Today, This Week, This Month, All Time
- Pagination: View 10, 25, 50, or 100 per page
- Quick Actions: Mark as read, Delete, Mark all read, Clear all
Access your profile settings via the top-right user menu:
- Update full name and email
- View account creation date
- Check last login timestamp
- Email verification status
- Change password securely
- Password strength requirements
- Security best practices
- View All Sessions: See every device where you're logged in
- Session Details: Location (country, city), ISP, device type, browser
- Country Flags: Visual indicators for each session location
- Session Age: See when each session was created
- Last Activity: Monitor recent activity per session
- Remember Me Indicator: See which sessions have "remember me" enabled
- Remote Logout: Terminate individual sessions or all other sessions
- Instant Termination: Deleted sessions are logged out immediately
All settings are stored in the database and can be updated at any time through the web interface.
Domain Monitor/
โโโ app/
โ โโโ Controllers/ # Application controllers
โ โโโ Models/ # Database models (User, Domain, SessionManager, etc.)
โ โโโ Services/ # Business logic & services
โ โ โโโ Channels/ # Notification channel implementations
โ โ โโโ NotificationService.php # Notification creation & management
โ โโโ Helpers/ # Helper classes for formatting & display logic
โ โ โโโ LayoutHelper.php # Global layout data (notifications, stats)
โ โ โโโ DomainHelper.php # Domain formatting & calculations
โ โ โโโ SessionHelper.php # Session display formatting
โ โโโ Views/ # HTML views (pure display, no business logic)
โโโ core/ # Core MVC framework
โ โโโ DatabaseSessionHandler.php # Database session storage
โ โโโ SessionValidator.php # Session validation middleware
โ โโโ Auth.php # Authentication helpers
โ โโโ ...
โโโ cron/ # Cron job scripts
โโโ database/
โ โโโ migrations/ # Database migrations
โโโ public/ # Web root (index.php, assets)
โโโ routes/ # Route definitions
โโโ vendor/ # Composer dependencies
โโโ .env # Environment configuration
- 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
- Some domain TLDs may not be supported
- Check if the domain is valid and registered
- Verify your server can make outbound connections
- Check logs:
logs/cron.log - Verify notification channel configuration in Settings โ Email
- Test email using the built-in test function in Settings
- Check SMTP/API credentials in Settings
- Verify database credentials in
.env - Ensure MySQL service is running
- Check if database exists
- Verify cron syntax and paths
- Check server logs
- Test manually:
php cron/check_domains.php
We welcome bug reports and feature requests! Please use GitHub Issues:
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.)
Have an idea? Submit a feature request with:
- Clear description of the feature
- Use case and benefits
- Any implementation ideas
Contributions are welcome and appreciated! Here's how you can help:
- 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
- Follow PSR-12 coding standards
- Write clear commit messages
- Add comments for complex logic
- Test your changes before submitting
- Update documentation as needed
- ๐ Bug fixes
- โจ New features
- ๐ Documentation improvements
- ๐ Translations
- ๐จ UI/UX enhancements
- โก Performance optimizations
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.
- ๐ฌ Discussions: GitHub Discussions
- ๐ Issues: Bug Tracker
- ๐ Documentation: Wiki
- โญ Star the project if you find it useful!
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
Made with โค๏ธ by Hosteroid
Report Bug โข Request Feature โข Visit Hosteroid