Maintenance mode

This guide is for Northwind Studio operators who need to take DeskFlow offline during deploys — visitors get HTTP 503, while Alex can still reach the API with a bypass token.

What you will learn

  • How to enable and disable maintenance mode from the CLI
  • Where bypass tokens live (environment/.env, not committed docs)
  • Why RoadRunner picks up toggles without a restart
Before you start

How it works

flowchart TD Req[Incoming request] --> Gate{Maintenance enabled?} Gate -->|No| App[DeskFlow API / static] Gate -->|Yes| Bypass{Bypass token valid?} Bypass -->|Yes| App Bypass -->|No| Block[HTTP 503 JSON or HTML] Assets["/__pionia/* assets"] --> Always[Always served]

Maintenance mode returns HTTP 503 for all routes except framework assets at /__pionia/*. Visitors see a configurable message; API clients get a JSON envelope.

CLI

php pionia maintenance:on --message="Deploying" --retry-after=300 --bypass="$(php -r 'require "vendor/autoload.php"; echo (new Pionia\Security\Security())->randomHex(16);')"
php pionia maintenance:off

Or generate a token in php pionia shell with secure_random_hex(16) and pass it to --bypass= manually.

Unique bypass tokens

Use a unique random bypass token each time. Do not copy example tokens from documentation into production.

Aliases: down / up.

Configuration

environment/settings.ini:

[maintenance]
ENABLED = true
MESSAGE = We will be back shortly.
RETRY_AFTER = 120
; Set MAINTENANCE_BYPASS in environment/.env — do not commit the real value
BYPASS =
# environment/.env (gitignored)
MAINTENANCE_BYPASS=your-generated-random-string

Map MAINTENANCE_BYPASS into settings in your provider, or set BYPASS locally only on machines that need it.

SettingPurpose
ENABLEDGate active when true
MESSAGEBody text / JSON message
RETRY_AFTERRetry-After header (seconds)
BYPASSQuery ?bypass=<token> or header X-Maintenance-Bypass: <token>

Or set MAINTENANCE_MODE=true in .env.

RoadRunner

Workers re-read settings.ini on each request — toggle maintenance without restarting RR.

What stays available

  • /__pionia/* — framework CSS, logos, welcome assets
  • Bypass URL/header when configured

Static files under /static/ and the API are blocked while maintenance is on.

Common mistakes

  • Committing bypass tokens to git — generate per deploy with secure_random_hex(16) (Security utilities) and store in .env only.
  • Copying doc example tokens into production — treat every published token as compromised.
  • Expecting /static/ to stay up — only /__pionia/* framework assets bypass the gate.
  • Restarting RoadRunner to toggle maintenance — not required; settings reload per request.

What’s next

RoadRunner

Workers that re-read settings.ini.

Production performance

Deploy optimize after maintenance:off.

Commands

Full CLI reference.