Files
chat/compose.prod.yml
hanzoandAntje Worring c2aff88ca6 fix(branding): real @hanzo blocky-H logo+favicon, dev-only devtools, working OIDC button icon
- App.jsx: gate ReactQueryDevtools behind import.meta.env.DEV via lazy dynamic
  import so the devtools floating button (red flower) never ships in prod.
- librechat.yaml + compose.prod.yml: OIDC/model iconURL & OPENID_IMAGE_URL
  hanzo.ai/logo/icon.svg (404) -> hanzo.chat/assets/logo.svg (served, canonical).
- index.html: add scalable SVG favicon (canonical blocky-H) as primary icon.
- post-build.cjs: copy favicon.ico into dist root so /favicon.ico serves.
- add real multi-size favicon.ico generated from @hanzo/brand favicon (blocky-H).

logo.svg/favicons already match @hanzo/brand canonical blocky-H byte-for-byte;
prod was serving a stale dist (title 'Chat', no assets) -> fresh build fixes.
2026-06-23 14:29:53 -07:00

129 lines
4.3 KiB
YAML

# Hanzo AI Chat - Production Override
# Use with: docker compose -f compose.yml -f compose.prod.yml up -d
# Requires Traefik reverse proxy running
services:
# Production chat configuration
chat:
image: hanzoai/chat:${VERSION:-latest}
container_name: hanzo-chat-prod
restart: unless-stopped
ports: [] # No direct port exposure in production
environment:
# Production settings
NODE_ENV: production
DOMAIN_CLIENT: https://hanzo.chat
DOMAIN_SERVER: https://hanzo.chat
ALLOW_REGISTRATION: ${ALLOW_REGISTRATION:-false}
# All AI requests go through Hanzo API gateway
OPENAI_BASE_URL: https://api.hanzo.ai/v1
# Production secrets (use real values)
JWT_SECRET: ${JWT_SECRET:?JWT_SECRET is required}
JWT_REFRESH_SECRET: ${JWT_REFRESH_SECRET:?JWT_REFRESH_SECRET is required}
OPENAI_API_KEY: ${OPENAI_API_KEY:?OPENAI_API_KEY is required}
# Hanzo IAM OpenID Connect
OPENID_CLIENT_ID: ${OPENID_CLIENT_ID:?OPENID_CLIENT_ID is required}
OPENID_CLIENT_SECRET: ${OPENID_CLIENT_SECRET:?OPENID_CLIENT_SECRET is required}
OPENID_ISSUER: https://hanzo.id
OPENID_SESSION_SECRET: ${OPENID_SESSION_SECRET:?OPENID_SESSION_SECRET is required}
OPENID_SCOPE: openid profile email
OPENID_CALLBACK_URL: /oauth/openid/callback
OPENID_BUTTON_LABEL: Log in with Hanzo
OPENID_IMAGE_URL: https://hanzo.chat/assets/logo.svg
OPENID_USERNAME_CLAIM: name
OPENID_NAME_CLAIM: name
OPENID_USE_PKCE: "true"
labels:
# Traefik routing
- "traefik.enable=true"
- "traefik.docker.network=traefik"
# HTTPS router
- "traefik.http.routers.hanzo-chat.rule=Host(`hanzo.chat`) || Host(`chat.hanzo.ai`)"
- "traefik.http.routers.hanzo-chat.entrypoints=websecure"
- "traefik.http.routers.hanzo-chat.tls=true"
- "traefik.http.routers.hanzo-chat.tls.certresolver=letsencrypt"
# Service
- "traefik.http.services.hanzo-chat.loadbalancer.server.port=3080"
# Security headers
- "traefik.http.middlewares.hanzo-chat-headers.headers.stsSeconds=31536000"
- "traefik.http.middlewares.hanzo-chat-headers.headers.stsIncludeSubdomains=true"
- "traefik.http.middlewares.hanzo-chat-headers.headers.stsPreload=true"
- "traefik.http.middlewares.hanzo-chat-headers.headers.contentTypeNosniff=true"
- "traefik.http.middlewares.hanzo-chat-headers.headers.browserXssFilter=true"
- "traefik.http.middlewares.hanzo-chat-headers.headers.referrerPolicy=strict-origin-when-cross-origin"
- "traefik.http.middlewares.hanzo-chat-headers.headers.customFrameOptionsValue=SAMEORIGIN"
# Apply middlewares
- "traefik.http.routers.hanzo-chat.middlewares=hanzo-chat-headers"
networks:
- hanzo-network
- traefik
deploy:
resources:
limits:
cpus: '2'
memory: 2G
reservations:
cpus: '0.5'
memory: 512M
# MongoDB production settings
mongodb:
restart: unless-stopped
volumes:
- mongodb_data:/data/db
- mongodb_backup:/backup
environment:
MONGO_INITDB_ROOT_USERNAME: ${MONGO_USERNAME:?MONGO_USERNAME is required}
MONGO_INITDB_ROOT_PASSWORD: ${MONGO_PASSWORD:?MONGO_PASSWORD is required}
deploy:
resources:
limits:
cpus: '1'
memory: 1G
# Meilisearch production settings
meilisearch:
restart: unless-stopped
environment:
MEILI_ENV: production
MEILI_MASTER_KEY: ${MEILI_MASTER_KEY:?MEILI_MASTER_KEY is required}
deploy:
resources:
limits:
cpus: '1'
memory: 1G
# Optional: MongoDB backup service
mongodb-backup:
image: hanzoai/mongodb-backup:latest
container_name: hanzo-mongodb-backup
restart: unless-stopped
environment:
MONGO_URI: mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@mongodb:27017/HanzoChat?authSource=admin
BACKUP_SCHEDULE: "0 2 * * *" # Daily at 2 AM
BACKUP_RETENTION_DAYS: 7
S3_BUCKET: ${BACKUP_S3_BUCKET:-}
AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID:-}
AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY:-}
volumes:
- mongodb_backup:/backup
depends_on:
- mongodb
networks:
- hanzo-network
profiles:
- with-backup
volumes:
mongodb_backup:
networks:
traefik:
external: true