Container information

Vibe container projects are standard Docker containers — Python or Node, a real image, your application, and the Diode client for publish and identity. There is no proprietary runtime to learn. If your team already ships with a Dockerfile, requirements.txt, or package-lock.json, you are already speaking Vibe’s language.

Why it matters

Consumer vibe platforms hide the runtime. Vibe shows you a container: Docker name, bind mount, pip and npm, /healthz. Coding agents deploy onto infrastructure you can inspect, host yourself, and take through an audit — not a shared consumer sandbox.

That is how you put the same app on your own servers, watch it with Website monitoring, and land it in an enclave. Standards-based containers are the capability; Diode is the network and identity layer that makes them publishable without opening a public SSH hole.

What you get

  • One container per project (the Docker name is the project UUID)
  • Python and Node from catalog images, or a custom image on Standard and Enterprise
  • Your source on a bind mount, durable data next to it, Diode publish from inside the same container
  • Fast restarts: pip and npm run only when the dependency tree actually changed
  • The same container model on hub hosts or servers you bring

Anatomy of a container

A running project is an ordinary Docker container plus a project directory on the host:

Piece What it is What a code deploy does
Image Docker image — OS, Python or Node, startup Unchanged. Rebuild only when the image itself must change.
Project mount Host files mapped to /diodedeploy Application source, start script, Diode wallet, logs, and durable data. Survives restart and container recreate.

Inside /diodedeploy:

Path Role
site/ Your application (the deploy tarball)
data/ Durable files — databases, uploads, anything a full replace of site/ must not wipe
runtime.log App output and dependency-install decisions
project_start.sh Platform-generated: install if needed, then your start command
diode_client.db Diode identity. Stays on the mount so the client id survives a recreate

Keep durable state in /diodedeploy/data/ (for example /diodedeploy/data/app.db). Files only under site/ disappear on a full deploy. Files only in the container writable layer (/tmp, /app/data, system site-packages) disappear if the container is recreated from the base image.

How a deploy lands

  1. Your agent (or the Automation API) uploads a tarball.
  2. Vibe writes files onto the project mount. A partial deploy updates named files; a full deploy replaces site/ (Node’s node_modules is parked and restored so you do not re-download the world).
  3. The container is stopped and started. Diode publish and the app both run inside that one container, so public traffic pauses for the restart.
  4. Startup launches Diode, then your start command.

Deploy is marked successful when the container is running again. Confirm the site the same way you would on any Docker host — /healthz or a browser. There is no rolling cutover and no second container: one Diode client id cannot be published from two processes at once. For most teams that restart is seconds; treat it as a real process restart, not a magic zero-downtime swap.

Dependencies: pip and npm, only when needed

Python and Node containers install from the files you already know:

  • Python — requirements.txt via pip
  • Node — lockfile (package-lock.json or npm-shrinkwrap.json) with npm ci --omit=dev, or package.json alone with npm install --omit=dev

On each start, Vibe skips the install when it can prove the tree would not change. Python asks pip whether requirements.txt is already satisfied. Node fingerprints the manifest, lockfile, runtime, and OS, and checks that production packages are actually on disk.

Routine deploys come up quickly because you are not paying a full pip install / npm ci tax every time you change a template. Install still runs when it should: first start, missing node_modules, a lockfile or requirements change, a Node/Python version change, or any checker error. The decision is written to runtime.log (skipping pip install, npm ci --omit=dev, and similar).

Operator notes

  • Ship build output (dist/, and so on) in the tarball, or build from your start command. Skipping npm ci also skips postinstall / prepare.
  • Prefer a lockfile. Without one, ^ ranges stay at whatever the last npm install resolved.
  • Python packages land in the image’s site-packages. They survive restart and a full site/ replace; they do not survive recreating the container from the base image (pip then reinstalls).
  • Editable or path Python deps (-e .) can look “satisfied” after the first install even if that local source changed.

Custom images

Available on Standard and Enterprise.

Upload a Dockerfile and startup.sh for the Python or Node container type. FROM must be a catalog base image for that type — you extend a real container; you do not invent a third language.

A custom image is how you add OS packages, pin a Python or Node version, or change process startup. Keep the built-in startup pattern so Vibe still:

  • Starts Diode with the wallet on the mount (/diodedeploy/diode_client.db)
  • Runs project_start.sh (dependency check, your start command, runtime.log)

If custom startup.sh stops calling project_start.sh, you own start, logs, and health yourself. Images that install with pnpm, Yarn, or poetry still get the platform’s npm or pip check unless startup no longer runs that script.

Rebuild the image (and recreate existing containers) when the Dockerfile or baked-in startup.sh changes. Application files, the generated start script, and publish settings still arrive on a normal code deploy — no image rebuild.