Add comfyui-model-init sidecar for ComfyUI model preseeding

Mirrors the Ollama model-init pattern: a one-shot Alpine container that
mounts the comfyui-models volume and runs comfyui-init-models.sh, which
curls direct download URLs (HuggingFace by default) into the right
subdirectories. Idempotent — already-present files are skipped.

HF_TOKEN is plumbed through for gated repos (Flux-dev, SD3, etc.) and is
opt-in via .env. The default list ships SD 1.5 only, matching the
placeholder filename in workflows/*.json. Examples for SDXL, Flux, and
upscalers are commented in the script.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-19 11:57:24 -05:00
co-authored by Claude Opus 4.7
parent 21e976e275
commit 0ad99b6199
4 changed files with 115 additions and 19 deletions
+5
View File
@@ -22,3 +22,8 @@ ANUBIS_OWUI_KEY=replace-with-32-byte-hex
# ComfyUI image tag to deploy. `latest` tracks whatever the release workflow
# last pushed; pin to a v* tag (e.g. 0.1.0) for reproducible deploys.
COMFYUI_IMAGE_TAG=latest
# HuggingFace access token. Only needed if comfyui-init-models.sh references
# gated repos (Flux-dev, SD3, etc.). Generate a read token at
# https://huggingface.co/settings/tokens. Leave empty for public-only.
HF_TOKEN=
+28 -19
View File
@@ -10,12 +10,13 @@ production `srvno.de` deployment.
## Files
| File | Purpose |
| ------------------- | -------------------------------------------------------- |
| `docker-compose.yml`| Service definitions, volumes, GPU reservations |
| `Caddyfile` | TLS + reverse proxy config (one site block per hostname) |
| `init-models.sh` | Models to preseed into Ollama on first boot |
| `.env.example` | Secrets and image-tag pins. Copy to `.env` |
| File | Purpose |
| -------------------------- | -------------------------------------------------------- |
| `docker-compose.yml` | Service definitions, volumes, GPU reservations |
| `Caddyfile` | TLS + reverse proxy config (one site block per hostname) |
| `init-models.sh` | LLMs to preseed into Ollama on first boot |
| `comfyui-init-models.sh` | Checkpoints/VAEs/LoRAs to preseed into ComfyUI on first boot |
| `.env.example` | Secrets and image-tag pins. Copy to `.env` |
## 1. Host prerequisites
@@ -61,6 +62,10 @@ Then edit:
- **`init-models.sh`** — keep the LLMs you want preseeded, drop the rest.
Check sizes at <https://ollama.com/library> first; the host needs disk
for everything listed.
- **`comfyui-init-models.sh`** — checkpoints/VAEs/LoRAs to preseed into
ComfyUI. Default ships SD 1.5 only (matches the workflow placeholder).
Uncomment the SDXL/Flux/upscaler examples or add your own. Set `HF_TOKEN`
in `.env` if any are gated repos.
## 3. Bring it up
@@ -80,22 +85,26 @@ docker compose exec comfyui curl -sf http://127.0.0.1:8188/system_stats | head -
docker compose exec open-webui curl -sf http://127.0.0.1:8080/health
```
## 4. Drop in at least one ComfyUI checkpoint
## 4. ComfyUI checkpoints
ComfyUI ships no models. The shipped workflow templates reference
`v1-5-pruned-emaonly.safetensors` as a placeholder; drop any
SD/SDXL/Flux checkpoint into the `comfyui-models` volume under
`checkpoints/`:
ComfyUI ships no models. Three ways to get one in:
```sh
docker run --rm -v ai-stack_comfyui-models:/models -w /models/checkpoints \
curlimages/curl:latest -L -O \
https://huggingface.co/runwayml/stable-diffusion-v1-5/resolve/main/v1-5-pruned-emaonly.safetensors
```
1. **Preseed via the sidecar (default).** `comfyui-model-init` runs once
on `compose up`, downloads everything `comfyui-init-models.sh` lists,
and exits. The default list pulls SD 1.5 to match the workflow
placeholder. Edit the script to add SDXL, Flux, LoRAs, upscalers, etc.
Re-run with `docker compose up -d comfyui-model-init` after edits;
already-present files are skipped.
2. **ComfyUI-Manager UI.** Open `https://comfyui.example.com` (after
basic-auth login), click **Manager**, then **Model Manager**, install
from the catalogue.
3. **Direct copy into the volume.** Useful if you already have the file
locally:
Or open the ComfyUI native UI at `https://comfyui.example.com` (after
basic-auth login), use the **Manager** button (added by ComfyUI-Manager),
and install one through **Model Manager**.
```sh
docker run --rm -v ai-stack_comfyui-models:/models -v $PWD:/src alpine \
cp /src/your-model.safetensors /models/checkpoints/
```
## 5. First-user signup in Open WebUI
@@ -0,0 +1,65 @@
#!/bin/sh
# Preseed ComfyUI's models volume with checkpoints, VAEs, LoRAs, etc.
# Runs once via the comfyui-model-init service (see docker-compose.yml).
# Safe to re-run — already-present files are skipped.
#
# ComfyUI doesn't have a "pull" command of its own, so this is plain curl
# against direct download URLs. For HuggingFace, the direct URL is:
# https://huggingface.co/<repo>/resolve/main/<file>
# For gated HF repos (Flux-dev, SD3, etc.), set HF_TOKEN in .env — the
# script attaches it as a bearer token automatically.
set -e
apk add --no-cache curl >/dev/null
mkdir -p /models/checkpoints /models/vae /models/loras /models/controlnet \
/models/clip /models/clip_vision /models/upscale_models /models/embeddings
fetch() {
dest="$1"; name="$2"; url="$3"
target="/models/$dest/$name"
if [ -f "$target" ]; then
echo "$dest/$name already present"
return
fi
echo "→ Downloading $dest/$name"
mkdir -p "/models/$dest"
if [ -n "$HF_TOKEN" ] && echo "$url" | grep -q huggingface.co; then
curl -fL -C - --retry 3 -H "Authorization: Bearer $HF_TOKEN" \
-o "$target.partial" "$url"
else
curl -fL -C - --retry 3 -o "$target.partial" "$url"
fi
mv "$target.partial" "$target"
}
# ─── Edit the list below to choose what gets preseeded ──────────────────────
# Format: fetch <subdir under /models> <filename to save as> <direct URL>
# SD 1.5 base — matches the placeholder filename in workflows/*.json
fetch checkpoints v1-5-pruned-emaonly.safetensors \
https://huggingface.co/stable-diffusion-v1-5/stable-diffusion-v1-5/resolve/main/v1-5-pruned-emaonly.safetensors
# Examples — uncomment what you want.
# SDXL Base 1.0 (~6.9 GB)
# fetch checkpoints sd_xl_base_1.0.safetensors \
# https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/resolve/main/sd_xl_base_1.0.safetensors
# SDXL VAE (fixes washed-out colours on some SDXL checkpoints)
# fetch vae sdxl_vae.safetensors \
# https://huggingface.co/stabilityai/sdxl-vae/resolve/main/sdxl_vae.safetensors
# Flux.1-dev (~23 GB, gated — needs HF_TOKEN with access to black-forest-labs)
# fetch checkpoints flux1-dev.safetensors \
# https://huggingface.co/black-forest-labs/FLUX.1-dev/resolve/main/flux1-dev.safetensors
# 4x-UltraSharp upscaler
# fetch upscale_models 4x-UltraSharp.pth \
# https://huggingface.co/lokCX/4x-Ultrasharp/resolve/main/4x-UltraSharp.pth
echo "Done."
+17
View File
@@ -129,6 +129,23 @@ services:
retries: 5
start_period: 120s
# One-shot model puller for ComfyUI. Mounts the same models volume,
# downloads whatever comfyui-init-models.sh lists, exits. ComfyUI doesn't
# need to be running for this — files just land on the volume; ComfyUI
# picks them up next time it scans (or on a restart).
comfyui-model-init:
image: alpine:latest
container_name: comfyui-model-init
volumes:
- comfyui-models:/models
- ./comfyui-init-models.sh:/init.sh:ro
environment:
# Optional — set in .env to download from gated HuggingFace repos
# (Flux-dev, SD3, etc.). Leave empty for public-only.
HF_TOKEN: "${HF_TOKEN:-}"
entrypoint: ["/bin/sh", "/init.sh"]
restart: "no"
# ---------------------------------------------------------------------------
# Open WebUI — multi-user chat.
# ---------------------------------------------------------------------------