instamesh-docker/CLAUDE.md
Travis Herbranson 5cff79d211 docs: add CLAUDE.md + initial README
Repo had a 0-byte README and no CLAUDE.md.

README: requirements (NVIDIA GPU + CUDA 12.1 + ≥12GB VRAM), build/run
quickstart, project structure, callout that the root-level uv
scaffolding is not part of the build path.

CLAUDE.md captures the three upstream patches that are deliberately
applied (CUDA 12.1 pin, dedup'd conda create, onnxruntime fix for
upstream issue #175), the intentional `|| true` on bulk pip install
(nvdiffrast needs --no-build-isolation), build performance gotchas,
and the absence of an outputs bind mount.

Untracked .python-version / InstantMesh/ / uv.lock left out of this commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 07:22:25 -04:00

122 lines
4.7 KiB
Markdown

# Claude notes — instamesh-docker
Agent context for this repo. Read before non-trivial changes.
## What this is
Docker wrapper around upstream [TencentARC/InstantMesh](https://github.com/TencentARC/InstantMesh)
for single-image → 3D mesh generation. **Not** a fork of InstantMesh
itself — this repo owns the docker build + compose plus a small set of
patches that fix known upstream build breakage.
## Repo shape
```
instamesh-docker/
InstantMesh/ # UNTRACKED — upstream clone. Operators run
# `git clone https://github.com/TencentARC/InstantMesh.git`
# once before `docker compose build`. Not a submodule.
docker/
Dockerfile # patched (see "Patches applied" below)
compose.yml # GPU compose, named volume for model cache, port 43839
requirements.txt # InstantMesh's pip deps, kept here so the Dockerfile
# can ADD them without changing the upstream tree
main.py, pyproject.toml, uv.lock, .python-version
# leftover uv scaffolding from initial repo init;
# NOT part of the build path. Don't extend these.
README.md
CLAUDE.md
```
`InstantMesh/` is intentionally untracked. Don't add it as a submodule
or vendor it into source control — keep the upstream boundary clean.
## Patches applied (vs. upstream)
The Dockerfile is forked from InstantMesh's docker config with three
deliberate changes — call out any churn around these:
1. **CUDA aligned to 12.1.** Base image is
`nvidia/cuda:12.1.0-runtime-ubuntu22.04`; conda installs `cuda` from
`nvidia/label/cuda-12.1.0`; pip installs `torch==2.1.0 + cu121` and
`xformers==0.0.22.post7`. All four must stay in sync. Don't bump CUDA
without re-pinning all of them.
2. **Duplicate `conda create` removed.** Upstream's Dockerfile created
the conda env twice; the second one nuked the first's pinned
packages. Don't reintroduce.
3. **`onnxruntime` added.** Missing from upstream's `requirements.txt`
(InstantMesh issue #175). Installed as a separate `pip install` step
after the bulk requirements install so it's not silently dropped by
the `|| true` below.
## Intentional `|| true` on the bulk pip install
```dockerfile
RUN pip install --no-cache-dir -r requirements.txt || true
```
This is **on purpose**. The requirements include `nvdiffrast` via a git
URL that needs `--no-build-isolation`, which pip's bulk install won't
do. We let that line fail, then install `nvdiffrast` correctly:
```dockerfile
RUN pip install git+https://github.com/NVlabs/nvdiffrast.git --no-build-isolation
```
Don't "fix" the bulk install by removing `|| true` — the build will
hard-fail on nvdiffrast.
## Hardware contract
- **NVIDIA GPU required**, exposed through Docker via the nvidia
runtime. InstantMesh wants **≥ 12 GB VRAM** comfortably; smaller cards
may OOM during inference.
- **CUDA 12.1** — see patch #1 above.
## Build is slow + brittle
Expect a 15+ minute first build. Conda + nvdiffrast compilation +
PyTorch wheels add up. Triggers that re-run the slow layers:
- Editing `docker/requirements.txt` invalidates the conda install layer.
- Editing the Dockerfile's `apt-get install` line redoes the whole
thing from a fresh base image.
Lean on Docker's layer cache; don't restructure for "cleanliness"
without measuring the rebuild cost.
## Compose
```yaml
ports:
- "43839:43839" # Gradio app, host-published
volumes:
- instantmesh-models:/workspace/models # weights cache (named volume)
```
No host-network mode, no bind mounts for code (the upstream tree is
COPYed at build time). If you need to iterate on InstantMesh source,
edit `InstantMesh/` locally and rebuild — there's no dev-mode wiring.
## Where outputs go
InstantMesh's Gradio app writes generated meshes inside the container
(under `/workspace/instantmesh/`). There's **no bind mount** for
outputs in `compose.yml` — operator downloads results from the Gradio
UI. If you find yourself wanting to bind-mount an outputs dir, mirror
`hunyuan3d-sunnie/docker/outputs/`.
## Don't-touch zones
- The CUDA 12.1 pins (base image / conda label / PyTorch wheel index /
xformers wheel) — load-bearing as a set.
- The `|| true` on bulk requirements install — required for nvdiffrast.
- The `onnxruntime` separate install line — load-bearing per upstream #175.
- The untracked `InstantMesh/` directory — let operators reclone.
## Bigger picture
Personal/one-off project, GPU-only. Runs on the dev tower; not part of
the homelab production stack. Sibling project `hunyuan3d-sunnie/` uses
a different model (Hunyuan3D-2) for the same general shape of problem
on a 10 GB card — pick that one if VRAM is tight.