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

4.7 KiB

Claude notes — instamesh-docker

Agent context for this repo. Read before non-trivial changes.

What this is

Docker wrapper around upstream 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

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:

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

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.