- Dockerfile: php:apache base, installs PHP extensions + Composer, configures Apache to listen on port 7876, bundles app code, runs composer install at build time - docker-compose.yml: web service (port 7876) + MariaDB LTS with healthcheck; writable volume for DB persistence - docker/entrypoint.sh: generates .env from environment variables at container start, fixes runtime permissions - docker/php.ini: tuned PHP limits (512M memory, 32M upload) - .dockerignore: excludes .git, vendor, logs, cache, old docker dir - .env.example: template for required environment variables Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
🌐 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, Mattermost, Pushover, Webhook). 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, 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
Advanced Features
- 🔐 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
📋 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
- 🛡️ 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
⚠️ 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
Note:
- 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)
4. Create Database
Create a MySQL database:
CREATE DATABASE domain_monitor CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
5. Run Web Installer
Option A: Apache/Nginx (Recommended)
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.
Option B: PHP Built-in Server
php -S localhost:8000 -t public
Then 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!)
⚠️ IMPORTANT: The installer will display your admin credentials only once. Save them to a secure password manager!
6. Import TLD Registry Data (Optional but Recommended)
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.php
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 "/path/to/domain-monitor/public"
<Directory "/path/to/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
Application & Email Settings
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
Notification Channels
✈️ 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
🌐 Webhook (Custom)
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.
📅 Setting Up Cron Jobs
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.
Linux/Mac
crontab -e
Add this line (or copy from Settings → System):
0 9 * * * /usr/bin/php /your/actual/path/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: Copy from Settings → System tab (auto-detected path)
🧪 Testing Notifications
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
📖 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 Settings
All system settings are managed through the Settings page (/settings) in your browser:
Application Settings
- 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
Email Settings
- SMTP Configuration: Host, port, encryption
- Authentication: Username and password
- From Address: Email sender details
Monitoring Settings
-
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
System Settings
- Auto-Detected Cron Path: Copy-paste ready cron commands with your actual installation path
- Log File Locations: Find logs for troubleshooting
User Notifications
Stay informed with the in-app notification system:
Notification Center
- 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
Notification Types
- 📬 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
Notification Features
- 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
Profile Management
Access your profile settings via the top-right user menu:
My Profile
- Update full name and email
- View account creation date
- Check last login timestamp
- Email verification status
Security
- Change password securely
- Password strength requirements
- Security best practices
Active Sessions
- 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.
📁 Project Structure
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
🔐 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 in Settings → Email
- Test email using the built-in test function in Settings
- Check SMTP/API credentials in Settings
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