Skip to content

fly target: no deploy provider exists — DEPLOY_PROVIDER silently falls back to docker, every publish fails with spawn docker ENOENT #209

Description

@fo82

Summary

On the fly target there is no deploy provider that can actually publish: DEPLOY_PROVIDER selection only knows aws and docker, and anything else — including unset, including "fly" — silently falls back to docker. The core runs in a Fly machine whose image ships no docker binary and no daemon (and Fly Machines are Firecracker VMs, so there is no host socket to mount either). Every publish therefore fails with:

deploy run failed: spawn docker ENOENT

This is reproducible with a trivial app (one server.py on $PORT + one index.html) from any scope. Publish on a target: fly + sprites topology has never worked — it is a feature gap, not a regression, but nothing fails loudly at config/doctor/up time, so it presents as a runtime bug.

Evidence

  1. Provider selection is a two-way ternarysrc/config.ts:636 (current main, checked at 47a6d6c):

    const deployProvider: "aws" | "docker" = env.DEPLOY_PROVIDER === "aws" ? "aws" : "docker";

    DEPLOY_PROVIDER=fly still selects docker.

  2. The docker spawn site is hardcoded and not overridablesrc/deploy/docker-deploy-provider.ts:16:

    const docker = opts.docker ?? "docker";

    Wiring (src/wiring.ts:775-785) passes no opts; there is no DOCKER_BIN-style env override. The child_process error event surfaces as the spawn docker ENOENT message via docker-deploy-provider.ts:76.

  3. Live probe of a fly-target core machine: which docker → nothing, /var/run/docker.sock → does not exist, DEPLOY_PROVIDER → unset.

  4. The fly publisher is half-landed. The CLI and secret schema already anticipate it — cli/src/backends/fly.ts:957,1435 and src/deployment/secret-schema.ts:48 gate FLY_DEPLOY_API_TOKEN on DEPLOY_PROVIDER === "fly", and .env.example documents the token — but no fly-deploy-provider.ts exists in src/deploy/. The scaffolding shipped; the provider didn't.

Asks

Either (ideally both):

  1. Implement the fly deploy provider the scaffolding anticipates — the DeployProvider seam is small (apply / destroy / resolveEndpoint); one Fly app or machine per deployment via the Machines API using the FLY_DEPLOY_API_TOKEN the CLI already verifies and pushes. profile.managedScaleToZero maps naturally onto Fly autostop.
  2. Fail loudly instead of falling back. When target: fly (or any config whose resolved provider can't exist in the core's own runtime) resolves to docker, qm check / qm doctor / qm up should error at that point — not let every publish die at spawn time with an ENOENT that reads like a host misconfiguration.

Environment: qm on target: fly, SANDBOX_BACKEND=sprites, core deployed via qm up. Related in spirit to #137 (fly/sprites contracts that configure cleanly but have no implementation behind them).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions