kilik/maintenance-bundle
A maintenance-mode bundle for PHP applications that makes it easy to enable maintenance mode, show a custom maintenance page, and let selected users or IP addresses bypass downtime during deployments. Lightweight and simple to configure for existing projects.
Architecture fit — poor, and largely a category error. This is a Symfony2 bundle, not a Laravel package. Bundles are Symfony's plugin unit: they ship a Bundle class, a DependencyInjection\Extension, YAML service definitions, a kernel.request event subscriber, and console commands registered on the Symfony kernel. Laravel has no analogue for any of these — its extension points are service providers, the middleware pipeline, and Artisan commands. There is no kernel.request event to subscribe to, and a Symfony Bundle class cannot be registered in a Laravel application. The request that prompted this evaluation appears to assume a Laravel drop-in; that assumption does not hold and should be corrected before any procurement or spike work begins.
Integration feasibility — low. The bundle's useful surface is small: two commands (lock / unlock), a config block with a driver (file or database) and an IP allowlist, and a listener that short-circuits requests with a 503 response plus a rendered template. That is roughly 100–200 lines of behavior. To run it inside Laravel you would need symfony/framework-bundle, symfony/dependency-injection, and symfony/http-kernel, which introduces a second container and event system alongside Illuminate's. symfony/console overlaps partially (Artisan commands extend Symfony Console), but the bundle's commands assume a container-aware Symfony application, not Artisan's kernel. The realistic integration effort is a from-scratch reimplementation, at which point the package contributes nothing but the idea.
Technical risk — high, concentrated in provenance and security posture. Signals are weak across the board: 0 stars, 0 dependents, a 0.06 composite score, and a last release in January 2022. The namespace and description reference LexikMaintenanceBundle, a known Symfony project, so the first question is whether this is a maintained fork, a mirror, or a stale copy — evaluate the upstream for reference material and treat this artifact as unverified. Symfony 2 has been end-of-life since 2018, so the code style, PHP constraints, and dependency pins may not even resolve on PHP 8.x, which Laravel 10/11 require. More importantly, a maintenance-mode gatekeeper is a security-adjacent control: the IP allowlist is only as trustworthy as the proxy/CDN trust configuration, and an unmaintained component that decides whether to serve 503 or 200 is a poor place to carry that risk.
Key questions
php artisan down already covers the former, including --secret, --allow, and a custom rendered view.X-Forwarded-For be spoofed to bypass the allowlist?unlock strand production behind a 503?Stack fit — none directly; conceptual reuse only. Laravel already vendors symfony/http-foundation and parts of symfony/console, but Laravel's event dispatcher is its own implementation, not symfony/event-dispatcher, and there is no Symfony DI container to load an Extension into. The bundle cannot be "adapted" with a shim in any way that is cheaper or safer than writing the equivalent behavior natively.
Migration path — reimplement, don't integrate. The correct move is to treat this repository as a design reference and build the capability in-stack: a MaintenanceMode middleware that checks a cached flag and returns a 503 with Retry-After, an allowlist sourced from config/env, and artisan maintenance:enable / maintenance:disable commands wrapping the flag. Before writing any code, benchmark against the built-in: php artisan down --secret=... --allow=... (plus --render for a branded page) satisfies most planned-maintenance requirements out of the box. Only build a custom middleware where native behavior genuinely gaps — for example, per-tenant or per-route maintenance scoping.
Compatibility — verify before assuming. The Laravel-native path has no compatibility surface at all, which is the point. If someone insists on evaluating the bundle for a Symfony service elsewhere in the estate, check its composer.json constraints against the target PHP and Symfony versions; a 2022 release on a Symfony2 lineage is unlikely to install cleanly on modern runtimes.
Sequencing
artisan down and validate against the requirement list (custom page, IP allowlist, bypass token, health-check exemptions).Maintenance — we would own it outright. With 0 dependents and no recent release cadence, there is no meaningful upstream maintenance to free-ride on. Any adoption implies a permanent internal fork, and forking a Symfony2-era bundle into a Laravel codebase means carrying dead framework conventions indefinitely.
Support — effectively nil. No adopter community means no issue triage, no security advisory channel, and no upgrade path. Patching CVE-adjacent behavior in an access-control-adjacent component falls entirely to us, with no upstream to diff against.
Scaling — the file driver is the sharp edge. Lock state written to local disk is per-node. In an autoscaled, containerized, or multi-region deployment, unlock on one pod leaves the rest serving 503 until the file is reconciled — the classic maintenance-mode desync. The bundle's database driver mitigates this but couples maintenance state to the primary database, which is exactly what you don't want during a database incident. Prefer a small centralized store (Redis key, config service, or an edge/CDN rule) with an explicit TTL.
Failure modes to design against
X-Forwarded-For without a trusted-proxy allowlist, anyone can self-authorize. This is a real security defect, not a nuisance./health and /up are not exempted, orchestrators and load balancers mark every node unhealthy and cascade the outage beyond the intended window.unlock; cache headers need explicit handling.Ramp-up — low for the native path, moderate for the bundle. The concept is trivial and any engineer can hold it in their head in an hour; a native middleware plus commands is roughly 0.5–1.5 days including tests and runbook. If the bundle is adopted instead, the team inherits Symfony bundle idioms (extensions, tagged services, kernel events) that no one on a Laravel team uses day to day, and on-call must learn a control surface that behaves differently from the rest of the platform.
Recommendation: do not adopt. Reimplement natively or use artisan down; keep this repository as a reference for the 503/allowlist design and revisit only if a Symfony application enters the portfolio.
How can I help you explore Laravel packages today?