321 lines
9.0 KiB
YAML
321 lines
9.0 KiB
YAML
version: '3.8'
|
|
|
|
# ⚠️ AUDIO PROCESSING WARNING:
|
|
# Docker containers with insufficient resources will drop audio chunks when
|
|
# the processing queue becomes full (MAX_AUDIO_QUEUE_SIZE=10, lib.rs:54).
|
|
# Symptoms: "Dropped old audio chunk" in logs (lib.rs:330-333).
|
|
#
|
|
# RECOMMENDED RESOURCE ALLOCATION:
|
|
# - Memory: 8GB minimum per service (16GB total recommended)
|
|
# - CPU: 2+ cores per service
|
|
# - Monitor logs for audio drop warnings during operation
|
|
|
|
services:
|
|
# Original whisper-server service (Windows/Linux compatibility)
|
|
whisper-server:
|
|
build:
|
|
context: .
|
|
dockerfile: ${DOCKERFILE:-Dockerfile.server-cpu}
|
|
args:
|
|
CUDA_VERSION: ${CUDA_VERSION:-12.3.1}
|
|
UBUNTU_VERSION: ${UBUNTU_VERSION:-22.04}
|
|
image: whisper-server:${TAG:-cpu}
|
|
container_name: whisper-server
|
|
restart: unless-stopped
|
|
|
|
# Port mapping
|
|
ports:
|
|
- "${WHISPER_PORT:-8178}:8178"
|
|
|
|
# Environment variables
|
|
environment:
|
|
- WHISPER_HOST=0.0.0.0
|
|
- WHISPER_PORT=8178
|
|
- WHISPER_MODEL=${WHISPER_MODEL:-models/ggml-base.en.bin}
|
|
- WHISPER_THREADS=${WHISPER_THREADS:-0}
|
|
- WHISPER_USE_GPU=${WHISPER_USE_GPU:-true}
|
|
- WHISPER_LANGUAGE=${WHISPER_LANGUAGE:-en}
|
|
- WHISPER_TRANSLATE=${WHISPER_TRANSLATE:-false}
|
|
- WHISPER_DIARIZE=${WHISPER_DIARIZE:-false}
|
|
- WHISPER_PRINT_PROGRESS=${WHISPER_PRINT_PROGRESS:-true}
|
|
|
|
# Volume mounts
|
|
volumes:
|
|
# Model storage - persistent across container restarts
|
|
- whisper_models:/app/models
|
|
# Upload directory for temporary files
|
|
- whisper_uploads:/app/uploads
|
|
# Optional: mount local models directory
|
|
- ${LOCAL_MODELS_DIR:-./models}:/app/local_models:ro
|
|
# Optional: mount custom configuration
|
|
- ${CONFIG_DIR:-./config}:/app/config:ro
|
|
|
|
# Exclude from macOS profile
|
|
profiles:
|
|
- default
|
|
|
|
# macOS-optimized whisper-server service
|
|
whisper-server-macos:
|
|
build:
|
|
context: .
|
|
dockerfile: Dockerfile.server-macos
|
|
image: whisper-server:macos
|
|
container_name: whisper-server
|
|
restart: unless-stopped
|
|
|
|
# Port mapping
|
|
ports:
|
|
- "${WHISPER_PORT:-8178}:8178"
|
|
|
|
# Environment variables (GPU disabled for macOS)
|
|
environment:
|
|
- WHISPER_HOST=0.0.0.0
|
|
- WHISPER_PORT=8178
|
|
- WHISPER_MODEL=${WHISPER_MODEL:-models/ggml-large-v3.bin}
|
|
- WHISPER_THREADS=${WHISPER_THREADS:-0}
|
|
- WHISPER_USE_GPU=false
|
|
- WHISPER_LANGUAGE=${WHISPER_LANGUAGE:-en}
|
|
- WHISPER_TRANSLATE=${WHISPER_TRANSLATE:-false}
|
|
- WHISPER_DIARIZE=${WHISPER_DIARIZE:-false}
|
|
- WHISPER_PRINT_PROGRESS=${WHISPER_PRINT_PROGRESS:-true}
|
|
- WHISPER_PLATFORM=macos
|
|
|
|
# Volume mounts for macOS (using actual models directory)
|
|
volumes:
|
|
# Map to actual model location on macOS
|
|
- ./models:/app/models
|
|
# Upload directory for temporary files
|
|
- whisper_uploads:/app/uploads
|
|
# Optional: mount custom configuration
|
|
- ${CONFIG_DIR:-./config}:/app/config:ro
|
|
|
|
# macOS profile only
|
|
profiles:
|
|
- macos
|
|
|
|
# GPU support (uncomment for GPU version)
|
|
# deploy:
|
|
# resources:
|
|
# reservations:
|
|
# devices:
|
|
# - driver: nvidia
|
|
# count: all
|
|
# capabilities: [gpu]
|
|
|
|
# Health check
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-f", "http://localhost:8178/"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
start_period: 30s
|
|
|
|
# Resource limits (optional)
|
|
mem_limit: 4g
|
|
mem_reservation: 1g
|
|
|
|
# Logging configuration
|
|
logging:
|
|
driver: "json-file"
|
|
options:
|
|
max-size: "10m"
|
|
max-file: "3"
|
|
|
|
# Model downloader service - ensures models are downloaded before whisper server starts
|
|
model-downloader:
|
|
image: alpine/curl:latest
|
|
container_name: whisper-model-downloader
|
|
volumes:
|
|
- whisper_models:/models
|
|
environment:
|
|
- MODEL_NAME=${MODEL_NAME:-base.en}
|
|
command: |
|
|
sh -c "
|
|
echo '🔍 Checking for model: ggml-\${MODEL_NAME}.bin'
|
|
if [ ! -f /models/ggml-\${MODEL_NAME}.bin ] || [ ! -s /models/ggml-\${MODEL_NAME}.bin ]; then
|
|
echo '📦 Downloading model: \${MODEL_NAME}...'
|
|
echo '📋 This may take a few minutes depending on model size and connection speed'
|
|
# Create temp file to avoid partial downloads
|
|
curl -L -f --progress-bar \
|
|
--connect-timeout 30 \
|
|
--max-time 3600 \
|
|
--retry 3 \
|
|
--retry-delay 5 \
|
|
--retry-connrefused \
|
|
-o /models/ggml-\${MODEL_NAME}.bin.tmp \
|
|
https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-\${MODEL_NAME}.bin
|
|
|
|
# Verify download completed successfully
|
|
if [ -s /models/ggml-\${MODEL_NAME}.bin.tmp ]; then
|
|
mv /models/ggml-\${MODEL_NAME}.bin.tmp /models/ggml-\${MODEL_NAME}.bin
|
|
echo '✅ Model downloaded successfully: \${MODEL_NAME}'
|
|
ls -lh /models/ggml-\${MODEL_NAME}.bin
|
|
else
|
|
echo '❌ Download failed or file is empty'
|
|
rm -f /models/ggml-\${MODEL_NAME}.bin.tmp
|
|
exit 1
|
|
fi
|
|
else
|
|
echo '✅ Model already exists: \${MODEL_NAME}'
|
|
ls -lh /models/ggml-\${MODEL_NAME}.bin
|
|
fi
|
|
echo '🎉 Model preparation complete'
|
|
"
|
|
healthcheck:
|
|
test: ["CMD", "test", "-f", "/models/ggml-${MODEL_NAME:-base.en}.bin"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 1
|
|
profiles:
|
|
- download
|
|
|
|
# Meeting Summarizer Python App (Windows/Linux)
|
|
meetily-backend:
|
|
build:
|
|
context: .
|
|
dockerfile: Dockerfile.app
|
|
image: meetily-backend:latest
|
|
container_name: meetily-backend
|
|
restart: unless-stopped
|
|
|
|
# Port mapping
|
|
ports:
|
|
- "${APP_PORT:-5167}:5167"
|
|
|
|
# Environment variables
|
|
environment:
|
|
- PYTHONUNBUFFERED=1
|
|
- PYTHONPATH=/app
|
|
- DATABASE_PATH=/app/data/meeting_minutes.db
|
|
- OLLAMA_HOST=${OLLAMA_HOST:-http://host.docker.internal:11434}
|
|
|
|
# Add extra host for Docker Desktop compatibility
|
|
extra_hosts:
|
|
- "host.docker.internal:host-gateway"
|
|
|
|
# Volume mounts
|
|
volumes:
|
|
# Local database directory (created by setup-db.sh)
|
|
- ./data:/app/data
|
|
# Logs directory
|
|
- meeting_app_logs:/app/logs
|
|
# Optional: mount local .env file
|
|
- ${LOCAL_ENV_FILE:-./app/.env}:/app/.env:ro
|
|
|
|
# Health check
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-f", "http://localhost:5167/get-meetings"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
start_period: 30s
|
|
|
|
# Resource limits (optional)
|
|
mem_limit: 2g
|
|
mem_reservation: 512m
|
|
|
|
# Logging configuration
|
|
logging:
|
|
driver: "json-file"
|
|
options:
|
|
max-size: "10m"
|
|
max-file: "3"
|
|
|
|
# Depends on whisper server for transcription
|
|
depends_on:
|
|
whisper-server:
|
|
condition: service_healthy
|
|
|
|
# Exclude from macOS profile
|
|
profiles:
|
|
- default
|
|
|
|
# Meeting Summarizer Python App (macOS)
|
|
meetily-backend-macos:
|
|
build:
|
|
context: .
|
|
dockerfile: Dockerfile.app
|
|
image: meetily-backend:latest
|
|
container_name: meetily-backend
|
|
restart: unless-stopped
|
|
|
|
# Port mapping
|
|
ports:
|
|
- "${APP_PORT:-5167}:5167"
|
|
|
|
# Environment variables
|
|
environment:
|
|
- PYTHONUNBUFFERED=1
|
|
- PYTHONPATH=/app
|
|
- DATABASE_PATH=/app/data/meeting_minutes.db
|
|
- OLLAMA_HOST=${OLLAMA_HOST:-http://host.docker.internal:11434}
|
|
|
|
# Add extra host for Docker Desktop compatibility
|
|
extra_hosts:
|
|
- "host.docker.internal:host-gateway"
|
|
|
|
# Volume mounts
|
|
volumes:
|
|
# Local database directory (created by setup-db.sh)
|
|
- ./data:/app/data
|
|
# Logs directory
|
|
- meeting_app_logs:/app/logs
|
|
# Optional: mount local .env file
|
|
- ${LOCAL_ENV_FILE:-./app/.env}:/app/.env:ro
|
|
|
|
# Health check
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-f", "http://localhost:5167/get-meetings"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
start_period: 30s
|
|
|
|
# Resource limits (optional)
|
|
mem_limit: 2g
|
|
mem_reservation: 512m
|
|
|
|
# Logging configuration
|
|
logging:
|
|
driver: "json-file"
|
|
options:
|
|
max-size: "10m"
|
|
max-file: "3"
|
|
|
|
# Depends on macOS whisper server for transcription
|
|
depends_on:
|
|
whisper-server-macos:
|
|
condition: service_healthy
|
|
|
|
# macOS profile only
|
|
profiles:
|
|
- macos
|
|
|
|
# Optional: Web UI service (if you want a separate frontend)
|
|
web-ui:
|
|
image: nginx:alpine
|
|
container_name: whisper-web-ui
|
|
ports:
|
|
- "${WEB_PORT:-80}:80"
|
|
volumes:
|
|
- ./web:/usr/share/nginx/html:ro
|
|
- ./nginx.conf:/etc/nginx/nginx.conf:ro
|
|
depends_on:
|
|
- whisper-server
|
|
- meetily-backend
|
|
profiles:
|
|
- web
|
|
|
|
# Named volumes for persistent data
|
|
volumes:
|
|
whisper_models:
|
|
driver: local
|
|
whisper_uploads:
|
|
driver: local
|
|
meeting_app_logs:
|
|
driver: local
|
|
|
|
# Networks (optional)
|
|
networks:
|
|
default:
|
|
name: whisper-network |