PhoenixHealthy

Kubernetes liveness and readiness probes for Phoenix (and Plug).

Default endpoints:

When a :repo is configured, readiness runs SELECT 1 through Ecto.Adapters.SQL.

Installation

def deps do
[
{:phoenix_healthy, "~> 0.1.0"}
]
end

Usage

Router (Phoenix)

defmodule MyAppWeb.Router do
use MyAppWeb, :router
import PhoenixHealthy.Router
phoenix_healthy("/health", repo: MyApp.Repo)
end

This exposes GET /health/live and GET /health/ready.

Or configure the repo once:

# config/config.exs
config :phoenix_healthy, repo: MyApp.Repo
import PhoenixHealthy.Router
phoenix_healthy("/health")

Endpoint plug

Place it near the top of endpoint.ex so probes skip the rest of the pipeline (sessions, parsers, request logs):

defmodule MyAppWeb.Endpoint do
use Phoenix.Endpoint, otp_app: :my_app_web
plug PhoenixHealthy.Plug, repo: MyApp.Repo
# ...
end

Your own controller (Swagger, custom plugs)

defmodule MyAppWeb.HealthController do
use MyAppWeb, :controller
use PhoenixHealthy, repo: MyApp.Repo
end
pipeline :health do
plug :accepts, ["html", "text", "json"]
end
scope "/health", MyAppWeb do
pipe_through :health
get "/live", HealthController, :live
get "/ready", HealthController, :ready
end

Options

OptionDefaultDescription
:reponilEcto repo used for the default readiness check
:path"/health"Base path for PhoenixHealthy.Plug
:live_path"live"Liveness segment
:ready_path"ready"Readiness segment
:livealways okCustom liveness probe (() -> probe_result) or MFA
:readyrepo check, else okCustom readiness probe (() -> probe_result) or MFA
:ok_body"ok"Body for a passing probe
:error_body"unavailable"Body for a failing probe

A probe may return :ok, true, :error, false, or {:error, reason}.

Custom readiness (for example Redis + DB):

phoenix_healthy("/health",
ready: fn ->
with :ok <- PhoenixHealthy.Checks.ecto(MyApp.Repo),
:ok <- MyApp.Redis.ping() do
:ok
end
end
)

Kubernetes

livenessProbe:
httpGet:
path: /health/live
port: http
readinessProbe:
httpGet:
path: /health/ready
port: http