vor: stack + playbook + workflow template for ana-docker deploy

Same shape as task-board: build-on-host from vh/vor, bind-mounted
persistence for sessions/ and responses/ (the user-published markdown
files), exposed at port 7879 (adjacent to task-board's 7878 since both
are claude-tooling sidecars).

Workflow template assumes the same DEPLOY_SSH_KEY + MGMT_REPO_TOKEN
secrets at user scope; nothing new to provision. Playbook accepts SHA
or branch refs (same fix as deploy-task-board.yaml) so manual runs
and CI runs share the same code path.

Centralized vs upstream-local: README documents the trade. Claude
fetches response markdown via /api/sessions/{id} JSON instead of a
local file read — the only API-flow change from the upstream README.
This commit is contained in:
vh
2026-04-29 21:31:59 -07:00
parent f44a1d1c02
commit a61b577c59
5 changed files with 300 additions and 0 deletions
+13
View File
@@ -0,0 +1,13 @@
# Built locally from vh/vor by the deploy playbook; not pulled from a registry.
VOR_IMAGE=vor:local
# Host port. Adjacent to task-board's 7878 since both are claude-tooling
# sidecars; keep them grouped for muscle memory.
VOR_PORT=7879
VOR_BIND=0.0.0.0
# Persistence — sessions/ holds Claude's posted markdown,
# responses/ holds the user's published response markdown. Both are
# bind-mounted so they survive `docker compose up --force-recreate`.
VOR_SESSIONS_DIR=/opt/docker/conf/vor/sessions
VOR_RESPONSES_DIR=/opt/docker/conf/vor/responses
+61
View File
@@ -0,0 +1,61 @@
# vor
[Inquisitor UI](https://gitea.phasefinal.com/vh/vor) deployed centrally.
A FastAPI sidecar that renders Claude's `/inquisitor` markdown as a
fillable form — Claude POSTs sessions, user fills + publishes via
browser, Claude reads the response back.
**Server:** ana-docker
**Port:** 7879 (configurable via `.env`)
**Upstream repo:** [vh/vor](https://gitea.phasefinal.com/vh/vor)
**Image:** `vor:local` — built on the host from the git repo by the
deploy playbook. Not pulled from a registry.
## Centralized vs local
The upstream README describes a **local** deployment pattern (Claude
on the workstation posts to `127.0.0.1:8765`, response file lives on
the local filesystem). Running vor on ana-docker changes that:
- Claude POSTs to `http://10.250.50.70:7879/api/sessions`
- The browser opens `http://10.250.50.70:7879/?session=<id>`
- The response markdown is **not** written to a path Claude can read
off its own disk; Claude reads it back via
`GET /api/sessions/{id}` (`response_markdown` field) instead.
Trade: central + always-on + multi-device (phone, tablet, second
workstation) at the cost of a network round-trip and an HTTP-fetch
step in Claude's flow instead of a file read.
## Deploy
Two paths — automated (preferred) and manual.
### Automated (Gitea Actions, push-to-main)
Every push to `main` on `vh/vor` triggers a deploy via the central
gitea-runner. Workflow template lives next to this README at
[`gitea-workflow-deploy.yaml.example`](gitea-workflow-deploy.yaml.example);
copy into the vor repo at `.gitea/workflows/deploy.yaml` (already
done on first wiring). Reuses the `DEPLOY_SSH_KEY` and
`MGMT_REPO_TOKEN` secrets at user scope; no per-repo setup needed
once those exist.
### Manual (elway from a workstation)
```bash
# First deploy / update to latest main
scripts/elway ana-docker --playbook playbooks/deploy-vor.yaml
# Pin to a specific ref
scripts/elway ana-docker --playbook playbooks/deploy-vor.yaml --var ref=v0.2.0
```
## Path layout (on ana-docker)
| Host path | Container path | Purpose | Restic? |
|---|---|---|---|
| `/opt/docker/build/vor/` | — | git checkout used as docker build context | excluded |
| `/opt/docker/compose/vor/` | — | compose.yaml + .env | included (via `/opt/docker`) |
| `/opt/docker/conf/vor/sessions/` | `/app/sessions` | Claude-posted markdown | **included** |
| `/opt/docker/conf/vor/responses/` | `/app/responses` | user-published response markdown | **included** |
+45
View File
@@ -0,0 +1,45 @@
# vor — Inquisitor UI sidecar.
#
# Image is built on the host from the vor git repo by the deploy
# playbook (`playbooks/deploy-vor.yaml`), which clones into
# /opt/docker/build/vor and runs `docker build -t vor:local .` before
# installing this compose and bringing it up.
#
# Sessions + responses persist under bind mounts so container rebuilds
# don't lose user-published response files (which Claude reads via the
# /api/sessions/{id} JSON path).
#
# All tunables live in .env — edit that, not this file.
services:
vor:
image: ${VOR_IMAGE}
container_name: vor
restart: unless-stopped
ports:
- "${VOR_BIND:-0.0.0.0}:${VOR_PORT}:8765"
volumes:
- ${VOR_SESSIONS_DIR}:/app/sessions
- ${VOR_RESPONSES_DIR}:/app/responses
environment:
# Container always listens on 8765 internally; host port is the only knob.
- PYTHONUNBUFFERED=1
healthcheck:
test: ["CMD-SHELL", "python -c 'import urllib.request,sys; r=urllib.request.urlopen(\"http://127.0.0.1:8765/api/sessions\",timeout=3); sys.exit(0 if r.status==200 else 1)' || exit 1"]
interval: 30s
timeout: 5s
retries: 3
start_period: 10s
networks:
- tnet
labels:
- homepage.group=Toolchain
- homepage.name=vor
- homepage.icon=mdi-clipboard-text-search
- homepage.description=Inquisitor UI — Claude session ↔ user response sidecar
- homepage.href=http://10.250.50.70:${VOR_PORT}
networks:
tnet:
name: traefik-net
external: true
@@ -0,0 +1,65 @@
# Gitea Actions workflow for vor.
#
# THIS FILE LIVES IN THE VOR REPO, NOT HERE.
# Copy to vh/vor:.gitea/workflows/deploy.yaml and commit.
#
# Identical pattern to stacks/task-board/gitea-workflow-deploy.yaml.example
# — checks out vor + eshpfi-management, then runs the elway playbook
# pinned to the triggering commit SHA. The playbook is the single
# source of truth for "how vor is deployed", manual or automated.
#
# Required Actions secrets (already set at user scope from earlier
# task-board wiring; nothing new needed):
#
# DEPLOY_SSH_KEY Private SSH key authorized for lkraven@ana-docker.
# MGMT_REPO_TOKEN Gitea PAT (read:repository) on vh/esh-pfi-infrastructure.
name: Deploy vor
on:
push:
branches: [main]
workflow_dispatch:
jobs:
deploy:
runs-on: pfi-fleet
steps:
- name: Install playbook prerequisites
run: |
apt-get update -qq
apt-get install -y --no-install-recommends \
python3 python3-yaml openssh-client
rm -rf /var/lib/apt/lists/*
- name: Checkout vor (triggering repo)
uses: actions/checkout@v4
- name: Checkout management repo (eshpfi-management)
uses: actions/checkout@v4
with:
repository: vh/esh-pfi-infrastructure
token: ${{ secrets.MGMT_REPO_TOKEN }}
path: _mgmt
- name: Configure SSH to ana-docker
run: |
mkdir -p ~/.ssh
printf '%s\n' "${{ secrets.DEPLOY_SSH_KEY }}" > ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519
cat > ~/.ssh/config <<'EOF'
Host ana-docker
HostName 10.250.50.70
User lkraven
IdentityFile ~/.ssh/id_ed25519
StrictHostKeyChecking accept-new
EOF
chmod 600 ~/.ssh/config
- name: Deploy vor (elway playbook, pinned to this commit)
working-directory: _mgmt
run: |
scripts/elway ana-docker \
--playbook playbooks/deploy-vor.yaml \
--var ref=${{ github.sha }}