-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy pathDockerfile.prod
More file actions
129 lines (108 loc) · 5.65 KB
/
Dockerfile.prod
File metadata and controls
129 lines (108 loc) · 5.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# =============================================================================
# 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
# =============================================================================
# Deno JS runtime — required by yt-dlp for YouTube PO-token generation.
# Using the official Deno binary image so we can COPY it without any
# shell scripts or network calls in the runtime stage.
FROM denoland/deno:bin AS deno-bin
# -----------------------------------------------------------------------------
# Stage 1: Build Stage - Install Python dependencies with compilation
# -----------------------------------------------------------------------------
FROM python:3.13-slim-trixie AS builder
WORKDIR /build
# Install build dependencies (only in this stage)
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
gcc \
g++ \
git \
&& rm -rf /var/lib/apt/lists/*
# Copy only requirements first for better layer caching
COPY requirements.txt .
# Upgrade pip to latest version first (security fix for CVE-2025-8869)
RUN pip install --user --no-cache-dir --upgrade pip
# Install Python dependencies
# All packages now use cuDNN 9 for CUDA 12.8 compatibility
# PyTorch 2.8.0+cu128 - includes CVE-2025-32434 security fix
# CTranslate2 4.6.0+ - cuDNN 9 support
# NumPy 2.x - fully compatible with all packages, no security issues
# 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
# Install WhisperX with --no-deps to keep our version pins in requirements.txt
# WhisperX 3.8.1 has native pyannote-audio>=4.0.0 support — no monkey patches needed
# We still use --no-deps to prevent surprise dependency upgrades
RUN pip install --user --no-cache-dir --no-warn-script-location --no-deps whisperx==3.8.1
# -----------------------------------------------------------------------------
# Stage 2: Runtime Stage - Minimal production image with non-root user
# -----------------------------------------------------------------------------
FROM python:3.13-slim-trixie
# 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="AGPL-3.0" \
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).
# `apt-get upgrade -y` pulls the latest security patches for system libs
# (libssl, libexpat, libpng, libgdk-pixbuf, etc.) on every image build, so
# we pick up Debian security updates without having to bump the base image
# tag manually. This is important because the base image (python:3.13-slim-
# trixie) may have been built before the latest security advisories landed.
RUN apt-get update && apt-get upgrade -y && 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 && \
mkdir -p /home/appuser/.cache/huggingface \
/home/appuser/.cache/torch \
/home/appuser/.cache/nltk_data \
/home/appuser/.cache/sentence-transformers \
/home/appuser/.cache/yt-dlp && \
chown -R appuser:appuser /home/appuser/.cache
# Set working directory
WORKDIR /app
# Copy Python packages from builder stage
COPY --from=builder --chown=appuser:appuser /root/.local /home/appuser/.local
# Copy Deno binary — required by yt-dlp (since 2025.11) to generate YouTube
# proof-of-origin (PO) tokens. Without a JS runtime every YouTube request is
# flagged as a bot. chmod ensures the bit is set even if the source image
# permission differs.
COPY --from=deno-bin /deno /usr/local/bin/deno
RUN chmod +x /usr/local/bin/deno
# 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
# Set cache directories to user home
ENV PATH=/home/appuser/.local/bin:$PATH \
PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
PYTHONWARNINGS=ignore::UserWarning:pyannote.audio.core.io \
LD_LIBRARY_PATH=/home/appuser/.local/lib/python3.13/site-packages/nvidia/cudnn/lib:/home/appuser/.local/lib/python3.13/site-packages/nvidia/cuda_runtime/lib \
HF_HOME=/home/appuser/.cache/huggingface \
TORCH_HOME=/home/appuser/.cache/torch \
NLTK_DATA=/home/appuser/.cache/nltk_data \
SENTENCE_TRANSFORMERS_HOME=/home/appuser/.cache/sentence-transformers
# Copy application code
COPY --chown=appuser:appuser . .
# Switch to non-root user
USER appuser
# Expose application port
EXPOSE 8080
# Health check to verify the application is responding
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
CMD curl -f http://localhost:8080/health || exit 1
# Command to run the application in production (no reload)
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8080"]