composer require atournayre/maintenance-bundle
config/bundles.php:
return [
Atournayre\MaintenanceBundle\AtournayreMaintenanceBundle::class => ['all' => true],
];
.env with basic settings:
MAINTENANCE_IS_ENABLED=false
MAINTENANCE_AUTHORIZED_IPS=localhost,127.0.0.1
services.yaml to bind env vars:
parameters:
atournayre_maintenance.is_enabled: '%env(MAINTENANCE_IS_ENABLED)%'
atournayre_maintenance.authorized_ips: '%env(MAINTENANCE_AUTHORIZED_IPS)%'
php bin/console maintenance --enable
Scheduled Deployments
--start to schedule maintenance for a future datetime (e.g., pre-deployment):
php bin/console maintenance --start="2024-01-01 00:00:00" --enable
--add-ip to whitelist your CI/CD server’s IP.Zero-Downtime Maintenance
# Pre-deploy
php bin/console maintenance --enable --add-ip="your-server-ip"
# Post-deploy
php bin/console maintenance --disable
Environment-Specific Configs
.env per environment (e.g., .env.prod):
MAINTENANCE_IS_ENABLED=false # Default: off in production
MAINTENANCE_AUTHORIZED_IPS=123.45.67.89 # Whitelist only your team's IPs
--debug to verify configs:
php bin/console maintenance --debug
Custom Templates
mkdir -p templates/bundles/AtournayreMaintenanceBundle
cp -r vendor/atournayre/maintenance-bundle/Resources/views/* templates/bundles/AtournayreMaintenanceBundle/
maintenance.html.twig) to add:
CI/CD Integration
# In your deploy.sh
php bin/console maintenance --enable --add-ip="$DEPLOY_IP"
# Run migrations/deploy...
php bin/console maintenance --disable
IP Whitelisting Quirks
.env uses the correct format (e.g., ::1 for localhost).MAINTENANCE_AUTHORIZED_IPS must be comma-separated (no spaces). Example:
MAINTENANCE_AUTHORIZED_IPS=192.168.1.1,2001:0db8::1
--dump-ips to verify whitelisted IPs:
php bin/console maintenance --dump-ips
Timezone Sensitivity
--start datetime uses the server’s timezone. If your server is in UTC but you’re in EST, add the timezone explicitly:
php bin/console maintenance --start="2024-01-01 00:00:00 America/New_York"
Template Overrides
templates/bundles/ structure works in Symfony 4.4+. For Symfony 5+, use templates/AtournayreMaintenanceBundle/ instead.php bin/console cache:clear
Command Conflicts
--enable/--disable with --start. Use --start alone to schedule maintenance without enabling it immediately.Environment Variables
.env: If MAINTENANCE_IS_ENABLED is undefined, the bundle defaults to false. Always define it explicitly..env.local.php for local overrides (e.g., disable maintenance for your dev machine).Verify Configs
php bin/console debug:config atournayre_maintenance
.env.Check Middleware
bundles.php.Symfony\WebServerBundle) is overriding the response.Log Entries
config/packages/dev/monolog.yaml to log maintenance events:
handlers:
maintenance:
type: stream
path: "%kernel.logs_dir%/maintenance.log"
level: info
channels: ["maintenance"]
$this->logger->info('Maintenance enabled', ['bundle' => 'AtournayreMaintenanceBundle']);
Custom Logic for Maintenance
// src/Command/CustomMaintenanceCommand.php
use Atournayre\MaintenanceBundle\Service\MaintenanceService;
class CustomMaintenanceCommand extends Command {
protected static $defaultName = 'app:custom-maintenance';
private $maintenanceService;
public function __construct(MaintenanceService $maintenanceService) {
$this->maintenanceService = $maintenanceService;
}
protected function execute(InputInterface $input, OutputInterface $output): int {
$this->maintenanceService->enable();
$this->maintenanceService->addIp('192.168.1.100');
$output->writeln('Custom maintenance enabled!');
return Command::SUCCESS;
}
}
Event Listeners
maintenance.enabled and maintenance.disabled events (if the bundle exposes them). If not, create a proxy service:
// src/Service/MaintenanceProxy.php
use Atournayre\MaintenanceBundle\Service\MaintenanceService;
class MaintenanceProxy {
private $maintenanceService;
public function __construct(MaintenanceService $maintenanceService) {
$this->maintenanceService = $maintenanceService;
$this->maintenanceService->enable(); // Example trigger
}
}
Database-Backed Maintenance
MaintenanceService:
// src/Service/DatabaseMaintenanceService.php
use Atournayre\MaintenanceBundle\Service\MaintenanceService;
class DatabaseMaintenanceService extends MaintenanceService {
public function enable() {
// Save to DB first
$this->entityManager->persist($this->createMaintenanceEntity());
$this->entityManager->flush();
// Then call parent
parent::enable();
}
}
config/services.yaml:
services:
Atournayre\MaintenanceBundle\Service\MaintenanceService:
class: App\Service\DatabaseMaintenanceService
How can I help you explore Laravel packages today?