190 lines
5.6 KiB
YAML
190 lines
5.6 KiB
YAML
# Meeting Intelligence System - Full Docker Compose
|
|
# Deploy on Netcup RS 8000 at /opt/meeting-intelligence/
|
|
#
|
|
# Components:
|
|
# - Jibri (recording)
|
|
# - Transcriber (whisper.cpp + diarization)
|
|
# - Meeting Intelligence API
|
|
# - PostgreSQL (storage)
|
|
# - Redis (job queue)
|
|
|
|
services:
|
|
# ============================================================
|
|
# PostgreSQL Database
|
|
# ============================================================
|
|
postgres:
|
|
image: pgvector/pgvector:pg16
|
|
container_name: meeting-intelligence-db
|
|
restart: unless-stopped
|
|
environment:
|
|
POSTGRES_USER: meeting_intelligence
|
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-changeme}
|
|
POSTGRES_DB: meeting_intelligence
|
|
volumes:
|
|
- postgres_data:/var/lib/postgresql/data
|
|
- ./postgres/init.sql:/docker-entrypoint-initdb.d/init.sql:ro
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U meeting_intelligence"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
networks:
|
|
- meeting-intelligence
|
|
|
|
# ============================================================
|
|
# Redis Job Queue
|
|
# ============================================================
|
|
redis:
|
|
image: redis:7-alpine
|
|
container_name: meeting-intelligence-redis
|
|
restart: unless-stopped
|
|
command: redis-server --appendonly yes
|
|
volumes:
|
|
- redis_data:/data
|
|
healthcheck:
|
|
test: ["CMD", "redis-cli", "ping"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
networks:
|
|
- meeting-intelligence
|
|
|
|
# ============================================================
|
|
# Transcription Service (whisper.cpp + diarization)
|
|
# ============================================================
|
|
transcriber:
|
|
build:
|
|
context: ./transcriber
|
|
dockerfile: Dockerfile
|
|
container_name: meeting-intelligence-transcriber
|
|
restart: unless-stopped
|
|
environment:
|
|
REDIS_URL: redis://redis:6379
|
|
POSTGRES_URL: postgresql://meeting_intelligence:${POSTGRES_PASSWORD:-changeme}@postgres:5432/meeting_intelligence
|
|
WHISPER_MODEL: /models/ggml-small.bin
|
|
WHISPER_THREADS: 8
|
|
NUM_WORKERS: 4
|
|
volumes:
|
|
- recordings:/recordings:ro
|
|
- audio_processed:/audio
|
|
depends_on:
|
|
postgres:
|
|
condition: service_healthy
|
|
redis:
|
|
condition: service_healthy
|
|
deploy:
|
|
resources:
|
|
limits:
|
|
cpus: '12'
|
|
memory: 16G
|
|
networks:
|
|
- meeting-intelligence
|
|
|
|
# ============================================================
|
|
# Meeting Intelligence API
|
|
# ============================================================
|
|
api:
|
|
build:
|
|
context: ./api
|
|
dockerfile: Dockerfile
|
|
container_name: meeting-intelligence-api
|
|
restart: unless-stopped
|
|
environment:
|
|
REDIS_URL: redis://redis:6379
|
|
POSTGRES_URL: postgresql://meeting_intelligence:${POSTGRES_PASSWORD:-changeme}@postgres:5432/meeting_intelligence
|
|
OLLAMA_URL: http://host.docker.internal:11434
|
|
RECORDINGS_PATH: /recordings
|
|
SECRET_KEY: ${API_SECRET_KEY:-changeme}
|
|
volumes:
|
|
- recordings:/recordings
|
|
depends_on:
|
|
postgres:
|
|
condition: service_healthy
|
|
redis:
|
|
condition: service_healthy
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.meeting-intelligence.rule=Host(`meet.jeffemmett.com`) && PathPrefix(`/api/intelligence`)"
|
|
- "traefik.http.services.meeting-intelligence.loadbalancer.server.port=8000"
|
|
- "traefik.http.routers.meeting-intelligence.middlewares=strip-intelligence-prefix"
|
|
- "traefik.http.middlewares.strip-intelligence-prefix.stripprefix.prefixes=/api/intelligence"
|
|
networks:
|
|
- meeting-intelligence
|
|
- traefik-public
|
|
|
|
# ============================================================
|
|
# Jibri Recording Service
|
|
# ============================================================
|
|
jibri:
|
|
image: jitsi/jibri:stable-9584
|
|
container_name: meeting-intelligence-jibri
|
|
restart: unless-stopped
|
|
privileged: true
|
|
environment:
|
|
# XMPP Connection - uses internal Docker DNS names
|
|
XMPP_SERVER: jeffsi-meet-prosody-1
|
|
XMPP_DOMAIN: meet.jitsi
|
|
XMPP_AUTH_DOMAIN: auth.meet.jitsi
|
|
XMPP_INTERNAL_MUC_DOMAIN: internal-muc.meet.jitsi
|
|
XMPP_RECORDER_DOMAIN: hidden.meet.jitsi
|
|
XMPP_MUC_DOMAIN: muc.meet.jitsi
|
|
XMPP_TRUST_ALL_CERTS: "true"
|
|
|
|
# Jibri Settings
|
|
JIBRI_BREWERY_MUC: JibriBrewery
|
|
JIBRI_PENDING_TIMEOUT: 90
|
|
JIBRI_RECORDING_DIR: /recordings
|
|
JIBRI_FINALIZE_RECORDING_SCRIPT_PATH: /config/finalize.sh
|
|
JIBRI_XMPP_USER: jibri
|
|
JIBRI_XMPP_PASSWORD: ${JIBRI_XMPP_PASSWORD:-changeme}
|
|
JIBRI_RECORDER_USER: recorder
|
|
JIBRI_RECORDER_PASSWORD: ${JIBRI_RECORDER_PASSWORD:-changeme}
|
|
|
|
# Display Settings
|
|
DISPLAY: ":0"
|
|
CHROMIUM_FLAGS: --use-fake-ui-for-media-stream,--start-maximized,--kiosk,--enabled,--disable-infobars,--autoplay-policy=no-user-gesture-required
|
|
|
|
# Public URL
|
|
PUBLIC_URL: https://meet.jeffemmett.com
|
|
|
|
# Timezone
|
|
TZ: UTC
|
|
volumes:
|
|
- recordings:/recordings
|
|
- ./jibri/config:/config
|
|
- /dev/shm:/dev/shm
|
|
cap_add:
|
|
- SYS_ADMIN
|
|
- NET_BIND_SERVICE
|
|
security_opt:
|
|
- seccomp:unconfined
|
|
shm_size: 2gb
|
|
networks:
|
|
- meeting-intelligence
|
|
- jeffsi-meet
|
|
|
|
volumes:
|
|
postgres_data:
|
|
redis_data:
|
|
recordings:
|
|
driver: local
|
|
driver_opts:
|
|
type: none
|
|
o: bind
|
|
device: /opt/meetings/recordings
|
|
audio_processed:
|
|
driver: local
|
|
driver_opts:
|
|
type: none
|
|
o: bind
|
|
device: /opt/meetings/audio
|
|
|
|
networks:
|
|
meeting-intelligence:
|
|
driver: bridge
|
|
traefik-public:
|
|
external: true
|
|
jeffsi-meet:
|
|
external: true
|
|
name: jeffsi-meet_meet.jitsi
|