feat(honcho): add role + day1 playbook + traefik route for lincoln
Deploys Honcho (plastic-labs/honcho) as a rootful Podman + Quadlet service on the lincoln VM (10.1.71.132). Three containers on a user-defined network: - honcho-postgres pgvector/pgvector:pg16 - honcho-api FastAPI on :8000 - honcho-deriver background worker for theory-of-mind derivations LLM provider: Anthropic Claude (claude-sonnet-4-5). Switching providers is two env-var changes — see README. Traefik route hall-of-presidents.local.mk-labs.cloud -> lincoln:8000 added under boilerplates/traefik/dynamic/. JARVIS itself talks to Honcho directly at lincoln:8000 (east-west); the Traefik alias exists only for browser access to the Swagger /docs UI. Requires three new vault entries before first run: - vault_honcho_database_password - vault_honcho_jwt_secret - vault_honcho_anthropic_api_key
This commit is contained in:
34
ansible/roles/honcho/tasks/api.yml
Normal file
34
ansible/roles/honcho/tasks/api.yml
Normal file
@@ -0,0 +1,34 @@
|
||||
---
|
||||
# ============================================================================
|
||||
# Honcho API container (Quadlet)
|
||||
# ----------------------------------------------------------------------------
|
||||
# Runs `fastapi run src/main.py` via the image's default CMD. The
|
||||
# entrypoint.sh in the image runs the DB migration first; safe to do on
|
||||
# every restart (idempotent).
|
||||
# ============================================================================
|
||||
|
||||
- name: Deploy Honcho API Quadlet
|
||||
ansible.builtin.template:
|
||||
src: honcho-api.container.j2
|
||||
dest: "{{ honcho_quadlet_dir }}/{{ honcho_container_name }}.container"
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0644"
|
||||
register: honcho_api_quadlet
|
||||
|
||||
- name: Reload systemd to pick up Quadlet changes
|
||||
ansible.builtin.systemd:
|
||||
daemon_reload: true
|
||||
when: honcho_api_quadlet.changed
|
||||
|
||||
- name: Ensure Honcho API container is started and enabled
|
||||
ansible.builtin.systemd:
|
||||
name: "{{ honcho_container_name }}.service"
|
||||
state: started
|
||||
enabled: true
|
||||
|
||||
- name: Restart Honcho API on Quadlet change
|
||||
ansible.builtin.systemd:
|
||||
name: "{{ honcho_container_name }}.service"
|
||||
state: restarted
|
||||
when: honcho_api_quadlet.changed
|
||||
34
ansible/roles/honcho/tasks/deriver.yml
Normal file
34
ansible/roles/honcho/tasks/deriver.yml
Normal file
@@ -0,0 +1,34 @@
|
||||
---
|
||||
# ============================================================================
|
||||
# Honcho deriver worker container (Quadlet)
|
||||
# ----------------------------------------------------------------------------
|
||||
# Same image as the API container, but runs the deriver script instead of
|
||||
# the FastAPI server. Pulls jobs off the in-database queue and calls the
|
||||
# configured LLM provider for theory-of-mind derivations.
|
||||
# ============================================================================
|
||||
|
||||
- name: Deploy Honcho deriver Quadlet
|
||||
ansible.builtin.template:
|
||||
src: honcho-deriver.container.j2
|
||||
dest: "{{ honcho_quadlet_dir }}/{{ honcho_deriver_container_name }}.container"
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0644"
|
||||
register: honcho_deriver_quadlet
|
||||
|
||||
- name: Reload systemd to pick up Quadlet changes
|
||||
ansible.builtin.systemd:
|
||||
daemon_reload: true
|
||||
when: honcho_deriver_quadlet.changed
|
||||
|
||||
- name: Ensure Honcho deriver container is started and enabled
|
||||
ansible.builtin.systemd:
|
||||
name: "{{ honcho_deriver_container_name }}.service"
|
||||
state: started
|
||||
enabled: true
|
||||
|
||||
- name: Restart Honcho deriver on Quadlet change
|
||||
ansible.builtin.systemd:
|
||||
name: "{{ honcho_deriver_container_name }}.service"
|
||||
state: restarted
|
||||
when: honcho_deriver_quadlet.changed
|
||||
42
ansible/roles/honcho/tasks/main.yml
Normal file
42
ansible/roles/honcho/tasks/main.yml
Normal file
@@ -0,0 +1,42 @@
|
||||
---
|
||||
# ============================================================================
|
||||
# honcho / main entrypoint
|
||||
# ----------------------------------------------------------------------------
|
||||
# Order matters:
|
||||
# 1. Podman + Quadlet support installed and ready
|
||||
# 2. Network created (containers reference it by name)
|
||||
# 3. Volumes created (postgres data)
|
||||
# 4. Postgres started (Honcho API + deriver depend on it being ready)
|
||||
# 5. Honcho API started
|
||||
# 6. Honcho deriver worker started
|
||||
# 7. Verify reachable on listen port
|
||||
# ============================================================================
|
||||
|
||||
- name: Install Podman and dependencies
|
||||
ansible.builtin.import_tasks: podman.yml
|
||||
tags: [honcho, podman]
|
||||
|
||||
- name: Ensure podman network exists
|
||||
ansible.builtin.import_tasks: network.yml
|
||||
tags: [honcho, network]
|
||||
|
||||
- name: Ensure podman volumes exist
|
||||
ansible.builtin.import_tasks: volumes.yml
|
||||
tags: [honcho, volumes]
|
||||
|
||||
- name: Deploy PostgreSQL (pgvector) container
|
||||
ansible.builtin.import_tasks: postgres.yml
|
||||
tags: [honcho, postgres]
|
||||
|
||||
- name: Deploy Honcho API container
|
||||
ansible.builtin.import_tasks: api.yml
|
||||
tags: [honcho, api]
|
||||
|
||||
- name: Deploy Honcho deriver worker
|
||||
ansible.builtin.import_tasks: deriver.yml
|
||||
when: honcho_deriver_enabled | bool
|
||||
tags: [honcho, deriver]
|
||||
|
||||
- name: Verify Honcho is reachable
|
||||
ansible.builtin.import_tasks: verify.yml
|
||||
tags: [honcho, verify]
|
||||
17
ansible/roles/honcho/tasks/network.yml
Normal file
17
ansible/roles/honcho/tasks/network.yml
Normal file
@@ -0,0 +1,17 @@
|
||||
---
|
||||
# ============================================================================
|
||||
# Podman network — single user-defined network shared by api/deriver/postgres
|
||||
# ============================================================================
|
||||
|
||||
- name: Check if honcho network exists
|
||||
ansible.builtin.command:
|
||||
cmd: "podman network exists {{ honcho_network_name }}"
|
||||
register: honcho_network_check
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
|
||||
- name: Create honcho podman network
|
||||
ansible.builtin.command:
|
||||
cmd: "podman network create {{ honcho_network_name }}"
|
||||
when: honcho_network_check.rc != 0
|
||||
changed_when: true
|
||||
24
ansible/roles/honcho/tasks/podman.yml
Normal file
24
ansible/roles/honcho/tasks/podman.yml
Normal file
@@ -0,0 +1,24 @@
|
||||
---
|
||||
# ============================================================================
|
||||
# Podman + Quadlet prerequisites
|
||||
# ----------------------------------------------------------------------------
|
||||
# Mirrors the pattern from the semaphore role. Ubuntu 24.04's podman is new
|
||||
# enough that Quadlet ships out of the box (>= 4.4).
|
||||
# ============================================================================
|
||||
|
||||
- name: Ensure Podman is installed
|
||||
ansible.builtin.package:
|
||||
name:
|
||||
- podman
|
||||
- podman-compose
|
||||
state: present
|
||||
become: true
|
||||
|
||||
- name: Ensure Quadlet drop-in directory exists
|
||||
ansible.builtin.file:
|
||||
path: "{{ honcho_quadlet_dir }}"
|
||||
state: directory
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0755"
|
||||
become: true
|
||||
48
ansible/roles/honcho/tasks/postgres.yml
Normal file
48
ansible/roles/honcho/tasks/postgres.yml
Normal file
@@ -0,0 +1,48 @@
|
||||
---
|
||||
# ============================================================================
|
||||
# pgvector PostgreSQL container (Quadlet)
|
||||
# ----------------------------------------------------------------------------
|
||||
# Honcho stores embeddings in pgvector, so we use the pgvector-enabled
|
||||
# image rather than stock postgres. Same env-var surface as the upstream
|
||||
# image; the pgvector extension is created by Honcho's migration script
|
||||
# on first start (scripts/provision_db.py).
|
||||
# ============================================================================
|
||||
|
||||
- name: Deploy Honcho PostgreSQL Quadlet
|
||||
ansible.builtin.template:
|
||||
src: honcho-postgres.container.j2
|
||||
dest: "{{ honcho_quadlet_dir }}/{{ honcho_postgres_container_name }}.container"
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0644"
|
||||
register: postgres_quadlet
|
||||
|
||||
- name: Reload systemd to pick up Quadlet changes
|
||||
ansible.builtin.systemd:
|
||||
daemon_reload: true
|
||||
when: postgres_quadlet.changed
|
||||
|
||||
- name: Ensure Honcho PostgreSQL container is started and enabled
|
||||
ansible.builtin.systemd:
|
||||
name: "{{ honcho_postgres_container_name }}.service"
|
||||
state: started
|
||||
enabled: true
|
||||
|
||||
- name: Wait for PostgreSQL to accept connections
|
||||
ansible.builtin.command:
|
||||
cmd: >-
|
||||
podman exec {{ honcho_postgres_container_name }}
|
||||
pg_isready -U {{ honcho_db_user }} -d {{ honcho_db_name }}
|
||||
register: pg_ready
|
||||
until: pg_ready.rc == 0
|
||||
retries: 30
|
||||
delay: 2
|
||||
changed_when: false
|
||||
|
||||
# Quadlet does not auto-restart on .container changes — same pitfall as
|
||||
# semaphore role. Force restart only when the template was modified.
|
||||
- name: Restart Honcho PostgreSQL on Quadlet change
|
||||
ansible.builtin.systemd:
|
||||
name: "{{ honcho_postgres_container_name }}.service"
|
||||
state: restarted
|
||||
when: postgres_quadlet.changed
|
||||
27
ansible/roles/honcho/tasks/verify.yml
Normal file
27
ansible/roles/honcho/tasks/verify.yml
Normal file
@@ -0,0 +1,27 @@
|
||||
---
|
||||
# ============================================================================
|
||||
# Post-deploy verification
|
||||
# ----------------------------------------------------------------------------
|
||||
# Polls the local Honcho API port until it responds. Fails loudly if the
|
||||
# service doesn't come up — the operator should not get an "all green"
|
||||
# playbook result while Honcho is silently broken.
|
||||
# ============================================================================
|
||||
|
||||
- name: Wait for Honcho HTTP endpoint
|
||||
ansible.builtin.uri:
|
||||
url: "http://127.0.0.1:{{ honcho_listen_port }}/docs"
|
||||
status_code: [200, 307]
|
||||
return_content: false
|
||||
register: honcho_ping
|
||||
until: honcho_ping.status in [200, 307]
|
||||
retries: "{{ honcho_health_check_retries }}"
|
||||
delay: "{{ honcho_health_check_delay }}"
|
||||
|
||||
- name: Report Honcho status
|
||||
ansible.builtin.debug:
|
||||
msg: >-
|
||||
Honcho API reachable on http://127.0.0.1:{{ honcho_listen_port }}/docs.
|
||||
Traefik should now route hall-of-presidents.local.mk-labs.cloud to
|
||||
this backend. Deriver enabled: {{ honcho_deriver_enabled }};
|
||||
LLM transport: {{ honcho_llm_transport }};
|
||||
deriver model: {{ honcho_deriver_model }}.
|
||||
17
ansible/roles/honcho/tasks/volumes.yml
Normal file
17
ansible/roles/honcho/tasks/volumes.yml
Normal file
@@ -0,0 +1,17 @@
|
||||
---
|
||||
# ============================================================================
|
||||
# Named podman volumes
|
||||
# ----------------------------------------------------------------------------
|
||||
# Honcho itself is stateless; only postgres needs durable storage.
|
||||
# ============================================================================
|
||||
|
||||
- name: Ensure named volumes exist
|
||||
ansible.builtin.command:
|
||||
cmd: "podman volume create {{ item }}"
|
||||
register: volume_create
|
||||
changed_when: "'already exists' not in (volume_create.stderr | default(''))"
|
||||
failed_when:
|
||||
- volume_create.rc != 0
|
||||
- "'already exists' not in (volume_create.stderr | default(''))"
|
||||
loop:
|
||||
- "{{ honcho_postgres_volume }}"
|
||||
Reference in New Issue
Block a user