Deployment — Docker & CDP-Endpunkt
Betreiben Sie Clearcote als dauerhaften CDP-Endpunkt und richten Sie jedes vorhandene Framework darauf — Playwright, Puppeteer, browser-use, Crawl4AI, Stagehand —, ohne Code zu ändern. Das Binary wird direkt gestartet (ohne --enable-automation), daher bleibt navigator.webdriver auf false: konstruktionsbedingt unauffällig.
Offizielles Docker-Image
Image ziehen und loslegen. Jeder CDP-Client verbindet sich über den freigegebenen Port.
docker run -d --rm -p 127.0.0.1:9222:9222 -e CC_FINGERPRINT=user-7423 teamflatearth/clearcote # CDP on http://localhost:9222from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.connect_over_cdp("http://localhost:9222") # your code, unchanged
page = browser.contexts[0].new_page() # the container's own profile
page.goto("https://example.com")
print(page.title())Das Image enthält fest eingebaut den per SHA-256 verifizierten offenen Build für Linux und die metrikkompatiblen Nachbauten der Windows-Schriften (damit lateinischer Text dieselben Maße hat wie mit den Schriften der Persona; das Bundle des offenen Builds enthält keine CJK-Schriften, chinesischer, japanischer und koreanischer Text wird also ohne Schrift dargestellt, bis Sie den lizenzierten Build verwenden, dessen Bundle sie enthält) und nutzt standardmäßig eine kohärente native Linux-Persona. Der Browser läuft im Headed-Modus auf einem virtuellen Display (CC_HEADLESS=1 für reinen Headless-Betrieb). Konfigurieren lässt sich das Image vollständig über Umgebungsvariablen:
docker run -d -p 127.0.0.1:9222:9222 -e CC_PLATFORM=linux -e CC_FINGERPRINT=user-7423 -e CC_ACCEPT_LANGUAGE=en-US -e CC_TIMEZONE=America/New_York teamflatearth/clearcote| Variable | Bedeutung |
|---|---|
CC_FINGERPRINT | Seed → stabile Identität. Ohne diese Variable präsentieren alle Container dieselbe Identität (Seed clearcote-docker); geben Sie also jedem Container einen eigenen. |
CC_PLATFORM | linux (Standard) | windows | macos | android. Eine Windows-Persona schaltet außerdem Widevine ein und auf dem lizenzierten Build (151 r15+) den HLSL-Shader-Dialekt (zum Überschreiben: CC_WIDEVINE / CC_SHADER_DIALECT). |
CC_BRAND, CC_BRAND_VERSION | Chrome (Standard) | Edge | Opera | Vivaldi sowie die Version, die diese Marke angibt. |
CC_ACCEPT_LANGUAGE, CC_TIMEZONE | Sprachliste und IANA-Zeitzone. |
CC_TLS_PROFILE | Nicht setzen: TLS folgt dann der Chrome-Version, die die Persona angibt. Pinnen Sie chrome-<major> nur zusammen mit einer passenden CC_BRAND_VERSION. |
CC_HARDWARE_CONCURRENCY, CC_GPU_VENDOR, CC_GPU_RENDERER, CC_STORAGE_QUOTA | Einzelne Persona-Werte. |
CC_HEADLESS, CC_SCREEN | 1 für reinen Headless-Betrieb; die Größe des virtuellen Bildschirms (Standard 1920x1080x24). |
CC_EXTRA_ARGS | Zusätzliche Browser-Switches, durch Leerzeichen getrennt. |
CLEARCOTE_LICENSE_KEY, CC_VERSION | Startet den lizenzierten Build — siehe unten. |
Geben Sie sich als das Betriebssystem aus, auf dem der Container läuft. Manches, was eine Seite auslesen kann, stammt vom Host-Betriebssystem unterhalb des Browsers, und keine Persona-Einstellung reicht bis dorthin. In diesem Linux-Image wird Text vom FreeType-Scaler von Linux skaliert, und die Schriften kommen aus fontconfig, ganz gleich, wasCC_PLATFORMsagt. Gemessen auf diesem Image mitCC_PLATFORM=windows: Wird die Schriftgröße in Schritten von 0,01 px verändert, ändert sich die Textbreite bei 66 % der Schritte (echtes Chrome unter Windows: 99 %), und Segoe UI und Georgia gelten bei der Messung als installiert, lassen sich aber nicht per Name laden. Der Fingerprint-Test schlägt bei beidem an. Die Standard-Linux-Persona besteht. Für eine Windows-Identität nutzen Sie den Windows-Build oder gehostete Browser, die auf Windows-Rechnern laufen. Dasselbe gilt fürserve()undlaunch()auf einem Linux-Server. Details: Der Font-Stack unter dem User-Agent.
Lizenzierter Build in Docker — Schlüssel übergeben, Cache mounten
Das Image bringt den offenen Build fest eingebaut mit. Setzen Sie CLEARCOTE_LICENSE_KEY, und der Container bezieht stattdessen den lizenzierten Build — den neuesten oder, im Pro-Plan, einen bestimmten per CC_VERSION. Mit kostenlosen Schlüsseln läuft immer der neueste Build; eine gepinnte Version wird abgelehnt.
docker run -d -p 127.0.0.1:9222:9222 -v clearcote-cache:/opt/xdg-cache -e CLEARCOTE_LICENSE_KEY=cc_lic_... teamflatearth/clearcote
# Pro only: pin a major, an exact build, or a revision
# -e CC_VERSION=153 -e CC_VERSION=153.0.8010.36 -e CC_VERSION=r28Mounten Sie immer das Cache-Volume. Ein lizenzierter Container lädt die Engine beim ersten Start herunter; ohne persistentes Volume tut das jeder Container erneut. Mit dem Volume starten spätere Container aus dem gecachten Build.
Das Startup-Log zeigt, welche Engine Sie bekommen haben — ein falsch konfigurierter Schlüssel fällt so sofort auf und nicht erst beim ersten blockierten Request:
[clearcote] engine: /opt/xdg-cache/clearcote/pro-153.0.8010.36-r28/browser/chrome (licensed)
[clearcote] licence lease acquiredErfordert ein Image, das mit SDK 0.26.1 oder neuer gebaut wurde, und mit 0.30.0 oder neuer für einen kostenlosen Schlüssel von GitHub — der lizenzierte Browser erwartet, dass ein kostenloser Container seine Lizenz während der Laufzeit aktuell hält, und verweigert ein älteres Image. Ältere veröffentlichte Images ignorieren den Schlüssel und liefern stillschweigend den offenen Build aus — aktualisieren Sie mit docker pull teamflatearth/clearcote. Ein lizenzierter Lauf bezieht beim Start außerdem ein Concurrency-Lease, der Container braucht also ausgehenden Zugriff auf die Lizenz-API; schlägt das Lease fehl, beendet sich der Container unter Angabe des Grundes, statt eine Engine zu starten, die nicht laufen kann. Mit einem kostenlosen Schlüssel läuft über alle Ihre Container hinweg immer nur ein Browser gleichzeitig — siehe wie lizenzierte Browser gezählt werden.Sicherheit: Wer den CDP-Endpunkt erreicht, hat volle Kontrolle über den Browser. Geben Sie ihn nur in vertrauenswürdigen Netzen frei — -p 127.0.0.1:9222:9222 hält ihn lokal auf dem Host. Das docker/ Dockerfile ist nachprüfbar — bauen und verifizieren Sie es selbst.Dauerhafter CDP-Endpunkt aus dem SDK — serve()
Starten Sie das Binary selbst und erhalten Sie eine cdp_url, an die sich jeder Client anhängen kann. Derselbe unauffällige Direktstart wie beim Image, gesteuert aus Ihrem eigenen Prozess.
from clearcote import serve
srv = serve(fingerprint="seed-123", platform="windows") # -> srv.cdp_url
# attach ANY CDP client:
# playwright: p.chromium.connect_over_cdp(srv.cdp_url)
# puppeteer: puppeteer.connect({ browserURL: srv.cdp_url, defaultViewport: null })
# browser-use / Crawl4AI / Stagehand: point them at srv.cdp_url
srv.close()import { serve } from "clearcote";
const srv = await serve({ fingerprint: "seed-123", platform: "windows" });
// srv.cdpUrl -> connectOverCDP / puppeteer.connect({ browserURL, defaultViewport: null })
await srv.close();Im Headless-Modus bekommt der bereitgestellte Browser ein Display in realer Größe — das der Persona oder eines, das aus echten Desktops ausgewählt wird —, und sein Fenster wird an den Arbeitsbereich angepasst, bevor sich ein Client verbindet. So meldet jede Seite, jeder Tab und jedes Popup ein Fenster, das auf den Bildschirm passt (SDK 0.31+). Für ein kleineres Fenster übergeben Sie windowSize: { width, height } (window_size in Python, WindowSize in .NET); mit Ihrem eigenen --window-size in args übernehmen Sie selbst die Kontrolle.
Ein Endpunkt, viele Identitäten — clearcote serve
Aus der Shell (Python- und Node-Pakete, 0.29+) betreibt clearcote serve einen dauerhaften Endpunkt, der für jede Identität, die eine Verbindung anfordert, einen eigenen Browser startet — Seed, Proxy, Zeitzone und Sprache kommen aus der Verbindungs-URL. Derselbe Seed nutzt seinen bereits laufenden Browser wieder.
clearcote serve --port 9222 --idle-timeout 300 --max-browsers 16
# then, from any Playwright client:
# chromium.connect_over_cdp("http://127.0.0.1:9222?fingerprint=acct-1&platform=windows")
# chromium.connect_over_cdp("http://127.0.0.1:9222?fingerprint=acct-2&proxy=socks5://user:pass@host:1080&geoip=true")
# (a password-protected proxy needs the licensed build)Standardmäßig bindet sich der Endpunkt an localhost und lehnt Requests ab, die eine Webseite auslösen könnte. Inaktive Identitäten werden nach --idle-timeout Sekunden geschlossen, --max-browsers begrenzt, wie viele gleichzeitig laufen (weitere Identitäten erhalten HTTP 429), --data-dir behält das Profil jeder Identität über Neustarts hinweg, und --allow-host / --allow-origin ermöglichen den Betrieb hinter einem Reverse-Proxy. Unter http://127.0.0.1:9222/ sehen Sie, was gerade läuft. Mit einem Schlüssel „Kostenlos mit GitHub“ läuft jeweils nur ein Browser. Das ältere Skript clearcote-serve --port 9222 --fingerprint seed-123 für eine einzelne Identität ist weiterhin im Python-Paket enthalten.
Direkt — der offene Build ohne SDK
Der offene Build auf der Releases-Seite ist ein gewöhnliches Chromium-Binary, das Sie selbst mit executable_path und Switches starten können. Der lizenzierte Build braucht das SDK, das sein Lizenz-Token verwaltet. Die zusätzlichen Argumente unten sind die wichtigsten Standardwerte, die das SDK für diesen Seed unter Windows hinzufügt (außerdem führt es Feature-Flags zusammen und schaltet hinter einem Proxy QUIC ab):
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(
executable_path=r"C:\clearcote\chrome.exe",
ignore_default_args=["--enable-automation", "--enable-unsafe-swiftshader"],
args=[
"--fingerprint=seed-123",
"--fingerprint-platform=windows",
"--fingerprint-brand=chrome",
"--accept-lang=en-US,en",
"--lang=en-US",
"--timezone=America/New_York",
"--webrtc-ip-handling-policy=disable_non_proxied_udp",
"--ignore-gpu-blocklist",
],
)
browser.new_page().goto("https://example.com")Eigenes Image bauen (SDK-gesteuert)
Clearcote liefert ein Linux-x64-Binary und läuft daher headless in einem Container. Das Image braucht die Laufzeitbibliotheken des Browsers, fontconfig und das SDK. Der Browser verwendet das Schriften-Bundle seines Releases statt der Systemschriften; wie beim offiziellen Image enthält der offene Build keine CJK-Schriften (das Bundle des lizenzierten Builds enthält sie). Unter Linux ist die Persona standardmäßig eine kohärente native Linux-Identität. Der Schutz vor WebRTC-Leaks ist standardmäßig aktiv; die Privacy-Sandbox-APIs bleiben an, wie in Google Chrome.
FROM node:22-slim
RUN apt-get update && apt-get install -y --no-install-recommends \
xz-utils libnss3 libnspr4 libgbm1 libasound2 libatk1.0-0 libatk-bridge2.0-0 libcups2 libdrm2 \
libxkbcommon0 libxcomposite1 libxdamage1 libxrandr2 libxfixes3 libxext6 libxrender1 \
libpango-1.0-0 libcairo2 libx11-6 libxcb1 libexpat1 libdbus-1-3 ca-certificates \
fontconfig fonts-liberation fonts-noto-color-emoji fonts-unifont fonts-ipafont-gothic fonts-wqy-zenhei \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
RUN npm i clearcote
RUN node --input-type=module -e "import { download } from 'clearcote'; await download();" # bake the binary in
COPY run.mjs .
CMD ["node", "run.mjs"]import { launchPersistentContext } from "clearcote";
const ctx = await launchPersistentContext("/tmp/prof", {
headless: true,
fingerprint: "user-1",
proxy: { server: "http://gateway:8080", username: "u", password: "p" },
geoip: true, // timezone + languages + WebRTC IP matched to the proxy exit
humanize: true, // trusted bezier input; navigator.webdriver stays false
args: ["--no-sandbox"],
});
const page = ctx.pages()[0] ?? (await ctx.newPage());
await page.goto("https://example.com");
await ctx.close();Starten Sie den Container mit--shm-size=1g, um Abstürze wegen/dev/shmauf aufwendigen Seiten zu vermeiden. In Python funktioniert es genauso (from clearcote import launch_persistent_context, Optionen insnake_case).
Was sich per CDP verbinden lässt
| Client | Vorgehen |
|---|---|
| Playwright | chromium.connect_over_cdp(url) / connectOverCDP(url) |
| Puppeteer | puppeteer.connect({ browserURL: url, defaultViewport: null }) |
| browser-use · Crawl4AI · Stagehand | die CDP-/Endpoint-Einstellung auf die URL richten |
| Alles, was CDP spricht | das rohe DevTools Protocol auf dem Port |
Soll stattdessen ein KI-Agent den Browser steuern? Siehe den MCP-Server. Sie fragen sich, warum ein Direktstart unauffälliger ist? Siehe Wie Erkennung funktioniert.