FROM python:3.11-slim # ffmpeg does the TS -> fragmented MP4 remux. ca-certificates for HTTPS. # nodejs + npm are required by the any-dl binary (npm install -g any-dl). # chromium is required so the Kick rungs that rely on a real browser can work: # * streamlink's Kick plugin falls back to headless Chromium over CDP on 403 # * any-dl reads Kick through a real --headless=new --dump-dom Chrome # Neither can work on Kick in this image without a Chromium binary. RUN apt-get update \ && apt-get install -y --no-install-recommends \ ffmpeg \ ca-certificates \ nodejs \ npm \ chromium \ && rm -rf /var/lib/apt/lists/* ENV PYTHONUNBUFFERED=1 \ PYTHONDONTWRITEBYTECODE=1 \ PYTHONPATH=/app \ PIP_NO_CACHE_DIR=1 \ LOG_LEVEL=INFO \ # Chromium discovery for the Kick solutions: prefer an explicit path, then # fall back to the standard Linux names this image provides. KICK_CHROME_PATH=/usr/bin/chromium \ CHROME_PATH=/usr/bin/chromium WORKDIR /app COPY requirements.txt . # yt-dlp moves fast and its extractors break weekly: always take the latest. # streamlink and curl_cffi are kept because kick-api and the Kick HLS paths use # them, and curl_cffi's Chrome TLS fingerprint is what lets kick-api call # Kick's own API from a datacenter IP instead of getting 403. RUN pip install --no-cache-dir -U pip \ && pip install --no-cache-dir -U -r requirements.txt # any-dl is the fourth independent Kick solution. Installing it globally rather # than from a package.json keeps the image small and matches how the binary is # invoked (/usr/local/bin/any-dl after npm install -g). RUN npm install -g any-dl COPY app.py /app/app.py COPY core /app/core COPY solutions /app/solutions EXPOSE 7860 CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]