Laravel Doctor adds real checks before deployment
Laravel Doctor checks your application configuration and dependencies before they become production failures.
The failure usually appears after deployment
A Laravel application can pass its tests, build its assets, and deploy without obvious errors. Even then, the release may leave a queue using sync, a directory that cannot be written to, or an unreachable cache store. Those issues are often discovered only after deployment, with real traffic or jobs piling up. Laravel Doctor adds another layer of checks for finding those problems earlier.
It is not bundled with a default Laravel installation: it is a first-party package installed as a development dependency. It registers the php artisan doctor command and runs diagnostics against configuration, environment, and the services configured by the application. The goal is not to replace tests, but to verify that the application can run against the infrastructure it expects.
composer require laravel/doctor --dev
php artisan doctorWhat the command checks
The included diagnostics cover the areas that commonly differ between local development and production. They check for a .env file, the application key, the PHP version, required or recommended extensions, and the configured timezone. They also inspect Composer dependencies, configuration loading and caching, database connectivity, and pending migrations.
Doctor also checks active cache, queue, session, and filesystem drivers. It can detect active Redis connections that do not respond, flag a sync queue outside a local environment, and confirm that required storage directories are writable. When the application expects the public storage symlink, it checks that as well.
Results are reported as pass, notice, warn, fail, skip, or error. By default, a failure or an error produces a failing exit code. Use --fail-on=warn when warnings should also block the process, or --fail-on=never when you only need a report.
An additional CI gate
This is where I find it most useful for self-managed deployments. Doctor does not need to become a large deployment stage, and there is no reason to run every diagnostic in every context. Run it after dependencies are installed and before promoting a build, then set the severity level according to what should actually block a release.
- name: Check Laravel deployment health
run: php artisan doctor --format=github --fail-on=warnThe github format emits annotations for GitHub Actions. For other automated consumers, there is --format=json, while --format=agent provides compact output intended for coding agents. You can also narrow the scope with --only or exclude diagnostics with --except, using groups, diagnostic classes, or packages.
php artisan doctor --only=storage
php artisan doctor --except=laravel/*Environment mode changes the result
Doctor does not judge a local application and one serving traffic by the same rules. In local development, an enabled APP_DEBUG, a sync queue, or missing bootstrap caches may be perfectly acceptable. In production, those same conditions can become warnings or problems worth resolving before deployment.
It recognizes local, production, and staging out of the box. If your environments are named dev, qa, or something custom, publish the configuration with php artisan vendor:publish --tag=doctor-config and map them to local or production mode. This deserves attention: unknown environments are treated as production, which is a conservative default rather than silently weakening checks.
'environments' => [
'local' => ['local', 'dev'],
'production' => ['production', 'staging', 'qa'],
],Fix what is safe, not what requires a guess
The --fix option can apply deterministic repairs without prompting. Included fixes cover creating a missing .env, generating APP_KEY, disabling debug mode in production, adding .env to Git ignore rules, creating the public storage link, and repairing writable storage directories. It does not try to make changes that require a human decision.
That boundary matters. If several cache stores could be used, for example, Doctor can present options during an interactive run, but --fix will not choose one by itself. It also rejects --fix with JSON or GitHub formats so a reporting-oriented run cannot mutate the application. I would keep --fix for local machines or explicit maintenance tasks, not as a side effect of a deployment pipeline.
The fine print
Doctor does not prove that an application works end to end. It can verify that the database is reachable, but it will not find a slow query, incorrect authorization logic, or a broken business workflow. Tests, observability, alerts, and post-deployment checks are still necessary.
It also does not know every part of your infrastructure by default. If you rely on Horizon, an internal service, a bucket with specific policies, or a critical external API, you will need your own diagnostics. The package provides make:diagnostic to scaffold a class and lets you register it through the Doctor facade, so extending it does not require modifying the package.
Finally, installing it with --dev affects where it is available. If your production image runs Composer with --no-dev, you cannot execute it inside that container unless you change that choice. For many teams, the better fit is a release-validation stage with representative configuration and controlled access to the services being checked.
Source: Laravel Magazine Official documentation: Laravel Doctor