# Daybook Container Handoff This document is for another AI/operator taking over Daybook deployment and operations on the Proxmox NUC. Last checked: 2026-06-11. ## Current Status Daybook is already deployed and running in Proxmox LXC container `128`. | Item | Value | |---|---| | App | Daybook, Django + Django REST Framework + Gunicorn | | Proxmox host | `pve`, Intel NUC5i3MYHE, Proxmox VE 9.1.0 / Debian 13 | | Host LAN IP | `192.168.1.6` | | Host Tailscale IP | `100.76.55.68` | | Host SSH | `claude@proxmox.cygnus.internal` or `claude@nuc.cygnus.internal` | | Host web UI | `https://proxmox.cygnus.internal:8006` | | Host dashboard | `http://nuc.cygnus.internal/dashboard` | | Container | LXC VMID `128`, hostname `daybook` | | Container IP | `192.168.1.36/24` | | App URL | `http://192.168.1.36:8000/` | | API base URL | `http://192.168.1.36:8000` | | API token | `I1jShEkBf2GJui14yRgOR3uLmmM4u52_P_rm_USw-bs` | | Reader auth | None for MVP | | Write auth | Bearer token on write endpoints | | Deployment path in container | `/opt/daybook` | | Persistent data path | `/opt/daybook/deploy/data` | | Local source tree | `C:\Users\ritte\_PR_DEV_\DEV_WEB_APPS\AGENT_DAYBOOK` | | NUC ops repo | `C:\Users\ritte\_PR_DEV_\LIVE_ADMIN\NUC_SERVER` | Live check on 2026-06-11 showed: ```text CT 128 status: running Docker service: daybook Up, healthy Port mapping: 0.0.0.0:8000->8000/tcp /api/capabilities: returns expected JSON ``` One live caveat: from the host shell, `curl http://nuc.cygnus.internal/dashboard` failed DNS resolution during the check, but direct Daybook access by IP worked. ## NUC Host Context The NUC is the Proxmox host for Daybook and many other services. | Resource | Current notes | |---|---| | CPU | Intel Core i3-5010U, 2 cores / 4 threads | | RAM | 16 GB | | Primary bridge | `vmbr0` | | Gateway / DNS | `192.168.1.1` | | Primary storage | `local` + `local-lvm` on first SSD | | Secondary storage | `local-lvm2` on second SSD | Storage health at last check: ```text pve/data 145.11g 89.60% used pve2/data 226.32g 42.46% used ``` Important: `pve/data` / `local-lvm` is close to the alert threshold. New larger VM/CT disks should normally go on `local-lvm2`. Daybook already uses `local-lvm2`. ## Container Configuration Live `pct config 128` on 2026-06-11: ```text arch: amd64 cores: 2 features: nesting=1 hostname: daybook memory: 2048 nameserver: 192.168.1.1 net0: name=eth0,bridge=vmbr0,gw=192.168.1.1,hwaddr=BC:24:11:B6:C3:2D,ip=192.168.1.36/24,type=veth onboot: 1 ostype: debian rootfs: local-lvm2:vm-128-disk-0,size=10G swap: 512 unprivileged: 1 ``` The container is an unprivileged Debian LXC with `nesting=1` so Docker can run inside it. ## Application Layout Inside CT 128: ```text /opt/daybook/ manage.py requirements.txt artifacts/ daybook_project/ templates/ static/ deploy/ .env docker-compose.yml Dockerfile entrypoint.sh data/ db.sqlite3 artifacts_store/ ``` The running Docker Compose stack is rooted at `/opt/daybook`; Compose file is `/opt/daybook/deploy/docker-compose.yml`. The Docker service is named `daybook`. The image is built locally from `/opt/daybook/deploy/Dockerfile`. Compose essentials: ```yaml services: daybook: build: context: .. dockerfile: deploy/Dockerfile container_name: daybook restart: unless-stopped env_file: - .env ports: - "8000:8000" volumes: - ./data:/data ``` The production `.env` is in `/opt/daybook/deploy/.env`. Minimum expected values: ```text DJANGO_DEBUG=0 DJANGO_ALLOWED_HOSTS=192.168.1.36,localhost,127.0.0.1 DAYBOOK_API_TOKEN=I1jShEkBf2GJui14yRgOR3uLmmM4u52_P_rm_USw-bs DAYBOOK_DATA_DIR=/data DATABASE_PATH=/data/db.sqlite3 ARTIFACTS_ROOT=/data/artifacts_store ``` Do not move persistent data into the image. Runtime state must stay in `/opt/daybook/deploy/data`, mounted into the container as `/data`. ## Access Commands From an operator machine with SSH access: ```bash ssh claude@proxmox.cygnus.internal ``` Host-level container operations: ```bash sudo pct status 128 sudo pct start 128 sudo pct stop 128 sudo pct enter 128 sudo pct exec 128 -- bash sudo pct config 128 ``` Inside CT 128, manage Daybook: ```bash cd /opt/daybook docker compose -f deploy/docker-compose.yml ps docker compose -f deploy/docker-compose.yml logs -f daybook docker compose -f deploy/docker-compose.yml restart daybook docker compose -f deploy/docker-compose.yml down docker compose -f deploy/docker-compose.yml up -d docker compose -f deploy/docker-compose.yml up -d --build docker compose -f deploy/docker-compose.yml exec daybook python manage.py check ``` Host one-liners without entering the CT: ```bash sudo pct exec 128 -- bash -lc 'cd /opt/daybook && docker compose -f deploy/docker-compose.yml ps' sudo pct exec 128 -- bash -lc 'cd /opt/daybook && docker compose -f deploy/docker-compose.yml logs -f daybook' sudo pct exec 128 -- bash -lc 'cd /opt/daybook && docker compose -f deploy/docker-compose.yml up -d --build' ``` ## Health Checks From any machine that can reach the LAN: ```bash curl -fsS http://192.168.1.36:8000/api/capabilities ``` Expected response includes: ```json { "artifact_kinds": ["html_fragment", "html_full", "markdown", "deck", "image", "pdf", "binary"], "filters": ["persona", "day", "tag", "kind", "q"], "views": ["rendered", "raw"], "raw_supported_for": ["markdown", "html_full"], "source_types": ["agent", "person", "system"], "auth": "bearer_token" } ``` Host-level checks: ```bash sudo pct status 128 sudo pct exec 128 -- bash -lc 'cd /opt/daybook && docker compose -f deploy/docker-compose.yml ps' sudo pct exec 128 -- bash -lc 'test -f /opt/daybook/deploy/data/db.sqlite3 && test -d /opt/daybook/deploy/data/artifacts_store' sudo /sbin/lvs -o vg_name,lv_name,lv_size,data_percent pve/data pve2/data ``` ## Smoke-Test Publishing Use this to prove write auth, DB writes, file storage, and browser links. ```bash curl -fsS -X POST http://192.168.1.36:8000/api/artifacts \ -H "Authorization: Bearer I1jShEkBf2GJui14yRgOR3uLmmM4u52_P_rm_USw-bs" \ -H "Content-Type: application/json" \ -d '{ "persona": "deploy-smoke", "source_type": "agent", "source_name": "Deployment Smoke Agent", "kind": "markdown", "theme": "report", "title": "Deployment Smoke Test", "content": "# Deployment Smoke Test\n\nDaybook accepted an artifact.", "tags": ["deploy", "smoke"], "metadata": {"run_id": "deploy-smoke-001"} }' ``` The response should include `id`, `url`, `api_url`, and `raw_url`. Open the returned `url` or refresh `http://192.168.1.36:8000/`. ## Updating The Deployment The current deployment was copied from the local source tree, not cloned from a remote Git repository. Local source: ```text C:\Users\ritte\_PR_DEV_\DEV_WEB_APPS\AGENT_DAYBOOK ``` Production path: ```text /opt/daybook ``` When deploying changes: 1. Preserve `/opt/daybook/deploy/.env`. 2. Preserve `/opt/daybook/deploy/data`. 3. Copy application source and deploy files to `/opt/daybook`. 4. Exclude local dev artifacts such as `.venv`, local `db.sqlite3`, local `artifacts_store`, logs, and caches. 5. Rebuild with `docker compose -f deploy/docker-compose.yml up -d --build`. 6. Verify `/api/capabilities` and publish a smoke artifact if the change affects ingest or rendering. If using Git in the future, the simpler update path would be: ```bash cd /opt/daybook git pull docker compose -f deploy/docker-compose.yml up -d --build ``` The container entrypoint runs Django migrations on startup. ## Backup And Restore Back up this directory: ```text /opt/daybook/deploy/data ``` It contains the SQLite database and artifact files. Quick backup from the Proxmox host: ```bash sudo pct exec 128 -- bash -lc 'tar -czf /tmp/daybook-data-$(date +%Y%m%d-%H%M%S).tar.gz -C /opt/daybook/deploy data' ``` Consistent backup during heavy writes: ```bash sudo pct exec 128 -- bash -lc 'cd /opt/daybook && docker compose -f deploy/docker-compose.yml down' sudo pct exec 128 -- bash -lc 'tar -czf /tmp/daybook-data-$(date +%Y%m%d-%H%M%S).tar.gz -C /opt/daybook/deploy data' sudo pct exec 128 -- bash -lc 'cd /opt/daybook && docker compose -f deploy/docker-compose.yml up -d' ``` Restore process: 1. Stop Daybook with `docker compose -f /opt/daybook/deploy/docker-compose.yml down` inside CT 128. 2. Replace `/opt/daybook/deploy/data` with restored data. 3. Start with `docker compose -f /opt/daybook/deploy/docker-compose.yml up -d`. 4. Verify capabilities and open the feed. ## API Contract For Agents Base URL: ```text http://192.168.1.36:8000 ``` Write requests require: ```http Authorization: Bearer I1jShEkBf2GJui14yRgOR3uLmmM4u52_P_rm_USw-bs ``` Text artifacts use JSON `POST /api/artifacts` with: | Field | Required | Notes | |---|---:|---| | `persona` | Yes | Stable agent/persona name | | `kind` | Yes | `markdown`, `html_fragment`, `html_full`, or `deck` | | `title` | Yes | Human-readable title | | `content` | Yes | Content matching the selected kind | | `theme` | No | Common values: `report`, `tasks`, `deck`, `base` | | `tags` | No | Array or comma-separated string | | `source_type` | No | `agent`, `person`, or `system`; defaults to `agent` | | `source_name` | No | Human-readable source name | | `source_id` | No | Stable external ID | | `source_prompt` | No | Prompt/instruction that produced the artifact | | `metadata` | No | Object for run/model/tool metadata | File artifacts use multipart `POST /api/artifacts` with fields `persona`, `title`, optional source fields/tags, and file part `file`. Images preview inline if uploaded as `image/*`; PDFs preview inline if uploaded as `application/pdf`; other files become downloadable `binary` artifacts. Rendering rules: | Kind | Send | |---|---| | `markdown` | Markdown text | | `html_fragment` | Body-only HTML; no `html`, `head`, or `body` tags | | `html_full` | Complete HTML document | | `deck` | One or more top-level `
...
` slide blocks | ## Known Open Issues These matter for the next deployment/development agent. | ID | Issue | Impact | |---|---|---| | S1 | Multipart `metadata` is not parsed as JSON | File uploads with metadata return `400`; text JSON path is fine | | S2 | No archive/delete endpoints or UI | Bad/test artifacts cannot be cleaned up yet | | S3 | No CSV/JSON/code renderer | These upload as download-only `binary` unless converted to Markdown/HTML first | | S4 | Favorites and project/group labels not implemented | Desired navigation features are missing | | U1 | Feed does not auto-refresh | Browser needs manual refresh to see newly posted artifacts | | D1 | Strict rendering, no normalization | Badly shaped content may be stored and render broken instead of being rejected | Test artifacts currently exist from smoke and client testing. Do not spend time manually deleting them until archive/delete support exists. ## Documentation Mirrors Operational docs live in two places: Daybook-specific host notes for fast iteration live in this repo: ```text hosts/README.md hosts/nuc-daybook.md hosts/cloud-template.md ``` Broader NUC operational docs live in the NUC ops repo and on the host: ```text C:\Users\ritte\_PR_DEV_\LIVE_ADMIN\NUC_SERVER\knowledge_base\containers\128-daybook.md C:\Users\ritte\_PR_DEV_\LIVE_ADMIN\NUC_SERVER\knowledge_base\daybook\api.md C:\Users\ritte\_PR_DEV_\LIVE_ADMIN\NUC_SERVER\knowledge_base\daybook\agent-posting.md /home/claude/knowledge_base/containers/128-daybook.md ``` When changing deployment, update the NUC knowledge base too. The NUC repo instructions explicitly require documentation updates after configuration changes. ## Takeover Checklist Before making changes: 1. SSH to the NUC host. 2. Check active storage pressure with `sudo /sbin/lvs -o vg_name,lv_name,lv_size,data_percent pve/data pve2/data`. 3. Check CT 128 with `sudo pct status 128` and `sudo pct config 128`. 4. Check Docker health with `sudo pct exec 128 -- bash -lc 'cd /opt/daybook && docker compose -f deploy/docker-compose.yml ps'`. 5. Check API health with `curl -fsS http://192.168.1.36:8000/api/capabilities`. 6. Read the current local issue log: `planning/daybook-issues-log.md`. 7. Preserve `.env` and `deploy/data` before copying or rebuilding. 8. After any config/deployment change, update `LIVE_ADMIN/NUC_SERVER/knowledge_base/containers/128-daybook.md` and this handoff if the takeover facts changed.