Skip to content

CLI: rustybuns containers (list, build, run, smoke) plus a Docker preflight on deploy #815

Closed as not planned

Description

@QuinnsCode

Problem

Any RustyBuns app can declare { type: "container", dockerfile, className, ... } bindings. The CLI writes them into Alchemy and wrangler config (packages/cli/src/gen/alchemy.ts, gen/wrangler.ts), but it gives you no way to work with the images yourself. Trying one locally means hand-writing docker build -f ... <context> and docker run -p 8080:8080 ... and knowing what each server expects. A deploy with container bindings needs Docker running, and nothing checks that up front.

What good looks like

A rustybuns containers command family that knows the app's bindings:

$ rustybuns containers
  AGENT_SANDBOX   sandbox/Dockerfile             basic ×2   built 3m ago · 812 MB
  DEPLOY_RUNNER   deploy-sandbox/Dockerfile      basic ×1   not built
  CI_RUNNER       deploy-sandbox/ci.Dockerfile   basic ×2   stale (server.mjs changed)
  • rustybuns containers build [BINDING…] builds the bindings (all of them by default) for linux/amd64 with the right context. It shows a live progress line per image (step n/m, current layer, elapsed time) instead of raw BuildKit output, which --verbose restores. It finishes with a size table and a size delta against the last local build.

  • rustybuns containers run BINDING builds the image if it's stale, starts it on a free port, waits until it's ready (:8080 answering), then prints a ready line with the URL and the docker commands it ran (so nothing is magic). It streams logs prefixed with the binding name until Ctrl-C, then removes the container.

    • Env without secrets. It reads .env.schema for the names a binding expects and passes only values the user sets explicitly (--env NAME=... or an env file they name). It never reads .env or 1Password itself, and it lists which expected names were left empty.
    • --shell drops into sh in the same image as the user the image runs as, for poking around.
  • rustybuns containers smoke [BINDING…] runs each image headless, checks it boots and answers, prints ✅/❌ per binding, and exits non-zero on failure. The CI job in the sibling issue can call this, so local and CI behave the same.

  • Docker preflight, everywhere it matters. deploy, containers * and build box (with cross crates) check the daemon first and fail with a single clear message:

    Docker isn't running. This app has 3 container bindings, and deploy builds their images locally. Start Docker Desktop and run this again.

    Today build box has a version of this (packages/cli/src/build.ts:580); share one helper so they all say the same thing.

  • Staleness tracking. A hash of each binding's context folder plus its Dockerfile, stored under .rustybuns/containers/, drives "stale" in the list and lets run skip a rebuild when nothing changed.

Docs

  • Add a "Containers" section to REFERENCE.md (binding fields, the commands, what local runs don't replicate; see the parity issue).
  • Add a row in GETTING_STARTED.md's table for container bindings.

Acceptance

  • In apps/codesplitter, rustybuns containers run CI_RUNNER boots the check image and prints a working URL.
  • deploy with Docker stopped fails in under a second with the preflight message, before any Alchemy work.
  • Tests cover binding discovery, staleness hashing and the preflight message (Docker itself mocked).

Activity

  1. QuinnsCode commented on Oct 12, 2026

    @QuinnsCode
    OwnerAuthor

    Folded into #818, which now holds this spec in full along with the other container and Docker work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions