diff --git a/README.md b/README.md index 58a3f13..03298d0 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,7 @@ Read these if you want to understand the machinery instead of cargo-culting comm - [How It Works](docs/how-it-works.md) - [Philosophy](docs/philosophy.md) - [Advanced Usage](docs/advanced-usage.md) +- [Custom Images](docs/custom-images.md) - [Docs Home](docs/index.md) Project policy and OSS housekeeping: diff --git a/docs/advanced-usage.md b/docs/advanced-usage.md index 8029edb..c5309cc 100644 --- a/docs/advanced-usage.md +++ b/docs/advanced-usage.md @@ -104,6 +104,9 @@ deva.sh codex -p rust If the image tag is missing locally, deva pulls it. If that fails and a matching Dockerfile exists, it points you at the build command. +If you want your own image entirely, read [Custom Images](custom-images.md). +That covers local builds, private tags, per-project overrides, and personal-only setups. + ## Multi-Agent Workflow One default container shape can serve all supported agents in the same project: diff --git a/docs/custom-images.md b/docs/custom-images.md new file mode 100644 index 0000000..7f898cc --- /dev/null +++ b/docs/custom-images.md @@ -0,0 +1,199 @@ +# Custom Images + +This is the guide for people who want their own deva image instead of +the stock one. + +Common reasons: + +- you want extra tools baked in +- you want a personal image in your own registry +- you want local experiments without waiting for upstream releases + +That is fine. deva does not care where the image came from. It cares +that the image exists and that the tag you asked for is real. + +## The Two Knobs + +Deva picks the runtime image from two host-side variables: + +- `DEVA_DOCKER_IMAGE` +- `DEVA_DOCKER_TAG` + +If you do nothing, it uses: + +```text +DEVA_DOCKER_IMAGE=ghcr.io/thevibeworks/deva +DEVA_DOCKER_TAG=latest +``` + +For the rust profile, the default tag becomes `rust`. + +Important detail: + +- if you set only `DEVA_DOCKER_IMAGE`, `PROFILE=rust` can still change the + tag to `rust` +- if you want zero surprises, set both `DEVA_DOCKER_IMAGE` and + `DEVA_DOCKER_TAG` + +## Build A Local Image + +Base image: + +```bash +docker build -t deva-local:latest . +``` + +Rust profile image: + +```bash +docker build -f Dockerfile.rust -t deva-local:rust . +``` + +Then run deva against it: + +```bash +DEVA_DOCKER_IMAGE=deva-local \ +DEVA_DOCKER_TAG=latest \ +deva.sh codex +``` + +Or for the rust image: + +```bash +DEVA_DOCKER_IMAGE=deva-local \ +DEVA_DOCKER_TAG=rust \ +deva.sh claude +``` + +Deva checks local images first. If the image is already there, it does +not need to pull anything. + +## Build A Personal Registry Image + +If you want your own registry namespace, tag it that way from the start: + +```bash +docker build -t ghcr.io/yourname/deva:daily . +docker push ghcr.io/yourname/deva:daily +``` + +Then point deva at it: + +```bash +export DEVA_DOCKER_IMAGE=ghcr.io/yourname/deva +export DEVA_DOCKER_TAG=daily +deva.sh codex +``` + +That is the whole trick. This is not Kubernetes. It is just an image +name plus a tag. + +## Keep It Personal + +If this is only for you, put the override in `.deva.local`: + +```text +DEVA_DOCKER_IMAGE=ghcr.io/yourname/deva +DEVA_DOCKER_TAG=daily +``` + +That file is the right place for personal registry tags, private images, +and "I am trying weird stuff" experiments. + +If the whole team should use the same custom image, put it in `.deva` +instead: + +```text +DEVA_DOCKER_IMAGE=ghcr.io/acme/deva +DEVA_DOCKER_TAG=team-rust-20260312 +``` + +Yes, deva's config loader will export those variables for the wrapper. +That is intentional. + +## Extend The Official Image Instead Of Starting From Nothing + +If you just need a few extra tools, do not rebuild the universe. + +Use the published image as your base: + +```dockerfile +FROM ghcr.io/thevibeworks/deva:latest + +RUN apt-get update && apt-get install -y --no-install-recommends \ + graphviz \ + postgresql-client \ + && rm -rf /var/lib/apt/lists/* +``` + +Build and run it: + +```bash +docker build -t deva-local:extras . +DEVA_DOCKER_IMAGE=deva-local DEVA_DOCKER_TAG=extras deva.sh gemini +``` + +That is usually the sane move. + +## What Still Comes From The Wrapper + +Changing the image does not change the wrapper model. + +Deva still controls: + +- workspace mounts +- auth mounts +- config-home wiring +- container naming +- persistent vs ephemeral behavior +- debug and dry-run output + +So a custom image is not a custom launcher. It is just a different root +filesystem under the same wrapper behavior. + +## Personal Use Without Installing Anything Globally + +You do not need to replace your whole system install. + +Per-shell: + +```bash +DEVA_DOCKER_IMAGE=deva-local \ +DEVA_DOCKER_TAG=latest \ +deva.sh codex +``` + +Per-project: + +```text +# .deva.local +DEVA_DOCKER_IMAGE=deva-local +DEVA_DOCKER_TAG=latest +``` + +That way your personal image only affects the project where you meant to +use it. Amazing concept. + +## Gotchas + +- If you set only the image and forget the tag, profile defaults may + still pick `latest` or `rust`. +- If the image is private, pulls need auth. Public docs pointing at a + private image are broken by definition. +- If you build a custom image that removes expected tools or paths, + deva will not magically repair your bad Dockerfile. +- If your image tag does not exist locally and cannot be pulled, deva + fails fast. Good. Silent nonsense would be worse. + +## Sanity Check + +Use this before blaming the wrapper: + +```bash +DEVA_DOCKER_IMAGE=deva-local \ +DEVA_DOCKER_TAG=latest \ +deva.sh codex --debug --dry-run +``` + +If the printed image is wrong, your override is wrong. +If the printed image is right, the problem is somewhere else. diff --git a/docs/index.md b/docs/index.md index 5c3268e..f7c2d9a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -19,6 +19,7 @@ If you want the internals instead of vague hand-waving: - [How It Works](how-it-works.md) - [Philosophy](philosophy.md) - [Advanced Usage](advanced-usage.md) +- [Custom Images](custom-images.md) ## What This Is diff --git a/mkdocs.yml b/mkdocs.yml index 9bb1d2f..3f28e9b 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,5 +1,5 @@ site_name: deva.sh docs -site_description: Docker-based multi-agent launcher for Claude, Codex, and Gemini +site_description: Docker-based multi-agent launcher for Codex, Claude, and Gemini site_url: https://docs.deva.sh repo_url: https://github.com/thevibeworks/deva repo_name: thevibeworks/deva @@ -33,6 +33,7 @@ nav: - Authentication: authentication.md - Philosophy: philosophy.md - Advanced Usage: advanced-usage.md + - Custom Images: custom-images.md - Troubleshooting: troubleshooting.md - Research: - UID/GID Handling: UID-GID-HANDLING-RESEARCH.md