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:9222Damit läuft Chrome ohne seine Sandbox, wie in jedem Image vor sdk-0.41.0. Fügen Sie das seccomp-Profil des Images hinzu, und Chrome läuft mit seiner Sandbox; siehe die Sandbox von Chrome weiter unten.
from 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, die metrikkompatiblen Nachbauten der Windows-Schriften (damit lateinischer Text dieselben Maße hat wie mit den Schriften der Persona) und ab sdk-0.41.0 Schriften für die übrigen Schriftsysteme, die ein Windows-Rechner von Haus aus darstellt (siehe Schriften), 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). Ohne GPU im Container rendert WebGL in Software, und zwar über das Backend, dessen Limits zu der von der Persona angegebenen GPU passen: Mesa für eine Linux-Persona, im Headed- wie im Headless-Modus, und SwiftShader für eine Windows-Persona. 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 erhält jeder Container einen eigenen zufälligen Seed, der beim Start ausgegeben und über Neustarts hinweg im Profil des Containers gespeichert wird (Images vor sdk-0.39.0 gaben allen Containern denselben Seed). Setzen Sie die Variable, um eine Identität gezielt zu wählen oder wiederzuverwenden. |
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. --disable-runtime-suppression entspricht hier stock_runtime des SDK (bleibt nur auf einer Engine erhalten, die den Switch kennt); --no-sandbox schaltet die Sandbox von Chrome ab. |
CLEARCOTE_LICENSE_KEY, CC_VERSION | Startet den lizenzierten Build — siehe unten. |
CC_IDLE_EXIT_SECONDS | Stoppt, sobald so viele Sekunden lang kein CDP-Client verbunden war, gezählt ab der ersten Antwort des Browsers (Standard: nie). Kombinieren Sie das mit --rm, damit ein verwaister Container ebenfalls verschwindet. Images ab sdk-0.40.0. |
CC_SECRETS_FILE | Eine JSON-Datei im Container mit CLEARCOTE_LICENSE_KEY und/oder CC_PROXY, die beim Start einmal gelesen und dann gelöscht wird — siehe Secrets aus docker inspect heraushalten. Images ab sdk-0.40.0. |
CLEARCOTE_FONT_DIRS | Ihre eigenen Schriften, in den Container gemountet (zum Beispiel eine Kopie des Fonts-Ordners eines Windows-Rechners) — siehe Schriften. Images ab sdk-0.41.0. |
CLEARCOTE_FALLBACK_FONT_DIRS | Schriften, die nur für Zeichen verwendet werden, die sonst keine Schrift abdeckt. Das Image setzt die Variable auf seine eigenen Schriften für weitere Schriftsysteme (/usr/local/share/clearcote/fonts); lassen Sie sie stehen, es sei denn, Sie ersetzen diese Schriften. |
CLEARCOTE_PERSONA_ENV | 0 belässt die Persona auf der Kommandozeile des Browsers. Standardmäßig erreicht die Persona auf einer Engine, die das unterstützt (lizenzierter Build ab r32), den Browser des Containers über seine Umgebung und taucht daher nicht in der Prozessliste des Hosts auf; die serve-state-Zeile meldet persona_env. Images ab sdk-0.41.0. |
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. Echte Windows-Schriften, die mitCLEARCOTE_FONT_DIRSgemountet werden, beheben auf dem lizenzierten Build ab r32 die Namen (Schriften), nicht aber den Scaler, den keine Einstellung erreicht. 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=154 -e CC_VERSION=154.0.8037.57 -e CC_VERSION=r36Mounten 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-154.0.8037.57-r36/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.Ab Image sdk-0.40.0 laden mehrere lizenzierte Container, die gleichzeitig mit demselben Cache-Volume starten, die Engine nur einmal herunter: Der erste holt sie, die anderen warten darauf.
Secrets aus docker inspect heraushalten
Jede -e-Variable ist Teil der Konfiguration des Containers. Wer also docker inspect darauf ausführen kann (oder docker compose config bzw. die meisten Container-Dashboards lesen kann), sieht CLEARCOTE_LICENSE_KEY und das Passwort in einer CC_PROXY-URL im Klartext. Ab Image sdk-0.40.0 können Sie beides stattdessen als Datei übergeben: eine JSON-Datei im Container, deren Pfad CC_SECRETS_FILE angibt und die der Container beim Start einmal liest und dann löscht. Die Datei muss dem Benutzer des Images gehören (uid 10001).
printf '{"CLEARCOTE_LICENSE_KEY": "%s"}' "$CLEARCOTE_LICENSE_KEY" > clearcote-secrets.json
tar --owner=10001 --group=10001 --mode=600 -cf clearcote-secrets.tar clearcote-secrets.json
id=$(docker create -p 127.0.0.1:9222:9222 -e CC_SECRETS_FILE=/tmp/clearcote-secrets.json -v clearcote-cache:/opt/xdg-cache teamflatearth/clearcote)
docker cp - "$id:/tmp" < clearcote-secrets.tar # copy the file in before the container starts
docker start "$id"
rm clearcote-secrets.json clearcote-secrets.tarSo geht auch der macOS-Start der SDKs vor. Wer Zugriff auf den Docker-Daemon hat, kann die Dateien und den Speicher eines laufenden Containers trotzdem lesen; behandeln Sie Zugriff auf den Daemon daher wie Zugriff auf den Schlüssel.
Seit sdk-0.40.0 läuft im Image tini als Init-Prozess. Hilfsprozesse des Browsers, die sich im Container beenden (etwa aus Skripten, die Sie per docker exec ausführen und die eigene Browser starten), werden so aufgeräumt, statt sich anzusammeln. docker stop erreicht den Browser weiterhin und gibt den Lizenz-Slot frei.
Schriften
Der Browser sieht nur die Schriften, auf die das SDK ihn verweist: die im Release gebündelten Nachbauten der Windows-Schriften, danach die unten genannten Verzeichnisse. Sonst erreicht ihn nichts unter /usr/share/fonts, eine im Image installierte Schrift kann also nie die Breiten ändern, die eine Windows-Persona meldet. Ab Image sdk-0.41.0:
- Schriften für weitere Schriftsysteme sind eingebaut. Farbige Emoji, Chinesisch, Japanisch und Koreanisch (WenQuanYi Zen Hei, IPA Gothic) sowie Noto-Schriften für Arabisch, Armenisch, Bengalisch, Cherokee, Devanagari, Äthiopisch, Georgisch, Gujarati, Gurmukhi, Kannada, Khmer, Laotisch, Malayalam, Myanmar, Singhalesisch, Tamil, Telugu, Thai, Tibetisch und weitere, in
/usr/local/share/clearcote/fonts, dasCLEARCOTE_FALLBACK_FONT_DIRShinter dem Bundle aufführt. Sie werden nur für Zeichen verwendet, die das Bundle nicht darstellen kann; diese Zeichen werden also gerendert, statt als leere Kästchen zu erscheinen, im offenen wie im lizenzierten Build. Eine lateinische Familie kommt nicht hinzu. - Ihre eigenen Schriften. Mounten Sie ein Verzeichnis mit Schriften, typischerweise eine Kopie von
C:\Windows\Fontseines Windows-Rechners, und nennen Sie es inCLEARCOTE_FONT_DIRS. Es wird vor dem Bundle eingereiht. Auf dem lizenzierten Build ab r32 wird jede Familie, die es mitbringt, als sie selbst unter ihrem eigenen Namen gerendert, und Helvetica, Times, Courier und die generischen CSS-Familien folgen; ältere Engines behalten ihre Nachbauten und nutzen das Verzeichnis nur für Zeichen, die sonst keine Schrift abdeckt. Verwenden Sie nur Schriften, für die Sie eine Lizenz haben. Außerhalb von Docker ist dieselbe Einstellung fontDirs des SDK.
docker run -d -p 127.0.0.1:9222:9222 -v /srv/windows-fonts:/fonts:ro -e CLEARCOTE_FONT_DIRS=/fonts \
-e CC_PLATFORM=windows -v clearcote-cache:/opt/xdg-cache -e CLEARCOTE_LICENSE_KEY=cc_lic_... teamflatearth/clearcote
docker exec <container> clearcote info --quick # which writing systems render, which families are genuineSicherheit: 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.Die Sandbox von Chrome
Die Linux-Sandbox von Chrome führt jeden Renderer (den Prozess, der eine Seite parst und ausführt) in eigenen Namespaces unter einem seccomp-Filter aus, sodass eine Seite, die ihren Renderer kompromittiert, trotzdem auf ihn beschränkt bleibt. Mit --no-sandbox hat dieser Renderer alles, was der Benutzer des Containers hat: seine Dateien, sein Netzwerk und seine anderen Prozesse. Das Standard-seccomp-Profil von Docker verweigert die Aufrufe, die diese Namespaces anlegen, deshalb starteten Images vor sdk-0.41.0 Chrome immer mit --no-sandbox.
Ab Image sdk-0.41.0 prüft der Container zuerst: Er führt dieselben Aufrufe aus wie die Sandbox von Chrome und startet Chrome mit seiner Sandbox, wenn sie funktionieren. Starten Sie ihn mit dem seccomp-Profil, das das Image mitliefert – dem Standardprofil von Docker, ergänzt um die zwei Namespace-Aufrufe, die Chrome braucht:
# copy the profile out of the image (--tmpfs keeps docker from first copying the engine into a volume)
docker run --rm --tmpfs /opt/xdg-cache --entrypoint cat teamflatearth/clearcote /etc/clearcote/seccomp.json > clearcote-seccomp.json
docker run -d -p 127.0.0.1:9222:9222 --security-opt seccomp=clearcote-seccomp.json teamflatearth/clearcote# docker compose
services:
clearcote:
image: teamflatearth/clearcote
ports: ["127.0.0.1:9222:9222"]
security_opt: ["seccomp=./clearcote-seccomp.json"]- Das Log zeigt, wie es ausgegangen ist:
[clearcote] sandbox: on (…)oder[clearcote] sandbox: OFF, Chrome runs with --no-sandbox: …mit dem Grund und der Anleitung zum Einschalten. Dieserve-state-Zeile enthält"sandbox": trueoderfalse. Ohne das Profil läuft der Container genau wie bisher. - Außerdem braucht es den eigenen Benutzer des Images (nicht
--user 0),CAP_SYS_CHROOT(standardmäßig gewährt; fügen Sie nach--cap-drop ALLwieder--cap-add SYS_CHROOThinzu), einen Host, der unprivilegierte User-Namespaces erlaubt, und einen amd64-Rechner. Fehlt etwas davon, fällt der Container auf--no-sandboxzurück und nennt den Grund. - Der Kompromiss: Mit dem Profil kann jeder Prozess im Container, nicht nur Chrome, einen User-Namespace mit eigenem Netzwerk-Namespace anlegen und erreicht damit Netzwerkcode des Kernels, den das Standardprofil von Docker außer Reichweite hält. Die Renderer von Chrome, in denen nicht vertrauenswürdige Seiten laufen, bleiben unter dem eigenen Filter von Chrome. Ohne die Sandbox hat ein kompromittierter Renderer alles, was der Benutzer des Containers hat; das Profil ist also trotzdem die bessere Wahl. Verwenden Sie stattdessen nicht
--privileged,--cap-add SYS_ADMINoderseccomp=unconfined: Diese schalten weit mehr vom Schutz des Containers ab. CC_EXTRA_ARGS=--no-sandboxschaltet die Sandbox bewusst ab.--no-zygote,--disable-namespace-sandbox,--renderer-cmd-prefix=und die Canvas-Bridge (--canvas-bridge-url=) schalten sie ebenfalls ab, weil Chrome seine Sandbox hier mit ihnen nicht betreiben kann.- Der macOS-Start der SDKs übergibt das Profil selbst, auf einem Docker, der auf einer x86_64-CPU läuft. Auf Apple Silicon läuft das Image emuliert, und die Sandbox bleibt dort vorerst aus.
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; Schriften, die Sie mit apt installieren, bleiben für ihn also unsichtbar, bis Sie sie aufführen: Verlinken Sie die Schriften für weitere Schriftsysteme in ein Verzeichnis und nennen Sie es in CLEARCOTE_FALLBACK_FONT_DIRS (SDK 0.41.0+), wie es das offizielle Image tut, oder Ihre eigenen Schriften in CLEARCOTE_FONT_DIRS (siehe Schriften). Führen Sie nie ganz /usr/share/fonts auf: Dessen lateinische Familien würden die Breiten einer Windows-Persona verändern. 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. Sind libegl1 und libgl1-mesa-dri installiert, rendert das SDK das WebGL einer Linux-Persona über Mesa auf EGL, mit den Limits und der Renderer-Form, die echte Linux-Rechner melden: headless ab SDK 0.39.0 und ab 0.42.0 auch headed, sodass beide Modi dieselbe WebGL-Oberfläche zeigen. Ohne diese Pakete fällt es auf SwiftShader zurück. Ein Headed-Start unter Xvfb ohne Fenstermanager bekommt sein Fenster vor der ersten Seite an den Bildschirm angepasst (SDK 0.42.0).
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 libegl1 libgl1-mesa-dri \
fontconfig fonts-noto-color-emoji fonts-ipafont-gothic fonts-wqy-zenhei \
&& F=/usr/local/share/clearcote/fonts && mkdir -p $F && cd /usr/share/fonts \
&& cp -l truetype/noto/NotoColorEmoji.ttf truetype/wqy/wqy-zenhei.ttc opentype/ipafont-gothic/ipag.ttf $F/ \
&& rm -rf /var/lib/apt/lists/*
# emoji + CJK, used only where the bundle has no glyph
ENV CLEARCOTE_FALLBACK_FONT_DIRS=/usr/local/share/clearcote/fonts
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.