From a3e99ea0d24a0e59aaf7cd574dea9932ad0ee606 Mon Sep 17 00:00:00 2001 From: kflame99 <261674183+kflame99@users.noreply.github.com> Date: Sat, 14 Feb 2026 23:08:04 +0000 Subject: [PATCH 01/13] feat(runpod): scaffold reproducible RunPod ComfyUI setup --- CHANGELOG.md | 11 ++++ README.md | 7 +++ Runpod_Comfy/README.md | 65 ++++++++++++++++++++ Runpod_Comfy/config/comfyui.lock | 3 + Runpod_Comfy/config/custom_nodes.lock.json | 12 ++++ Runpod_Comfy/config/models.json | 12 ++++ Runpod_Comfy/docker/Dockerfile | 22 +++++++ Runpod_Comfy/docker/start.sh | 12 ++++ Runpod_Comfy/docs/DEPLOY_RUNPOD.md | 34 ++++++++++ Runpod_Comfy/scripts/bootstrap.sh | 27 ++++++++ Runpod_Comfy/scripts/download_models.sh | 39 ++++++++++++ Runpod_Comfy/scripts/install_custom_nodes.sh | 42 +++++++++++++ 12 files changed, 286 insertions(+) create mode 100644 Runpod_Comfy/README.md create mode 100644 Runpod_Comfy/config/comfyui.lock create mode 100644 Runpod_Comfy/config/custom_nodes.lock.json create mode 100644 Runpod_Comfy/config/models.json create mode 100644 Runpod_Comfy/docker/Dockerfile create mode 100644 Runpod_Comfy/docker/start.sh create mode 100644 Runpod_Comfy/docs/DEPLOY_RUNPOD.md create mode 100644 Runpod_Comfy/scripts/bootstrap.sh create mode 100644 Runpod_Comfy/scripts/download_models.sh create mode 100644 Runpod_Comfy/scripts/install_custom_nodes.sh diff --git a/CHANGELOG.md b/CHANGELOG.md index 42dcf5b..d724467 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,17 @@ The format is inspired by Keep a Changelog and SemVer. - `.github/PULL_REQUEST_TEMPLATE.md` - `.github/ISSUE_TEMPLATE/release_checklist.md` - `docs/RELEASE_NOTES_TEMPLATE.md` +- RunPod_Comfy implementation scaffold: + - `Runpod_Comfy/README.md` + - `Runpod_Comfy/docker/Dockerfile` + - `Runpod_Comfy/docker/start.sh` + - `Runpod_Comfy/scripts/bootstrap.sh` + - `Runpod_Comfy/scripts/install_custom_nodes.sh` + - `Runpod_Comfy/scripts/download_models.sh` + - `Runpod_Comfy/config/comfyui.lock` + - `Runpod_Comfy/config/custom_nodes.lock.json` + - `Runpod_Comfy/config/models.json` + - `Runpod_Comfy/docs/DEPLOY_RUNPOD.md` ## [0.1.0] - 2026-02-14 diff --git a/README.md b/README.md index f95d615..0faecc1 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,13 @@ The code for the Easy Resize node is inspired by the Resize Image V2 node from C - **Error Handling**: Fallbacks for missing/invalid JSON in Wan 2.2 Easy Prompt; validation for aspect ratios and divisibility in Easy Resize. - **Compatibility**: Works with ComfyUI-Manager for easy installation via Git URL. No additional dependencies beyond standard Python and ComfyUI libraries. +## RunPod + +A dedicated RunPod setup scaffold is available in `Runpod_Comfy/`. + +- Entry guide: `Runpod_Comfy/README.md` +- Deploy notes: `Runpod_Comfy/docs/DEPLOY_RUNPOD.md` + ## Release & Stability For production usage, install a pinned stable tag/commit instead of following moving branch heads. diff --git a/Runpod_Comfy/README.md b/Runpod_Comfy/README.md new file mode 100644 index 0000000..19a08c8 --- /dev/null +++ b/Runpod_Comfy/README.md @@ -0,0 +1,65 @@ +# Runpod_Comfy + +Production-oriented scaffold for running ComfyUI on RunPod with pinned versions. + +## Goals + +- Reproducible ComfyUI runtime +- Clear version pinning for ComfyUI + custom nodes +- Optional model bootstrap from URLs +- Easy promotion from test to stable + +## Structure + +- `docker/` → image/runtime entrypoint +- `config/` → lock files and model manifests +- `scripts/` → bootstrap installers +- `docs/` → requirements and references + +## Quick Start + +### 1) Pin ComfyUI version + +Edit `config/comfyui.lock`: + +```ini +COMFYUI_REPO=https://github.com/comfyanonymous/ComfyUI.git +COMFYUI_REF=master +``` + +Set `COMFYUI_REF` to a commit SHA for stability. + +### 2) Add custom nodes + +Edit `config/custom_nodes.lock.json`. + +### 3) Add models (optional) + +Edit `config/models.json`. + +### 4) Build image + +```bash +docker build -t comfyui-koolook:runpod-v1 -f Runpod_Comfy/docker/Dockerfile . +``` + +### 5) Run locally (smoke test) + +```bash +docker run --rm -it -p 8188:8188 \ + -e COMFYUI_WORKDIR=/workspace/ComfyUI \ + comfyui-koolook:runpod-v1 +``` + +## Runtime env vars + +- `COMFYUI_PORT` (default: `8188`) +- `COMFYUI_WORKDIR` (default: `/workspace/ComfyUI`) +- `RUNPOD_VOLUME_ROOT` (default: `/workspace`) +- `HF_TOKEN` (optional for gated HuggingFace models) +- `CIVITAI_TOKEN` (optional) + +## Notes + +- This scaffold is intentionally conservative and explicit. +- For production users, pin refs to commits/tags before release. diff --git a/Runpod_Comfy/config/comfyui.lock b/Runpod_Comfy/config/comfyui.lock new file mode 100644 index 0000000..7d14f58 --- /dev/null +++ b/Runpod_Comfy/config/comfyui.lock @@ -0,0 +1,3 @@ +# Pin ComfyUI source and ref for reproducible builds +COMFYUI_REPO=https://github.com/comfyanonymous/ComfyUI.git +COMFYUI_REF=master diff --git a/Runpod_Comfy/config/custom_nodes.lock.json b/Runpod_Comfy/config/custom_nodes.lock.json new file mode 100644 index 0000000..fdc189f --- /dev/null +++ b/Runpod_Comfy/config/custom_nodes.lock.json @@ -0,0 +1,12 @@ +{ + "version": 1, + "nodes": [ + { + "id": "comfyui-koolook", + "repo": "https://github.com/malkuthro/ComfyUI-Koolook.git", + "ref": "main", + "target_dir": "ComfyUI-Koolook", + "install": [] + } + ] +} diff --git a/Runpod_Comfy/config/models.json b/Runpod_Comfy/config/models.json new file mode 100644 index 0000000..15c573e --- /dev/null +++ b/Runpod_Comfy/config/models.json @@ -0,0 +1,12 @@ +{ + "version": 1, + "models": [ + { + "name": "example_sdxl_checkpoint", + "url": "https://example.com/path/to/model.safetensors", + "dest": "models/checkpoints/model.safetensors", + "sha256": "", + "enabled": false + } + ] +} diff --git a/Runpod_Comfy/docker/Dockerfile b/Runpod_Comfy/docker/Dockerfile new file mode 100644 index 0000000..b6ce906 --- /dev/null +++ b/Runpod_Comfy/docker/Dockerfile @@ -0,0 +1,22 @@ +FROM runpod/pytorch:2.6.0-py3.11-cuda12.4.1-devel-ubuntu22.04 + +ENV DEBIAN_FRONTEND=noninteractive \ + PIP_DISABLE_PIP_VERSION_CHECK=1 \ + PYTHONUNBUFFERED=1 \ + COMFYUI_PORT=8188 \ + COMFYUI_WORKDIR=/workspace/ComfyUI \ + RUNPOD_VOLUME_ROOT=/workspace + +WORKDIR /opt/bootstrap + +RUN apt-get update && apt-get install -y --no-install-recommends \ + git curl ca-certificates jq \ + && rm -rf /var/lib/apt/lists/* + +COPY Runpod_Comfy /opt/bootstrap/Runpod_Comfy + +RUN chmod +x /opt/bootstrap/Runpod_Comfy/scripts/*.sh /opt/bootstrap/Runpod_Comfy/docker/start.sh + +EXPOSE 8188 + +ENTRYPOINT ["/opt/bootstrap/Runpod_Comfy/docker/start.sh"] diff --git a/Runpod_Comfy/docker/start.sh b/Runpod_Comfy/docker/start.sh new file mode 100644 index 0000000..c6eaa0b --- /dev/null +++ b/Runpod_Comfy/docker/start.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT=/opt/bootstrap/Runpod_Comfy +WORKDIR="${COMFYUI_WORKDIR:-/workspace/ComfyUI}" +PORT="${COMFYUI_PORT:-8188}" + +"$ROOT/scripts/bootstrap.sh" + +cd "$WORKDIR" + +exec python3 main.py --listen 0.0.0.0 --port "$PORT" diff --git a/Runpod_Comfy/docs/DEPLOY_RUNPOD.md b/Runpod_Comfy/docs/DEPLOY_RUNPOD.md new file mode 100644 index 0000000..1d56fc1 --- /dev/null +++ b/Runpod_Comfy/docs/DEPLOY_RUNPOD.md @@ -0,0 +1,34 @@ +# Deploy on RunPod + +## 1) Build and push image + +Use GitHub Container Registry or Docker Hub. + +Example (GHCR): + +```bash +docker build -t ghcr.io/malkuthro/comfyui-koolook:runpod-v1 -f Runpod_Comfy/docker/Dockerfile . +docker push ghcr.io/malkuthro/comfyui-koolook:runpod-v1 +``` + +## 2) Create RunPod template + +- Container image: `ghcr.io/malkuthro/comfyui-koolook:runpod-v1` +- Exposed HTTP port: `8188` +- Volume mount: `/workspace` (recommended) + +## 3) Optional env vars + +- `COMFYUI_PORT=8188` +- `COMFYUI_WORKDIR=/workspace/ComfyUI` +- `HF_TOKEN=...` (if needed) +- `CIVITAI_TOKEN=...` (if needed) + +## 4) First boot expectations + +On first start: +- ComfyUI is cloned at pinned ref from `config/comfyui.lock` +- custom nodes are installed from `config/custom_nodes.lock.json` +- models are downloaded from `config/models.json` (enabled entries only) + +Subsequent starts reuse existing files from volume storage. diff --git a/Runpod_Comfy/scripts/bootstrap.sh b/Runpod_Comfy/scripts/bootstrap.sh new file mode 100644 index 0000000..8de63a9 --- /dev/null +++ b/Runpod_Comfy/scripts/bootstrap.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT=/opt/bootstrap/Runpod_Comfy +WORKDIR="${COMFYUI_WORKDIR:-/workspace/ComfyUI}" +mkdir -p "$WORKDIR" + +source "$ROOT/config/comfyui.lock" + +if [[ ! -f "$WORKDIR/main.py" ]]; then + echo "[bootstrap] Cloning ComfyUI from $COMFYUI_REPO" + git clone "$COMFYUI_REPO" "$WORKDIR" +fi + +cd "$WORKDIR" + +echo "[bootstrap] Checking out ComfyUI ref: $COMFYUI_REF" +git fetch --all --tags || true +git checkout "$COMFYUI_REF" + +python3 -m pip install --upgrade pip +python3 -m pip install -r requirements.txt + +"$ROOT/scripts/install_custom_nodes.sh" +"$ROOT/scripts/download_models.sh" + +echo "[bootstrap] done" diff --git a/Runpod_Comfy/scripts/download_models.sh b/Runpod_Comfy/scripts/download_models.sh new file mode 100644 index 0000000..b1fcc4d --- /dev/null +++ b/Runpod_Comfy/scripts/download_models.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT=/opt/bootstrap/Runpod_Comfy +WORKDIR="${COMFYUI_WORKDIR:-/workspace/ComfyUI}" +LOCK="$ROOT/config/models.json" + +if [[ ! -f "$LOCK" ]]; then + echo "[models] lock file not found: $LOCK" + exit 0 +fi + +COUNT=$(jq '.models | length' "$LOCK") +for ((i=0; i $DST" + git clone "$REPO" "$DST" + fi + + pushd "$DST" >/dev/null + git fetch --all --tags || true + git checkout "$REF" + + if [[ -f requirements.txt ]]; then + python3 -m pip install -r requirements.txt || true + fi + + popd >/dev/null +done + +echo "[custom_nodes] done" From 6ee591bb8ff65297ed2626eb50880427d6464dea Mon Sep 17 00:00:00 2001 From: kflame99 <261674183+kflame99@users.noreply.github.com> Date: Sun, 15 Feb 2026 00:38:59 +0000 Subject: [PATCH 02/13] docs: add Runpod_Comfy progress tracker --- docs/RUNPOD_PROGRESS.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 docs/RUNPOD_PROGRESS.md diff --git a/docs/RUNPOD_PROGRESS.md b/docs/RUNPOD_PROGRESS.md new file mode 100644 index 0000000..f57638c --- /dev/null +++ b/docs/RUNPOD_PROGRESS.md @@ -0,0 +1,21 @@ +# Runpod_Comfy – Progress + +_Last updated: auto by kflame (OpenClaw) + +## Status +- Branch: `kflame-runpod-comfy-v1` +- Base: `main` (after phase1/phase2 work) + +## Completed so far +- [x] Scaffolded reproducible Runpod ComfyUI setup + - Dockerfile + bootstrap structure (see `Runpod_Comfy/`) + - Basic config files and docs +- [x] Verified clean branch state on server (`git status` clean) + +## Next steps (planned) +- [ ] Add template families (`upscaler`, `lora-training`, `wan22`) under `Runpod_Comfy/` or `tools/` +- [ ] Add quick-add scripts for models/nodes +- [ ] Document CUDA 12.x + Triton/SageAttn behavior in `docs/` +- [ ] Prepare final consolidated PR description + +You can edit this file freely; I’ll treat it as the single source of truth for high-level Runpod_Comfy progress. \ No newline at end of file From af028bfa1908e791393fa73343884c9846b370ba Mon Sep 17 00:00:00 2001 From: kflame99 <261674183+kflame99@users.noreply.github.com> Date: Sun, 15 Feb 2026 08:56:15 +0000 Subject: [PATCH 03/13] Add profile compiler scaffold for RunPod Comfy builds --- Runpod_Comfy/README.md | 40 ++-- Runpod_Comfy/config/comfyui.lock | 4 +- Runpod_Comfy/config/custom_nodes.lock.json | 7 + Runpod_Comfy/config/models.json | 7 + Runpod_Comfy/docker/Dockerfile | 3 +- Runpod_Comfy/profiles/models.example.yaml | 14 ++ Runpod_Comfy/profiles/nodes.example.yaml | 14 ++ Runpod_Comfy/profiles/runpod.example.yaml | 13 ++ Runpod_Comfy/profiles/urls.txt | 6 + Runpod_Comfy/tools/compile_profile.sh | 248 +++++++++++++++++++++ 10 files changed, 337 insertions(+), 19 deletions(-) create mode 100644 Runpod_Comfy/profiles/models.example.yaml create mode 100644 Runpod_Comfy/profiles/nodes.example.yaml create mode 100644 Runpod_Comfy/profiles/runpod.example.yaml create mode 100644 Runpod_Comfy/profiles/urls.txt create mode 100755 Runpod_Comfy/tools/compile_profile.sh diff --git a/Runpod_Comfy/README.md b/Runpod_Comfy/README.md index 19a08c8..378e4e2 100644 --- a/Runpod_Comfy/README.md +++ b/Runpod_Comfy/README.md @@ -18,29 +18,35 @@ Production-oriented scaffold for running ComfyUI on RunPod with pinned versions. ## Quick Start -### 1) Pin ComfyUI version +### 1) Create profile files -Edit `config/comfyui.lock`: +Copy and edit these files: -```ini -COMFYUI_REPO=https://github.com/comfyanonymous/ComfyUI.git -COMFYUI_REF=master -``` +- `profiles/runpod..yaml` +- `profiles/nodes..yaml` +- `profiles/models..yaml` +- Optional: `profiles/urls..txt` -Set `COMFYUI_REF` to a commit SHA for stability. +You can start from the `*.example.yaml` files. -### 2) Add custom nodes - -Edit `config/custom_nodes.lock.json`. - -### 3) Add models (optional) - -Edit `config/models.json`. - -### 4) Build image +### 2) Compile profile into lock files ```bash -docker build -t comfyui-koolook:runpod-v1 -f Runpod_Comfy/docker/Dockerfile . +Runpod_Comfy/tools/compile_profile.sh +``` + +This generates: + +- `config/comfyui.lock` +- `config/custom_nodes.lock.json` +- `config/models.json` + +### 3) Build image + +```bash +BASE_IMAGE=$(grep '^BASE_IMAGE=' Runpod_Comfy/config/comfyui.lock | cut -d= -f2-) +docker build --build-arg BASE_IMAGE="$BASE_IMAGE" \ + -t comfyui-koolook:runpod-v1 -f Runpod_Comfy/docker/Dockerfile . ``` ### 5) Run locally (smoke test) diff --git a/Runpod_Comfy/config/comfyui.lock b/Runpod_Comfy/config/comfyui.lock index 7d14f58..9899970 100644 --- a/Runpod_Comfy/config/comfyui.lock +++ b/Runpod_Comfy/config/comfyui.lock @@ -1,3 +1,5 @@ -# Pin ComfyUI source and ref for reproducible builds +# Generated by Runpod_Comfy/tools/compile_profile.sh +PROFILE_ID=example +BASE_IMAGE=runpod/pytorch:2.6.0-py3.11-cuda12.4.1-devel-ubuntu22.04 COMFYUI_REPO=https://github.com/comfyanonymous/ComfyUI.git COMFYUI_REF=master diff --git a/Runpod_Comfy/config/custom_nodes.lock.json b/Runpod_Comfy/config/custom_nodes.lock.json index fdc189f..739dd00 100644 --- a/Runpod_Comfy/config/custom_nodes.lock.json +++ b/Runpod_Comfy/config/custom_nodes.lock.json @@ -7,6 +7,13 @@ "ref": "main", "target_dir": "ComfyUI-Koolook", "install": [] + }, + { + "id": "comfyui-manager", + "repo": "https://github.com/ltdrdata/ComfyUI-Manager.git", + "ref": "main", + "target_dir": "ComfyUI-Manager", + "install": [] } ] } diff --git a/Runpod_Comfy/config/models.json b/Runpod_Comfy/config/models.json index 15c573e..5fb98e2 100644 --- a/Runpod_Comfy/config/models.json +++ b/Runpod_Comfy/config/models.json @@ -7,6 +7,13 @@ "dest": "models/checkpoints/model.safetensors", "sha256": "", "enabled": false + }, + { + "name": "example_vae", + "url": "https://example.com/path/to/vae.safetensors", + "dest": "models/vae/vae.safetensors", + "sha256": "", + "enabled": false } ] } diff --git a/Runpod_Comfy/docker/Dockerfile b/Runpod_Comfy/docker/Dockerfile index b6ce906..558b32c 100644 --- a/Runpod_Comfy/docker/Dockerfile +++ b/Runpod_Comfy/docker/Dockerfile @@ -1,4 +1,5 @@ -FROM runpod/pytorch:2.6.0-py3.11-cuda12.4.1-devel-ubuntu22.04 +ARG BASE_IMAGE=runpod/pytorch:2.6.0-py3.11-cuda12.4.1-devel-ubuntu22.04 +FROM ${BASE_IMAGE} ENV DEBIAN_FRONTEND=noninteractive \ PIP_DISABLE_PIP_VERSION_CHECK=1 \ diff --git a/Runpod_Comfy/profiles/models.example.yaml b/Runpod_Comfy/profiles/models.example.yaml new file mode 100644 index 0000000..7f1e2f5 --- /dev/null +++ b/Runpod_Comfy/profiles/models.example.yaml @@ -0,0 +1,14 @@ +profile_id: example + +models: + - name: example_sdxl_checkpoint + url: https://example.com/path/to/model.safetensors + dest: models/checkpoints/model.safetensors + sha256: "" + enabled: false + + - name: example_vae + url: https://example.com/path/to/vae.safetensors + dest: models/vae/vae.safetensors + sha256: "" + enabled: false diff --git a/Runpod_Comfy/profiles/nodes.example.yaml b/Runpod_Comfy/profiles/nodes.example.yaml new file mode 100644 index 0000000..22403a7 --- /dev/null +++ b/Runpod_Comfy/profiles/nodes.example.yaml @@ -0,0 +1,14 @@ +profile_id: example + +nodes: + - id: comfyui-koolook + repo: https://github.com/malkuthro/ComfyUI-Koolook.git + ref: main + target_dir: ComfyUI-Koolook + install: [] + + - id: comfyui-manager + repo: https://github.com/ltdrdata/ComfyUI-Manager.git + ref: main + target_dir: ComfyUI-Manager + install: [] diff --git a/Runpod_Comfy/profiles/runpod.example.yaml b/Runpod_Comfy/profiles/runpod.example.yaml new file mode 100644 index 0000000..a50adc7 --- /dev/null +++ b/Runpod_Comfy/profiles/runpod.example.yaml @@ -0,0 +1,13 @@ +profile_id: example + +# Base image used by Runpod_Comfy/docker/Dockerfile via --build-arg BASE_IMAGE +base_image: runpod/pytorch:2.6.0-py3.11-cuda12.4.1-devel-ubuntu22.04 + +comfyui: + repo: https://github.com/comfyanonymous/ComfyUI.git + ref: master + +# Optional metadata for your own notes. +notes: + cuda: "12.4" + image_tag: "runpod-v1" diff --git a/Runpod_Comfy/profiles/urls.txt b/Runpod_Comfy/profiles/urls.txt new file mode 100644 index 0000000..3cebe36 --- /dev/null +++ b/Runpod_Comfy/profiles/urls.txt @@ -0,0 +1,6 @@ +# Optional quick model list parser. +# Format (pipe-separated): +# url | dest | sha256(optional) | enabled(optional,true/false) | name(optional) +# +# Example: +# https://example.com/model.safetensors | models/checkpoints/model.safetensors | | false | my_model diff --git a/Runpod_Comfy/tools/compile_profile.sh b/Runpod_Comfy/tools/compile_profile.sh new file mode 100755 index 0000000..871265c --- /dev/null +++ b/Runpod_Comfy/tools/compile_profile.sh @@ -0,0 +1,248 @@ +#!/usr/bin/env bash +set -euo pipefail + +if [[ $# -lt 1 ]]; then + echo "Usage: $0 " + echo "Example: $0 example" + exit 1 +fi + +PROFILE_ID="$1" +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +PROFILES_DIR="$ROOT/profiles" +CONFIG_DIR="$ROOT/config" + +RUNPOD_PROFILE="$PROFILES_DIR/runpod.${PROFILE_ID}.yaml" +NODES_PROFILE="$PROFILES_DIR/nodes.${PROFILE_ID}.yaml" +MODELS_PROFILE="$PROFILES_DIR/models.${PROFILE_ID}.yaml" +URLS_FILE="$PROFILES_DIR/urls.${PROFILE_ID}.txt" + +if [[ ! -f "$RUNPOD_PROFILE" ]]; then + echo "Missing profile: $RUNPOD_PROFILE" + echo "Tip: copy from $PROFILES_DIR/runpod.example.yaml" + exit 1 +fi +if [[ ! -f "$NODES_PROFILE" ]]; then + echo "Missing profile: $NODES_PROFILE" + echo "Tip: copy from $PROFILES_DIR/nodes.example.yaml" + exit 1 +fi +if [[ ! -f "$MODELS_PROFILE" ]]; then + echo "Missing profile: $MODELS_PROFILE" + echo "Tip: copy from $PROFILES_DIR/models.example.yaml" + exit 1 +fi + +mkdir -p "$CONFIG_DIR" + +python3 - "$RUNPOD_PROFILE" "$NODES_PROFILE" "$MODELS_PROFILE" "$URLS_FILE" "$CONFIG_DIR" <<'PY' +import json +import pathlib +import re +import sys + +runpod_path = pathlib.Path(sys.argv[1]) +nodes_path = pathlib.Path(sys.argv[2]) +models_path = pathlib.Path(sys.argv[3]) +urls_path = pathlib.Path(sys.argv[4]) +config_dir = pathlib.Path(sys.argv[5]) + + +def parse_scalar(v: str): + v = v.strip() + if not v: + return "" + if v in ("true", "True"): + return True + if v in ("false", "False"): + return False + if (v.startswith('"') and v.endswith('"')) or (v.startswith("'") and v.endswith("'")): + return v[1:-1] + if re.fullmatch(r"-?\d+", v): + try: + return int(v) + except ValueError: + pass + return v + + +def parse_simple_yaml(path: pathlib.Path): + lines = path.read_text(encoding="utf-8").splitlines() + root = {} + i = 0 + n = len(lines) + + while i < n: + raw = lines[i] + stripped = raw.strip() + if not stripped or stripped.startswith("#"): + i += 1 + continue + + if stripped.startswith("- "): + raise ValueError(f"Top-level list not supported in {path}") + + if ":" not in raw: + raise ValueError(f"Invalid line in {path}: {raw}") + + key, val = raw.split(":", 1) + key = key.strip() + val = val.strip() + + if val: + root[key] = parse_scalar(val) + i += 1 + continue + + # block value + i += 1 + block = [] + while i < n: + raw2 = lines[i] + if not raw2.strip() or raw2.strip().startswith("#"): + i += 1 + continue + indent = len(raw2) - len(raw2.lstrip(" ")) + if indent < 2: + break + block.append(raw2) + i += 1 + + if block and block[0].lstrip().startswith("- "): + items = [] + current = None + for bl in block: + indent = len(bl) - len(bl.lstrip(" ")) + s = bl.strip() + if s.startswith("- "): + if current is not None: + items.append(current) + current = {} + payload = s[2:].strip() + if payload: + if ":" not in payload: + raise ValueError(f"Invalid list item in {path}: {bl}") + k, v = payload.split(":", 1) + current[k.strip()] = parse_scalar(v.strip()) + else: + if current is None: + raise ValueError(f"Malformed list block in {path}: {bl}") + if ":" not in s: + raise ValueError(f"Invalid nested mapping in {path}: {bl}") + k, v = s.split(":", 1) + current[k.strip()] = parse_scalar(v.strip()) + if current is not None: + items.append(current) + root[key] = items + else: + nested = {} + for bl in block: + s = bl.strip() + if ":" not in s: + raise ValueError(f"Invalid nested mapping in {path}: {bl}") + k, v = s.split(":", 1) + nested[k.strip()] = parse_scalar(v.strip()) + root[key] = nested + + return root + + +def parse_urls(path: pathlib.Path): + models = [] + if not path.exists(): + return models + for line in path.read_text(encoding="utf-8").splitlines(): + s = line.strip() + if not s or s.startswith("#"): + continue + parts = [p.strip() for p in s.split("|")] + if len(parts) < 2: + raise ValueError(f"Invalid urls entry: {line}") + url = parts[0] + dest = parts[1] + sha = parts[2] if len(parts) > 2 else "" + enabled_raw = parts[3] if len(parts) > 3 else "true" + name = parts[4] if len(parts) > 4 and parts[4] else pathlib.Path(dest).stem + enabled = str(enabled_raw).lower() != "false" + models.append({ + "name": name, + "url": url, + "dest": dest, + "sha256": sha, + "enabled": enabled, + }) + return models + +runpod = parse_simple_yaml(runpod_path) +nodes_data = parse_simple_yaml(nodes_path) +models_data = parse_simple_yaml(models_path) +url_models = parse_urls(urls_path) + +base_image = runpod.get("base_image") +comfyui = runpod.get("comfyui", {}) if isinstance(runpod.get("comfyui"), dict) else {} +comfy_repo = comfyui.get("repo", "https://github.com/comfyanonymous/ComfyUI.git") +comfy_ref = comfyui.get("ref", "master") + +if not base_image: + raise ValueError(f"base_image is required in {runpod_path}") + +nodes = nodes_data.get("nodes", []) +if not isinstance(nodes, list): + raise ValueError(f"nodes must be a list in {nodes_path}") + +for node in nodes: + if "repo" not in node or "ref" not in node: + raise ValueError(f"Each node requires repo and ref in {nodes_path}: {node}") + if "target_dir" not in node or not node["target_dir"]: + repo = str(node["repo"]).rstrip("/") + node["target_dir"] = pathlib.Path(repo).name.replace(".git", "") + node.setdefault("install", "[]") + if isinstance(node["install"], str): + node["install"] = [] + +models = models_data.get("models", []) +if not isinstance(models, list): + raise ValueError(f"models must be a list in {models_path}") + +for model in models: + for req in ("name", "url", "dest"): + if req not in model: + raise ValueError(f"Model missing '{req}' in {models_path}: {model}") + model.setdefault("sha256", "") + model.setdefault("enabled", True) + +models.extend(url_models) + +comfy_lock = "\n".join([ + "# Generated by Runpod_Comfy/tools/compile_profile.sh", + f"PROFILE_ID={runpod.get('profile_id', 'unknown')}", + f"BASE_IMAGE={base_image}", + f"COMFYUI_REPO={comfy_repo}", + f"COMFYUI_REF={comfy_ref}", + "", +]) + +(config_dir / "comfyui.lock").write_text(comfy_lock, encoding="utf-8") +(config_dir / "custom_nodes.lock.json").write_text( + json.dumps({"version": 1, "nodes": nodes}, indent=2) + "\n", + encoding="utf-8", +) +(config_dir / "models.json").write_text( + json.dumps({"version": 1, "models": models}, indent=2) + "\n", + encoding="utf-8", +) + +print("=== Runpod_Comfy profile compile summary ===") +print(f"Profile ID : {runpod.get('profile_id', 'unknown')}") +print(f"Base image : {base_image}") +print(f"ComfyUI repo : {comfy_repo}") +print(f"ComfyUI ref : {comfy_ref}") +print(f"Custom nodes : {len(nodes)}") +print(f"Models : {len(models)} (includes urls.txt additions: {len(url_models)})") +print("Generated:") +print(f" - {config_dir / 'comfyui.lock'}") +print(f" - {config_dir / 'custom_nodes.lock.json'}") +print(f" - {config_dir / 'models.json'}") +PY + +echo "[ok] compile complete" From f44f411d1a125836be70272cae5d93bf1744e348 Mon Sep 17 00:00:00 2001 From: kflame99 <261674183+kflame99@users.noreply.github.com> Date: Sun, 15 Feb 2026 09:21:52 +0000 Subject: [PATCH 04/13] Add project operating workflow and continuity docs --- DECISIONS.md | 19 +++++++++++++++++++ TODO.md | 20 ++++++++++++++++++++ WORKFLOW.md | 41 +++++++++++++++++++++++++++++++++++++++++ WORKLOG.md | 24 ++++++++++++++++++++++++ 4 files changed, 104 insertions(+) create mode 100644 DECISIONS.md create mode 100644 TODO.md create mode 100644 WORKFLOW.md create mode 100644 WORKLOG.md diff --git a/DECISIONS.md b/DECISIONS.md new file mode 100644 index 0000000..3ab3a8e --- /dev/null +++ b/DECISIONS.md @@ -0,0 +1,19 @@ +# DECISIONS + +## 2026-02-15 — Profile-first RunPod build flow +- We use profile files as inputs and generate lock files as build/runtime truth. +- Profile inputs: + - `Runpod_Comfy/profiles/runpod..yaml` + - `Runpod_Comfy/profiles/nodes..yaml` + - `Runpod_Comfy/profiles/models..yaml` + - Optional `Runpod_Comfy/profiles/urls..txt` +- Compiler output: + - `Runpod_Comfy/config/comfyui.lock` + - `Runpod_Comfy/config/custom_nodes.lock.json` + - `Runpod_Comfy/config/models.json` +- Docker base image is taken from generated `comfyui.lock` (`BASE_IMAGE` build arg). + +## 2026-02-15 — Work continuity model +- Planning/serious execution in OpenClaw web dashboard. +- Telegram for quick pings. +- Repo files (`TODO/WORKLOG/DECISIONS/WORKFLOW`) are continuity anchor across devices. diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..bf26396 --- /dev/null +++ b/TODO.md @@ -0,0 +1,20 @@ +# TODO + +## NOW +- [ ] Fill real values for RunPod profile files (`Runpod_Comfy/profiles/*.example.yaml` copies) +- [ ] Compile selected profile and verify generated lock files +- [ ] Build and push first RunPod image + +## NEXT +- [ ] Deploy image on RunPod and run smoke test workflow +- [ ] Add helper script: `Runpod_Comfy/tools/build_from_lock.sh` +- [ ] Add profile validation checks (schema-lite) + +## BLOCKED +- [ ] Final production model URLs and checksums (waiting on selection) + +## DONE +- [x] Add profile compiler scaffold (`compile_profile.sh`) +- [x] Add example profile files (runpod/nodes/models + urls format) +- [x] Wire Dockerfile to configurable base image via build-arg +- [x] Generate lock files from sample profile and sanity-check JSON diff --git a/WORKFLOW.md b/WORKFLOW.md new file mode 100644 index 0000000..5be3f6b --- /dev/null +++ b/WORKFLOW.md @@ -0,0 +1,41 @@ +# Workflow (Cristian + kflame) + +This is the operating flow for this repo. + +## 1) Where planning happens +- Primary workspace: OpenClaw web dashboard session. +- Telegram: quick pings only. + +## 2) Source of truth +- Tasks: `TODO.md` +- Progress/handoff: `WORKLOG.md` +- Decisions: `DECISIONS.md` +- Code/config truth: repo files + commits + +## 3) Start of each work block +1. Read `TODO.md` +2. Read latest entry in `WORKLOG.md` +3. Read `DECISIONS.md` +4. Pick one task and execute + +## 4) End of each work block +1. Update `WORKLOG.md` (done/next/blockers) +2. Update `TODO.md` statuses +3. If a meaningful choice was made, update `DECISIONS.md` +4. Commit changes with clear message + +## 5) Task status model +- `NOW`: actively working +- `NEXT`: queued next +- `BLOCKED`: waiting on external dependency +- `DONE`: complete + +## 6) Resume from any device +Use this order: +1. `WORKLOG.md` latest entry +2. `TODO.md` NOW/NEXT items +3. `DECISIONS.md` +4. Git history (`git log --oneline -n 10`) + +## 7) Rule of thumb +If it matters later, write it to file now. diff --git a/WORKLOG.md b/WORKLOG.md new file mode 100644 index 0000000..ddcfb35 --- /dev/null +++ b/WORKLOG.md @@ -0,0 +1,24 @@ +# WORKLOG + +## 2026-02-15 +### Done +- Implemented profile-driven scaffold for RunPod Comfy builds. +- Added: + - `Runpod_Comfy/profiles/runpod.example.yaml` + - `Runpod_Comfy/profiles/nodes.example.yaml` + - `Runpod_Comfy/profiles/models.example.yaml` + - `Runpod_Comfy/profiles/urls.txt` + - `Runpod_Comfy/tools/compile_profile.sh` +- Updated `Runpod_Comfy/docker/Dockerfile` to use `ARG BASE_IMAGE` + `FROM ${BASE_IMAGE}`. +- Updated `Runpod_Comfy/README.md` with compile/build flow. +- Ran sample compile: `Runpod_Comfy/tools/compile_profile.sh example`. +- Validated generated JSON structure via Python loader. +- Commit: `af028bf`. + +### Next (top 3) +1. Create real profile files for Cristian's RunPod target. +2. Compile and inspect generated lock files. +3. Build + push image, deploy pod, smoke test. + +### Blockers +- Real model URLs/checksums not finalized. From 014f125f2624e98f933e92147ebe7787e9265e6a Mon Sep 17 00:00:00 2001 From: kflame99 <261674183+kflame99@users.noreply.github.com> Date: Sun, 15 Feb 2026 09:34:15 +0000 Subject: [PATCH 05/13] Capture Telegram thread recap and tomorrow RunPod execution plan --- WORKLOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/WORKLOG.md b/WORKLOG.md index ddcfb35..46c233b 100644 --- a/WORKLOG.md +++ b/WORKLOG.md @@ -20,5 +20,17 @@ 2. Compile and inspect generated lock files. 3. Build + push image, deploy pod, smoke test. +### Thread recap (copied from Telegram for continuity) +- Agreed division of work: assistant builds production-ready profile compiler scaffold; Cristian fills real values next session. +- Delivered scaffold scope: + - Config layer with profile files for runpod/nodes/models (+ optional urls parser) + - Compiler that generates `config/comfyui.lock`, `config/custom_nodes.lock.json`, `config/models.json` + - Docker wired to consume generated lock data + - Sanity checks + dry docker build command validation +- Tomorrow execution plan: + 1. Edit 3–4 profile files with real CUDA/image/nodes/models. + 2. Run compiler + docker build + docker push. + 3. Deploy image on RunPod and run smoke test. + ### Blockers - Real model URLs/checksums not finalized. From 8a8ae635cc77ae5ce2f37186bacdeea6c5bd75e4 Mon Sep 17 00:00:00 2001 From: kflame99 <261674183+kflame99@users.noreply.github.com> Date: Sun, 15 Feb 2026 09:38:16 +0000 Subject: [PATCH 06/13] Record extended Telegram requirements for profile-driven RunPod UX --- DECISIONS.md | 6 ++++++ WORKLOG.md | 8 ++++++++ 2 files changed, 14 insertions(+) diff --git a/DECISIONS.md b/DECISIONS.md index 3ab3a8e..4b0d14e 100644 --- a/DECISIONS.md +++ b/DECISIONS.md @@ -12,6 +12,12 @@ - `Runpod_Comfy/config/custom_nodes.lock.json` - `Runpod_Comfy/config/models.json` - Docker base image is taken from generated `comfyui.lock` (`BASE_IMAGE` build arg). +- Goal: normal updates (new node repo/model URL/version bumps) should require editing config files only, not Python/Docker logic. +- Expected operator UX: + - Edit 3–4 simple profile files with real values. + - Run compiler. + - Build/push image. + - Deploy and smoke-test on RunPod. ## 2026-02-15 — Work continuity model - Planning/serious execution in OpenClaw web dashboard. diff --git a/WORKLOG.md b/WORKLOG.md index 46c233b..364ba6c 100644 --- a/WORKLOG.md +++ b/WORKLOG.md @@ -34,3 +34,11 @@ ### Blockers - Real model URLs/checksums not finalized. + +### Additional context imported from Telegram (extended) +- Desired abstraction confirmed: config-driven workflow where adding node repos/model URLs and bumping versions does not require code edits. +- Strong emphasis on "production-ready" compiler/scaffold with placeholders now and real values tomorrow. +- Tomorrow checklist reaffirmed: + 1. Fill real profile values (CUDA/image/nodes/models). + 2. Compile profile, build image, push image. + 3. Deploy on RunPod and validate. From c68a509f4d02efbb31185d4c7987632dd69bca2e Mon Sep 17 00:00:00 2001 From: kflame99 <261674183+kflame99@users.noreply.github.com> Date: Sun, 15 Feb 2026 10:08:27 +0000 Subject: [PATCH 07/13] Remove redundant root RunPod progress doc --- docs/RUNPOD_PROGRESS.md | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100644 docs/RUNPOD_PROGRESS.md diff --git a/docs/RUNPOD_PROGRESS.md b/docs/RUNPOD_PROGRESS.md deleted file mode 100644 index f57638c..0000000 --- a/docs/RUNPOD_PROGRESS.md +++ /dev/null @@ -1,21 +0,0 @@ -# Runpod_Comfy – Progress - -_Last updated: auto by kflame (OpenClaw) - -## Status -- Branch: `kflame-runpod-comfy-v1` -- Base: `main` (after phase1/phase2 work) - -## Completed so far -- [x] Scaffolded reproducible Runpod ComfyUI setup - - Dockerfile + bootstrap structure (see `Runpod_Comfy/`) - - Basic config files and docs -- [x] Verified clean branch state on server (`git status` clean) - -## Next steps (planned) -- [ ] Add template families (`upscaler`, `lora-training`, `wan22`) under `Runpod_Comfy/` or `tools/` -- [ ] Add quick-add scripts for models/nodes -- [ ] Document CUDA 12.x + Triton/SageAttn behavior in `docs/` -- [ ] Prepare final consolidated PR description - -You can edit this file freely; I’ll treat it as the single source of truth for high-level Runpod_Comfy progress. \ No newline at end of file From bc78ce85e0061792ec0568a0cbcf2799974c37e3 Mon Sep 17 00:00:00 2001 From: kflame99 <261674183+kflame99@users.noreply.github.com> Date: Sun, 15 Feb 2026 10:13:15 +0000 Subject: [PATCH 08/13] Add helper to create per-image profile sets --- Runpod_Comfy/README.md | 13 ++++++++--- Runpod_Comfy/tools/new_profile.sh | 36 +++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 3 deletions(-) create mode 100755 Runpod_Comfy/tools/new_profile.sh diff --git a/Runpod_Comfy/README.md b/Runpod_Comfy/README.md index 378e4e2..b7d397e 100644 --- a/Runpod_Comfy/README.md +++ b/Runpod_Comfy/README.md @@ -20,14 +20,21 @@ Production-oriented scaffold for running ComfyUI on RunPod with pinned versions. ### 1) Create profile files -Copy and edit these files: +Create a new profile set (recommended): + +```bash +Runpod_Comfy/tools/new_profile.sh +``` + +This creates: - `profiles/runpod..yaml` - `profiles/nodes..yaml` - `profiles/models..yaml` -- Optional: `profiles/urls..txt` +- Optional helper file: `profiles/urls..txt` -You can start from the `*.example.yaml` files. +> Keep one profile-id per image variant (e.g. `upscaler-v1`, `wan22-v1`). +> Do **not** edit the `*.example.yaml` files for real builds. ### 2) Compile profile into lock files diff --git a/Runpod_Comfy/tools/new_profile.sh b/Runpod_Comfy/tools/new_profile.sh new file mode 100755 index 0000000..25a574e --- /dev/null +++ b/Runpod_Comfy/tools/new_profile.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +set -euo pipefail + +if [[ $# -lt 1 ]]; then + echo "Usage: $0 " + echo "Example: $0 upscaler-v1" + exit 1 +fi + +ID="$1" +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +P="$ROOT/profiles" + +for kind in runpod nodes models; do + src="$P/${kind}.example.yaml" + dst="$P/${kind}.${ID}.yaml" + if [[ -f "$dst" ]]; then + echo "[skip] exists: $dst" + else + cp "$src" "$dst" + sed -i "s/^profile_id: .*/profile_id: ${ID}/" "$dst" || true + echo "[new] $dst" + fi +done + +u="$P/urls.${ID}.txt" +if [[ -f "$u" ]]; then + echo "[skip] exists: $u" +else + cp "$P/urls.txt" "$u" + echo "[new] $u" +fi + +echo "\nNext:" +echo " 1) edit profiles/*.${ID}.yaml" +echo " 2) Runpod_Comfy/tools/compile_profile.sh ${ID}" From b539c4be063c55f93426e274a537f09d4d66fb65 Mon Sep 17 00:00:00 2001 From: kflame99 <261674183+kflame99@users.noreply.github.com> Date: Sun, 15 Feb 2026 10:31:16 +0000 Subject: [PATCH 09/13] Refactor to admin_recipes with per-recipe builds and compiler flags --- DECISIONS.md | 6 + Runpod_Comfy/README.md | 75 ++-- .../examples}/models.example.yaml | 0 .../examples}/nodes.example.yaml | 0 .../examples}/runpod.example.yaml | 11 +- .../examples/urls.example.txt} | 0 Runpod_Comfy/builds/.gitkeep | 0 Runpod_Comfy/tools/compile_profile.sh | 366 +++++++----------- Runpod_Comfy/tools/new_profile.sh | 32 +- 9 files changed, 204 insertions(+), 286 deletions(-) rename Runpod_Comfy/{profiles => admin_recipes/examples}/models.example.yaml (100%) rename Runpod_Comfy/{profiles => admin_recipes/examples}/nodes.example.yaml (100%) rename Runpod_Comfy/{profiles => admin_recipes/examples}/runpod.example.yaml (50%) rename Runpod_Comfy/{profiles/urls.txt => admin_recipes/examples/urls.example.txt} (100%) create mode 100644 Runpod_Comfy/builds/.gitkeep diff --git a/DECISIONS.md b/DECISIONS.md index 4b0d14e..b4be2e9 100644 --- a/DECISIONS.md +++ b/DECISIONS.md @@ -23,3 +23,9 @@ - Planning/serious execution in OpenClaw web dashboard. - Telegram for quick pings. - Repo files (`TODO/WORKLOG/DECISIONS/WORKFLOW`) are continuity anchor across devices. + +## 2026-02-15 — Recipe architecture for long-term readability +- Rename `profiles/` concept to `admin_recipes/` for clearer ownership/intent. +- Keep one recipe folder per image variant (`upscaler-v1`, `wan22-v1`, etc.). +- Compiler supports explicit args (`--id`, `--out`, `--image-tag`, `--no-activate`). +- Generated artifacts are stored under `builds//` and can be activated to `config/`. diff --git a/Runpod_Comfy/README.md b/Runpod_Comfy/README.md index b7d397e..c2c1fc6 100644 --- a/Runpod_Comfy/README.md +++ b/Runpod_Comfy/README.md @@ -2,77 +2,68 @@ Production-oriented scaffold for running ComfyUI on RunPod with pinned versions. -## Goals - -- Reproducible ComfyUI runtime -- Clear version pinning for ComfyUI + custom nodes -- Optional model bootstrap from URLs -- Easy promotion from test to stable - ## Structure +- `base/` → stable scaffold area (reserved for core runtime layout) +- `admin_recipes/` → **your editable inputs** (one recipe per image variant) +- `builds/` → generated lock outputs per recipe +- `config/` → active lock set consumed by runtime scripts - `docker/` → image/runtime entrypoint -- `config/` → lock files and model manifests - `scripts/` → bootstrap installers -- `docs/` → requirements and references +- `tools/` → recipe helpers (`new_profile.sh`, `compile_profile.sh`) ## Quick Start -### 1) Create profile files - -Create a new profile set (recommended): +### 1) Create a recipe ```bash -Runpod_Comfy/tools/new_profile.sh +Runpod_Comfy/tools/new_profile.sh upscaler-v1 ``` This creates: -- `profiles/runpod..yaml` -- `profiles/nodes..yaml` -- `profiles/models..yaml` -- Optional helper file: `profiles/urls..txt` +- `admin_recipes/upscaler-v1/runpod.yaml` +- `admin_recipes/upscaler-v1/nodes.yaml` +- `admin_recipes/upscaler-v1/models.yaml` +- `admin_recipes/upscaler-v1/urls.txt` (optional helper) -> Keep one profile-id per image variant (e.g. `upscaler-v1`, `wan22-v1`). -> Do **not** edit the `*.example.yaml` files for real builds. - -### 2) Compile profile into lock files +### 2) Compile recipe ```bash -Runpod_Comfy/tools/compile_profile.sh +Runpod_Comfy/tools/compile_profile.sh --id upscaler-v1 ``` -This generates: +Generated outputs: -- `config/comfyui.lock` -- `config/custom_nodes.lock.json` -- `config/models.json` +- `builds/upscaler-v1/comfyui.lock` +- `builds/upscaler-v1/custom_nodes.lock.json` +- `builds/upscaler-v1/models.json` + +By default, compile also **activates** this recipe by copying outputs to `config/`. ### 3) Build image ```bash BASE_IMAGE=$(grep '^BASE_IMAGE=' Runpod_Comfy/config/comfyui.lock | cut -d= -f2-) +IMAGE_TAG=$(grep '^RUNPOD_IMAGE_TAG=' Runpod_Comfy/config/comfyui.lock | cut -d= -f2-) docker build --build-arg BASE_IMAGE="$BASE_IMAGE" \ - -t comfyui-koolook:runpod-v1 -f Runpod_Comfy/docker/Dockerfile . + -t comfyui-koolook:${IMAGE_TAG} -f Runpod_Comfy/docker/Dockerfile . ``` -### 5) Run locally (smoke test) +### 4) Iterate safely + +- Minor tweaks: keep same recipe folder, bump `image_tag` in `runpod.yaml`. +- Major changes: clone recipe to new id (`upscaler-v2`, `wan22-v1`). +- You can compile without activation using `--no-activate`. + +## Compiler arguments ```bash -docker run --rm -it -p 8188:8188 \ - -e COMFYUI_WORKDIR=/workspace/ComfyUI \ - comfyui-koolook:runpod-v1 +Runpod_Comfy/tools/compile_profile.sh --id [--out ] [--image-tag ] [--no-activate] ``` -## Runtime env vars +Backward compatible: -- `COMFYUI_PORT` (default: `8188`) -- `COMFYUI_WORKDIR` (default: `/workspace/ComfyUI`) -- `RUNPOD_VOLUME_ROOT` (default: `/workspace`) -- `HF_TOKEN` (optional for gated HuggingFace models) -- `CIVITAI_TOKEN` (optional) - -## Notes - -- This scaffold is intentionally conservative and explicit. -- For production users, pin refs to commits/tags before release. +```bash +Runpod_Comfy/tools/compile_profile.sh +``` diff --git a/Runpod_Comfy/profiles/models.example.yaml b/Runpod_Comfy/admin_recipes/examples/models.example.yaml similarity index 100% rename from Runpod_Comfy/profiles/models.example.yaml rename to Runpod_Comfy/admin_recipes/examples/models.example.yaml diff --git a/Runpod_Comfy/profiles/nodes.example.yaml b/Runpod_Comfy/admin_recipes/examples/nodes.example.yaml similarity index 100% rename from Runpod_Comfy/profiles/nodes.example.yaml rename to Runpod_Comfy/admin_recipes/examples/nodes.example.yaml diff --git a/Runpod_Comfy/profiles/runpod.example.yaml b/Runpod_Comfy/admin_recipes/examples/runpod.example.yaml similarity index 50% rename from Runpod_Comfy/profiles/runpod.example.yaml rename to Runpod_Comfy/admin_recipes/examples/runpod.example.yaml index a50adc7..9556a05 100644 --- a/Runpod_Comfy/profiles/runpod.example.yaml +++ b/Runpod_Comfy/admin_recipes/examples/runpod.example.yaml @@ -1,13 +1,12 @@ profile_id: example -# Base image used by Runpod_Comfy/docker/Dockerfile via --build-arg BASE_IMAGE +# Docker build base base_image: runpod/pytorch:2.6.0-py3.11-cuda12.4.1-devel-ubuntu22.04 +# Optional image metadata used by compiler summary/lock file +image_name: ghcr.io/your-user/comfyui-koolook +image_tag: upscaler-v1.0.0 + comfyui: repo: https://github.com/comfyanonymous/ComfyUI.git ref: master - -# Optional metadata for your own notes. -notes: - cuda: "12.4" - image_tag: "runpod-v1" diff --git a/Runpod_Comfy/profiles/urls.txt b/Runpod_Comfy/admin_recipes/examples/urls.example.txt similarity index 100% rename from Runpod_Comfy/profiles/urls.txt rename to Runpod_Comfy/admin_recipes/examples/urls.example.txt diff --git a/Runpod_Comfy/builds/.gitkeep b/Runpod_Comfy/builds/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/Runpod_Comfy/tools/compile_profile.sh b/Runpod_Comfy/tools/compile_profile.sh index 871265c..43cfdef 100755 --- a/Runpod_Comfy/tools/compile_profile.sh +++ b/Runpod_Comfy/tools/compile_profile.sh @@ -1,248 +1,164 @@ #!/usr/bin/env bash set -euo pipefail -if [[ $# -lt 1 ]]; then - echo "Usage: $0 " - echo "Example: $0 example" - exit 1 +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +RECIPE_ID="" +RECIPES_DIR="$ROOT/admin_recipes" +OUT_DIR="" +ACTIVATE=true +IMAGE_TAG_OVERRIDE="" + +usage() { + cat < [--recipes-dir ] [--out ] [--image-tag ] [--no-activate] + $0 # backward-compatible + +Defaults: + recipes-dir: Runpod_Comfy/admin_recipes + out: Runpod_Comfy/builds/ + activate: true (copies generated files to Runpod_Comfy/config) +EOF +} + +if [[ $# -eq 1 && "$1" != --* ]]; then + RECIPE_ID="$1" +else + while [[ $# -gt 0 ]]; do + case "$1" in + --id) RECIPE_ID="$2"; shift 2 ;; + --recipes-dir) RECIPES_DIR="$2"; shift 2 ;; + --out) OUT_DIR="$2"; shift 2 ;; + --image-tag) IMAGE_TAG_OVERRIDE="$2"; shift 2 ;; + --no-activate) ACTIVATE=false; shift ;; + -h|--help) usage; exit 0 ;; + *) echo "Unknown arg: $1"; usage; exit 1 ;; + esac + done fi -PROFILE_ID="$1" -ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" -PROFILES_DIR="$ROOT/profiles" +[[ -z "$RECIPE_ID" ]] && { usage; exit 1; } +[[ -z "$OUT_DIR" ]] && OUT_DIR="$ROOT/builds/$RECIPE_ID" + +RECIPE_DIR="$RECIPES_DIR/$RECIPE_ID" +RUNPOD_PROFILE="$RECIPE_DIR/runpod.yaml" +NODES_PROFILE="$RECIPE_DIR/nodes.yaml" +MODELS_PROFILE="$RECIPE_DIR/models.yaml" +URLS_FILE="$RECIPE_DIR/urls.txt" CONFIG_DIR="$ROOT/config" -RUNPOD_PROFILE="$PROFILES_DIR/runpod.${PROFILE_ID}.yaml" -NODES_PROFILE="$PROFILES_DIR/nodes.${PROFILE_ID}.yaml" -MODELS_PROFILE="$PROFILES_DIR/models.${PROFILE_ID}.yaml" -URLS_FILE="$PROFILES_DIR/urls.${PROFILE_ID}.txt" +for f in "$RUNPOD_PROFILE" "$NODES_PROFILE" "$MODELS_PROFILE"; do + [[ -f "$f" ]] || { echo "Missing: $f"; exit 1; } +done +mkdir -p "$OUT_DIR" -if [[ ! -f "$RUNPOD_PROFILE" ]]; then - echo "Missing profile: $RUNPOD_PROFILE" - echo "Tip: copy from $PROFILES_DIR/runpod.example.yaml" - exit 1 -fi -if [[ ! -f "$NODES_PROFILE" ]]; then - echo "Missing profile: $NODES_PROFILE" - echo "Tip: copy from $PROFILES_DIR/nodes.example.yaml" - exit 1 -fi -if [[ ! -f "$MODELS_PROFILE" ]]; then - echo "Missing profile: $MODELS_PROFILE" - echo "Tip: copy from $PROFILES_DIR/models.example.yaml" - exit 1 -fi +python3 - "$RUNPOD_PROFILE" "$NODES_PROFILE" "$MODELS_PROFILE" "$URLS_FILE" "$OUT_DIR" "$RECIPE_ID" "$IMAGE_TAG_OVERRIDE" <<'PY' +import json, pathlib, re, sys +runpod_path = pathlib.Path(sys.argv[1]); nodes_path = pathlib.Path(sys.argv[2]); models_path = pathlib.Path(sys.argv[3]); urls_path = pathlib.Path(sys.argv[4]); out_dir = pathlib.Path(sys.argv[5]); recipe_id = sys.argv[6]; image_tag_override = sys.argv[7] -mkdir -p "$CONFIG_DIR" - -python3 - "$RUNPOD_PROFILE" "$NODES_PROFILE" "$MODELS_PROFILE" "$URLS_FILE" "$CONFIG_DIR" <<'PY' -import json -import pathlib -import re -import sys - -runpod_path = pathlib.Path(sys.argv[1]) -nodes_path = pathlib.Path(sys.argv[2]) -models_path = pathlib.Path(sys.argv[3]) -urls_path = pathlib.Path(sys.argv[4]) -config_dir = pathlib.Path(sys.argv[5]) - - -def parse_scalar(v: str): - v = v.strip() - if not v: - return "" - if v in ("true", "True"): - return True - if v in ("false", "False"): - return False - if (v.startswith('"') and v.endswith('"')) or (v.startswith("'") and v.endswith("'")): - return v[1:-1] - if re.fullmatch(r"-?\d+", v): - try: - return int(v) - except ValueError: - pass +def scalar(v): + v=v.strip() + if not v: return "" + if v.lower()=="true": return True + if v.lower()=="false": return False + if (v.startswith('"') and v.endswith('"')) or (v.startswith("'") and v.endswith("'")): return v[1:-1] + if re.fullmatch(r"-?\d+", v): return int(v) return v - -def parse_simple_yaml(path: pathlib.Path): - lines = path.read_text(encoding="utf-8").splitlines() - root = {} - i = 0 - n = len(lines) - - while i < n: - raw = lines[i] - stripped = raw.strip() - if not stripped or stripped.startswith("#"): - i += 1 - continue - - if stripped.startswith("- "): - raise ValueError(f"Top-level list not supported in {path}") - - if ":" not in raw: - raise ValueError(f"Invalid line in {path}: {raw}") - - key, val = raw.split(":", 1) - key = key.strip() - val = val.strip() - - if val: - root[key] = parse_scalar(val) - i += 1 - continue - - # block value - i += 1 - block = [] - while i < n: - raw2 = lines[i] - if not raw2.strip() or raw2.strip().startswith("#"): - i += 1 - continue - indent = len(raw2) - len(raw2.lstrip(" ")) - if indent < 2: - break - block.append(raw2) - i += 1 - - if block and block[0].lstrip().startswith("- "): - items = [] - current = None - for bl in block: - indent = len(bl) - len(bl.lstrip(" ")) - s = bl.strip() - if s.startswith("- "): - if current is not None: - items.append(current) - current = {} - payload = s[2:].strip() +def parse(path): + lines=path.read_text(encoding='utf-8').splitlines(); root={}; i=0 + while i2 else ""; enabled=(p[3].lower()!='false') if len(p)>3 and p[3] else True; name=p[4] if len(p)>4 and p[4] else pathlib.Path(dest).stem + out.append({"name":name,"url":url,"dest":dest,"sha256":sha,"enabled":enabled}) + return out -def parse_urls(path: pathlib.Path): - models = [] - if not path.exists(): - return models - for line in path.read_text(encoding="utf-8").splitlines(): - s = line.strip() - if not s or s.startswith("#"): - continue - parts = [p.strip() for p in s.split("|")] - if len(parts) < 2: - raise ValueError(f"Invalid urls entry: {line}") - url = parts[0] - dest = parts[1] - sha = parts[2] if len(parts) > 2 else "" - enabled_raw = parts[3] if len(parts) > 3 else "true" - name = parts[4] if len(parts) > 4 and parts[4] else pathlib.Path(dest).stem - enabled = str(enabled_raw).lower() != "false" - models.append({ - "name": name, - "url": url, - "dest": dest, - "sha256": sha, - "enabled": enabled, - }) - return models - -runpod = parse_simple_yaml(runpod_path) -nodes_data = parse_simple_yaml(nodes_path) -models_data = parse_simple_yaml(models_path) -url_models = parse_urls(urls_path) - -base_image = runpod.get("base_image") -comfyui = runpod.get("comfyui", {}) if isinstance(runpod.get("comfyui"), dict) else {} -comfy_repo = comfyui.get("repo", "https://github.com/comfyanonymous/ComfyUI.git") -comfy_ref = comfyui.get("ref", "master") - -if not base_image: - raise ValueError(f"base_image is required in {runpod_path}") - -nodes = nodes_data.get("nodes", []) -if not isinstance(nodes, list): - raise ValueError(f"nodes must be a list in {nodes_path}") - -for node in nodes: - if "repo" not in node or "ref" not in node: - raise ValueError(f"Each node requires repo and ref in {nodes_path}: {node}") - if "target_dir" not in node or not node["target_dir"]: - repo = str(node["repo"]).rstrip("/") - node["target_dir"] = pathlib.Path(repo).name.replace(".git", "") - node.setdefault("install", "[]") - if isinstance(node["install"], str): - node["install"] = [] - -models = models_data.get("models", []) -if not isinstance(models, list): - raise ValueError(f"models must be a list in {models_path}") - -for model in models: - for req in ("name", "url", "dest"): - if req not in model: - raise ValueError(f"Model missing '{req}' in {models_path}: {model}") - model.setdefault("sha256", "") - model.setdefault("enabled", True) - +runpod=parse(runpod_path); nodes_data=parse(nodes_path); models_data=parse(models_path) +base_image=runpod.get('base_image'); comfy=runpod.get('comfyui',{}) if isinstance(runpod.get('comfyui'),dict) else {} +if not base_image: raise ValueError('base_image is required') +image_name=runpod.get('image_name','') +image_tag= image_tag_override or runpod.get('image_tag', recipe_id) +nodes=nodes_data.get('nodes',[]); models=models_data.get('models',[]) +url_models=parse_urls(urls_path) +for n in nodes: + if 'repo' not in n or 'ref' not in n: raise ValueError(f'node requires repo/ref: {n}') + n.setdefault('target_dir', pathlib.Path(str(n['repo']).rstrip('/')).name.replace('.git','')) + if n.get('install') in ('',None): n['install']=[] +for m in models: + for req in ('name','url','dest'): + if req not in m: raise ValueError(f'model missing {req}: {m}') + m.setdefault('sha256',''); m.setdefault('enabled',True) models.extend(url_models) -comfy_lock = "\n".join([ - "# Generated by Runpod_Comfy/tools/compile_profile.sh", - f"PROFILE_ID={runpod.get('profile_id', 'unknown')}", - f"BASE_IMAGE={base_image}", - f"COMFYUI_REPO={comfy_repo}", - f"COMFYUI_REF={comfy_ref}", - "", +comfy_lock='\n'.join([ + '# Generated by Runpod_Comfy/tools/compile_profile.sh', + f'RECIPE_ID={recipe_id}', + f'BASE_IMAGE={base_image}', + f'IMAGE_NAME={image_name}', + f'RUNPOD_IMAGE_TAG={image_tag}', + f"COMFYUI_REPO={comfy.get('repo','https://github.com/comfyanonymous/ComfyUI.git')}", + f"COMFYUI_REF={comfy.get('ref','master')}", + '' ]) - -(config_dir / "comfyui.lock").write_text(comfy_lock, encoding="utf-8") -(config_dir / "custom_nodes.lock.json").write_text( - json.dumps({"version": 1, "nodes": nodes}, indent=2) + "\n", - encoding="utf-8", -) -(config_dir / "models.json").write_text( - json.dumps({"version": 1, "models": models}, indent=2) + "\n", - encoding="utf-8", -) - -print("=== Runpod_Comfy profile compile summary ===") -print(f"Profile ID : {runpod.get('profile_id', 'unknown')}") -print(f"Base image : {base_image}") -print(f"ComfyUI repo : {comfy_repo}") -print(f"ComfyUI ref : {comfy_ref}") -print(f"Custom nodes : {len(nodes)}") -print(f"Models : {len(models)} (includes urls.txt additions: {len(url_models)})") -print("Generated:") -print(f" - {config_dir / 'comfyui.lock'}") -print(f" - {config_dir / 'custom_nodes.lock.json'}") -print(f" - {config_dir / 'models.json'}") +(out_dir/'comfyui.lock').write_text(comfy_lock, encoding='utf-8') +(out_dir/'custom_nodes.lock.json').write_text(json.dumps({'version':1,'nodes':nodes},indent=2)+'\n',encoding='utf-8') +(out_dir/'models.json').write_text(json.dumps({'version':1,'models':models},indent=2)+'\n',encoding='utf-8') +print('=== compile summary ===') +print(f'Recipe ID : {recipe_id}') +print(f'Base image : {base_image}') +print(f'Image name : {image_name or "(unset)"}') +print(f'Image tag : {image_tag}') +print(f'ComfyUI ref : {comfy.get("ref","master")}') +print(f'Custom nodes : {len(nodes)}') +print(f'Models : {len(models)} (urls.txt additions: {len(url_models)})') +print(f'Output dir : {out_dir}') PY +if [[ "$ACTIVATE" == true ]]; then + mkdir -p "$CONFIG_DIR" + cp "$OUT_DIR/comfyui.lock" "$CONFIG_DIR/comfyui.lock" + cp "$OUT_DIR/custom_nodes.lock.json" "$CONFIG_DIR/custom_nodes.lock.json" + cp "$OUT_DIR/models.json" "$CONFIG_DIR/models.json" + echo "Activated build into: $CONFIG_DIR" +fi + echo "[ok] compile complete" diff --git a/Runpod_Comfy/tools/new_profile.sh b/Runpod_Comfy/tools/new_profile.sh index 25a574e..0d6337e 100755 --- a/Runpod_Comfy/tools/new_profile.sh +++ b/Runpod_Comfy/tools/new_profile.sh @@ -2,35 +2,41 @@ set -euo pipefail if [[ $# -lt 1 ]]; then - echo "Usage: $0 " + echo "Usage: $0 " echo "Example: $0 upscaler-v1" exit 1 fi ID="$1" ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" -P="$ROOT/profiles" +RECIPES="$ROOT/admin_recipes" +EXAMPLES="$RECIPES/examples" +TARGET="$RECIPES/$ID" + +mkdir -p "$TARGET" for kind in runpod nodes models; do - src="$P/${kind}.example.yaml" - dst="$P/${kind}.${ID}.yaml" + src="$EXAMPLES/${kind}.example.yaml" + dst="$TARGET/${kind}.yaml" if [[ -f "$dst" ]]; then echo "[skip] exists: $dst" else cp "$src" "$dst" sed -i "s/^profile_id: .*/profile_id: ${ID}/" "$dst" || true - echo "[new] $dst" + echo "[new] $dst" fi done -u="$P/urls.${ID}.txt" -if [[ -f "$u" ]]; then - echo "[skip] exists: $u" +src_urls="$EXAMPLES/urls.example.txt" +dst_urls="$TARGET/urls.txt" +if [[ -f "$dst_urls" ]]; then + echo "[skip] exists: $dst_urls" else - cp "$P/urls.txt" "$u" - echo "[new] $u" + cp "$src_urls" "$dst_urls" + echo "[new] $dst_urls" fi -echo "\nNext:" -echo " 1) edit profiles/*.${ID}.yaml" -echo " 2) Runpod_Comfy/tools/compile_profile.sh ${ID}" +echo +echo "Next:" +echo " 1) edit $TARGET/{runpod.yaml,nodes.yaml,models.yaml,urls.txt}" +echo " 2) Runpod_Comfy/tools/compile_profile.sh --id $ID" From 473cfdc93a66b7c52c5bc3a980fe2ebd3eed2f23 Mon Sep 17 00:00:00 2001 From: kflame99 <261674183+kflame99@users.noreply.github.com> Date: Sun, 15 Feb 2026 10:57:47 +0000 Subject: [PATCH 10/13] Reorganize Runpod_Comfy into setup/image/core layout --- DECISIONS.md | 9 ++- Runpod_Comfy/README.md | 71 ++----------------- Runpod_Comfy/{ => core}/docker/Dockerfile | 4 +- Runpod_Comfy/{ => core}/docker/start.sh | 2 +- Runpod_Comfy/{ => core}/scripts/bootstrap.sh | 6 +- .../{ => core}/scripts/download_models.sh | 2 +- .../scripts/install_custom_nodes.sh | 2 +- .../{config => image/active}/comfyui.lock | 2 +- .../active}/custom_nodes.lock.json | 0 .../{config => image/active}/models.json | 0 Runpod_Comfy/{ => image}/builds/.gitkeep | 0 Runpod_Comfy/setup/USER_README.md | 62 ++++++++++++++++ .../{ => setup}/docs/DEPLOY_RUNPOD.md | 2 +- .../features/runpod_Container_REQUIRMENTS.md | 0 .../references/github-repos_andOr_LINKS.md | 0 .../recipes}/examples/models.example.yaml | 0 .../recipes}/examples/nodes.example.yaml | 0 .../recipes}/examples/runpod.example.yaml | 0 .../recipes}/examples/urls.example.txt | 0 .../{ => setup}/tools/compile_profile.sh | 16 ++--- Runpod_Comfy/{ => setup}/tools/new_profile.sh | 6 +- 21 files changed, 95 insertions(+), 89 deletions(-) rename Runpod_Comfy/{ => core}/docker/Dockerfile (74%) rename Runpod_Comfy/{ => core}/docker/start.sh (86%) mode change 100644 => 100755 rename Runpod_Comfy/{ => core}/scripts/bootstrap.sh (80%) mode change 100644 => 100755 rename Runpod_Comfy/{ => core}/scripts/download_models.sh (95%) mode change 100644 => 100755 rename Runpod_Comfy/{ => core}/scripts/install_custom_nodes.sh (94%) mode change 100644 => 100755 rename Runpod_Comfy/{config => image/active}/comfyui.lock (73%) rename Runpod_Comfy/{config => image/active}/custom_nodes.lock.json (100%) rename Runpod_Comfy/{config => image/active}/models.json (100%) rename Runpod_Comfy/{ => image}/builds/.gitkeep (100%) create mode 100644 Runpod_Comfy/setup/USER_README.md rename Runpod_Comfy/{ => setup}/docs/DEPLOY_RUNPOD.md (95%) rename Runpod_Comfy/{ => setup}/docs/features/runpod_Container_REQUIRMENTS.md (100%) rename Runpod_Comfy/{ => setup}/docs/references/github-repos_andOr_LINKS.md (100%) rename Runpod_Comfy/{admin_recipes => setup/recipes}/examples/models.example.yaml (100%) rename Runpod_Comfy/{admin_recipes => setup/recipes}/examples/nodes.example.yaml (100%) rename Runpod_Comfy/{admin_recipes => setup/recipes}/examples/runpod.example.yaml (100%) rename Runpod_Comfy/{admin_recipes => setup/recipes}/examples/urls.example.txt (100%) rename Runpod_Comfy/{ => setup}/tools/compile_profile.sh (93%) rename Runpod_Comfy/{ => setup}/tools/new_profile.sh (83%) diff --git a/DECISIONS.md b/DECISIONS.md index b4be2e9..0dc98d4 100644 --- a/DECISIONS.md +++ b/DECISIONS.md @@ -25,7 +25,10 @@ - Repo files (`TODO/WORKLOG/DECISIONS/WORKFLOW`) are continuity anchor across devices. ## 2026-02-15 — Recipe architecture for long-term readability -- Rename `profiles/` concept to `admin_recipes/` for clearer ownership/intent. -- Keep one recipe folder per image variant (`upscaler-v1`, `wan22-v1`, etc.). +- Use a 3-zone layout inside `Runpod_Comfy/`: + - `setup/` (operator-facing edits/docs/tools) + - `image/` (generated outputs + active locks) + - `core/` (runtime internals) +- Keep one recipe folder per image variant under `setup/recipes//`. - Compiler supports explicit args (`--id`, `--out`, `--image-tag`, `--no-activate`). -- Generated artifacts are stored under `builds//` and can be activated to `config/`. +- Default outputs go to `image/builds//` and can be activated to `image/active/`. diff --git a/Runpod_Comfy/README.md b/Runpod_Comfy/README.md index c2c1fc6..9cb89f6 100644 --- a/Runpod_Comfy/README.md +++ b/Runpod_Comfy/README.md @@ -1,69 +1,10 @@ # Runpod_Comfy -Production-oriented scaffold for running ComfyUI on RunPod with pinned versions. +This module is organized in three top-level folders: -## Structure +- `setup/` → operator-facing inputs/docs/tools +- `image/` → generated build artifacts and active lock set +- `core/` → runtime internals (docker/scripts) -- `base/` → stable scaffold area (reserved for core runtime layout) -- `admin_recipes/` → **your editable inputs** (one recipe per image variant) -- `builds/` → generated lock outputs per recipe -- `config/` → active lock set consumed by runtime scripts -- `docker/` → image/runtime entrypoint -- `scripts/` → bootstrap installers -- `tools/` → recipe helpers (`new_profile.sh`, `compile_profile.sh`) - -## Quick Start - -### 1) Create a recipe - -```bash -Runpod_Comfy/tools/new_profile.sh upscaler-v1 -``` - -This creates: - -- `admin_recipes/upscaler-v1/runpod.yaml` -- `admin_recipes/upscaler-v1/nodes.yaml` -- `admin_recipes/upscaler-v1/models.yaml` -- `admin_recipes/upscaler-v1/urls.txt` (optional helper) - -### 2) Compile recipe - -```bash -Runpod_Comfy/tools/compile_profile.sh --id upscaler-v1 -``` - -Generated outputs: - -- `builds/upscaler-v1/comfyui.lock` -- `builds/upscaler-v1/custom_nodes.lock.json` -- `builds/upscaler-v1/models.json` - -By default, compile also **activates** this recipe by copying outputs to `config/`. - -### 3) Build image - -```bash -BASE_IMAGE=$(grep '^BASE_IMAGE=' Runpod_Comfy/config/comfyui.lock | cut -d= -f2-) -IMAGE_TAG=$(grep '^RUNPOD_IMAGE_TAG=' Runpod_Comfy/config/comfyui.lock | cut -d= -f2-) -docker build --build-arg BASE_IMAGE="$BASE_IMAGE" \ - -t comfyui-koolook:${IMAGE_TAG} -f Runpod_Comfy/docker/Dockerfile . -``` - -### 4) Iterate safely - -- Minor tweaks: keep same recipe folder, bump `image_tag` in `runpod.yaml`. -- Major changes: clone recipe to new id (`upscaler-v2`, `wan22-v1`). -- You can compile without activation using `--no-activate`. - -## Compiler arguments - -```bash -Runpod_Comfy/tools/compile_profile.sh --id [--out ] [--image-tag ] [--no-activate] -``` - -Backward compatible: - -```bash -Runpod_Comfy/tools/compile_profile.sh -``` +Start here: +- `Runpod_Comfy/setup/USER_README.md` diff --git a/Runpod_Comfy/docker/Dockerfile b/Runpod_Comfy/core/docker/Dockerfile similarity index 74% rename from Runpod_Comfy/docker/Dockerfile rename to Runpod_Comfy/core/docker/Dockerfile index 558b32c..03fc462 100644 --- a/Runpod_Comfy/docker/Dockerfile +++ b/Runpod_Comfy/core/docker/Dockerfile @@ -16,8 +16,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ COPY Runpod_Comfy /opt/bootstrap/Runpod_Comfy -RUN chmod +x /opt/bootstrap/Runpod_Comfy/scripts/*.sh /opt/bootstrap/Runpod_Comfy/docker/start.sh +RUN chmod +x /opt/bootstrap/Runpod_Comfy/core/scripts/*.sh /opt/bootstrap/Runpod_Comfy/core/docker/start.sh EXPOSE 8188 -ENTRYPOINT ["/opt/bootstrap/Runpod_Comfy/docker/start.sh"] +ENTRYPOINT ["/opt/bootstrap/Runpod_Comfy/core/docker/start.sh"] diff --git a/Runpod_Comfy/docker/start.sh b/Runpod_Comfy/core/docker/start.sh old mode 100644 new mode 100755 similarity index 86% rename from Runpod_Comfy/docker/start.sh rename to Runpod_Comfy/core/docker/start.sh index c6eaa0b..959e81f --- a/Runpod_Comfy/docker/start.sh +++ b/Runpod_Comfy/core/docker/start.sh @@ -5,7 +5,7 @@ ROOT=/opt/bootstrap/Runpod_Comfy WORKDIR="${COMFYUI_WORKDIR:-/workspace/ComfyUI}" PORT="${COMFYUI_PORT:-8188}" -"$ROOT/scripts/bootstrap.sh" +"$ROOT/core/scripts/bootstrap.sh" cd "$WORKDIR" diff --git a/Runpod_Comfy/scripts/bootstrap.sh b/Runpod_Comfy/core/scripts/bootstrap.sh old mode 100644 new mode 100755 similarity index 80% rename from Runpod_Comfy/scripts/bootstrap.sh rename to Runpod_Comfy/core/scripts/bootstrap.sh index 8de63a9..0f1049e --- a/Runpod_Comfy/scripts/bootstrap.sh +++ b/Runpod_Comfy/core/scripts/bootstrap.sh @@ -5,7 +5,7 @@ ROOT=/opt/bootstrap/Runpod_Comfy WORKDIR="${COMFYUI_WORKDIR:-/workspace/ComfyUI}" mkdir -p "$WORKDIR" -source "$ROOT/config/comfyui.lock" +source "$ROOT/image/active/comfyui.lock" if [[ ! -f "$WORKDIR/main.py" ]]; then echo "[bootstrap] Cloning ComfyUI from $COMFYUI_REPO" @@ -21,7 +21,7 @@ git checkout "$COMFYUI_REF" python3 -m pip install --upgrade pip python3 -m pip install -r requirements.txt -"$ROOT/scripts/install_custom_nodes.sh" -"$ROOT/scripts/download_models.sh" +"$ROOT/core/scripts/install_custom_nodes.sh" +"$ROOT/core/scripts/download_models.sh" echo "[bootstrap] done" diff --git a/Runpod_Comfy/scripts/download_models.sh b/Runpod_Comfy/core/scripts/download_models.sh old mode 100644 new mode 100755 similarity index 95% rename from Runpod_Comfy/scripts/download_models.sh rename to Runpod_Comfy/core/scripts/download_models.sh index b1fcc4d..a0f382c --- a/Runpod_Comfy/scripts/download_models.sh +++ b/Runpod_Comfy/core/scripts/download_models.sh @@ -3,7 +3,7 @@ set -euo pipefail ROOT=/opt/bootstrap/Runpod_Comfy WORKDIR="${COMFYUI_WORKDIR:-/workspace/ComfyUI}" -LOCK="$ROOT/config/models.json" +LOCK="$ROOT/image/active/models.json" if [[ ! -f "$LOCK" ]]; then echo "[models] lock file not found: $LOCK" diff --git a/Runpod_Comfy/scripts/install_custom_nodes.sh b/Runpod_Comfy/core/scripts/install_custom_nodes.sh old mode 100644 new mode 100755 similarity index 94% rename from Runpod_Comfy/scripts/install_custom_nodes.sh rename to Runpod_Comfy/core/scripts/install_custom_nodes.sh index b3a6fa2..2035762 --- a/Runpod_Comfy/scripts/install_custom_nodes.sh +++ b/Runpod_Comfy/core/scripts/install_custom_nodes.sh @@ -4,7 +4,7 @@ set -euo pipefail ROOT=/opt/bootstrap/Runpod_Comfy WORKDIR="${COMFYUI_WORKDIR:-/workspace/ComfyUI}" NODES_DIR="$WORKDIR/custom_nodes" -LOCK="$ROOT/config/custom_nodes.lock.json" +LOCK="$ROOT/image/active/custom_nodes.lock.json" mkdir -p "$NODES_DIR" diff --git a/Runpod_Comfy/config/comfyui.lock b/Runpod_Comfy/image/active/comfyui.lock similarity index 73% rename from Runpod_Comfy/config/comfyui.lock rename to Runpod_Comfy/image/active/comfyui.lock index 9899970..f493005 100644 --- a/Runpod_Comfy/config/comfyui.lock +++ b/Runpod_Comfy/image/active/comfyui.lock @@ -1,4 +1,4 @@ -# Generated by Runpod_Comfy/tools/compile_profile.sh +# Generated by Runpod_Comfy/setup/tools/compile_profile.sh PROFILE_ID=example BASE_IMAGE=runpod/pytorch:2.6.0-py3.11-cuda12.4.1-devel-ubuntu22.04 COMFYUI_REPO=https://github.com/comfyanonymous/ComfyUI.git diff --git a/Runpod_Comfy/config/custom_nodes.lock.json b/Runpod_Comfy/image/active/custom_nodes.lock.json similarity index 100% rename from Runpod_Comfy/config/custom_nodes.lock.json rename to Runpod_Comfy/image/active/custom_nodes.lock.json diff --git a/Runpod_Comfy/config/models.json b/Runpod_Comfy/image/active/models.json similarity index 100% rename from Runpod_Comfy/config/models.json rename to Runpod_Comfy/image/active/models.json diff --git a/Runpod_Comfy/builds/.gitkeep b/Runpod_Comfy/image/builds/.gitkeep similarity index 100% rename from Runpod_Comfy/builds/.gitkeep rename to Runpod_Comfy/image/builds/.gitkeep diff --git a/Runpod_Comfy/setup/USER_README.md b/Runpod_Comfy/setup/USER_README.md new file mode 100644 index 0000000..24c9d79 --- /dev/null +++ b/Runpod_Comfy/setup/USER_README.md @@ -0,0 +1,62 @@ +# Runpod_Comfy Setup Guide + +This package is split into 3 readable zones: + +- `setup/` → what you edit (recipes, docs, helper tools) +- `image/` → generated outputs (build artifacts + active locks) +- `core/` → runtime internals (Docker + bootstrap scripts) + +## Quick Start + +### 1) Create a recipe + +```bash +Runpod_Comfy/setup/tools/new_profile.sh upscaler-v1 +``` + +Creates: +- `Runpod_Comfy/setup/recipes/upscaler-v1/runpod.yaml` +- `Runpod_Comfy/setup/recipes/upscaler-v1/nodes.yaml` +- `Runpod_Comfy/setup/recipes/upscaler-v1/models.yaml` +- `Runpod_Comfy/setup/recipes/upscaler-v1/urls.txt` + +### 2) Compile recipe + +```bash +Runpod_Comfy/setup/tools/compile_profile.sh --id upscaler-v1 +``` + +Generates into: +- `Runpod_Comfy/image/builds/upscaler-v1/comfyui.lock` +- `Runpod_Comfy/image/builds/upscaler-v1/custom_nodes.lock.json` +- `Runpod_Comfy/image/builds/upscaler-v1/models.json` + +By default compile also **activates** to: +- `Runpod_Comfy/image/active/comfyui.lock` +- `Runpod_Comfy/image/active/custom_nodes.lock.json` +- `Runpod_Comfy/image/active/models.json` + +### 3) Build image + +```bash +BASE_IMAGE=$(grep '^BASE_IMAGE=' Runpod_Comfy/image/active/comfyui.lock | cut -d= -f2-) +IMAGE_TAG=$(grep '^RUNPOD_IMAGE_TAG=' Runpod_Comfy/image/active/comfyui.lock | cut -d= -f2-) +docker build --build-arg BASE_IMAGE="$BASE_IMAGE" \ + -t comfyui-koolook:${IMAGE_TAG} -f Runpod_Comfy/core/docker/Dockerfile . +``` + +## Iterate safely + +- Minor tweaks: keep same recipe id, bump `image_tag` in `runpod.yaml` +- Major changes: clone to new id (`upscaler-v2`, `wan22-v1`) +- Optional no-activate compile: + +```bash +Runpod_Comfy/setup/tools/compile_profile.sh --id upscaler-v1 --no-activate +``` + +## Compiler args + +```bash +Runpod_Comfy/setup/tools/compile_profile.sh --id [--out ] [--image-tag ] [--no-activate] +``` diff --git a/Runpod_Comfy/docs/DEPLOY_RUNPOD.md b/Runpod_Comfy/setup/docs/DEPLOY_RUNPOD.md similarity index 95% rename from Runpod_Comfy/docs/DEPLOY_RUNPOD.md rename to Runpod_Comfy/setup/docs/DEPLOY_RUNPOD.md index 1d56fc1..c4376ef 100644 --- a/Runpod_Comfy/docs/DEPLOY_RUNPOD.md +++ b/Runpod_Comfy/setup/docs/DEPLOY_RUNPOD.md @@ -7,7 +7,7 @@ Use GitHub Container Registry or Docker Hub. Example (GHCR): ```bash -docker build -t ghcr.io/malkuthro/comfyui-koolook:runpod-v1 -f Runpod_Comfy/docker/Dockerfile . +docker build -t ghcr.io/malkuthro/comfyui-koolook:runpod-v1 -f Runpod_Comfy/core/docker/Dockerfile . docker push ghcr.io/malkuthro/comfyui-koolook:runpod-v1 ``` diff --git a/Runpod_Comfy/docs/features/runpod_Container_REQUIRMENTS.md b/Runpod_Comfy/setup/docs/features/runpod_Container_REQUIRMENTS.md similarity index 100% rename from Runpod_Comfy/docs/features/runpod_Container_REQUIRMENTS.md rename to Runpod_Comfy/setup/docs/features/runpod_Container_REQUIRMENTS.md diff --git a/Runpod_Comfy/docs/references/github-repos_andOr_LINKS.md b/Runpod_Comfy/setup/docs/references/github-repos_andOr_LINKS.md similarity index 100% rename from Runpod_Comfy/docs/references/github-repos_andOr_LINKS.md rename to Runpod_Comfy/setup/docs/references/github-repos_andOr_LINKS.md diff --git a/Runpod_Comfy/admin_recipes/examples/models.example.yaml b/Runpod_Comfy/setup/recipes/examples/models.example.yaml similarity index 100% rename from Runpod_Comfy/admin_recipes/examples/models.example.yaml rename to Runpod_Comfy/setup/recipes/examples/models.example.yaml diff --git a/Runpod_Comfy/admin_recipes/examples/nodes.example.yaml b/Runpod_Comfy/setup/recipes/examples/nodes.example.yaml similarity index 100% rename from Runpod_Comfy/admin_recipes/examples/nodes.example.yaml rename to Runpod_Comfy/setup/recipes/examples/nodes.example.yaml diff --git a/Runpod_Comfy/admin_recipes/examples/runpod.example.yaml b/Runpod_Comfy/setup/recipes/examples/runpod.example.yaml similarity index 100% rename from Runpod_Comfy/admin_recipes/examples/runpod.example.yaml rename to Runpod_Comfy/setup/recipes/examples/runpod.example.yaml diff --git a/Runpod_Comfy/admin_recipes/examples/urls.example.txt b/Runpod_Comfy/setup/recipes/examples/urls.example.txt similarity index 100% rename from Runpod_Comfy/admin_recipes/examples/urls.example.txt rename to Runpod_Comfy/setup/recipes/examples/urls.example.txt diff --git a/Runpod_Comfy/tools/compile_profile.sh b/Runpod_Comfy/setup/tools/compile_profile.sh similarity index 93% rename from Runpod_Comfy/tools/compile_profile.sh rename to Runpod_Comfy/setup/tools/compile_profile.sh index 43cfdef..93ed578 100755 --- a/Runpod_Comfy/tools/compile_profile.sh +++ b/Runpod_Comfy/setup/tools/compile_profile.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash set -euo pipefail -ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" RECIPE_ID="" -RECIPES_DIR="$ROOT/admin_recipes" +RECIPES_DIR="$ROOT/setup/recipes" OUT_DIR="" ACTIVATE=true IMAGE_TAG_OVERRIDE="" @@ -15,9 +15,9 @@ Usage: $0 # backward-compatible Defaults: - recipes-dir: Runpod_Comfy/admin_recipes - out: Runpod_Comfy/builds/ - activate: true (copies generated files to Runpod_Comfy/config) + recipes-dir: Runpod_Comfy/setup/recipes + out: Runpod_Comfy/image/builds/ + activate: true (copies generated files to Runpod_Comfy/image/active) EOF } @@ -38,14 +38,14 @@ else fi [[ -z "$RECIPE_ID" ]] && { usage; exit 1; } -[[ -z "$OUT_DIR" ]] && OUT_DIR="$ROOT/builds/$RECIPE_ID" +[[ -z "$OUT_DIR" ]] && OUT_DIR="$ROOT/image/builds/$RECIPE_ID" RECIPE_DIR="$RECIPES_DIR/$RECIPE_ID" RUNPOD_PROFILE="$RECIPE_DIR/runpod.yaml" NODES_PROFILE="$RECIPE_DIR/nodes.yaml" MODELS_PROFILE="$RECIPE_DIR/models.yaml" URLS_FILE="$RECIPE_DIR/urls.txt" -CONFIG_DIR="$ROOT/config" +CONFIG_DIR="$ROOT/image/active" for f in "$RUNPOD_PROFILE" "$NODES_PROFILE" "$MODELS_PROFILE"; do [[ -f "$f" ]] || { echo "Missing: $f"; exit 1; } @@ -130,7 +130,7 @@ for m in models: models.extend(url_models) comfy_lock='\n'.join([ - '# Generated by Runpod_Comfy/tools/compile_profile.sh', + '# Generated by Runpod_Comfy/setup/tools/compile_profile.sh', f'RECIPE_ID={recipe_id}', f'BASE_IMAGE={base_image}', f'IMAGE_NAME={image_name}', diff --git a/Runpod_Comfy/tools/new_profile.sh b/Runpod_Comfy/setup/tools/new_profile.sh similarity index 83% rename from Runpod_Comfy/tools/new_profile.sh rename to Runpod_Comfy/setup/tools/new_profile.sh index 0d6337e..17eb1a7 100755 --- a/Runpod_Comfy/tools/new_profile.sh +++ b/Runpod_Comfy/setup/tools/new_profile.sh @@ -8,8 +8,8 @@ if [[ $# -lt 1 ]]; then fi ID="$1" -ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" -RECIPES="$ROOT/admin_recipes" +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +RECIPES="$ROOT/setup/recipes" EXAMPLES="$RECIPES/examples" TARGET="$RECIPES/$ID" @@ -39,4 +39,4 @@ fi echo echo "Next:" echo " 1) edit $TARGET/{runpod.yaml,nodes.yaml,models.yaml,urls.txt}" -echo " 2) Runpod_Comfy/tools/compile_profile.sh --id $ID" +echo " 2) Runpod_Comfy/setup/tools/compile_profile.sh --id $ID" From 85f18c5b3cfff6cf73dcfaf750b429e92710c168 Mon Sep 17 00:00:00 2001 From: kflame99 <261674183+kflame99@users.noreply.github.com> Date: Sun, 15 Feb 2026 11:09:16 +0000 Subject: [PATCH 11/13] Simplify setup area and relocate deploy/technical docs --- DECISIONS.md | 6 +++--- Runpod_Comfy/README.md | 6 +++--- .../docs/features/runpod_Container_REQUIRMENTS.md | 0 .../docs/references/github-repos_andOr_LINKS.md | 0 Runpod_Comfy/{setup/docs => image}/DEPLOY_RUNPOD.md | 0 Runpod_Comfy/setup/USER_README.md | 11 ++++++++--- 6 files changed, 14 insertions(+), 9 deletions(-) rename Runpod_Comfy/{setup => core}/docs/features/runpod_Container_REQUIRMENTS.md (100%) rename Runpod_Comfy/{setup => core}/docs/references/github-repos_andOr_LINKS.md (100%) rename Runpod_Comfy/{setup/docs => image}/DEPLOY_RUNPOD.md (100%) diff --git a/DECISIONS.md b/DECISIONS.md index 0dc98d4..3e2717d 100644 --- a/DECISIONS.md +++ b/DECISIONS.md @@ -26,9 +26,9 @@ ## 2026-02-15 — Recipe architecture for long-term readability - Use a 3-zone layout inside `Runpod_Comfy/`: - - `setup/` (operator-facing edits/docs/tools) - - `image/` (generated outputs + active locks) - - `core/` (runtime internals) + - `setup/` (operator-facing edits/tools; keep lightweight) + - `image/` (generated outputs + active locks + deploy runbook) + - `core/` (runtime internals + technical references) - Keep one recipe folder per image variant under `setup/recipes//`. - Compiler supports explicit args (`--id`, `--out`, `--image-tag`, `--no-activate`). - Default outputs go to `image/builds//` and can be activated to `image/active/`. diff --git a/Runpod_Comfy/README.md b/Runpod_Comfy/README.md index 9cb89f6..7ff8954 100644 --- a/Runpod_Comfy/README.md +++ b/Runpod_Comfy/README.md @@ -2,9 +2,9 @@ This module is organized in three top-level folders: -- `setup/` → operator-facing inputs/docs/tools -- `image/` → generated build artifacts and active lock set -- `core/` → runtime internals (docker/scripts) +- `setup/` → operator-facing inputs and helper tools +- `image/` → generated build artifacts, active lock set, and deploy runbook +- `core/` → runtime internals (docker/scripts) and technical references Start here: - `Runpod_Comfy/setup/USER_README.md` diff --git a/Runpod_Comfy/setup/docs/features/runpod_Container_REQUIRMENTS.md b/Runpod_Comfy/core/docs/features/runpod_Container_REQUIRMENTS.md similarity index 100% rename from Runpod_Comfy/setup/docs/features/runpod_Container_REQUIRMENTS.md rename to Runpod_Comfy/core/docs/features/runpod_Container_REQUIRMENTS.md diff --git a/Runpod_Comfy/setup/docs/references/github-repos_andOr_LINKS.md b/Runpod_Comfy/core/docs/references/github-repos_andOr_LINKS.md similarity index 100% rename from Runpod_Comfy/setup/docs/references/github-repos_andOr_LINKS.md rename to Runpod_Comfy/core/docs/references/github-repos_andOr_LINKS.md diff --git a/Runpod_Comfy/setup/docs/DEPLOY_RUNPOD.md b/Runpod_Comfy/image/DEPLOY_RUNPOD.md similarity index 100% rename from Runpod_Comfy/setup/docs/DEPLOY_RUNPOD.md rename to Runpod_Comfy/image/DEPLOY_RUNPOD.md diff --git a/Runpod_Comfy/setup/USER_README.md b/Runpod_Comfy/setup/USER_README.md index 24c9d79..ebf4826 100644 --- a/Runpod_Comfy/setup/USER_README.md +++ b/Runpod_Comfy/setup/USER_README.md @@ -2,9 +2,9 @@ This package is split into 3 readable zones: -- `setup/` → what you edit (recipes, docs, helper tools) -- `image/` → generated outputs (build artifacts + active locks) -- `core/` → runtime internals (Docker + bootstrap scripts) +- `setup/` → what you edit (recipes + helper tools) +- `image/` → generated outputs (build artifacts + active locks) + deploy runbook +- `core/` → runtime internals (Docker + bootstrap scripts + technical references) ## Quick Start @@ -55,6 +55,11 @@ docker build --build-arg BASE_IMAGE="$BASE_IMAGE" \ Runpod_Comfy/setup/tools/compile_profile.sh --id upscaler-v1 --no-activate ``` +## Deploy + +RunPod deploy runbook: +- `Runpod_Comfy/image/DEPLOY_RUNPOD.md` + ## Compiler args ```bash From a305a4fa36afc957ad2a80f48ca809cb24fe3ad8 Mon Sep 17 00:00:00 2001 From: kflame99 <261674183+kflame99@users.noreply.github.com> Date: Sun, 15 Feb 2026 11:17:00 +0000 Subject: [PATCH 12/13] Add context headers to moved technical reference docs --- .../core/docs/features/runpod_Container_REQUIRMENTS.md | 4 ++++ Runpod_Comfy/core/docs/references/github-repos_andOr_LINKS.md | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/Runpod_Comfy/core/docs/features/runpod_Container_REQUIRMENTS.md b/Runpod_Comfy/core/docs/features/runpod_Container_REQUIRMENTS.md index ade9a11..632b2d1 100644 --- a/Runpod_Comfy/core/docs/features/runpod_Container_REQUIRMENTS.md +++ b/Runpod_Comfy/core/docs/features/runpod_Container_REQUIRMENTS.md @@ -1,3 +1,7 @@ +# RunPod Container Requirements + +> Note: moved to `Runpod_Comfy/core/docs/features/` during the 3-zone refactor (`setup/image/core`) so technical references live under `core/`. + # Requirments: 1. Cuda 12.8 - 12.9 - should work with RTX pro 6000 and B200 gpus !!! diff --git a/Runpod_Comfy/core/docs/references/github-repos_andOr_LINKS.md b/Runpod_Comfy/core/docs/references/github-repos_andOr_LINKS.md index 29b0eef..53df15e 100644 --- a/Runpod_Comfy/core/docs/references/github-repos_andOr_LINKS.md +++ b/Runpod_Comfy/core/docs/references/github-repos_andOr_LINKS.md @@ -1,3 +1,7 @@ +# GitHub and Reference Links + +> Note: moved to `Runpod_Comfy/core/docs/references/` during the 3-zone refactor (`setup/image/core`) so technical references live under `core/`. + # Github - Links ### Runpod.io official - documentation From 2752a017174a99a86ea4202bfce637a515748472 Mon Sep 17 00:00:00 2001 From: kflame99 <261674183+kflame99@users.noreply.github.com> Date: Sun, 15 Feb 2026 11:28:04 +0000 Subject: [PATCH 13/13] Address review: restore registry files and fix lock/docs/tooling sync --- .github/workflows/publish.yml | 28 +++++++++++++++++++ CHANGELOG.md | 19 ++++++------- Runpod_Comfy/image/active/comfyui.lock | 4 ++- Runpod_Comfy/setup/tools/new_profile.sh | 9 ++++++- pyproject.toml | 36 +++++++++++++++++++++++++ 5 files changed, 85 insertions(+), 11 deletions(-) create mode 100644 .github/workflows/publish.yml create mode 100644 pyproject.toml diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..d7fbd80 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,28 @@ +name: Publish to Comfy registry +on: + workflow_dispatch: + push: + branches: + - main + - master + paths: + - "pyproject.toml" + +permissions: + issues: write + +jobs: + publish-node: + name: Publish Custom Node to registry + runs-on: ubuntu-latest + if: ${{ github.repository_owner == 'malkuthro' }} + steps: + - name: Check out code + uses: actions/checkout@v4 + with: + submodules: true + - name: Publish Custom Node + uses: Comfy-Org/publish-node-action@v1 + with: + ## Add your own personal access token to your Github Repository secrets and reference it here. + personal_access_token: ${{ secrets.REGISTRY_ACCESS_TOKEN }} diff --git a/CHANGELOG.md b/CHANGELOG.md index d724467..d1e43ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,15 +19,16 @@ The format is inspired by Keep a Changelog and SemVer. - `docs/RELEASE_NOTES_TEMPLATE.md` - RunPod_Comfy implementation scaffold: - `Runpod_Comfy/README.md` - - `Runpod_Comfy/docker/Dockerfile` - - `Runpod_Comfy/docker/start.sh` - - `Runpod_Comfy/scripts/bootstrap.sh` - - `Runpod_Comfy/scripts/install_custom_nodes.sh` - - `Runpod_Comfy/scripts/download_models.sh` - - `Runpod_Comfy/config/comfyui.lock` - - `Runpod_Comfy/config/custom_nodes.lock.json` - - `Runpod_Comfy/config/models.json` - - `Runpod_Comfy/docs/DEPLOY_RUNPOD.md` + - `Runpod_Comfy/setup/USER_README.md` + - `Runpod_Comfy/core/docker/Dockerfile` + - `Runpod_Comfy/core/docker/start.sh` + - `Runpod_Comfy/core/scripts/bootstrap.sh` + - `Runpod_Comfy/core/scripts/install_custom_nodes.sh` + - `Runpod_Comfy/core/scripts/download_models.sh` + - `Runpod_Comfy/image/active/comfyui.lock` + - `Runpod_Comfy/image/active/custom_nodes.lock.json` + - `Runpod_Comfy/image/active/models.json` + - `Runpod_Comfy/image/DEPLOY_RUNPOD.md` ## [0.1.0] - 2026-02-14 diff --git a/Runpod_Comfy/image/active/comfyui.lock b/Runpod_Comfy/image/active/comfyui.lock index f493005..6afeb27 100644 --- a/Runpod_Comfy/image/active/comfyui.lock +++ b/Runpod_Comfy/image/active/comfyui.lock @@ -1,5 +1,7 @@ # Generated by Runpod_Comfy/setup/tools/compile_profile.sh -PROFILE_ID=example +RECIPE_ID=example BASE_IMAGE=runpod/pytorch:2.6.0-py3.11-cuda12.4.1-devel-ubuntu22.04 +IMAGE_NAME=ghcr.io/your-user/comfyui-koolook +RUNPOD_IMAGE_TAG=upscaler-v1.0.0 COMFYUI_REPO=https://github.com/comfyanonymous/ComfyUI.git COMFYUI_REF=master diff --git a/Runpod_Comfy/setup/tools/new_profile.sh b/Runpod_Comfy/setup/tools/new_profile.sh index 17eb1a7..84da873 100755 --- a/Runpod_Comfy/setup/tools/new_profile.sh +++ b/Runpod_Comfy/setup/tools/new_profile.sh @@ -22,7 +22,14 @@ for kind in runpod nodes models; do echo "[skip] exists: $dst" else cp "$src" "$dst" - sed -i "s/^profile_id: .*/profile_id: ${ID}/" "$dst" || true + python3 - "$dst" "$ID" <<'PY' +from pathlib import Path +import re, sys +p=Path(sys.argv[1]); rid=sys.argv[2] +t=p.read_text(encoding='utf-8') +t=re.sub(r'^profile_id:\s*.*$', f'profile_id: {rid}', t, flags=re.M) +p.write_text(t, encoding='utf-8') +PY echo "[new] $dst" fi done diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..fac1533 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,36 @@ +[project] +name = "koolook" +description = "This repository provides custom nodes for ComfyUI tailored for VFX and AI image/video generation workflows" +version = "1.0.1" +license = {file = "LICENSE"} +# classifiers = [ +# # For OS-independent nodes (works on all operating systems) +# "Operating System :: OS Independent", +# +# # OR for OS-specific nodes, specify the supported systems: +# "Operating System :: Microsoft :: Windows", # Windows specific +# "Operating System :: POSIX :: Linux", # Linux specific +# "Operating System :: MacOS", # macOS specific +# +# # GPU Accelerator support. Pick the ones that are supported by your extension. +# "Environment :: GPU :: NVIDIA CUDA", # NVIDIA CUDA support +# "Environment :: GPU :: AMD ROCm", # AMD ROCm support +# "Environment :: GPU :: Intel Arc", # Intel Arc support +# "Environment :: NPU :: Huawei Ascend", # Huawei Ascend support +# "Environment :: GPU :: Apple Metal", # Apple Metal support +# ] + + +[project.urls] +Repository = "https://github.com/malkuthro/ComfyUI-Koolook" +# Used by Comfy Registry https://registry.comfy.org +Documentation = "https://github.com/malkuthro/ComfyUI-Koolook/wiki" +"Bug Tracker" = "https://github.com/malkuthro/ComfyUI-Koolook/issues" + +[tool.comfy] +PublisherId = "CristianP" +DisplayName = "ComfyUI-Koolook" +Icon = "" +includes = [] +# "requires-comfyui" = ">=1.0.0" # ComfyUI version compatibility +