# Deploying on Unraid The reference deployment: an Unraid server ("GPU Node") acting as the GPU compute node, with the control plane either on the same host or elsewhere. For the general procedure see [INSTALLATION.md](INSTALLATION.md). This page is only what is different about Unraid. ## Paths Unraid's container-local storage does not survive an update. Everything ModelForge must keep goes on `appdata` or an array share: | What | Where | Why | | --- | --- | --- | | Agent identity | `/mnt/user/appdata/modelforge/agent-state` | A node that loses its identity re-enrols as a different node | | Verified artifacts | `/mnt/user/appdata/modelforge/artifacts` | Large, and re-acquisition is expensive | | Quarantine | `/mnt/user/appdata/modelforge/quarantine` | Holds artifacts mid-verification | | Hugging Face cache | `/mnt/user/appdata/modelforge/hf-cache` | Avoids repeated downloads | | Backups | an array share, ideally a different disk from the database | A backup on the disk it protects is not a backup | Set them through `MODELFORGE_AGENT_STATE_VOLUME`, `MODELFORGE_AGENT_ARTIFACT_VOLUME`, `MODELFORGE_AGENT_QUARANTINE_VOLUME`, `MODELFORGE_AGENT_HF_CACHE_VOLUME` and `MODELFORGE_BACKUP_VOLUME` — all of them accept an absolute bind path as well as a volume name. **Do not point the backup destination at the same disk as the PostgreSQL data directory.** ## GPU The NVIDIA plugin and the NVIDIA container runtime must both be present. The Runtime Worker needs device access: ```bash docker compose -f docker-compose.yml -f docker-compose.gpu.yml \ -f docker-compose.runtime-worker.yml up -d runtime-worker ``` ## External GPU workloads An Unraid box usually runs other things that want VRAM — Ollama, Plex transcoding, Tdarr. ModelForge **observes** that usage and counts it as external pressure in its admission decisions. It never reclaims it: it will not stop, pause, throttle or reconfigure a workload it does not own, and it has no mechanism to do so. The practical consequence: if Plex starts a transcode, ModelForge may begin refusing placements with `CAPACITY_CONSTRAINED`. That is the intended behaviour. Size your GPU for the sum of what you run, or accept that the two compete. ## Networking The agent is outbound-only, so GPU Node needs to reach the control plane and the control plane needs no route to GPU Node. If the control plane runs elsewhere behind a private CA, use the private-CA overlay rather than disabling TLS verification — see [NODE_AGENT.md](NODE_AGENT.md). ## Updates An Unraid OS update restarts containers. Nothing here depends on container-local state, so a node comes back with the same identity — provided the state volume is on `appdata` as above. Set `MODELFORGE_NODE_AGENT_IMAGE=modelforge-node-agent:1.1.1` (or the published digest) before a release deployment. Compose keeps the optional local `build:` path, but production should run the immutable released image and verify its OCI revision after recreation. ## Scheduled backups M15 delivered scheduled backups; enabling them on GPU Node is an operator action, not something the release does for you. `scripts/modelforge_scheduled_backup.sh` is the entry point. Verify one execution after enabling, and check the recovery dashboard shows a recent verified backup.