Ship FrankenPHP Compose services with Reverb WebSockets for real-time transcription status, skip re-uploading identical audio via content hash, and format disk usage without requiring intl.
180 lines
5.3 KiB
YAML
180 lines
5.3 KiB
YAML
x-data volumes:
|
|
app-data: &app-data
|
|
- ./database:/app/database
|
|
- ./storage/app:/app/storage/app
|
|
- ./storage/logs:/app/storage/logs
|
|
|
|
x-app-env: &app-env
|
|
APP_NAME: AndyTranscribe
|
|
APP_ENV: ${APP_ENV:-local}
|
|
APP_KEY: ${APP_KEY}
|
|
APP_DEBUG: ${APP_DEBUG:-true}
|
|
APP_URL: ${APP_URL:-http://localhost:8080}
|
|
APP_PORT: ${APP_HOST_PORT:-8080}
|
|
LOG_CHANNEL: stderr
|
|
DB_CONNECTION: sqlite
|
|
DB_DATABASE: /app/database/database.sqlite
|
|
SESSION_DRIVER: database
|
|
QUEUE_CONNECTION: database
|
|
CACHE_STORE: database
|
|
BROADCAST_CONNECTION: reverb
|
|
FILESYSTEM_DISK: local
|
|
REVERB_APP_ID: ${REVERB_APP_ID:-andytranscribe}
|
|
REVERB_APP_KEY: ${REVERB_APP_KEY:-andytranscribe-key}
|
|
REVERB_APP_SECRET: ${REVERB_APP_SECRET:-andytranscribe-secret}
|
|
# Server-side publish target (Docker DNS)
|
|
REVERB_HOST: reverb
|
|
REVERB_PORT: 8080
|
|
REVERB_SCHEME: http
|
|
REVERB_SERVER_HOST: 0.0.0.0
|
|
REVERB_SERVER_PORT: 8080
|
|
LOCAL_WHISPER_URL: http://whisper:8000/v1
|
|
LOCAL_WHISPER_API_KEY: ${LOCAL_WHISPER_API_KEY:-not-needed}
|
|
LOCAL_WHISPER_MODEL: ${LOCAL_WHISPER_MODEL:-Systran/faster-whisper-base}
|
|
TRANSCRIPTION_TIMEOUT: ${TRANSCRIPTION_TIMEOUT:-600}
|
|
DB_QUEUE_RETRY_AFTER: ${DB_QUEUE_RETRY_AFTER:-660}
|
|
|
|
services:
|
|
app:
|
|
build:
|
|
context: .
|
|
dockerfile: Dockerfile
|
|
args:
|
|
VITE_APP_NAME: ${VITE_APP_NAME:-AndyTranscribe}
|
|
VITE_REVERB_APP_KEY: ${REVERB_APP_KEY:-andytranscribe-key}
|
|
VITE_REVERB_HOST: ${VITE_REVERB_HOST:-localhost}
|
|
VITE_REVERB_PORT: ${REVERB_HOST_PORT:-8081}
|
|
VITE_REVERB_SCHEME: ${VITE_REVERB_SCHEME:-http}
|
|
image: andytranscribe-app:latest
|
|
container_name: andytranscribe-app
|
|
ports:
|
|
- "${APP_HOST_PORT:-8080}:80"
|
|
environment:
|
|
<<: *app-env
|
|
volumes: *app-data
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-f", "http://127.0.0.1/up"]
|
|
interval: 15s
|
|
timeout: 5s
|
|
retries: 5
|
|
start_period: 20s
|
|
depends_on:
|
|
whisper:
|
|
condition: service_healthy
|
|
reverb:
|
|
condition: service_started
|
|
queue:
|
|
condition: service_started
|
|
restart: unless-stopped
|
|
|
|
queue:
|
|
build:
|
|
context: .
|
|
dockerfile: Dockerfile
|
|
args:
|
|
VITE_APP_NAME: ${VITE_APP_NAME:-AndyTranscribe}
|
|
VITE_REVERB_APP_KEY: ${REVERB_APP_KEY:-andytranscribe-key}
|
|
VITE_REVERB_HOST: ${VITE_REVERB_HOST:-localhost}
|
|
VITE_REVERB_PORT: ${REVERB_HOST_PORT:-8081}
|
|
VITE_REVERB_SCHEME: ${VITE_REVERB_SCHEME:-http}
|
|
image: andytranscribe-app:latest
|
|
container_name: andytranscribe-queue
|
|
command:
|
|
- php
|
|
- artisan
|
|
- queue:work
|
|
- database
|
|
- --sleep=1
|
|
- --tries=1
|
|
- --timeout=${TRANSCRIPTION_TIMEOUT:-600}
|
|
environment:
|
|
<<: *app-env
|
|
volumes: *app-data
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "tr '\\0' ' ' </proc/1/cmdline | grep -q 'queue:work'"]
|
|
interval: 30s
|
|
timeout: 5s
|
|
retries: 3
|
|
start_period: 20s
|
|
depends_on:
|
|
whisper:
|
|
condition: service_healthy
|
|
reverb:
|
|
condition: service_started
|
|
restart: unless-stopped
|
|
|
|
reverb:
|
|
build:
|
|
context: .
|
|
dockerfile: Dockerfile
|
|
args:
|
|
VITE_APP_NAME: ${VITE_APP_NAME:-AndyTranscribe}
|
|
VITE_REVERB_APP_KEY: ${REVERB_APP_KEY:-andytranscribe-key}
|
|
VITE_REVERB_HOST: ${VITE_REVERB_HOST:-localhost}
|
|
VITE_REVERB_PORT: ${REVERB_HOST_PORT:-8081}
|
|
VITE_REVERB_SCHEME: ${VITE_REVERB_SCHEME:-http}
|
|
image: andytranscribe-app:latest
|
|
container_name: andytranscribe-reverb
|
|
command:
|
|
- php
|
|
- artisan
|
|
- reverb:start
|
|
- --host=0.0.0.0
|
|
- --port=8080
|
|
ports:
|
|
- "${REVERB_HOST_PORT:-8081}:8080"
|
|
environment:
|
|
<<: *app-env
|
|
# Browser connects to localhost:8081; hostname used in app config for allowed hosts
|
|
REVERB_HOST: localhost
|
|
volumes: *app-data
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "tr '\\0' ' ' </proc/1/cmdline | grep -q 'reverb:start'"]
|
|
interval: 30s
|
|
timeout: 5s
|
|
retries: 3
|
|
start_period: 20s
|
|
restart: unless-stopped
|
|
|
|
whisper:
|
|
image: fedirz/faster-whisper-server:latest-cpu
|
|
container_name: andytranscribe-whisper
|
|
ports:
|
|
# Host 8090 avoids clashing with the FrankenPHP app on 8080
|
|
- "${WHISPER_HOST_PORT:-8090}:8000"
|
|
volumes:
|
|
- whisper-huggingface-cache:/root/.cache/huggingface
|
|
environment:
|
|
WHISPER__MODEL: ${LOCAL_WHISPER_MODEL:-Systran/faster-whisper-base}
|
|
restart: unless-stopped
|
|
healthcheck:
|
|
test: ["CMD", "python3", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8000/health')"]
|
|
interval: 15s
|
|
timeout: 5s
|
|
retries: 10
|
|
start_period: 30s
|
|
|
|
# GPU variant (NVIDIA). Start with:
|
|
# docker compose --profile gpu up -d whisper-gpu
|
|
whisper-gpu:
|
|
profiles: ["gpu"]
|
|
image: fedirz/faster-whisper-server:latest-cuda
|
|
container_name: andytranscribe-whisper-gpu
|
|
ports:
|
|
- "${WHISPER_HOST_PORT:-8090}:8000"
|
|
volumes:
|
|
- whisper-huggingface-cache:/root/.cache/huggingface
|
|
environment:
|
|
WHISPER__MODEL: ${LOCAL_WHISPER_MODEL:-Systran/faster-whisper-base}
|
|
restart: unless-stopped
|
|
deploy:
|
|
resources:
|
|
reservations:
|
|
devices:
|
|
- driver: nvidia
|
|
count: 1
|
|
capabilities: [gpu]
|
|
|
|
volumes:
|
|
whisper-huggingface-cache:
|