Weave Code
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

carteni/maintenance-bundle

Symfony bundle to put your site into maintenance mode while allowing access for a whitelist of IP addresses. Configure via YAML or XML, optionally route to a custom controller, and override the maintenance Twig templates to match your app.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Install the package via Composer:

    composer require carteni/maintenance-bundle
    
  2. Enable the bundle in config/app.php (Laravel 5.5+) or AppKernel.php (older versions):

    'providers' => [
        // ...
        Mes\Misc\MaintenanceBundle\MesMaintenanceBundle::class,
    ],
    
  3. Configure maintenance mode in config/packages/mes_maintenance.yaml (or config/mes_maintenance.php if using PHP config):

    mes_maintenance:
        enabled: true
        ips_allowed: [127.0.0.1, 192.168.1.100]  # Replace with your allowed IPs
        controller: ""  # Leave blank for default maintenance page
    
  4. Override the maintenance template (optional): Copy vendor/carteni/maintenance-bundle/resources/views/index.html.twig to resources/views/vendor/mes_maintenance/index.html.twig and customize.

  5. Test maintenance mode:

    • Access your site from an allowed IP (should work normally).
    • Access from a disallowed IP (should show maintenance page).

First Use Case

Deploying a quick maintenance page during a critical update:

  • Enable enabled: true in config.
  • Add your team’s IPs to ips_allowed.
  • Run php artisan config:clear if changes don’t apply.
  • Immediately test by accessing the site from a non-allowed IP.

Implementation Patterns

Usage Patterns

1. Dynamic IP Whitelisting

  • Store allowed IPs in a database (e.g., allowed_ips table) and fetch them dynamically in a custom config loader:
    // app/Providers/MesMaintenanceServiceProvider.php
    public function boot()
    {
        $ips = DB::table('allowed_ips')->pluck('ip')->toArray();
        config(['mes_maintenance.ips_allowed' => $ips]);
    }
    
  • Useful for multi-tenant apps or role-based access.

2. Conditional Maintenance Mode

  • Toggle maintenance mode via an environment variable (e.g., .env):
    # config/packages/mes_maintenance.yaml
    mes_maintenance:
        enabled: "%env(bool:MAINTENANCE_MODE,false)%"
    
  • Trigger via CI/CD pipeline:
    echo "MAINTENANCE_MODE=true" >> .env && php artisan config:clear
    

3. Custom Maintenance Pages per Route

  • Override the controller in config to serve different pages for different routes:
    mes_maintenance:
        controller: "App\\Http\\Controllers\\MaintenanceController@showCustomPage"
    
  • Example controller:
    public function showCustomPage(Request $request)
    {
        if ($request->is('admin/*')) {
            return view('admin.maintenance');
        }
        return view('public.maintenance');
    }
    

4. Integration with Laravel Middleware

  • Use the bundle’s logic in custom middleware for granular control:
    public function handle($request, Closure $next)
    {
        if (config('mes_maintenance.enabled') &&
            !in_array($request->ip(), config('mes_maintenance.ips_allowed'))) {
            return redirect()->route('maintenance.page');
        }
        return $next($request);
    }
    
  • Register middleware in app/Http/Kernel.php:
    protected $middleware = [
        \App\Http\Middleware\CheckMaintenance::class,
    ];
    

5. API-Specific Maintenance Mode

  • Extend the bundle to bypass maintenance for API requests:
    mes_maintenance:
        enabled: true
        ips_allowed: [...]
        bypass_for_paths: ["/api/*"]  # Custom config key
    
  • Modify the bundle’s HTTP kernel integration (see "Extension Points" below).

Workflows

Deployment Workflow

  1. Pre-deployment:

    • Enable maintenance mode (enabled: true).
    • Add your IP to ips_allowed.
    • Commit config changes.
  2. During deployment:

    • Run database migrations/updates.
    • Deploy code.
    • Clear caches (php artisan config:clear, php artisan cache:clear).
  3. Post-deployment:

    • Disable maintenance mode (enabled: false).
    • Remove your IP from ips_allowed (or add others).
    • Test from a non-allowed IP.

