Files
2026-07-13 13:29:13 +08:00

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