Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 35 additions & 5 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ For production deployments, migrations will be handled differently.
- Environment config: `.env` (never overwrite without confirmation)
- Database init: `database/init_db.sql`
- Docker config: `docker-compose.yml` (development only)
- Production config: Generated by `setup-opentranscribe.sh`
- Production config: Generated by `setup-opentranscribe.sh`
- Frontend build: `frontend/vite.config.ts`

## AI Processing Workflow
Expand Down Expand Up @@ -196,7 +196,7 @@ The application now includes optional AI-powered features using Large Language M

**Deployment Options:**
- **Cloud-Only**: Use `.env` configuration with external providers (OpenAI, Claude, etc.)
- **Local vLLM**: Run `docker compose -f docker-compose.yml -f docker-compose.vllm.yml up`
- **Local vLLM**: Run `docker compose -f docker-compose.yml -f docker-compose.vllm.yml up`
- **Local Ollama**: Uncomment ollama service in `docker-compose.vllm.yml` and use same command
- **No LLM**: Leave LLM_PROVIDER empty for transcription-only mode

Expand Down Expand Up @@ -224,8 +224,8 @@ ${MODEL_CACHE_DIR}/
The system uses simple volume mappings to cache models to their natural locations:
```yaml
volumes:
- ${MODEL_CACHE_DIR}/huggingface:/root/.cache/huggingface
- ${MODEL_CACHE_DIR}/torch:/root/.cache/torch
- ${MODEL_CACHE_DIR}/huggingface:/home/appuser/.cache/huggingface
- ${MODEL_CACHE_DIR}/torch:/home/appuser/.cache/torch
```

### Key Benefits
Expand All @@ -234,6 +234,36 @@ volumes:
- **User configurable**: Simple `.env` variable controls cache location
- **No re-downloads**: Models cached after first download (2.5GB total)

## Security Features

### Non-Root Container User

OpenTranscribe backend containers run as a non-root user (`appuser`, UID 1000) following Docker security best practices.

**Benefits:**
- Follows principle of least privilege
- Reduces security risk from container escape vulnerabilities
- Compliant with security scanning tools (Trivy, Snyk, etc.)
- Prevents host root compromise in case of container breach

**Migration for Existing Deployments:**

If you have an existing installation with model cache owned by root, run the permission fix script:

```bash
# Fix permissions on existing model cache
./scripts/fix-model-permissions.sh
```

This script will change ownership of your model cache to UID:GID 1000:1000, making it accessible to the non-root container user.

**Technical Details:**
- Container user: `appuser` (UID 1000, GID 1000)
- User groups: `appuser`, `video` (for GPU access)
- Cache directories: `/home/appuser/.cache/huggingface`, `/home/appuser/.cache/torch`
- Multi-stage build for minimal attack surface
- Health checks for container orchestration

## Common Tasks

### Adding New API Endpoints
Expand All @@ -254,4 +284,4 @@ volumes:
1. Modify `database/init_db.sql`
2. Update SQLAlchemy models
3. Update Pydantic schemas
4. Reset dev environment: `./opentr.sh reset dev`
4. Reset dev environment: `./opentr.sh reset dev`
188 changes: 0 additions & 188 deletions backend/DOCKER_STRATEGY.md

This file was deleted.

90 changes: 73 additions & 17 deletions backend/Dockerfile.prod
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
FROM python:3.12-slim-bookworm
# =============================================================================
# OpenTranscribe Backend - Production Dockerfile
# Multi-stage build optimized for security with non-root user
# Updated with cuDNN 9 compatibility for PyTorch 2.8.0+cu128
# =============================================================================

WORKDIR /app
# -----------------------------------------------------------------------------
# Stage 1: Build Stage - Install Python dependencies with compilation
# -----------------------------------------------------------------------------
FROM python:3.12-slim-bookworm AS builder

WORKDIR /build

# Install system dependencies
RUN apt-get update && apt-get install -y \
# Install build dependencies (only in this stage)
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
curl \
ffmpeg \
libsndfile1 \
libimage-exiftool-perl \
gcc \
g++ \
&& rm -rf /var/lib/apt/lists/*

# Copy requirements file
# Copy only requirements first for better layer caching
COPY requirements.txt .

# Install Python dependencies
Expand All @@ -20,20 +27,69 @@ COPY requirements.txt .
# CTranslate2 4.6.0+ - cuDNN 9 support
# WhisperX 3.7.0 - latest version with ctranslate2 4.5+ compatibility
# NumPy 2.x - fully compatible with all packages, no security issues
RUN pip install --no-cache-dir -r requirements.txt
# Use --user to install to /root/.local which we'll copy to final stage
RUN pip install --user --no-cache-dir --no-warn-script-location -r requirements.txt

# -----------------------------------------------------------------------------
# Stage 2: Runtime Stage - Minimal production image with non-root user
# -----------------------------------------------------------------------------
FROM python:3.12-slim-bookworm

# OCI annotations for container metadata and compliance
LABEL org.opencontainers.image.title="OpenTranscribe Backend" \
org.opencontainers.image.description="AI-powered transcription backend with WhisperX and PyAnnote" \
org.opencontainers.image.vendor="OpenTranscribe" \
org.opencontainers.image.authors="OpenTranscribe Contributors" \
org.opencontainers.image.licenses="MIT" \
org.opencontainers.image.source="https://github.com/davidamacey/OpenTranscribe" \
org.opencontainers.image.documentation="https://github.com/davidamacey/OpenTranscribe/blob/master/README.md"

# Install only runtime dependencies (no build tools)
RUN apt-get update && apt-get install -y --no-install-recommends \
curl \
ffmpeg \
libsndfile1 \
libimage-exiftool-perl \
libgomp1 \
&& rm -rf /var/lib/apt/lists/* \
&& apt-get clean

# Create non-root user for security
# Add to video group for GPU access
RUN groupadd -r appuser && \
useradd -r -g appuser -G video -u 1000 -m -s /bin/bash appuser && \
mkdir -p /app /app/models /app/temp && \
chown -R appuser:appuser /app

# Set working directory
WORKDIR /app

# Copy Python packages from builder stage
COPY --from=builder --chown=appuser:appuser /root/.local /home/appuser/.local

# Ensure scripts in .local are usable by adding to PATH
# Set LD_LIBRARY_PATH for cuDNN libraries from PyTorch package
# This ensures PyAnnote and other tools can find cuDNN 9 libraries
# Must be set at build time to persist in the container
ENV LD_LIBRARY_PATH=/usr/local/lib/python3.12/site-packages/nvidia/cudnn/lib:/usr/local/lib/python3.12/site-packages/nvidia/cuda_runtime/lib

# Create directories for models and temporary files
RUN mkdir -p /app/models /app/temp
# Set cache directories to user home
ENV PATH=/home/appuser/.local/bin:$PATH \
PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
LD_LIBRARY_PATH=/home/appuser/.local/lib/python3.12/site-packages/nvidia/cudnn/lib:/home/appuser/.local/lib/python3.12/site-packages/nvidia/cuda_runtime/lib \
HF_HOME=/home/appuser/.cache/huggingface \
TRANSFORMERS_CACHE=/home/appuser/.cache/huggingface/transformers \
TORCH_HOME=/home/appuser/.cache/torch

# Copy application code
COPY . .
COPY --chown=appuser:appuser . .

# Switch to non-root user
USER appuser

# Health check for container orchestration
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
CMD curl -f http://localhost:8080/health || exit 1

# Expose port
# Expose application port
EXPOSE 8080

# Command to run the application in production (no reload)
Expand Down
Loading
Loading