Spaces:
Paused
Paused
File size: 5,147 Bytes
f26e640 69f12cd f26e640 0c3bfb5 f26e640 e84ef16 f26e640 e84ef16 f26e640 e84ef16 f26e640 e84ef16 f26e640 e84ef16 f26e640 e84ef16 69f12cd f26e640 69f12cd a9d5f67 69f12cd 0c3bfb5 a920dd4 f26e640 69f12cd a920dd4 f26e640 a9d5f67 69f12cd f26e640 a9d5f67 69f12cd f26e640 69f12cd a9d5f67 69f12cd f26e640 a920dd4 f26e640 0c3bfb5 dc59771 f26e640 a9d5f67 f26e640 69f12cd f26e640 e84ef16 f26e640 e84ef16 a920dd4 e84ef16 69f12cd f26e640 | 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 | # All-in-one Dockerfile: Playwright API + bundled turnstile-solver.
# This is what HF Space builds (single container).
# For VPS, prefer `docker compose up` which uses solver/Dockerfile +
# this same file but with multi-service split (see docker-compose.yml).
FROM mcr.microsoft.com/playwright:v1.49.0-jammy
USER root
# --- Step 1: essential packages ---
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
util-linux procps psmisc ca-certificates curl unzip wget gnupg \
python3 python3-pip python3-venv \
&& rm -rf /var/lib/apt/lists/*
# --- Step 2: fonts (best-effort) ---
RUN apt-get update && \
for pkg in fonts-liberation fonts-noto fonts-noto-color-emoji fonts-noto-cjk \
fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg \
fonts-dejavu-core; do \
apt-get install -y --no-install-recommends "$pkg" || echo "skip: $pkg"; \
done && \
rm -rf /var/lib/apt/lists/*
# --- Step 3: Xvfb + GTK/X11 deps for Camoufox (used by the solver) ---
RUN apt-get update && \
apt-get install -y --no-install-recommends \
xvfb x11-utils dbus-x11 dumb-init \
libgtk-3-0 libdbus-glib-1-2 libxt6 libasound2 \
libx11-xcb1 libxcomposite1 libxdamage1 libxfixes3 libxrandr2 \
libpango-1.0-0 libnss3 libatk1.0-0 libatk-bridge2.0-0 \
libcups2 libxkbcommon0 libgbm1 libglib2.0-0 libexpat1 \
|| echo "Xvfb/GTK stack partial — solver may degrade" && \
rm -rf /var/lib/apt/lists/*
# --- Step 4: Google Chrome stable (best-effort) ---
RUN set -eux; \
( \
wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | gpg --dearmor -o /usr/share/keyrings/google-chrome.gpg && \
echo 'deb [signed-by=/usr/share/keyrings/google-chrome.gpg] https://dl.google.com/linux/chrome/deb/ stable main' > /etc/apt/sources.list.d/google-chrome.list && \
apt-get update && \
apt-get install -y --no-install-recommends google-chrome-stable \
) || echo "Google Chrome install failed — channel:'chrome' will be unavailable, chromium still works"; \
rm -rf /var/lib/apt/lists/*
ENV PORT=7860 \
SOLVER_PORT=9988 \
TIMEOUT_MS=1800000 \
HOME=/home/pwuser \
BUN_INSTALL=/home/pwuser/.bun \
PATH=/home/pwuser/.bun/bin:/usr/local/bin:/usr/bin:/bin \
PLAYWRIGHT_BROWSERS_PATH=/ms-playwright \
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 \
NODE_PATH=/app/node_modules:/app/helpers \
TRANSFORMERS_CACHE=/app/.cache/transformers \
TESSDATA_PREFIX=/app/tesseract-data \
COOKIES_DIR=/app/cookies \
CAMOUFOX_HEADLESS=virtual \
PYTHONUNBUFFERED=1 \
TURNSTILE_SOLVER_URL=http://127.0.0.1:9988
WORKDIR /app
RUN mkdir -p /app/runs /app/helpers /app/public /app/cookies \
/app/.cache/transformers /app/tesseract-data \
/app/solver /home/pwuser \
&& chown -R 1000:1000 /app /home/pwuser
# --- Solver: install Python deps as root (needs system site-packages access) ---
COPY --chown=1000:1000 solver/requirements.txt /app/solver/requirements.txt
RUN pip3 install --no-cache-dir --break-system-packages \
-r /app/solver/requirements.txt \
&& python3 -m camoufox fetch \
|| echo "[warn] solver dep install partial — /solve may degrade"
USER 1000
# --- Bun for the Playwright API server ---
RUN curl -fsSL https://bun.sh/install | bash
COPY --chown=1000:1000 package.json ./
RUN bun install --production --ignore-scripts
# --- Pre-fetch CAPTCHA models so first request is fast ---
RUN bun -e 'try { \
const { pipeline, env } = await import("@huggingface/transformers"); \
env.cacheDir = "/app/.cache/transformers"; \
console.log("[prefetch] whisper-tiny.en..."); \
await pipeline("automatic-speech-recognition", "Xenova/whisper-tiny.en", { quantized: true }); \
console.log("[prefetch] whisper done"); \
} catch (e) { console.warn("[prefetch] whisper skipped:", e.message); }' \
|| echo "whisper prefetch skipped"
RUN cd /app/tesseract-data && \
(curl -fsSLO https://github.com/tesseract-ocr/tessdata_fast/raw/main/eng.traineddata \
&& echo "[prefetch] tesseract eng.traineddata done") \
|| echo "tesseract prefetch skipped"
# --- Application code ---
COPY --chown=1000:1000 helpers/ ./helpers/
COPY --chown=1000:1000 public/ ./public/
COPY --chown=1000:1000 solver/solver.py solver/service.py solver/entrypoint.sh ./solver/
COPY --chown=1000:1000 solver/web ./solver/web
COPY --chown=1000:1000 server.js ./
COPY --chown=1000:1000 supervisor.sh ./
USER root
RUN chmod +x /app/solver/entrypoint.sh /app/supervisor.sh \
&& chown -R 1000:1000 /app
USER 1000
# --- Sanity check ---
RUN test -f /app/server.js \
&& test -f /app/supervisor.sh \
&& test -f /app/solver/service.py \
&& test -f /app/public/index.html \
&& test -d /app/helpers/stealth \
&& test -d /app/helpers/captcha \
&& test -f /app/node_modules/playwright/package.json \
&& echo "build artifacts OK"
EXPOSE 7860
# Supervisor launches the solver in the background, then the API in the
# foreground. If either dies the whole container exits and HF/Docker
# restarts it.
CMD ["bash", "/app/supervisor.sh"]
|