PHPackages                             laravel/doctor - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Framework](/categories/framework)
4. /
5. laravel/doctor

ActiveLibrary[Framework](/categories/framework)

laravel/doctor
==============

First-party diagnostics for Laravel applications

v0.1.0(6d ago)00MITPHPPHP ^8.3CI passing

Since Jul 11Pushed todayCompare

[ Source](https://github.com/laravel/doctor)[ Packagist](https://packagist.org/packages/laravel/doctor)[ Docs](https://github.com/laravel/doctor)[ RSS](/packages/laravel-doctor/feed)WikiDiscussions main Synced today

READMEChangelog (1)Dependencies (13)Versions (6)Used By (0)

[![Build Status](https://github.com/laravel/doctor/workflows/tests/badge.svg)](https://github.com/laravel/doctor/actions)[![Total Downloads](https://camo.githubusercontent.com/a24d14664c49e1f59188290ce19a456ee60141613f51d5be2ceaf3389aa124a5/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6c61726176656c2f646f63746f72)](https://packagist.org/packages/laravel/doctor)[![Latest Stable Version](https://camo.githubusercontent.com/96d0d2d4487ae7ab0c95b2e89d40a122256a61254921b7577a66fdc3820a0778/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6c61726176656c2f646f63746f72)](https://packagist.org/packages/laravel/doctor)[![License](https://camo.githubusercontent.com/40a28a2ab3e2367d452c602e7447d7702de657a5ae7f61be5b94ee38ae3d18fc/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6c61726176656c2f646f63746f72)](https://packagist.org/packages/laravel/doctor)

Introduction
------------

[](#introduction)

Laravel Doctor diagnoses common configuration, environment, and infrastructure problems in your application.

Each diagnostic is a single check. It inspects one thing, such as whether Laravel can write to its storage directories, and reports one of several statuses. A diagnostic may also offer a fix when the repair is safe and deterministic. Issues that can't be repaired safely, such as a failed asset build, are reported with remediation steps instead.

Installation
------------

[](#installation)

Install Laravel Doctor using Composer:

```
composer require laravel/doctor --dev
```

Running Doctor
--------------

[](#running-doctor)

Once installed, the package registers the `doctor` Artisan command:

```
php artisan doctor
```

When a failing diagnostic can be fixed, Doctor reports the problem and prompts before applying the fix:

```
Storage is writable: The application cannot write to every required storage directory.

 Make the storage directories writable? (yes/no) [yes]

```

Some fixes offer a choice of repairs instead of a yes/no confirmation. When the default cache store is unreachable on a developer machine, for example, Doctor presents a select list of the configured stores that actually work, along with an entry to keep the current store and repair it manually — declining the switch leaves the failure in the report with its remediation text.

To run available fixes without prompting, pass the `--fix` option:

```
php artisan doctor --fix
```

First-party fixes cover deterministic local repairs such as creating a missing `.env`, generating `APP_KEY`, disabling production debug mode, adding `.env` to `.gitignore`, creating the public storage link, and repairing writable storage directories. Because `--fix` never prompts, it applies every fix that does not require a choice; fixes that need one are reported as ordinary failures with their remediation text.

Note

Fixes are only available with the CLI and agent [output formats](#output-formats). With agent output, `--fix` applies every available deterministic fix and reports the outcomes in the payload's `fixes` array. Doctor rejects `--fix` with the JSON and GitHub report formats so machine-readable reports never mutate the application.

Diagnostic Statuses
-------------------

[](#diagnostic-statuses)

Every diagnostic returns one of the following statuses. Doctor uses them to render output and to determine the command's exit code:

StatusMeaningAffects exit code`pass`The check succeeded and nothing is wrong.No`notice`Informational context worth surfacing to the developer.No`warn`A potential problem that may not require action.Only with `--fail-on=warn``fail`The check found a problem that should be resolved.Yes`skip`The check did not apply to the current environment.No`error`The diagnostic threw an exception while running.YesBy default, the command exits with a failing status when a diagnostic fails or errors. Use `--fail-on=warn` to also fail on warnings, or `--fail-on=never` when Doctor should only report issues.

### Bailing on Failure

[](#bailing-on-failure)

Use `--bail` to stop after the first diagnostic that fails or errors. Warnings, notices, passes, and skips do not stop the run:

```
php artisan doctor --bail
```

The flag works with every output format and may be combined with diagnostic selectors. Programmatic runs may enable the same behavior with `Doctor::bail()->run()`.

Selecting Diagnostics
---------------------

[](#selecting-diagnostics)

Diagnostics may be selected or excluded by class name, group, package, or package wildcard. Multiple values may be passed either by repeating the option or by separating values with commas.

```
php artisan doctor --only=storage

php artisan doctor --only=StorageIsWritable

php artisan doctor --only=vendor/package

php artisan doctor --except=laravel/*

php artisan doctor --except=laravel/doctor

php artisan doctor --except=storage
```

Configuring Doctor
------------------

[](#configuring-doctor)

To configure persistent diagnostic selection and environment modes, publish Doctor's configuration file:

```
php artisan vendor:publish --tag=doctor-config
```

The `only` and `except` options accept the same selectors as the command line: diagnostic class names, groups, packages, or package wildcards.

```
'only' => [
    // 'laravel/doctor',
    // 'vendor/*',
    // 'security',
],

'except' => [
    // \Laravel\Doctor\Diagnostics\EnvironmentFileIsGitIgnored::class,
],
```

Configured `only` selectors act as a persistent allowlist. Passing `--only` at runtime narrows that allowlist further, while configured `except` selectors and `--except` are combined.

Environment Modes
-----------------

[](#environment-modes)

Some facts about an application cannot be judged on their own. A `sync` queue connection is a sensible default on a developer's machine, but in production it means queued jobs silently run inside web requests. Uncached bootstrap files are correct while code is changing, but in production they mean the deployment never ran `php artisan optimize`. Debug mode is essential locally and a security problem on a public server.

To judge these diagnostics, Doctor resolves the application to one of two modes:

ModeExpectations`local`The application is under active development. Debug mode, `sync` queues, and uncached bootstrap files are normal.`production`The application serves real traffic. Debug mode is a security risk, queues should run asynchronously, and bootstrap files should be cached.The mode changes the verdict, not just the message. Missing bootstrap caches warn in production but pass locally, while present bootstrap caches pass in production but produce a notice locally, since a stale cache is a common reason recent changes do not appear during development.

Doctor recognizes Laravel's conventional `local`, `production`, and `staging` environment names out of the box. If your application uses other names, group each one under the appropriate Doctor mode in the configuration file:

```
'environments' => [
    'local' => ['local', 'dev'],
    'production' => ['production', 'staging', 'qa'],
],
```

Any environment not listed is treated as `production`, so unfamiliar environments are held to the strictest expectations rather than quietly excused. An unsupported mode name, an environment list that is not an array, or an environment assigned to both modes throws an exception.

Custom diagnostics may branch on the current mode. Here, a `sync` queue connection passes on a developer's machine but warns in production:

```
use Laravel\Doctor\EnvironmentMode;

public function check(): DiagnosticResult
{
    if (config('queue.default') !== 'sync') {
        return $this->pass('async');
    }

    if (EnvironmentMode::current()->isProduction()) {
        return $this->warn('sync-in-production');
    }

    return $this->pass('sync-local');
}
```

The `pass` and `warn` methods build results from the diagnostic's named messages, which are covered in [Creating Diagnostics](#creating-diagnostics).

Default Diagnostics
-------------------

[](#default-diagnostics)

Doctor ships with a focused suite of diagnostics that cover common configuration, environment, dependency, database, queue, and storage problems. The default suite includes:

- **Environment** — `.env` presence, `APP_KEY`, PHP version, required and recommended PHP extensions, and timezone.
- **Composer** — Composer dependencies are installed before autoload validation runs, Composer can dump optimized autoload files, and repairable `composer.lock` problems can be fixed automatically in local environments.
- **Configuration** — configuration files can be loaded and cached, configuration values required by the active drivers are set, and bootstrap cache files are reported when their presence does not match the current environment.
- **Database** — the default connection is reachable, the SQLite database file exists when needed, and pending migrations can be applied automatically in local environments.
- **Cache, queue, scheduler, and session** — configured drivers are reachable, active Redis connections are checked, `sync` queues are flagged outside local environments, and registered scheduled tasks are surfaced as a notice.
- **Storage** — the default filesystem disk is reachable, required directories are writable, and the `storage:link` symlink exists when expected.
- **Security** — debug mode matches the environment, `.env` is ignored, and Composer dependencies are audited.

Creating Diagnostics
--------------------

[](#creating-diagnostics)

A diagnostic is a single class that, like an Artisan command, can declare its definition as properties. Extend `Laravel\Doctor\Diagnostic` and implement a `check` method that returns a `DiagnosticResult`. When `$name` or `$group` are not set, Doctor derives defaults from the class name.

The `make:diagnostic` Artisan command scaffolds a diagnostic into `app/Doctor/Diagnostics`. The command asks whether the diagnostic should offer a fix, or accepts the `--fixable` option directly:

```
php artisan make:diagnostic HorizonIsRunning --fixable
```

To offer a fix, implement the `Laravel\Doctor\Contracts\Fixable` contract and mark each repairable failure with `->fixable()`. Doctor only attempts fixes for explicitly fixable `fail` results from diagnostics that implement the contract. Other failures and unexpected `error` results are never fixed automatically. Pass one or more `EnvironmentMode` values to limit where an automatic fix may run, such as `->fixable(EnvironmentMode::Local)` for a developer-machine-only repair.

The following diagnostic checks whether the application key is set. Because Laravel already provides a safe key generator, it implements `Fixable`:

```
