Installation:
composer require corley/maintenance-bundle
For Symfony 5.4/6.x, use ^0.5; for older versions, adjust as per the README.
Enable the Bundle:
AppKernel changes needed).AppKernel.php:
new Corley\MaintenanceBundle\CorleyMaintenanceBundle(),
First Use Case: Trigger maintenance mode via CLI:
php bin/console corley:maintenance:enable
503.html page with a 503 Service Unavailable header.Customize the Maintenance Page:
Override the default template by copying vendor/corley/maintenance-bundle/Resources/views/maintenance.html.twig to templates/maintenance.html.twig and modify it.
Enable/Disable Maintenance:
php bin/console corley:maintenance:enable
or programmatically:
$this->get('corley_maintenance.maintenance')->enable();
php bin/console corley:maintenance:disable
or programmatically:
$this->get('corley_maintenance.maintenance')->disable();
Conditional Maintenance:
Use the MaintenanceChecker service to conditionally block requests (e.g., during deployments):
if ($this->get('corley_maintenance.maintenance_checker')->isEnabled()) {
throw new \Symfony\Component\HttpKernel\Exception\HttpException(503);
}
Scheduled Maintenance:
Combine with Symfony’s CronBundle or a task scheduler to enable maintenance before deployments and disable afterward:
# config/packages/corley_maintenance.yaml
corley_maintenance:
enabled: false # Default state
API-Specific Exceptions:
Whitelist certain routes (e.g., health checks) by overriding the MaintenanceListener:
// src/EventListener/CustomMaintenanceListener.php
public function onKernelRequest(GetResponseEvent $event)
{
if (!$this->maintenanceChecker->isEnabled()) {
return;
}
$request = $event->getRequest();
if ($request->getPathInfo() === '/health') {
return; // Allow health checks
}
throw new HttpException(503);
}
Load Balancer Compatibility:
The 503 header ensures load balancers (e.g., Nginx, AWS ALB) drop the instance. Test with:
curl -I http://your-site.com
Should return HTTP/1.1 503 Service Unavailable.
Environment-Specific Config:
Disable maintenance in dev environments:
# config/packages/dev/corley_maintenance.yaml
corley_maintenance:
enabled: false
Custom Templates:
Extend the Twig template by creating templates/maintenance.html.twig with blocks like:
{% extends 'maintenance.html.twig' %}
{% block title %}Custom Maintenance{% endblock %}
{% block content %}
<h1>We're back soon!</h1>
{{ parent() }}
{% endblock %}
Symfony 5+ Event Changes:
<0.3 are incompatible with Symfony 5 due to event system changes. Use ^0.5 for 5.4/6.x.503 loops: Ensure no other middleware/firewall is overriding the 503 response.Static File Caching:
php bin/console cache:clear
Race Conditions:
#!/bin/bash
php bin/console corley:maintenance:enable
# Run deployments...
php bin/console corley:maintenance:disable
API Routes Leaks:
Check Status:
php bin/console corley:maintenance:status
Outputs enabled/disabled.
Log Errors: Enable debug mode to log blocked requests:
# config/packages/dev/monolog.yaml
handlers:
maintenance:
type: stream
path: "%kernel.logs_dir%/maintenance.log"
level: debug
Test Locally: Use a reverse proxy (e.g., Nginx) to simulate load balancer behavior:
location / {
proxy_pass http://localhost:8000;
error_page 503 /maintenance.html;
}
Custom Maintenance Logic:
Override the MaintenanceChecker service to add dynamic rules (e.g., IP whitelisting):
# config/services.yaml
Corley\MaintenanceBundle\Checker\MaintenanceChecker:
arguments:
$ipWhitelist: ['192.168.1.100'] # Allow specific IPs
Custom HTTP Codes:
Extend the MaintenanceListener to return different status codes (e.g., 502 Bad Gateway):
throw new HttpException(502, 'Gateway Error');
Database-Backed State:
Store maintenance state in the database by implementing MaintenanceStorageInterface:
class DatabaseMaintenanceStorage implements MaintenanceStorageInterface
{
public function isEnabled(): bool
{
return DB::table('maintenance')->value('enabled') === true;
}
// ...
}
How can I help you explore Laravel packages today?