diff --git a/ai/compose.yml b/ai/compose.yml index 194a088..5f518fe 100755 --- a/ai/compose.yml +++ b/ai/compose.yml @@ -161,13 +161,11 @@ services: - "303" - "26" - # --- Honcho: AI-native user modeling --- - honcho: + # --- Honcho + OpenConcho combiné: API + Web UI nginx/FastAPI --- + honcho-ui: build: ./honcho - container_name: honcho + container_name: honcho-ui restart: unless-stopped - ports: - - "127.0.0.1:8001:8000" environment: - DB_CONNECTION_URI=postgresql+psycopg://honcho:honcho_pass@honcho-db:5432/honcho - CACHE_URL=redis://honcho-redis:6379/0 @@ -181,47 +179,27 @@ services: - ai_net labels: - "traefik.enable=true" - - "traefik.http.routers.honcho-http.rule=Host(`api.honcho.lazyworkhorse.net`)" + + # Router for HTTP + redirect to HTTPS + - "traefik.http.routers.honcho-http.rule=Host(`honcho.lazyworkhorse.net`)" - "traefik.http.routers.honcho-http.entrypoints=web" - "traefik.http.routers.honcho-http.middlewares=redirect-to-https" - - "traefik.http.routers.honcho-https.rule=Host(`api.honcho.lazyworkhorse.net`)" + + # Router for HTTPS with TLS — protected by Authelia + - "traefik.http.routers.honcho-https.rule=Host(`honcho.lazyworkhorse.net`)" - "traefik.http.routers.honcho-https.entrypoints=websecure" - "traefik.http.routers.honcho-https.tls=true" - "traefik.http.routers.honcho-https.tls.certresolver=njalla" - "traefik.http.routers.honcho-https.middlewares=hermes-auth" - - "traefik.http.services.honcho.loadbalancer.server.port=8000" + + # Service Loadbalancer (nginx port) + - "traefik.http.services.honcho.loadbalancer.server.port=80" depends_on: honcho-db: condition: service_healthy honcho-redis: condition: service_healthy - # --- OpenConcho: Honcho web UI --- - openconcho: - build: ./openconcho - container_name: openconcho - restart: unless-stopped - networks: - - ai_backend - - ai_net - labels: - - "traefik.enable=true" - - # Router for HTTP + redirect to HTTPS - - "traefik.http.routers.openconcho-http.rule=Host(`honcho.lazyworkhorse.net`)" - - "traefik.http.routers.openconcho-http.entrypoints=web" - - "traefik.http.routers.openconcho-http.middlewares=redirect-to-https" - - # Router for HTTPS with TLS — protected by Authelia - - "traefik.http.routers.openconcho-https.rule=Host(`honcho.lazyworkhorse.net`)" - - "traefik.http.routers.openconcho-https.entrypoints=websecure" - - "traefik.http.routers.openconcho-https.tls=true" - - "traefik.http.routers.openconcho-https.tls.certresolver=njalla" - - "traefik.http.routers.openconcho-https.middlewares=hermes-auth" - - # Service Loadbalancer - - "traefik.http.services.openconcho.loadbalancer.server.port=80" - honcho-db: image: pgvector/pgvector:pg15 container_name: honcho-db diff --git a/ai/honcho/Dockerfile b/ai/honcho/Dockerfile index e654667..b44aa6f 100644 --- a/ai/honcho/Dockerfile +++ b/ai/honcho/Dockerfile @@ -1,6 +1,5 @@ # build stage — fetches and builds Honcho from source -# Using buildkit cache mounts for speed across rebuilds -FROM python:3.13-slim-bookworm AS builder +FROM python:3.13-slim-bookworm AS honcho-builder RUN apt-get update && \ apt-get install -y --no-install-recommends git && \ @@ -8,7 +7,6 @@ RUN apt-get update && \ COPY --from=ghcr.io/astral-sh/uv:0.9.24 /uv /bin/uv -# Clone Honcho at a pinned commit for reproducibility ARG HONCHO_REPO=https://github.com/plastic-labs/honcho ARG HONCHO_REF=main RUN git clone --depth 1 --branch ${HONCHO_REF} ${HONCHO_REPO} /app @@ -21,21 +19,51 @@ ENV UV_PYTHON=/usr/local/bin/python3.13 RUN uv sync --frozen -# --- runtime stage --- +# build stage — builds OpenConcho SPA +FROM node:22-bookworm AS openconcho-builder + +ENV PNPM_HOME=/pnpm +ENV PATH=$PNPM_HOME:$PATH +RUN corepack enable && corepack prepare pnpm@latest --activate + +WORKDIR /app +RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/* + +ARG OPENCONCHO_SHA=e490d911fcb27ee193558fd9a28856cde2057665 +RUN git clone --depth 1 https://github.com/offendingcommit/openconcho.git /app && \ + git -C /app fetch --depth 1 origin ${OPENCONCHO_SHA} && \ + git -C /app checkout ${OPENCONCHO_SHA} + +RUN pnpm install --frozen-lockfile +RUN pnpm --filter @openconcho/web build + +# runtime stage — nginx + Honcho FastAPI FROM python:3.13-slim-bookworm -RUN groupadd --system app && \ - useradd --system --gid app --create-home app - -COPY --from=builder /app /app +RUN apt-get update && apt-get install -y --no-install-recommends nginx && \ + rm -rf /var/log/nginx/* && \ + rm -rf /var/lib/apt/lists/* +# Honcho +COPY --from=honcho-builder /app /app WORKDIR /app ENV PATH="/app/.venv/bin:$PATH" ENV HOME=/app +COPY config.toml /app/config.toml -COPY --chown=app:app config.toml /app/config.toml +# OpenConcho SPA +COPY --from=openconcho-builder /app/packages/web/dist /usr/share/nginx/html + +# nginx config (proxies /v3/, /v2/ to Honcho on localhost:8000) +COPY honcho-nginx.conf /etc/nginx/conf.d/default.conf +RUN rm -f /etc/nginx/sites-enabled/default + +RUN groupadd --system app && \ + useradd --system --gid app --create-home app && \ + chown -R app:app /app /usr/share/nginx/html USER app -EXPOSE 8000 -CMD ["fastapi", "run", "--host", "0.0.0.0", "src/main.py"] +EXPOSE 80 + +CMD ["sh", "-c", "nginx && exec fastapi run --host 127.0.0.1 --port 8000 src/main.py"] diff --git a/ai/honcho/honcho-nginx.conf b/ai/honcho/honcho-nginx.conf new file mode 100644 index 0000000..90d13b2 --- /dev/null +++ b/ai/honcho/honcho-nginx.conf @@ -0,0 +1,52 @@ +server { + listen 80 default_server; + listen [::]:80 default_server; + server_name _; + + root /usr/share/nginx/html; + index index.html; + + # Honcho API proxy + location /v3/ { + proxy_pass http://127.0.0.1:8000; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + location /v2/ { + proxy_pass http://127.0.0.1:8000; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + # Honcho health + location /health { + proxy_pass http://127.0.0.1:8000; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + # OpenAPI docs + location /openapi.json { + proxy_pass http://127.0.0.1:8000; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + # SPA: fallback to index.html for client-side routing + location / { + try_files $uri $uri/ /index.html; + } +} diff --git a/ai/openconcho/Dockerfile b/ai/openconcho/Dockerfile deleted file mode 100644 index de9ed48..0000000 --- a/ai/openconcho/Dockerfile +++ /dev/null @@ -1,23 +0,0 @@ -# build stage -FROM node:22-bookworm AS builder - -ENV PNPM_HOME=/pnpm -ENV PATH=$PNPM_HOME:$PATH -RUN corepack enable && corepack prepare pnpm@latest --activate - -WORKDIR /app -RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/* - -ARG OPENCONCHO_SHA=e490d911fcb27ee193558fd9a28856cde2057665 -RUN git clone --depth 1 https://github.com/offendingcommit/openconcho.git /app && \ - git -C /app fetch --depth 1 origin ${OPENCONCHO_SHA} && \ - git -C /app checkout ${OPENCONCHO_SHA} - -RUN pnpm install --frozen-lockfile -RUN pnpm --filter @openconcho/web build - -# runtime stage -FROM nginx:alpine -COPY --from=builder /app/packages/web/dist /usr/share/nginx/html -EXPOSE 80 -CMD ["nginx", "-g", "daemon off;"]