Skip to content

Instantly share code, notes, and snippets.

@jfcherng
Last active January 8, 2026 09:39
Show Gist options
  • Select an option

  • Save jfcherng/2fa6cccd68ad4cc84a31b974066db293 to your computer and use it in GitHub Desktop.

Select an option

Save jfcherng/2fa6cccd68ad4cc84a31b974066db293 to your computer and use it in GitHub Desktop.
Symfony 5 maintenance mode
MAINTENANCE_MODE=0
<?php
declare(strict_types=1);
namespace App\EventSubscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Twig\Environment as TwigEnvironment;
class KernelRequestSubscriber implements EventSubscriberInterface
{
private TwigEnvironment $twig;
public function __construct(TwigEnvironment $twig)
{
$this->twig = $twig;
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents(): array
{
return [
KernelEvents::REQUEST => [
['onMaintenance', \PHP_INT_MAX - 1000],
],
];
}
public function onMaintenance(RequestEvent $event): void
{
/** @var bool $isMaintenance */
$isMaintenance = \filter_var($_ENV['MAINTENANCE_MODE'] ?? '0', \FILTER_VALIDATE_BOOLEAN);
if ($isMaintenance) {
$event->setResponse(new Response(
$this->twig->render('maintenance.html.twig'),
Response::HTTP_SERVICE_UNAVAILABLE,
));
$event->stopPropagation();
}
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Site temporarily under maintenance</title>
</head>
<body>
<h1>Site temporarily under maintenance</h1>
<p>Sorry for the inconvenience, we will get back soon!</p>
</body>
</html>
@jfcherng
Copy link
Author

Haha thanks you guys. Though I haven't written any PHP for years.

@yann-eugone
Copy link

I can suggest an alternative that will let Symfony error rendering do the job for us

<?php

declare(strict_types=1);

namespace App\Maintenance;

use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\Exception\HttpException;

/**
 * Detects if maintenance mode is enabled (via the environment variable of the same name).
 * When this mode is enabled, an HTTP 503 exception is thrown.
 * The error handling system is then responsible for rendering the appropriate response.
 */
final readonly class MaintenanceListener
{
    public function __construct(
        #[Autowire('%env(bool:MAINTENANCE)%')]
        private bool $maintenance,
    ) {
    }

    #[AsEventListener(priority: \PHP_INT_MAX - 1000)]
    public function __invoke(RequestEvent $event): void
    {
        if (!$this->maintenance) {
            return;
        }

        // We definitely don't want to interfere with subrequests, especially since they are used for error rendering
        if (!$event->isMainRequest()) {
            return;
        }

        // We want to avoid blocking certain requests
        $uri = $event->getRequest()->getRequestUri();
        if (
            \str_starts_with($uri, '/_profiler')
            || \str_starts_with($uri, '/_wdt')
            || \str_starts_with($uri, '/_error')
        ) {
            return;
        }

        throw new HttpException(Response::HTTP_SERVICE_UNAVAILABLE);
    }
}

Then, following the documentation, you can create a templates/bundles/TwigBundle/Exception/error503.html.twig for your maintenance page

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment