Diagnoses PhoenixKit installation, migration, and runtime issues.
Runs a comprehensive suite of checks covering database connectivity, pool configuration, PgBouncer detection, migration state, lock conflicts, and application configuration. Prints a clear pass/fail report with actionable remediation steps.
Usage
$ mix phoenix_kit.doctor
$ mix phoenix_kit.doctor --prefix=auth
$ mix phoenix_kit.doctor --exit-code
Options
--prefix- Database schema prefix. When omitted, resolves fromconfig :phoenix_kit, :prefix, then"public"— the same resolutionmix phoenix_kit.update/--statususe, so a prefixed install is diagnosed against the schema it actually lives in.--exit-code- Exit non-zero when any check FAILED. Without it this task prints "N failures" and still exits 0, so a deploy script that runs it cannot act on the result — the same silent successmix phoenix_kit.status --exit-codeexists to remove. Warnings never fail the run; they are advisory by construction and several fire on healthy installs. Off by default so deploys that run this purely for its report keep passing.
Checks Performed
- Repo Detection — Can we find and start the Ecto repo?
- DB Connectivity — Can we execute a simple query?
- Pool Configuration — Pool size, checkout timeout, queue settings
- PgBouncer Detection — Is PgBouncer between app and PostgreSQL?
- Migration State — PhoenixKit version (COMMENT), schema_migrations alignment
- Module Schema Versions — Modules owning their own chain, vs what their code expects
- Schema Drift — Columns a migration should have added but the DB lacks
- Pending Migrations — Migration files not yet recorded in schema_migrations
- UUID Column Types — Detects varchar uuid columns that crash Ecto on startup
- UUID Primary Keys — Detects primary keys that are not the expected uuid type
- NULL UUIDs in FK Sources — Detects NULL uuids that cause infinite backfill loops
- Orphaned FK References — Detects orphaned rows that block FK constraint creation
- Lock Conflicts — Any blocked or long-running queries?
- Orphaned Connections — Idle-in-transaction or stuck connections
- Oban Configuration — Queues and plugins that consume pool connections
- PhoenixKit Supervisor — What's running (update_mode vs full)?
- Child Start Order — Does the Repo start before PhoenixKit/Oban in application.ex?
- Update Mode — Is update_mode active?
- daisyUI Version — Is the host's vendored daisyUI recent enough?
- User Dashboard (deprecated) — Is the host still on the retired dashboard?
- Sitemap Discoverability — Is the sitemap actually reachable?
- Demo Auth Pages — Are the demo auth routes still exposed?
- Manifest Repair (dry-run) —
PhoenixKit.Migrations.Repair.verify/1runs read-only against the generatedPhoenixKit.Migrations.ExpectedSchemamanifest as an additional, non-fatal check (never:fail). Passes and says so if the manifest has been removed or overridden away in this checkout.
Summary
Functions
The process exit status --exit-code should produce: 1 when any check
failed, 0 otherwise.
Functions
The process exit status --exit-code should produce: 1 when any check
failed, 0 otherwise.
Public because run/1 is not a unit-test seam (it starts the app and needs a
real database) — this is the pure decision behind the flag, in the same shape
as Mix.Tasks.PhoenixKit.Status.exit_code/2 and
Mix.Tasks.PhoenixKit.Repair.exit_code/1.
Only :fail gates. A :warn is advisory by construction — several fire on
perfectly healthy installs (a capped pool under update_mode, an unreadable
application.ex) — and gating on them would make the flag unusable, which is
how a task ends up back at "reports a problem and exits 0".