# syntax=docker/dockerfile:1 # Real Google Chrome for the latest-chapter poller and the kagane cover proxy. # # Not chromedp/headless-shell, which this replaces. headless-shell is a stripped # Chrome build and Cloudflare's managed challenge on kagane.to never clears for # it: measured 2026-08-08, 60s of a held-open tab still served the interstitial, # while stock Chrome from the same IP cleared in ~4s. The tells are structural # rather than a header — navigator.webdriver true, an empty plugin list, and # Chromium- rather than Chrome-branded client hints. Overriding webdriver alone # was tried and did not move it, so the browser build itself is the fix. # # zenika/alpine-chrome was also tried: its Chrome is 124 (2024), old enough that # Cloudflare refuses it outright and old enough to break chromedp's CDP structs. FROM debian:trixie-slim # Chrome is deliberately unpinned, against the usual rule. A pinned build goes # stale, and a stale browser is exactly what Cloudflare turns away — the 124 in # alpine-chrome is the worked example. Rebuild is the upgrade path. RUN apt-get update \ && apt-get install -y --no-install-recommends ca-certificates wget gnupg \ && wget -qO- https://dl.google.com/linux/linux_signing_key.pub \ | gpg --dearmor -o /usr/share/keyrings/google-chrome.gpg \ && echo "deb [arch=amd64 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 socat \ && rm -rf /var/lib/apt/lists/* # Unprivileged: Chrome refuses to run as root, and the CDP endpoint is a shell # on whatever user owns it. RUN useradd --create-home --shell /usr/sbin/nologin chrome USER chrome WORKDIR /home/chrome COPY entrypoint.sh /entrypoint.sh EXPOSE 9222 ENTRYPOINT ["/entrypoint.sh"]