Skip to main content
Validate your project config, detect runtimes, and check deploy readiness. No auth required, no side effects. Run this before pushing to catch config errors early.
Pushing is the deploy. After floo apps github connect, every git push to your default branch deploys to dev automatically. floo preflight is the local check you run before that push — there is no separate floo deploy step in the everyday flow. See git-push deploys for the full trigger table.
floo preflight [PATH]

Arguments

ArgumentDescriptionDefault
PATHProject directory to validate. (current directory)

Flags

FlagDescription
--app APPExisting app name to validate against
--services NAMEValidate only specific services (repeatable)

Examples

# Validate current directory
floo preflight

# Validate with JSON output (for agents)
floo preflight --json

# Validate a specific directory
floo preflight ./my-project

# Validate specific services only
floo preflight --services api --services web

What it checks

  1. Config files — reads floo.app.toml (and any per-service floo.service.toml in a delegated layout) and validates structure
  2. Service discovery — resolves all services, checks for duplicates and naming rules
  3. Port validation — verifies ports are set and match Dockerfile EXPOSE directives
  4. Runtime detection — scans project files to determine language and framework
  5. Env file check — verifies referenced env_file paths exist on disk
  6. Env injection plan — shows each service’s managed attachments, generated env keys, required keys, and optional keys
  7. Managed services — reconciles declared services (CLI + legacy TOML) against the platform DB and surfaces them in five bins:
    • to_provision — declared, no row yet. Will be created on the next deploy or floo services add.
    • to_retain — declared and exists. No-op.
    • to_retry — declared, but the existing row is in failed state. The next deploy retries provisioning.
    • to_orphan — exists, not declared anywhere. Deploy will not destroy. Run floo services remove to actually delete.
    • in_flight_deprovisioning — a deprovisioning row is mid-flight. Excluded from to_retain / to_orphan until it completes.

JSON output

{
  "success": true,
  "data": {
    "app": "my-app",
    "services": [
      {
        "name": "web",
        "path": ".",
        "port": 3000,
        "type": "web",
        "ingress": "public",
        "runtime": "nodejs",
        "framework": "Next.js",
        "confidence": "high"
      }
    ],
    "env_injection_plan": {
      "mode": "explicit",
      "services": [
        {
          "service": "web",
          "managed": [],
          "required": [],
          "optional": []
        },
        {
          "service": "api",
          "managed": [
            {
              "handle": "postgres",
              "keys": ["DATABASE_URL", "PGHOST", "PGPORT", "PGDATABASE", "PGUSER", "PGPASSWORD"]
            }
          ],
          "required": ["STRIPE_SECRET_KEY"],
          "optional": []
        }
      ],
      "notes": []
    },
    "managed_services": [],
    "warnings": [],
    "valid": true
  }
}

Errors

CodeMeaning
INVALID_PATHPath is not a valid directory
NO_CONFIG_FOUNDNo floo.app.toml found. Run floo init first
CONFIG_INVALIDValidation failed (duplicate service names, invalid ports, etc.)
SERVICE_CONFIG_MISSINGA delegated service declared in floo.app.toml is missing its floo.service.toml