Make ai-stack the only deployment shape

Drops the duplicate standalone compose / .env.example / SETUP.md at the
repo root. Bring-up content folded into deployments/ai-stack/README.md
so there's exactly one set of deployment instructions, sitting next to
the files it describes. Root README is now just the repo overview and a
pointer at the deployment.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
57_WolveandClaude Opus 4.7 committed 2026-04-19 10:45:23 -05:00
1 parent b1c9bff15f
commit 97547c783c
5 files changed
+173 -333

No files matched your search

+151 -29
View File
@@ -1,12 +1,12 @@
# ai-stack — combined deployment example
# ai-stack — deployment
The full multi-service stack: Caddy (TLS + reverse proxy) in front of Open
WebUI (chat + image generation panel), Ollama (LLMs), and ComfyUI (image
generation), with an optional Anubis PoW anti-bot sidecar. One GPU host,
one bridge network, one TLS entry point.
This is what runs in production for the `srvno.de` deployment, sanitized
for sharing.
This is the only supported deployment shape — sanitized snapshot of the
production `srvno.de` deployment.
## Files
@@ -17,43 +17,165 @@ for sharing.
| `init-models.sh` | Models to preseed into Ollama on first boot |
| `.env.example` | Secrets and image-tag pins. Copy to `.env` |
## Bring it up
## 1. Host prerequisites
- Linux (or WSL2) with an NVIDIA GPU and a recent driver.
- cu126 wheels (default Dockerfile): driver >= 545
- cu130 wheels (swap in Dockerfile): driver >= 580
- Docker Engine + Compose v2.
- [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html)
installed and the Docker runtime configured (`nvidia-ctk runtime configure
--runtime=docker && systemctl restart docker`).
- DNS for the chat / ComfyUI hostnames already pointing at this host
(Caddy needs working DNS to provision Let's Encrypt certs on first boot).
Confirm GPU passthrough works before bringing the stack up:
```sh
docker run --rm --gpus all nvidia/cuda:12.6.3-base-ubuntu24.04 nvidia-smi
```
## 2. Configure
```sh
cp .env.example .env
# edit .env — generate the two keys with `openssl rand -hex 32`
# generate the two keys with: openssl rand -hex 32
```
# edit Caddyfile — replace example.com hostnames with yours, replace the
# basic_auth bcrypt placeholder, point DNS at this host
Then edit:
# edit init-models.sh — keep the models you want, drop the rest
- **`.env`** — fill in `WEBUI_SECRET_KEY` and (if using Anubis) `ANUBIS_OWUI_KEY`.
Optionally pin `COMFYUI_IMAGE_TAG` to a specific `v*` release instead of
`latest`.
- **`Caddyfile`** — replace the `chat.example.com` and `comfyui.example.com`
hostnames with yours; replace `REPLACE_WITH_BCRYPT_HASH` with a real
bcrypt hash:
```sh
docker run --rm caddy:latest caddy hash-password --plaintext 'your-password'
```
- **`init-models.sh`** — keep the LLMs you want preseeded, drop the rest.
Check sizes at <https://ollama.com/library> first; the host needs disk
for everything listed.
- **`docker-compose.yml`** — update `WEBUI_URL` and `COOKIE_DOMAIN` to
match the hostnames you set in the Caddyfile.
## 3. Bring it up
```sh
docker compose up -d
docker compose logs -f
```
First boot: Caddy provisions Let's Encrypt certs (DNS must already point
here), the model-init container pulls the LLMs listed in `init-models.sh`
(can take a while — `mistral-nemo:12b` is ~7 GB), and ComfyUI initialises
its volumes empty. Drop a checkpoint into the `comfyui-models` volume
under `checkpoints/` before the first image generation — see the repo
root [SETUP.md](../../SETUP.md) §4.
First boot: Caddy provisions Let's Encrypt certs, the `model-init`
container pulls the LLMs in `init-models.sh` (slow — `mistral-nemo:12b`
alone is ~7 GB), and ComfyUI initialises empty volumes.
After Open WebUI is up, finish the ComfyUI integration via the admin
panel — paste the four workflow JSONs from [`../../workflows/`](../../workflows/).
See [SETUP.md §6](../../SETUP.md).
Health-check:
## What's different from the upstream `comfyui-nvidia` standalone compose
```sh
docker compose exec comfyui curl -sf http://127.0.0.1:8188/system_stats | head -c 200
docker compose exec open-webui curl -sf http://127.0.0.1:8080/health
```
The standalone compose at the repo root is just `comfyui` + `open-webui`
on a fresh bridge — meant for kicking the tyres or running ComfyUI on a
single-purpose box. This deployment adds:
## 4. Drop in at least one ComfyUI checkpoint
- **Caddy** with auto-TLS, so Open WebUI and ComfyUI are reachable on
real hostnames over HTTPS instead of `localhost:3000`.
- **Ollama** for chat models, with a one-shot `model-init` puller that
preseeds whatever `init-models.sh` lists.
- **Anubis** anti-bot stub for protected hostnames (commented in by
default; uncomment + provide a key to activate).
- No host ports published for ComfyUI or Open WebUI — Caddy is the only
service bound to 80/443.
ComfyUI ships no models. The shipped workflow templates reference
`v1-5-pruned-emaonly.safetensors` as a placeholder; drop any
SD/SDXL/Flux checkpoint into the `comfyui-models` volume under
`checkpoints/`:
```sh
docker run --rm -v ai-stack_comfyui-models:/models -w /models/checkpoints \
curlimages/curl:latest -L -O \
https://huggingface.co/runwayml/stable-diffusion-v1-5/resolve/main/v1-5-pruned-emaonly.safetensors
```
Or open the ComfyUI native UI at `https://comfyui.example.com` (after
basic-auth login), use the **Manager** button (added by ComfyUI-Manager),
and install one through **Model Manager**.
## 5. First-user signup in Open WebUI
Open `https://chat.example.com`. The first account created becomes the
admin. Subsequent signups land in `pending` and need admin approval (set
by `DEFAULT_USER_ROLE: pending` in compose).
## 6. Wire Open WebUI to ComfyUI
Open WebUI ships the ComfyUI integration but won't know which workflow to
submit until you paste one in. Do this once for txt2img, once for img2img.
In Open WebUI: **Admin Panel -> Settings -> Images**.
1. **Image Generation Engine** -> `ComfyUI` (preselected via env var).
2. **ComfyUI Base URL** -> `http://comfyui:8188` (preselected).
3. **ComfyUI Workflow** -> paste the entire contents of
[`../../workflows/txt2img.json`](../../workflows/txt2img.json).
4. **ComfyUI Workflow Nodes** -> paste the contents of
[`../../workflows/txt2img.nodes.json`](../../workflows/txt2img.nodes.json).
5. **Default Model** -> the filename of the checkpoint you dropped in
step 4 (e.g. `v1-5-pruned-emaonly.safetensors`).
6. Save.
For image editing (img2img), scroll to the **Image Editing** section in
the same panel and repeat with
[`../../workflows/img2img.json`](../../workflows/img2img.json) and
[`../../workflows/img2img.nodes.json`](../../workflows/img2img.nodes.json).
## 7. Test it
In any chat, click the image-generation button and prompt for an image.
Open WebUI submits the workflow to ComfyUI; the result drops back into
the chat when KSampler finishes. To test img2img, attach an image and
use the edit action.
## Enabling Anubis (later)
The `anubis-owui` service is defined in compose but no Caddy site block
points at it yet. To activate:
1. Generate a key: `openssl rand -hex 32` and set `ANUBIS_OWUI_KEY` in `.env`.
2. In `Caddyfile`, change `reverse_proxy open-webui:8080` to
`reverse_proxy anubis-owui:8923` for the chat hostname.
3. `docker compose up -d`.
## How the workflow node mappings work
Open WebUI doesn't introspect the workflow graph. The `*.nodes.json`
files tell it which node IDs and input fields to overwrite when the user
provides a prompt, image, seed, etc. Each entry:
```json
{ "type": "<placeholder>", "node_ids": ["<id>"], "key": "<input field>" }
```
Recognised `type` strings (per Open WebUI source): `model`, `prompt`,
`negative_prompt`, `width`, `height`, `n` (batch size), `steps`, `seed`,
and `image` (img2img / edit only).
If you swap in a fancier workflow (SDXL, Flux, ControlNet, custom
samplers, NL masking via SAM nodes, etc.), update the matching
`*.nodes.json` so the node IDs and input keys still line up.
## Common gotchas
- **"Model not found" in Open WebUI's image panel.** ComfyUI lists
models from `/opt/comfyui/models/checkpoints/`. Confirm the file is
there and that **Default Model** matches the filename exactly
(including extension).
- **Out-of-memory on first generate.** Lower `IMAGE_SIZE` in compose
(e.g. `768x768`) or pass `--lowvram` / `--medvram` in the Dockerfile
CMD and rebuild.
- **Custom nodes need extra pip packages.** Install via ComfyUI-Manager
(it pip-installs into the container's venv). The `custom_nodes`
volume persists, but `/opt/venv` does not — so packages installed by
the manager survive container restarts only because the manager
re-installs them on boot. For permanent custom-node deps, add a
`RUN pip install …` to the Dockerfile and rebuild.
- **GPU not visible inside container.** Re-run the `nvidia-smi` test in
step 1. If it fails, the toolkit is misconfigured.
- **Caddy can't get a cert.** First-boot ACME requires DNS A/AAAA
records pointing at this host's public IP and ports 80+443 reachable
from the internet. Check `docker compose logs caddy` for the specific
challenge failure.