markup/status-bundle
A lightweight PHP bundle for exposing and managing application status. Integrates cleanly with your framework to report health and runtime state through simple configuration. Useful for monitoring endpoints, status pages, and quick operational checks.
Read this before you composer require anything. markup/status-bundle is effectively a dead package: last tagged release July 2017, zero stars, zero dependents. That release date places it squarely in the Symfony 2.8/3.x era — before Symfony 4's bundle-less config/bundles.php, before the AbstractController rewrite, and before PHP 7.2. Treat the install as a compatibility investigation, not a normal dependency add.
Inspect the constraint surface first, without installing:
composer show markup/status-bundle --all
Look at require for symfony/symfony or symfony/framework-bundle bounds and the PHP floor. If you are on Symfony 5/6/7 or PHP 8.x, expect composer require to fail on constraint resolution. If it does, do not reach for --ignore-platform-reqs on a production app; fork the repo, bump the constraints, and test — or just don't use it.
If it resolves, install and register it. On Symfony 3 and earlier, add to app/AppKernel.php:
new Markup\StatusBundle\MarkupStatusBundle(),
On Symfony 4+, add to config/bundles.php:
Markup\StatusBundle\MarkupStatusBundle::class => ['all' => true],
Find the moving parts before writing config. This is the first place to look, and it is the fastest way to understand a bundle this old:
ls vendor/markup/status-bundle
cat vendor/markup/status-bundle/composer.json
ls vendor/markup/status-bundle/Resources/config
bin/console debug:config markup_status # container extension alias — confirm the exact name
bin/console debug:router | grep -i status
The DependencyInjection/Configuration.php file is the authoritative list of config keys. The Resources/config/routing.* file tells you whether routes are imported manually or shipped as a route resource. Don't guess the extension alias (markup_status, markup_status_bundle, etc.) — debug:config without an argument lists all registered aliases.
First real use case: a health endpoint for your load balancer or uptime monitor. Once the bundle is registered and routes are imported, hit the route the router reports:
curl -i http://localhost:8000/status
The value of a bundle like this is that it centralises the "is the app alive" answer — HTTP 200 with a body, or a non-2xx when a dependency is down — instead of every project hand-rolling a /health controller.
Monitoring integration. The primary day-to-day use is pointing external probes at the status route. Configure your uptime monitor (Pingdom, UptimeRobot, Datadog synthetics) against the endpoint the router exposes and assert on both status code and a substring in the body. If the bundle returns JSON, assert on a field rather than the whole payload so you don't break probes when the bundle's serialisation changes.
Environment gating. Status endpoints should not be publicly reachable in production unless you intend them to be. The common pattern:
# config/routes.yaml
markup_status:
resource: "@MarkupStatusBundle/Resources/config/routing.xml"
prefix: /_status
…plus restricting /_status at the web-server or firewall level to your monitoring provider's IP ranges. If the bundle exposes a check that reveals stack traces, DB DSNs, or versions, keep it on an internal network or behind a token.
Wrapping rather than calling directly. Even if the bundle ships a controller, the durable pattern is to have your own thin controller or service delegate to the bundle's status service and shape the response yourself:
final class HealthController
{
public function __construct(private StatusCheckerInterface $checker) {}
public function __invoke(): JsonResponse
{
$result = $this->checker->check(); // exact API — read the bundle's service definitions
return new JsonResponse(
['status' => $result->isHealthy() ? 'ok' : 'fail'],
$result->isHealthy() ? 200 : 503
);
}
}
That contract is yours, so replacing the bundle later (with symfony/health-check, or a 40-line controller) is a local change rather than a rewrite of every probe.
Extending the checks. If the bundle exposes a tagged-services mechanism for status providers (the usual markup_status.check tag pattern), register your own — DB connectivity, Redis ping, queue depth, disk space — and tag them in config/services.yaml:
services:
App\Health\DatabaseCheck:
tags: ['markup_status.check']
Check debug:container --tag=<tagname> after reading the bundle's CompilerPass to confirm the exact tag string; do not copy a tag name from a blog post.
Deploy gates. A cheap, high-value pattern: run the status route check at the end of your deploy script and fail the deploy on non-200. This catches "container compiles but the DB credentials are wrong in this environment" before traffic is shifted.
CI smoke test. Boot the app in the test environment and issue a request to the status route in your functional test suite. It's one of the few tests that genuinely exercises the DI wiring end-to-end.
composer.json repositories VCS entry so you control patches.app/config/routing.yml imports. In Symfony 4+ the file goes in config/routes/ and uses an attribute-style resource path — verify with debug:router rather than assuming the route exists.security.yaml has a catch-all access_control that requires authentication, the route will 302 to your login page and your monitor will report a false failure (or worse, a false success if it only checks for a response). Add an explicit access_control entry with roles: PUBLIC_ACCESS (or IS_AUTHENTICATED_ANONYMOUSLY on older Symfony) above the catch-all.cache:clear after config changes. Old bundles frequently use container parameters that are compiled in; editing YAML without clearing the cache silently has no effect. If a config change "doesn't work", this is the first thing to check, followed by debug:config to confirm the value actually landed.getContainerExtension, getPath against a newer Bundle base class). Diff the bundle's MarkupStatusBundle.php against a modern AbstractBundle subclass and patch the two or three methods.symfony/symfony monorepo requirements. 2017-era bundles often require the whole framework rather than individual components, which will fight with a modern per-component install. A fork replacing symfony/symfony with symfony/http-kernel + symfony/dependency-injection + symfony/routing is usually enough.Configuration tree you can override, and an event dispatched around the check. If none of the three exist, the bundle is a thin controller and you should replace it.How can I help you explore Laravel packages today?