Rollback Workflow

  1. Revert code changes.
  2. Re-enable maintenance mode.
  3. Add your IP back to ips_allowed.
  4. Test and debug issues.

Integration Tips

Laravel Ecosystem

  • Service Providers: The bundle registers itself automatically. No manual binding needed.
  • Events: Extend the bundle to dispatch events (e.g., MaintenanceModeEnabled) for logging or notifications:
    // In a listener
    public function handle()
    {
        Log::info('Maintenance mode enabled. Allowed IPs: ' . implode(', ', config('mes_maintenance.ips_allowed')));
    }
    
  • Commands: Create a custom Artisan command to toggle maintenance mode:
    php artisan maintenance:enable --ips="192.168.1.1,127.0.0.1"
    

Frontend Integration

  • JavaScript Detection: Detect maintenance mode via a hidden meta tag in the template:
    <meta name="maintenance-mode" content="{{ app.maintenanceMode ? 'true' : 'false' }}">
    
    if (document.querySelector('meta[name="maintenance-mode"]').content === 'true') {
        window.location.href = '/maintenance';
    }
    

Testing

  • Unit Tests: Mock the Request object to test IP checks:
    $request = new Request(['ip' => '192.168.1.100']);
    $this->assertFalse(MaintenanceChecker::isInMaintenance($request));
    
  • Feature Tests: Test routes with allowed/disallowed IPs:
    $response = $this->get('/');
    $response->assertStatus(200); // Allowed IP
    
    $this->actingAsUserWithIp('1.2.3.4')->get('/')->assertRedirect('/maintenance');
    

Gotchas and Tips

Pitfalls

1. IP Matching Quirks

  • The bundle uses exact IP matching. Subnet ranges (e.g., 192.168.1.0/24) won’t work by default. Fix: Use a library like digitalbush/ip-range to parse CIDR notation:
    $ips = IpRange::parse(config('mes_maintenance.ips_allowed'));
    $isAllowed = $ips->contains($request->ip());
    
  • Localhost issues: 127.0.0.1 and ::1 (IPv6) may not work as expected in shared hosting. Fix: Add all variants:
    ips_allowed: [127.0.0.1, ::1, 127.0.1.1]
    

2. Caching Headaches

  • The bundle does not cache IP checks by default. In high-traffic apps, this can cause performance issues. Fix: Cache the allowed IPs array:
    $ips = Cache::remember('mes_maintenance.ips', 60, function () {
        return config('mes_maintenance.ips_allowed');
    });
    
  • Config caching: After changing ips_allowed, run:
    php artisan config:clear
    

3. Middleware Conflicts

  • If you use Laravel’s built-in maintenance middleware, conflicts may arise. Fix: Disable Laravel’s middleware and rely solely on this bundle:
    // app/Http/Kernel.php
    protected $middlewareGroups = [
        'web' => [
            // Remove \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class
        ],
    ];
    

4. Template Overrides Not Working

  • Custom templates in resources/views/vendor/mes_maintenance/ may not load. Fix: Ensure the bundle’s service provider publishes assets:
    // In MesMaintenanceBundle ServiceProvider
    public function boot()
    {
        $this->publishes([
            __DIR__.'/../resources/views' => resource_path('views/vendor/mes_maintenance'),
        ], 'mes-maintenance-views');
    }
    
    Then run:
    php artisan vendor:publish --tag=mes-maintenance-views
    

5. HTTPS/Proxy IPs

  • Behind a proxy (e
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.
craftcms/url-validator
directorytree/privacy-filter-classifier
directorytree/privacy-filter
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi
splash/scopes
splash/toolkit
testo/output-teamcity
testo/bridge-symfony