Production-grade maintenance mode for CodeIgniter 4 β typed, testable, and ready for distributed deployments.
- π‘ Timing-safe bypass β
hash_equals()for every secret/cookie comparison. - π¦ Multiple bypass paths β IP / CIDR (IPv4 + IPv6), URL secret, signed cookie, route allow-list.
- π Scheduled windows β
--start/--end, auto-deactivation on the next request. - π¦ Pluggable storage β
cache(Redis/Memcached/file via CI4 Cache) orfiledriver, switch with one config flag. - π Framework events β
maintenance.activated,.deactivated,.bypassed,.access_denied,.scheduled.expired. - π§± JSON or HTML β content-negotiated 503 (or 302 redirect) per request.
- π§ͺ 149 unit tests, PHPStan + Psalm + Rector clean, PHP 8.2 / 8.3 / 8.4.
composer require daycry/maintenancemode
php spark mm:publishThen wire the filter in app/Config/Filters.php:
public array $aliases = [
'maintenance' => \Daycry\Maintenance\Filters\Maintenance::class,
];
public array $globals = [
'before' => ['maintenance'],
];# Activate (with an allow-listed IP, a secret URL bypass, and a 30 min ETA)
php spark mm:down --message "Upgrading the database" \
--ip "203.0.113.5" \
--secret "ops-token" \
--duration 30
# Inspect state
php spark mm:status
# Bring the site back up
php spark mm:up# Schedule a window
php spark mm:down --start "2026-05-10 02:00" --end "2026-05-10 04:00"
# Skip 503 for healthchecks (config option)
$config->bypassRoutes = ['/health', '/api/webhooks/*'];
# Force JSON response on /api/* routes
$config->jsonRoutes = ['/api/*'];
# Render a custom view for THIS window
php spark mm:down --render errors/html/branded_503
# Redirect to a status page instead of 503
php spark mm:down --redirect https://status.example.comEverything else lives in docs/:
- Installation & first run
- Full configuration reference
- CLI commands
- Bypass methods & priority
- Filter & framework events
- Storage drivers (cache / file)
- Architecture
- Security model
- Troubleshooting Β· FAQ Β· Upgrade guide Β· Roadmap
- Basic maintenance
- Scheduled window
- JSON 503 for APIs
- Slack / PagerDuty notifications
- Multi-tenant (planned)
- Cloudflare / CDN trusted proxies (planned)
This package treats the toolchain as part of the contract. Every push runs:
| Workflow | Tool | What it guards |
|---|---|---|
| PHPUnit | PHPUnit Β· matrix PHP 8.2 / 8.3 / 8.4 + lowest-deps | Behaviour |
| Code Style | PHP-CS-Fixer (CodeIgniter 4 ruleset) | Formatting |
| PHPStan | PHPStan level 6 | Static types |
| Psalm | Psalm error level 6 | Static types & dead code |
| Rector | Rector dry-run | Refactor drift |
| CodeQL | GitHub CodeQL (Actions) | Supply-chain (workflow injection, secret leaks) |
Reproduce them locally with composer ci.
Bug reports, feature requests and PRs are welcome. Please read CONTRIBUTING.md and the Code of Conduct first. For security issues, follow SECURITY.md β please don't file them as public issues.
MIT Β· made for the CodeIgniter 4 community.