docker v3: bake everything into /workspace (ComfyUI, workflows, download_missing_models.sh) + auto-start ComfyUI
Browse files- docker/Dockerfile +40 -24
- docker/README.md +40 -30
- docker/comfy +7 -15
- docker/seed-workspace.sh +19 -0
- docker/start-comfy.sh +9 -7
docker/Dockerfile
CHANGED
|
@@ -1,30 +1,39 @@
|
|
| 1 |
# ComfyUI Qwen-Image-Edit base image (H100 / RunPod)
|
| 2 |
#
|
| 3 |
# NOTE: published plx1029/comfyui-qwen tags were NOT built from this file — they
|
| 4 |
-
# were assembled daemonlessly (v1: crane append on the pod; v2: skopeo + umoci
|
| 5 |
-
#
|
| 6 |
-
# with Docker produces the
|
|
|
|
| 7 |
#
|
| 8 |
-
# Build from the REPO ROOT (context needs download_missing_models.sh):
|
| 9 |
-
# docker build -t plx1029/comfyui-qwen:
|
| 10 |
-
# docker push plx1029/comfyui-qwen:
|
| 11 |
#
|
| 12 |
# No secrets are baked into this image (it is public). The model-download
|
| 13 |
# script prompts for your Hugging Face token at runtime (or reads $HF_TOKEN).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
|
| 15 |
FROM runpod/pytorch:1.0.2-cu1281-torch280-ubuntu2404
|
| 16 |
|
| 17 |
ARG COMFYUI_COMMIT=35c1470935044be5610a81d46e57922a8a598c6c
|
| 18 |
ARG RGTHREE_COMMIT=27b4f4cdcf3b127c29d5d8135ac1536ecbd4c383
|
| 19 |
|
| 20 |
-
# ComfyUI pinned to the exact commit; torch stack already in
|
| 21 |
-
|
| 22 |
-
|
|
|
|
| 23 |
pip install -r requirements.txt
|
| 24 |
|
| 25 |
# Custom nodes: rgthree (Power Lora Loader) + ComfyUI-Manager
|
| 26 |
-
RUN git clone https://github.com/rgthree/rgthree-comfy.git /ComfyUI/custom_nodes/rgthree-comfy && \
|
| 27 |
-
cd /ComfyUI/custom_nodes/rgthree-comfy && git checkout ${RGTHREE_COMMIT} && \
|
| 28 |
pip install comfyui-manager==4.2.2
|
| 29 |
|
| 30 |
# Hugging Face hub tooling for fast model downloads (hf_transfer is best-effort:
|
|
@@ -42,21 +51,28 @@ RUN curl -fsSL https://claude.ai/install.sh | bash && \
|
|
| 42 |
ENV PATH="/root/.local/bin:${PATH}"
|
| 43 |
|
| 44 |
# Manager config baked in: security_level=weak, network_mode=personal_cloud
|
| 45 |
-
COPY docker/config.ini /ComfyUI/user/__manager/config.ini
|
| 46 |
-
COPY docker/comfy.settings.json /ComfyUI/user/default/comfy.settings.json
|
| 47 |
-
COPY
|
| 48 |
-
|
| 49 |
-
#
|
| 50 |
-
#
|
| 51 |
-
#
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 57 |
COPY docker/comfy /usr/local/bin/comfy
|
| 58 |
COPY docker/start-comfy.sh /start-comfy.sh
|
| 59 |
-
RUN chmod +x /usr/local/bin/comfy /
|
| 60 |
|
| 61 |
EXPOSE 7865
|
| 62 |
CMD ["/start-comfy.sh"]
|
|
|
|
| 1 |
# ComfyUI Qwen-Image-Edit base image (H100 / RunPod)
|
| 2 |
#
|
| 3 |
# NOTE: published plx1029/comfyui-qwen tags were NOT built from this file — they
|
| 4 |
+
# were assembled daemonlessly (v1: crane append on the pod; v2: skopeo + umoci;
|
| 5 |
+
# v3: crane append of a /workspace layer on top of v2). This Dockerfile is the
|
| 6 |
+
# reproducible equivalent: building it on any machine with Docker produces the
|
| 7 |
+
# same setup.
|
| 8 |
#
|
| 9 |
+
# Build from the REPO ROOT (context needs download_missing_models.sh + workflows/):
|
| 10 |
+
# docker build -t plx1029/comfyui-qwen:v3 -f docker/Dockerfile .
|
| 11 |
+
# docker push plx1029/comfyui-qwen:v3
|
| 12 |
#
|
| 13 |
# No secrets are baked into this image (it is public). The model-download
|
| 14 |
# script prompts for your Hugging Face token at runtime (or reads $HF_TOKEN).
|
| 15 |
+
#
|
| 16 |
+
# v3: EVERYTHING lives in /workspace — /workspace/ComfyUI, /workspace/workflows,
|
| 17 |
+
# /workspace/download_missing_models.sh — and ComfyUI auto-starts on boot.
|
| 18 |
+
# A compressed seed of the /workspace payload is kept at /opt/workspace-seed.tar.gz
|
| 19 |
+
# so that when a network volume is mounted over /workspace (shadowing the baked
|
| 20 |
+
# files), seed-workspace.sh restores the missing pieces without touching
|
| 21 |
+
# anything already on the volume.
|
| 22 |
|
| 23 |
FROM runpod/pytorch:1.0.2-cu1281-torch280-ubuntu2404
|
| 24 |
|
| 25 |
ARG COMFYUI_COMMIT=35c1470935044be5610a81d46e57922a8a598c6c
|
| 26 |
ARG RGTHREE_COMMIT=27b4f4cdcf3b127c29d5d8135ac1536ecbd4c383
|
| 27 |
|
| 28 |
+
# ComfyUI pinned to the exact commit, IN /workspace; torch stack already in
|
| 29 |
+
# base -> only light deps install
|
| 30 |
+
RUN git clone https://github.com/comfyanonymous/ComfyUI.git /workspace/ComfyUI && \
|
| 31 |
+
cd /workspace/ComfyUI && git checkout ${COMFYUI_COMMIT} && \
|
| 32 |
pip install -r requirements.txt
|
| 33 |
|
| 34 |
# Custom nodes: rgthree (Power Lora Loader) + ComfyUI-Manager
|
| 35 |
+
RUN git clone https://github.com/rgthree/rgthree-comfy.git /workspace/ComfyUI/custom_nodes/rgthree-comfy && \
|
| 36 |
+
cd /workspace/ComfyUI/custom_nodes/rgthree-comfy && git checkout ${RGTHREE_COMMIT} && \
|
| 37 |
pip install comfyui-manager==4.2.2
|
| 38 |
|
| 39 |
# Hugging Face hub tooling for fast model downloads (hf_transfer is best-effort:
|
|
|
|
| 51 |
ENV PATH="/root/.local/bin:${PATH}"
|
| 52 |
|
| 53 |
# Manager config baked in: security_level=weak, network_mode=personal_cloud
|
| 54 |
+
COPY docker/config.ini /workspace/ComfyUI/user/__manager/config.ini
|
| 55 |
+
COPY docker/comfy.settings.json /workspace/ComfyUI/user/default/comfy.settings.json
|
| 56 |
+
COPY workflows/ /workspace/ComfyUI/user/default/workflows/
|
| 57 |
+
|
| 58 |
+
# Workflows + model downloader live in /workspace too. The downloader picks
|
| 59 |
+
# workflows, finds their models in the HF repo (aleph65/ComfyUI), and downloads
|
| 60 |
+
# the missing ones into /workspace/ComfyUI/models/. Prompts for the HF token
|
| 61 |
+
# (or reads $HF_TOKEN). Kept on PATH via a symlink.
|
| 62 |
+
COPY workflows/ /workspace/workflows/
|
| 63 |
+
COPY download_missing_models.sh /workspace/download_missing_models.sh
|
| 64 |
+
RUN chmod +x /workspace/download_missing_models.sh && \
|
| 65 |
+
ln -sf /workspace/download_missing_models.sh /usr/local/bin/download_missing_models.sh
|
| 66 |
+
|
| 67 |
+
# Seed tarball: restores /workspace when a network volume shadows it
|
| 68 |
+
RUN tar -czf /opt/workspace-seed.tar.gz -C /workspace ComfyUI workflows download_missing_models.sh
|
| 69 |
+
|
| 70 |
+
# Startup: seed /workspace if needed, then AUTO-START ComfyUI (v3 default).
|
| 71 |
+
# Set COMFY_AUTOSTART=false in the pod env to disable; `comfy` runs it manually.
|
| 72 |
+
COPY docker/seed-workspace.sh /usr/local/bin/seed-workspace.sh
|
| 73 |
COPY docker/comfy /usr/local/bin/comfy
|
| 74 |
COPY docker/start-comfy.sh /start-comfy.sh
|
| 75 |
+
RUN chmod +x /usr/local/bin/comfy /usr/local/bin/seed-workspace.sh /start-comfy.sh
|
| 76 |
|
| 77 |
EXPOSE 7865
|
| 78 |
CMD ["/start-comfy.sh"]
|
docker/README.md
CHANGED
|
@@ -3,52 +3,62 @@
|
|
| 3 |
Everything from the manual setup is baked in — **no reinstalling on new pods**:
|
| 4 |
|
| 5 |
- Base: `runpod/pytorch:1.0.2-cu1281-torch280-ubuntu2404` (torch 2.8.0+cu128, Python 3.12)
|
| 6 |
-
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
- rgthree-comfy @ `27b4f4c` in `custom_nodes/`
|
| 8 |
-
- comfyui-manager 4.2.2 + all pip deps
|
| 9 |
- Manager config baked: `security_level = weak`, `network_mode = personal_cloud`
|
| 10 |
-
-
|
| 11 |
-
-
|
| 12 |
-
- **v2:** [Claude Code](https://claude.com/claude-code) CLI preinstalled (`claude`), on PATH,
|
| 13 |
with `bypassPermissions` as the default permission mode
|
| 14 |
-
-
|
| 15 |
-
|
| 16 |
-
bootstraps `/workspace/workflows` from the repo if absent)
|
| 17 |
-
- **v2:** ComfyUI **no longer auto-starts** — run `comfy` yourself, or set
|
| 18 |
-
`COMFY_AUTOSTART=true` in the pod env for the old behaviour (port **7865**,
|
| 19 |
-
log: `/workspace/comfyui.log`)
|
| 20 |
|
| 21 |
Models are NOT in the image (keep them on the network volume, as before).
|
| 22 |
-
No secrets are baked in either (the image is public)
|
| 23 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
|
| 25 |
## Using it on RunPod
|
| 26 |
|
| 27 |
-
1. Create a template with container image `plx1029/comfyui-qwen:
|
| 28 |
2. Expose HTTP port **7865** (plus 8888/22 as usual).
|
| 29 |
-
3.
|
| 30 |
-
4. In a terminal: `download_missing_models.sh`
|
| 31 |
-
|
| 32 |
-
When ComfyUI starts it:
|
| 33 |
-
- uses `/workspace/ComfyUI` if it exists (your current volume — models already there);
|
| 34 |
-
- otherwise seeds a fresh `/workspace/ComfyUI` from the baked-in copy;
|
| 35 |
-
- SSH / Jupyter / nginx from the stock RunPod start script work normally either way.
|
| 36 |
|
| 37 |
-
`COMFY_PORT` overrides the port. `COMFY_AUTOSTART=
|
|
|
|
| 38 |
|
| 39 |
## How the image was built
|
| 40 |
|
| 41 |
-
No Docker daemon exists on RunPod pods, so images are
|
| 42 |
-
v1 with [`crane`](https://github.com/google/go-containerregistry)
|
| 43 |
-
git clones appended as one OCI layer); v2 with `skopeo` + `umoci`
|
| 44 |
-
|
| 45 |
-
|
|
|
|
|
|
|
| 46 |
|
| 47 |
`Dockerfile` in this directory is the reproducible equivalent for rebuilding on
|
| 48 |
any machine with real Docker (build from the repo root — the context needs
|
| 49 |
-
`download_missing_models.sh`):
|
| 50 |
|
| 51 |
```bash
|
| 52 |
-
docker build -t plx1029/comfyui-qwen:
|
| 53 |
-
docker push plx1029/comfyui-qwen:
|
| 54 |
```
|
|
|
|
| 3 |
Everything from the manual setup is baked in — **no reinstalling on new pods**:
|
| 4 |
|
| 5 |
- Base: `runpod/pytorch:1.0.2-cu1281-torch280-ubuntu2404` (torch 2.8.0+cu128, Python 3.12)
|
| 6 |
+
- **v3: everything lives in `/workspace`:**
|
| 7 |
+
- ComfyUI @ `35c1470935044be5610a81d46e57922a8a598c6c` at **`/workspace/ComfyUI`**
|
| 8 |
+
- workflows at **`/workspace/workflows/`** (`qwen-loras-very-good-nsfw.json`,
|
| 9 |
+
`qwen-edit-nsfw.json`, `head-swap-flux-klein.json`) — also baked into the
|
| 10 |
+
ComfyUI workflow browser
|
| 11 |
+
- **`/workspace/download_missing_models.sh`** — pick workflows, it fetches their
|
| 12 |
+
missing models from `hf.co/aleph65/ComfyUI` into place (prompts for HF token
|
| 13 |
+
or reads `$HF_TOKEN`); still on PATH via symlink
|
| 14 |
+
- **v3: ComfyUI AUTO-STARTS on boot** (port **7865**, log `/workspace/comfyui.log`,
|
| 15 |
+
auto-restart loop). Set `COMFY_AUTOSTART=false` in the pod env to disable.
|
| 16 |
- rgthree-comfy @ `27b4f4c` in `custom_nodes/`
|
| 17 |
+
- comfyui-manager 4.2.2 + all pip deps preinstalled system-wide
|
| 18 |
- Manager config baked: `security_level = weak`, `network_mode = personal_cloud`
|
| 19 |
+
- `huggingface_hub` + `hf_transfer` preinstalled for fast model downloads
|
| 20 |
+
- [Claude Code](https://claude.com/claude-code) CLI preinstalled (`claude`), on PATH,
|
|
|
|
| 21 |
with `bypassPermissions` as the default permission mode
|
| 22 |
+
- The old image-root `/ComfyUI` copy is **removed** (whiteout) — `/workspace` is
|
| 23 |
+
the single source of truth.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
|
| 25 |
Models are NOT in the image (keep them on the network volume, as before).
|
| 26 |
+
No secrets are baked in either (the image is public).
|
| 27 |
+
|
| 28 |
+
## Network volumes
|
| 29 |
+
|
| 30 |
+
If a network volume is mounted at `/workspace` it shadows the baked-in files.
|
| 31 |
+
On boot, `seed-workspace.sh` restores whatever is missing (`ComfyUI/`,
|
| 32 |
+
`workflows/`, `download_missing_models.sh`) from a compressed seed at
|
| 33 |
+
`/opt/workspace-seed.tar.gz` — **never overwriting existing files**, so models
|
| 34 |
+
and outputs already on the volume are untouched.
|
| 35 |
|
| 36 |
## Using it on RunPod
|
| 37 |
|
| 38 |
+
1. Create a template with container image `plx1029/comfyui-qwen:v3`.
|
| 39 |
2. Expose HTTP port **7865** (plus 8888/22 as usual).
|
| 40 |
+
3. (Optional) attach your network volume at `/workspace`.
|
| 41 |
+
4. ComfyUI starts automatically. In a terminal: `download_missing_models.sh`
|
| 42 |
+
to fetch models for your workflows.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 43 |
|
| 44 |
+
`COMFY_PORT` overrides the port. `COMFY_AUTOSTART=false` disables auto-start
|
| 45 |
+
(then run `comfy` manually).
|
| 46 |
|
| 47 |
## How the image was built
|
| 48 |
|
| 49 |
+
No Docker daemon exists on RunPod pods (or the build sandbox), so images are
|
| 50 |
+
assembled daemonlessly: v1 with [`crane`](https://github.com/google/go-containerregistry)
|
| 51 |
+
(pip-delta + git clones appended as one OCI layer); v2 with `skopeo` + `umoci`;
|
| 52 |
+
**v3 with `crane append`** — a single layer holding `/workspace` (ComfyUI +
|
| 53 |
+
workflows + downloader), the seed tarball, the new startup scripts, and a
|
| 54 |
+
whiteout of the old `/ComfyUI`, appended on top of v2 (the ~11 GB base is never
|
| 55 |
+
re-uploaded).
|
| 56 |
|
| 57 |
`Dockerfile` in this directory is the reproducible equivalent for rebuilding on
|
| 58 |
any machine with real Docker (build from the repo root — the context needs
|
| 59 |
+
`download_missing_models.sh` and `workflows/`):
|
| 60 |
|
| 61 |
```bash
|
| 62 |
+
docker build -t plx1029/comfyui-qwen:v3 -f docker/Dockerfile .
|
| 63 |
+
docker push plx1029/comfyui-qwen:v3
|
| 64 |
```
|
docker/comfy
CHANGED
|
@@ -1,22 +1,14 @@
|
|
| 1 |
#!/bin/bash
|
| 2 |
-
# Run ComfyUI in the foreground.
|
| 3 |
-
#
|
| 4 |
-
#
|
| 5 |
-
#
|
| 6 |
set -e
|
| 7 |
|
| 8 |
COMFY_PORT="${COMFY_PORT:-7865}"
|
| 9 |
|
| 10 |
-
|
| 11 |
-
COMFY_HOME=/workspace/ComfyUI
|
| 12 |
-
elif [[ -d /workspace && -w /workspace ]]; then
|
| 13 |
-
echo "Seeding /workspace/ComfyUI from image..."
|
| 14 |
-
cp -a /ComfyUI /workspace/ComfyUI
|
| 15 |
-
COMFY_HOME=/workspace/ComfyUI
|
| 16 |
-
else
|
| 17 |
-
COMFY_HOME=/ComfyUI
|
| 18 |
-
fi
|
| 19 |
|
| 20 |
-
echo "Starting ComfyUI from
|
| 21 |
-
cd
|
| 22 |
exec python3 main.py --listen 0.0.0.0 --port "${COMFY_PORT}" "$@"
|
|
|
|
| 1 |
#!/bin/bash
|
| 2 |
+
# Run ComfyUI in the foreground from /workspace/ComfyUI.
|
| 3 |
+
# v3: everything lives in /workspace, baked into the image. If a network
|
| 4 |
+
# volume is mounted over /workspace (shadowing the baked-in files), the
|
| 5 |
+
# missing pieces are restored from the seed at /opt/workspace-seed.tar.gz.
|
| 6 |
set -e
|
| 7 |
|
| 8 |
COMFY_PORT="${COMFY_PORT:-7865}"
|
| 9 |
|
| 10 |
+
/usr/local/bin/seed-workspace.sh
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
|
| 12 |
+
echo "Starting ComfyUI from /workspace/ComfyUI on port ${COMFY_PORT}"
|
| 13 |
+
cd /workspace/ComfyUI
|
| 14 |
exec python3 main.py --listen 0.0.0.0 --port "${COMFY_PORT}" "$@"
|
docker/seed-workspace.sh
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/bash
|
| 2 |
+
# Ensure /workspace holds the full setup (ComfyUI, workflows,
|
| 3 |
+
# download_missing_models.sh). Everything is baked into the image at
|
| 4 |
+
# /workspace already; this only matters when a network volume is mounted
|
| 5 |
+
# over /workspace and shadows the baked-in files — then the missing pieces
|
| 6 |
+
# are restored from /opt/workspace-seed.tar.gz. Existing files are never
|
| 7 |
+
# overwritten (tar --skip-old-files), so models/outputs on a volume are safe.
|
| 8 |
+
set -e
|
| 9 |
+
|
| 10 |
+
if [[ ! -d /workspace || ! -w /workspace ]]; then
|
| 11 |
+
echo "[seed-workspace] /workspace missing or not writable — skipping." >&2
|
| 12 |
+
exit 0
|
| 13 |
+
fi
|
| 14 |
+
|
| 15 |
+
if [[ ! -d /workspace/ComfyUI || ! -d /workspace/workflows || ! -f /workspace/download_missing_models.sh ]]; then
|
| 16 |
+
echo "[seed-workspace] Restoring missing /workspace files from image seed..."
|
| 17 |
+
tar -xzf /opt/workspace-seed.tar.gz -C /workspace --skip-old-files
|
| 18 |
+
echo "[seed-workspace] Done."
|
| 19 |
+
fi
|
docker/start-comfy.sh
CHANGED
|
@@ -1,10 +1,12 @@
|
|
| 1 |
#!/bin/bash
|
| 2 |
-
# Image CMD:
|
| 3 |
-
#
|
| 4 |
-
#
|
| 5 |
-
#
|
| 6 |
|
| 7 |
-
|
|
|
|
|
|
|
| 8 |
LOG=/workspace/comfyui.log
|
| 9 |
[[ -d /workspace && -w /workspace ]] || LOG=/var/log/comfyui.log
|
| 10 |
(
|
|
@@ -15,9 +17,9 @@ if [[ "${COMFY_AUTOSTART:-false}" == "true" ]]; then
|
|
| 15 |
done
|
| 16 |
) &
|
| 17 |
echo "ComfyUI starting in background (log: $LOG, port ${COMFY_PORT:-7865})"
|
| 18 |
-
else
|
| 19 |
-
echo "ComfyUI not auto-started. Run 'comfy' to start it (port ${COMFY_PORT:-7865})."
|
| 20 |
echo "Run 'download_missing_models.sh' to fetch models for your workflows."
|
|
|
|
|
|
|
| 21 |
fi
|
| 22 |
|
| 23 |
exec /start.sh
|
|
|
|
| 1 |
#!/bin/bash
|
| 2 |
+
# Image CMD: make sure /workspace is fully populated, start ComfyUI in the
|
| 3 |
+
# background (auto-restart loop), then hand off to the stock RunPod
|
| 4 |
+
# /start.sh (SSH, Jupyter, nginx).
|
| 5 |
+
# v3: ComfyUI AUTO-STARTS by default. Set COMFY_AUTOSTART=false to disable.
|
| 6 |
|
| 7 |
+
/usr/local/bin/seed-workspace.sh || true
|
| 8 |
+
|
| 9 |
+
if [[ "${COMFY_AUTOSTART:-true}" != "false" ]]; then
|
| 10 |
LOG=/workspace/comfyui.log
|
| 11 |
[[ -d /workspace && -w /workspace ]] || LOG=/var/log/comfyui.log
|
| 12 |
(
|
|
|
|
| 17 |
done
|
| 18 |
) &
|
| 19 |
echo "ComfyUI starting in background (log: $LOG, port ${COMFY_PORT:-7865})"
|
|
|
|
|
|
|
| 20 |
echo "Run 'download_missing_models.sh' to fetch models for your workflows."
|
| 21 |
+
else
|
| 22 |
+
echo "ComfyUI not auto-started (COMFY_AUTOSTART=false). Run 'comfy' to start it (port ${COMFY_PORT:-7865})."
|
| 23 |
fi
|
| 24 |
|
| 25 |
exec /start.sh
|