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
- Your agent (or the Automation API) uploads a tarball.
- Vibe writes files onto the project mount. A partial deploy updates named files; a full deploy replaces
site/(Node’snode_modulesis parked and restored so you do not re-download the world). - The container is stopped and started. Diode publish and the app both run inside that one container, so public traffic pauses for the restart.
- 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.txtviapip - Node — lockfile (
package-lock.jsonornpm-shrinkwrap.json) withnpm ci --omit=dev, orpackage.jsonalone withnpm 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. Skippingnpm cialso skipspostinstall/prepare. - Prefer a lockfile. Without one,
^ranges stay at whatever the lastnpm installresolved. - 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.