Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Maintenance Bundle Laravel Package

uam/maintenance-bundle

UAM Maintenance Bundle adds a lightweight maintenance mode to Laravel/PHP apps, with configurable access rules and friendly downtime messaging so teams can safely handle deployments, upgrades, and planned outages.

View on GitHub
Deep Wiki
Context7

Getting Started

First, a compatibility check. Despite the "maintenance" name, uam/maintenance-bundle is a Symfony bundle, not a Laravel package. The Bundle suffix, the uam vendor namespace, and the DependencyInjection/ layout are Symfony conventions. If you're in a Laravel codebase, this is not a drop-in — you'd be fighting the framework boundary (no bundles.php, different container, different event dispatcher). Confirm your target framework before spending time on it.

Assuming a Symfony app:

  1. Read the repo before installing. With 1 star and 0 dependents, there is no community safety net. Open, in this order:

    • README.md — the only source of truth for config keys and the toggle mechanism.
    • composer.json — check require for the Symfony version constraint (symfony/framework-bundle, symfony/http-kernel). A stale constraint here is the most likely reason it won't boot on a modern Symfony (6/7).
    • src/ — look for a *Extension.php, a *Bundle.php, a Command/ directory, and any EventSubscriber/EventListener. Those four files tell you the entire design.
    • DependencyInjection/Configuration.php — the real config schema, more reliable than the README.
  2. Install and register.

    composer require uam/maintenance-bundle
    

    With Symfony Flex the bundle may auto-register; otherwise add it to config/bundles.php:

    Uam\MaintenanceBundle\UamMaintenanceBundle::class => ['all' => true],
    
  3. Find the toggle. Maintenance bundles almost always expose one of: a console command (bin/console uam:maintenance:enable|disable), a config flag (uam_maintenance.enabled: true), or a lock/sentinel file on disk. Run bin/console list and grep for maintenance — that's your fastest discovery step.

  4. First use case — verify the 503 path end to end. Enable maintenance mode, hit a route in a browser, and confirm you get an actual HTTP 503 (not 200, not 500) with a rendered page. Check curl -I https://your-app.test/ for the status code. If it 200s, the listener isn't registered or is being shadowed. If it 500s, the template or a service dependency is missing. This one check validates install, registration, listener wiring, and template resolution at once.

Implementation Patterns

Environment-scoped toggling. Don't wire maintenance mode to a single global boolean. Most teams end up with a config that resolves per-environment, so staging can be put into maintenance without touching prod:

# config/packages/uam_maintenance.yaml
uam_maintenance:
    enabled: '%env(bool:MAINTENANCE_MODE)%'

Then a deploy step sets MAINTENANCE_MODE=1 in the environment file. This is far more reliable than a filesystem sentinel when you run multiple app servers — a local lock file on server A does nothing for server B.

Deploy-window choreography. The standard pattern is a wrapper around your deploy, not a manual button:

bin/console uam:maintenance:enable   # or set env + cache:clear
php bin/console doctrine:migrations:migrate --no-interaction
bin/console cache:clear
bin/console uam:maintenance:disable

Treat enable/disable as idempotent so a failed deploy doesn't leave you stuck in maintenance. Wrap the disable in a trap/finally so a crash mid-migration still restores service.

Whitelisting for health checks and office IPs. The single most important integration detail: your load balancer health check and your uptime monitor will start paging you the moment maintenance mode goes on. Look for an IP allowlist and a path allowlist in the config and put /health, /healthz, and your internal ranges in it. If the bundle doesn't support path exclusions, you'll need a small kernel.request listener with a higher priority that returns early for those paths.

Custom maintenance page. The default template is almost certainly a bare placeholder. Override it per Symfony convention — the bundle's extension typically declares a template path, so check config/packages/uam_maintenance.yaml for a template: key and point it at templates/maintenance/index.html.twig. Keep it self-contained: no database calls, no auth, no service dependencies. A maintenance page that itself depends on the thing being maintained is a classic own-goal.

Set Retry-After. If the bundle doesn't already send it, add Retry-After: 3600 to the 503 response. Search engines and well-behaved clients honor it; without it you get crawl churn and repeated client retries during the window.

Compose with your own listener if the bundle is too thin. For anything beyond a static page — showing a countdown, notifying admins, logging who enabled it — attach to the same event the bundle uses. Find the priority in the bundle's service definition (tags: [{ name: kernel.event_listener, event: kernel.request, priority: N }]) and register yours slightly earlier so your logic runs first.

Gotchas and Tips

  • The dependency risk is the headline. 1 star, 0 dependents, and effectively no user base means no one else is finding the bugs. Pin the exact version in composer.json (don't use ^), commit composer.lock, and read every line of src/ before production. It's small enough that a full read is a 15-minute job — do it. If it's abandoned, forking into your own src/ namespace is cheaper than carrying an unmaintained dependency.
  • Symfony version drift is the #1 breakage. A bundle this obscure is likely pinned to an old major. Check composer.json constraints before composer require so you don't get a dependency resolution error and waste a cycle. If it targets Symfony 4/5 and you're on 7, expect ContainerBuilder and event-dispatcher-signature changes.
  • Config cache will bite you. In prod, bin/console cache:clear (or cache:warmup) is mandatory after changing config-driven maintenance flags. Editing a YAML file and expecting an immediate effect on a cached prod container is the single most common "it doesn't work" report.
  • Sub-requests and ESI/fragments. kernel.request fires for sub-requests too. If a fragment controller gets the maintenance page injected mid-page, you'll render a maintenance blob inside an otherwise-working layout. Confirm the listener checks $event->isMainRequest() (Symfony 6+) or isMasterRequest() (5 and below) — this is a frequent omission in small bundles.
  • Don't let maintenance mode block the console. Some implementations guard at the wrong layer and lock out bin/console commands, which means you can't run the disable command to get out of maintenance mode. Test the escape hatch before you need it: enable, then confirm bin/console uam:maintenance:disable still runs.
  • Debugging order when it silently does nothing: (1) is the bundle in config/bundles.php? (2) bin/console debug:event-dispatcher kernel.request — is the listener listed? (3) bin/console debug:container --tag=kernel.event_listener — is the service registered and is its priority sane? (4) bin/console debug:config uam_maintenance — did your YAML actually merge into the tree? That sequence finds the problem in under two minutes.
  • Extension points worth knowing: the container extension (for config schema), the template path (for the page), the listener priority (for ordering), and the toggle mechanism (for automation). Those four are the seams. Anything else, assume you'll be editing a fork.
  • Laravel-side note: if you landed here looking for the Laravel equivalent, use the built-in php artisan down --render="errors::503" --retry=60 --secret="..." and php artisan up. It ships with the framework, supports bypass secrets and Retry-After, and has zero dependency risk. There is no reason to reach for a Symfony bundle in a Laravel app.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core