Backend - dev-api.py: Q&A suggest endpoint, Log Contact, cf-orch node detection in wizard hardware step, canonical search_profiles format (profiles:[...]), connections settings endpoints, Resume Library endpoints - db_migrate.py: migrations 002/003/004 — ATS columns, resume review, final resume struct - discover.py: _normalize_profiles() for legacy wizard YAML format compat - resume_optimizer.py: section-by-section resume parsing + scoring - task_runner.py: Q&A and contact-log task types - company_research.py: accessibility brief column wiring - generate_cover_letter.py: restore _candidate module-level binding Frontend - InterviewPrepView.vue: Q&A chat tab, Log Contact form, MarkdownView rendering - InterviewCard.vue: new reusable card component for interviews kanban - InterviewsView.vue: rejected analytics section with stage breakdown chips - ResumeProfileView.vue: sync with new resume store shape - SearchPrefsView.vue: cf-orch toggle, profile format migration - SystemSettingsView.vue: connections settings wiring - ConnectionsSettingsView.vue: new view for integration connections - MarkdownView.vue: new component for safe markdown rendering - ApplyWorkspace.vue: a11y — h1→h2 demotion, aria-expanded on Q&A toggle, confirmation dialog on Reject action (#98 #99 #100) - peregrine.css: explicit [data-theme="dark"] token block for light-OS users (#101), :focus-visible outline (#97) - wizard.css: cf-orch hardware step styles - WizardHardwareStep.vue: cf-orch node display, profile selection with orch option - WizardLayout.vue: hardware step wiring Infra - compose.yml / compose.cloud.yml: cf-orch agent sidecar, llm.cloud.yaml mount - Dockerfile.cfcore: cf-core editable install in image build - HANDOFF-xanderland.md: Podman/systemd setup guide for beta tester - podman-standalone.sh: standalone Podman run script Tests - test_dev_api_settings.py: remove stale worktree path bootstrap (credential_store now in main repo); fix job_boards fixture to use non-empty list - test_wizard_api.py: update profiles assertion to superset check (cf-orch added); update step6 assertion to canonical profiles[].titles format
105 lines
3.5 KiB
YAML
105 lines
3.5 KiB
YAML
# compose.cloud.yml — Multi-tenant cloud stack for menagerie.circuitforge.tech/peregrine
|
|
#
|
|
# Each authenticated user gets their own encrypted SQLite data tree at
|
|
# /devl/menagerie-data/<user-id>/peregrine/
|
|
#
|
|
# Caddy injects the Directus session cookie as X-CF-Session header before forwarding.
|
|
# cloud_session.py resolves user_id → per-user db_path at session init.
|
|
#
|
|
# Usage:
|
|
# docker compose -f compose.cloud.yml --project-name peregrine-cloud up -d
|
|
# docker compose -f compose.cloud.yml --project-name peregrine-cloud down
|
|
# docker compose -f compose.cloud.yml --project-name peregrine-cloud logs app -f
|
|
|
|
services:
|
|
app:
|
|
build:
|
|
context: ..
|
|
dockerfile: peregrine/Dockerfile.cfcore
|
|
container_name: peregrine-cloud
|
|
ports:
|
|
- "8505:8501"
|
|
volumes:
|
|
- /devl/menagerie-data:/devl/menagerie-data # per-user data trees
|
|
- ./config/llm.cloud.yaml:/app/config/llm.yaml:ro # cloud-safe backends only (no claude_code/copilot/anthropic)
|
|
environment:
|
|
- CLOUD_MODE=true
|
|
- CLOUD_DATA_ROOT=/devl/menagerie-data
|
|
- DIRECTUS_JWT_SECRET=${DIRECTUS_JWT_SECRET}
|
|
- CF_SERVER_SECRET=${CF_SERVER_SECRET}
|
|
- PLATFORM_DB_URL=${PLATFORM_DB_URL}
|
|
- HEIMDALL_URL=${HEIMDALL_URL:-http://cf-license:8000}
|
|
- HEIMDALL_ADMIN_TOKEN=${HEIMDALL_ADMIN_TOKEN}
|
|
- STAGING_DB=/devl/menagerie-data/cloud-default.db # fallback only — never used
|
|
- DOCS_DIR=/tmp/cloud-docs
|
|
- STREAMLIT_SERVER_BASE_URL_PATH=peregrine
|
|
- PYTHONUNBUFFERED=1
|
|
- PEREGRINE_CADDY_PROXY=1
|
|
- CF_ORCH_URL=http://host.docker.internal:7700
|
|
- DEMO_MODE=false
|
|
- FORGEJO_API_TOKEN=${FORGEJO_API_TOKEN:-}
|
|
depends_on:
|
|
searxng:
|
|
condition: service_healthy
|
|
extra_hosts:
|
|
- "host.docker.internal:host-gateway"
|
|
restart: unless-stopped
|
|
|
|
api:
|
|
build:
|
|
context: ..
|
|
dockerfile: peregrine/Dockerfile.cfcore
|
|
command: >
|
|
bash -c "uvicorn dev_api:app --host 0.0.0.0 --port 8601"
|
|
ports:
|
|
- "127.0.0.1:8601:8601" # localhost-only — Caddy + avocet imitate tab
|
|
volumes:
|
|
- /devl/menagerie-data:/devl/menagerie-data
|
|
- ./config/llm.cloud.yaml:/app/config/llm.yaml:ro
|
|
environment:
|
|
- CLOUD_MODE=true
|
|
- CLOUD_DATA_ROOT=/devl/menagerie-data
|
|
- STAGING_DB=/devl/menagerie-data/cloud-default.db
|
|
- DIRECTUS_JWT_SECRET=${DIRECTUS_JWT_SECRET}
|
|
- CF_SERVER_SECRET=${CF_SERVER_SECRET}
|
|
- PLATFORM_DB_URL=${PLATFORM_DB_URL}
|
|
- HEIMDALL_URL=${HEIMDALL_URL:-http://cf-license:8000}
|
|
- HEIMDALL_ADMIN_TOKEN=${HEIMDALL_ADMIN_TOKEN}
|
|
- PYTHONUNBUFFERED=1
|
|
- FORGEJO_API_TOKEN=${FORGEJO_API_TOKEN:-}
|
|
- CF_ORCH_URL=http://host.docker.internal:7700
|
|
extra_hosts:
|
|
- "host.docker.internal:host-gateway"
|
|
restart: unless-stopped
|
|
|
|
web:
|
|
build:
|
|
context: .
|
|
dockerfile: docker/web/Dockerfile
|
|
args:
|
|
VITE_BASE_PATH: /peregrine/
|
|
ports:
|
|
- "8508:80"
|
|
depends_on:
|
|
- api
|
|
restart: unless-stopped
|
|
|
|
# cf-orch-agent: not needed in cloud — a host-native agent already runs on :7701
|
|
# and is registered with the coordinator. app/api reach it via CF_ORCH_URL.
|
|
|
|
searxng:
|
|
image: searxng/searxng:latest
|
|
volumes:
|
|
- ./docker/searxng:/etc/searxng:ro
|
|
healthcheck:
|
|
test: ["CMD", "wget", "-q", "--spider", "http://localhost:8080/"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 3
|
|
restart: unless-stopped
|
|
# No host port — internal only
|
|
|
|
networks:
|
|
default:
|
|
external: true
|
|
name: caddy-proxy_caddy-internal
|