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

Laravel Filament Maintenance Laravel Package

brickx/laravel-filament-maintenance

A Filament plugin for managing Laravel maintenance mode from your admin panel. Toggle maintenance on or off, customize the page shown to visitors, and control access without editing config files or running artisan commands.

View on GitHub
Deep Wiki
Context7

Getting Started

Verify it still fits your stack first. This package is archived (last release 1.1.2, June 2023) and targets Filament v3 / Laravel 9–10. If you are on Filament v4 or Laravel 11+, stop here — you cannot use it.

  1. Install via Composer:
    composer require brickx/laravel-filament-maintenance
    
  2. Register the plugin on the panel you want the toggle in — look in app/Providers/Filament/AdminPanelProvider.php first:
    use Brickx\Maintenance\MaintenancePlugin;
    
    public function panel(Panel $panel): Panel
    {
        return $panel
            ->default()
            ->id('admin')
            // ...
            ->plugin(MaintenancePlugin::make());
    }
    
  3. Clear caches and log in: php artisan optimize:clear, then look for the new Maintenance entry in the Filament sidebar.

First use case: the classic pre-deploy flow — an operator clicks the toggle in Filament to put the app into maintenance mode with a custom message and a secret bypass URL, runs php artisan migrate / config:cache on the server, then clicks the toggle again to bring it back up. Confirm it works by opening a private window in incognito without the secret token and checking you get the 503 page.

Implementation Patterns

Treat it as a thin wrapper around php artisan down. Everything the plugin does can be reproduced with the Artisan command, so plan for the day the plugin is removed:

Artisan::call('down', [
    '--secret'   => 'my-bypass-token',   // gives you /my-bypass-token
    '--render'   => 'errors::503',       // custom view
    '--retry'    => 60,                  // Retry-After header
]);

Artisan::call('up');

If your team's real need is "toggle from the panel with a nice UI," a 40-line custom Filament Page that calls these two commands is a safer long-term bet than an archived dependency.

Deploy-script integration. The most valuable pattern is calling maintenance mode from CI, not from the UI, because it guarantees the window covers the whole deploy:

php artisan down --secret="$MAINTENANCE_SECRET" --retry=15
php artisan migrate --force
php artisan config:cache && php artisan route:cache && php artisan view:cache
php artisan queue:restart
php artisan up

Keep the panel toggle for unplanned or manual mode; use the script for planned deploys.

Manual mode with the refresh button. 1.1.2 (PR #6) adds a refresh option to the maintenance page so an operator can re-read the current state from disk without reloading the whole panel. This matters when someone else flips the app up/down from the CLI — the Filament page will otherwise show stale state. Use it as the "did my php artisan up actually land?" check before you start debugging a phantom outage.

Wiring "maintenance mode" into application logic. Check state anywhere with the built-in helper rather than shelling out:

if (app()->isDownForMaintenance()) {
    // skip outgoing webhooks, pause cron jobs, etc.
}

This is also the cleanest way to unit-test that the toggle works: assert app()->isDownForMaintenance() flips after hitting your Filament page with Livewire's Livewire::test().

Pair with a scheduled window. Laravel 11's php artisan down --with-secret and --allow (IP whitelist) give finer control than most UI plugins do. If you need scheduled maintenance windows, drive them from routes/console.php:

Schedule::call(fn () => Artisan::call('down', ['--retry' => 60]))
    ->dailyAt('02:00')
    ->description('nightly maintenance');
Schedule::call(fn () => Artisan::call('up'))->dailyAt('02:30');

Then use the Filament page only as a manual override / status display.

Multi-user safety. If more than one admin can access the panel, add a policy or role gate around the page so a support user can't accidentally take prod down. The plugin's page is a normal Filament Page, so a canView() override or the standard Gate::define('manage-maintenance') + ->visible() chain applies.

Gotchas and Tips

  • Archived dependency = pin it. Add "brickx/laravel-filament-maintenance": "1.1.2" (or "1.*") and constrain filament/filament to ^3.0 in composer.json. A composer update that pulls Filament v4 will break the plugin with no maintainer to fix it. Note that 1.1.2 is a patch-level UI tweak — it does not change the support matrix, so nothing here becomes safe to float.
  • It is file-based. Under the hood it calls php artisan down, which writes storage/framework/down. On a load-balanced multi-server setup, only the node you hit goes down. Use shared storage (EFS/NFS) or a proper edge/load-balancer maintenance page instead.
  • The bypass secret only helps if you can reach PHP. If your Filament admin panel is served from the same app you just put down, the secret-token cookie is the only way back in — and it must be set before the toggle is flipped. In practice: open /your-secret-token in a tab in advance.
  • Queue workers and schedulers keep running. down doesn't stop them; jobs will fail against a 503 app if they make HTTP calls. Always run php artisan queue:restart after up, and guard scheduled jobs with app()->isDownForMaintenance().
  • Filesystem permissions are the #1 failure. The web user (php-fpm/www-data) usually writes storage/framework/down via the panel, but your deploy user (deploy) may then fail to remove it, leaving the app stuck down. Confirm storage/framework/ is group-writable and consistent across users.
  • Caches make up feel broken. If you cached config/routes during the window, clear or rebuild them after php artisan up; a stale config:cache will keep the old APP_URL/APP_KEY and produce confusing 500s that look like maintenance-related bugs.
  • Check --allow availability before relying on it. The IP allow-list option needs a reasonably modern Laravel (8.37+ / 9+). If you're on an older 9.x patch, fall back to the secret token.
  • Status codes matter for uptime monitors. php artisan down returns 503 — good, monitors alert — but if you use --render with a custom view, make sure you don't accidentally return 200, or your SLO dashboard will go quiet during outages.
  • Extension points are thin. The realistic customizations are (a) overriding the page's Blade view via ->view() on the Page class, (b) subclassing the plugin's page and re-registering it, or (c) publishing anything the package ships. Given it's unmaintained, don't expect events/hooks to hook into — verify by reading vendor/brickx/laravel-filament-maintenance/src/. The 1.1.2 refresh option is a UI affordance, not a hook: it re-reads disk state, but there is still no event fired on toggle, so don't build side-effects (Slack pings, audit logs) around it — wrap Artisan::call('down'/'up') yourself if you need those.
  • Debugging checklist when the toggle "does nothing": ls storage/framework/down (does the file exist?), php artisan about (is the app actually in maintenance?), check the reverse proxy/CDN isn't caching the 200 response, and confirm the panel you registered the plugin on is the one you're logged into (multi-panel installs silently do nothing on the wrong panel). Since 1.1.2, hit the refresh control before concluding the toggle failed — the UI may simply be showing a stale snapshot.
  • Plan the exit. Because the plugin is archived, document the removal path up front: delete the plugin registration, swap the page for a 30-line custom Filament Page calling Artisan::call('down'/'up'), and you lose nothing. A refresh button is trivial to reimplement with $this->redirect(request()->header('Referer')) or a Livewire $refresh action, so 1.1.2 doesn't move the needle on the build-vs-depend call.
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.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin