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 Guard Laravel Package

syriable/maintenance-guard

Maintenance Guard adds a flexible maintenance-mode layer to Laravel apps, letting you gate requests behind custom checks, whitelist routes or IPs, and return friendly responses while work is in progress. Easy to configure and toggle.

View on GitHub
Deep Wiki
Context7

Getting Started

syriable/maintenance-guard 1.0.0 is a brand-new package (first public release), so treat it as an early-adopter dependency: the surface area is small, but there is no long tail of community usage to lean on yet.

Minimal setup:

composer require syriable/maintenance-guard
php artisan vendor:publish --tag=maintenance-guard-config

Then read, in this order:

  1. config/maintenance-guard.php — this is where the package's whole behaviour is expressed (who is allowed through while php artisan down is active). Everything else is plumbing.
  2. README.md — for the exact middleware alias / service-provider registration expectations in 1.0.0.
  3. src/ — it's a small package at this point; skimming the guard class will take five minutes and save you an afternoon of guessing.

First real use case: you run php artisan down for a deploy, and you want your team, your uptime monitor, and your staging smoke tests to keep hitting the app while everyone else sees the maintenance page. Wire the guard so a known set of IPs / a header / a query token bypasses the 503, verify with curl -I, and only then roll it into your deploy script.

Because this is a 1.0.0 with a single contributor, pin the version ("syriable/maintenance-guard": "^1.0") and plan to re-read the config on each minor bump.

Implementation Patterns

Environment-driven allowlists. Keep the bypass list in config, sourced from env, so local/staging/production differ without code changes:

// config/maintenance-guard.php
'allowed_ips' => array_filter(explode(',', env('MAINTENANCE_ALLOWED_IPS', ''))),

Then MAINTENANCE_ALLOWED_IPS=203.0.113.10,198.51.100.0/24 in the deploy environment. Prefer CIDR support if the package provides it; otherwise list individual addresses and be explicit about the limitation in your runbook.

Secret-token bypass for CI and smoke tests. A query string or header token lets automated checks pass through without hardcoding office IPs:

curl -s -o /dev/null -w "%{http_code}" \
  -H "X-Maintenance-Token: $TOKEN" https://example.com/
# expect 200, not 503

Generate the token per environment, never commit it, and rotate it after an incident.

Keep the guard out of the public surface. Register the middleware on the web and api groups (or globally) rather than per-route — a bypass that only applies to / is a footgun during an incident. If the package ships a middleware alias, prefer group assignment in bootstrap/app.php (Laravel 11+) or Kernel.php (Laravel 10 and below).

Pair it with a predictable deploy sequence. The pattern that actually pays off day to day:

php artisan down --render="errors::503" --retry=60
# deploy / migrate
php artisan up

The guard makes down survivable for humans; --retry makes it survivable for browsers. Use both.

Cache and queue awareness. Maintenance mode does not stop queue workers. Decide explicitly whether jobs should keep running during the window — run php artisan queue:pause / drain, or scope the maintenance window to web traffic only. Write this down; it's the most common source of "we were down but emails still went out" surprises.

Scheduled-window integration. If you gate deploys behind a scheduled task, wrap the down/up calls in a command with a finally block so a failed deploy never leaves the app stuck in maintenance:

try {
    Artisan::call('down');
    // deploy steps
} finally {
    Artisan::call('up');
}

Gotchas and Tips

  • 1.0.0 means the API is still settling. With one contributor and two PRs of history, expect naming and config-key changes in 1.x. Pin the constraint, keep your integration behind a thin layer (a small service class or your own middleware that delegates), and re-check the changelog on every bump.
  • Trusted proxies will bite you. If you allowlist by IP and you sit behind a load balancer or Cloudflare, $request->ip() returns the proxy address unless TrustProxies is configured. You will either lock everyone out or let everyone in. Verify with $request->ip() logged during the maintenance window before you rely on it.
  • php artisan down returns 503, not 200. Uptime monitors and health checks configured for 2xx will page you. Either let the monitor through the guard or teach it that 503-with-Retry-After is the expected state during a window.
  • Bypass ≠ skip auth. Allowlisted users still hit your normal auth stack; a maintenance guard only removes the 503. Don't assume it grants any privileges.
  • Config caching. After changing config/maintenance-guard.php in production, run php artisan config:cache — otherwise you'll debug a change that silently isn't applied.
  • Stale maintenance state. If a deploy dies mid-flight, the app stays down. Keep the finally-based up (above) and know the manual escape hatch: php artisan up on the box. Some setups also need the storage/framework/down file removed if up was interrupted.
  • Extension point to watch. The guard's decision logic is the thing you'll want to customise (user-based bypass, feature-flag-driven bypass, tenant-aware rules). Check whether 1.0.0 exposes a config hook or a bindable contract; if not, wrapping it in your own middleware now avoids a refactor later.
  • Test it in CI. Add one assertion that an allowlisted request returns 2xx and a non-allowlisted one returns 503 while down is active. This is cheap and catches config drift immediately.
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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource