From f45b81aff15f693972a8af3cc311a1bde014dcf9 Mon Sep 17 00:00:00 2001 From: Artem Timoshenko Date: Tue, 19 May 2026 22:30:48 +0300 Subject: [PATCH] integration with CloakBrowser --- .env.example | 13 ++++++ READ.md | 36 ++++++++++++++++ browser_env/Dockerfile.browser | 14 +++++- browser_env/browser_use_runner.py | 2 +- browser_env/cloak_browser_launcher.py | 62 +++++++++++++++++++++++++++ browser_env/entrypoint.sh | 56 ++++++++++++++---------- 6 files changed, 158 insertions(+), 25 deletions(-) create mode 100644 browser_env/cloak_browser_launcher.py diff --git a/.env.example b/.env.example index 3afe0b99..811c6c81 100644 --- a/.env.example +++ b/.env.example @@ -15,6 +15,19 @@ TELEGRAM_HOME_CHANNEL= BROWSER_URL=http://browser:9222 BROWSER_VIEW_URL= +# Browser engine for browser-use container: +# - chromium: default local Chromium +# - cloak: CloakBrowser stealth browser over the same CDP/noVNC pipeline +BROWSER_ENGINE=cloak + +# CloakBrowser options are used only when BROWSER_ENGINE=cloak. +CLOAK_HEADLESS=false +CLOAK_HUMANIZE=true +CLOAK_HUMAN_PRESET=default +CLOAK_PROXY= +CLOAK_GEOIP=false +CLOAK_ARGS= + BROWSER_API_HOST=0.0.0.0 BROWSER_API_PORT=8088 BROWSER_USE_RPC_URL=http://browser:8787/run diff --git a/READ.md b/READ.md index e91b3841..7049a6a2 100644 --- a/READ.md +++ b/READ.md @@ -14,6 +14,42 @@ docker compose logs tunnel ``` После команды логов листаешь терминал и ищешь ссылку https в рамке. Её вписываешь в переменную BROWSER_VIEW_URL. Чтобы увидеть действия агента, переходишь по данной сслыке и выбираешь vnc.html. + +## Выбор браузера + +Browser-use контейнер поддерживает два движка через одну и ту же CDP/noVNC схему: + +```env +BROWSER_ENGINE=chromium +``` + +`chromium` — обычный локальный Chromium, используется по умолчанию. + +```env +BROWSER_ENGINE=cloak +``` + +`cloak` — CloakBrowser stealth-режим для задач, где важны fingerprint, +WebGL/Canvas/OS/CDP-сигналы и антибот-проверки. Telegram live-логи, noVNC, +CDP-порт `9222` и browser-use RPC остаются теми же. + +Дополнительные настройки CloakBrowser в `.env`: + +```env +CLOAK_HEADLESS=false +CLOAK_HUMANIZE=true +CLOAK_HUMAN_PRESET=default +CLOAK_PROXY= +CLOAK_GEOIP=false +CLOAK_ARGS= +``` + +После смены `BROWSER_ENGINE` пересобери и перезапусти контейнеры: + +```commandline +docker compose up -d --build +``` + Далее в мессенджере просишь агента сделать что-то через tool browser-use. Во время выполнения Hermes будет обновлять одно progress-сообщение в Telegram: текущая страница, короткие действия, ошибки и просьба помочь, если замечена капча diff --git a/browser_env/Dockerfile.browser b/browser_env/Dockerfile.browser index 0d66a360..4eda2bf7 100644 --- a/browser_env/Dockerfile.browser +++ b/browser_env/Dockerfile.browser @@ -16,6 +16,12 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ procps \ curl \ ca-certificates \ + fonts-noto-color-emoji \ + fonts-freefont-ttf \ + fonts-unifont \ + fonts-ipafont-gothic \ + fonts-wqy-zenhei \ + fonts-tlwg-loma-otf \ && rm -rf /var/lib/apt/lists/* WORKDIR /src @@ -23,12 +29,16 @@ RUN mkdir -p /src/browser_data RUN python3 -m pip install --no-cache-dir --break-system-packages \ "browser-use>=0.12.5" \ - "langchain-openai>=0.3.0" + "langchain-openai>=0.3.0" \ + "cloakbrowser[geoip]>=0.3.0" + +RUN python3 -m cloakbrowser install COPY entrypoint.sh /entrypoint.sh +COPY cloak_browser_launcher.py /src/cloak_browser_launcher.py COPY browser_use_runner.py /src/browser_use_runner.py RUN chmod +x /entrypoint.sh EXPOSE 6080 9222 8787 -ENTRYPOINT ["/entrypoint.sh"] \ No newline at end of file +ENTRYPOINT ["/entrypoint.sh"] diff --git a/browser_env/browser_use_runner.py b/browser_env/browser_use_runner.py index cb7786a6..972aafde 100644 --- a/browser_env/browser_use_runner.py +++ b/browser_env/browser_use_runner.py @@ -614,7 +614,7 @@ async def run_browser_task(task, run_id=None): try: logger.info("Creating Browser...") - _append_event(run_id, "setup", "Подключаюсь к Chromium через CDP.") + _append_event(run_id, "setup", "Подключаюсь к браузеру через CDP.") browser = Browser(cdp_url=cdp_url) logger.info("Browser created") except Exception as err: diff --git a/browser_env/cloak_browser_launcher.py b/browser_env/cloak_browser_launcher.py new file mode 100644 index 00000000..41340a3b --- /dev/null +++ b/browser_env/cloak_browser_launcher.py @@ -0,0 +1,62 @@ +import asyncio +import os +import shlex +import signal + +from cloakbrowser import launch_async + + +def _env_bool(name, default): + raw = os.getenv(name) + if raw is None: + return default + return raw.strip().lower() in {"1", "true", "yes", "on"} + + +async def main(): + debug_port = os.getenv("CHROME_LOCAL_DEBUG_PORT", "9223") + args = [ + f"--remote-debugging-port={debug_port}", + "--remote-debugging-address=127.0.0.1", + "--remote-allow-origins=*", + "--window-size=1280,720", + "--no-sandbox", + "--disable-dev-shm-usage", + "--ozone-platform=x11", + ] + extra_args = os.getenv("CLOAK_ARGS", "").strip() + if extra_args: + args.extend(shlex.split(extra_args)) + + launch_kwargs = { + "headless": _env_bool("CLOAK_HEADLESS", False), + "humanize": _env_bool("CLOAK_HUMANIZE", True), + "args": args, + } + + if launch_kwargs["humanize"]: + launch_kwargs["human_preset"] = os.getenv("CLOAK_HUMAN_PRESET", "default") + + proxy = os.getenv("CLOAK_PROXY", "").strip() + if proxy: + launch_kwargs["proxy"] = proxy + + if _env_bool("CLOAK_GEOIP", False): + launch_kwargs["geoip"] = True + + browser = await launch_async(**launch_kwargs) + print(f"CloakBrowser started on 127.0.0.1:{debug_port}", flush=True) + + stop_event = asyncio.Event() + loop = asyncio.get_running_loop() + for sig in (signal.SIGINT, signal.SIGTERM): + loop.add_signal_handler(sig, stop_event.set) + + try: + await stop_event.wait() + finally: + await browser.close() + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/browser_env/entrypoint.sh b/browser_env/entrypoint.sh index 052ca6c5..b42d0480 100644 --- a/browser_env/entrypoint.sh +++ b/browser_env/entrypoint.sh @@ -11,6 +11,7 @@ CHROME_LOCAL_DEBUG_PORT="${CHROME_LOCAL_DEBUG_PORT:-9223}" CHROME_PUBLIC_DEBUG_PORT="${CHROME_PUBLIC_DEBUG_PORT:-9222}" BROWSER_USE_RPC_PORT="${BROWSER_USE_RPC_PORT:-8787}" CHROME_PROFILE_DIR="${CHROME_PROFILE_DIR:-/src/browser_data}" +BROWSER_ENGINE="${BROWSER_ENGINE:-chromium}" MAX_RESTARTS="${MAX_RESTARTS:-10}" RESTART_WINDOW_SEC="${RESTART_WINDOW_SEC:-60}" @@ -147,26 +148,38 @@ while true; do rm -f "${CHROME_PROFILE_DIR}/SingletonLock" "${CHROME_PROFILE_DIR}/SingletonCookie" "${CHROME_PROFILE_DIR}/SingletonSocket" 2>/dev/null || true - log "starting Chromium (local DevTools:${CHROME_LOCAL_DEBUG_PORT})" - chromium \ - --no-sandbox \ - --disable-dev-shm-usage \ - --ozone-platform=x11 \ - --remote-debugging-port="${CHROME_LOCAL_DEBUG_PORT}" \ - --remote-debugging-address=127.0.0.1 \ - --remote-allow-origins='*' \ - --window-size=1280,720 \ - --user-data-dir="${CHROME_PROFILE_DIR}" \ - --disable-blink-features=AutomationControlled \ - --no-first-run \ - --disable-gpu \ - --mute-audio \ - --no-default-browser-check \ - --disable-software-rasterizer \ - --disable-features=site-per-process \ - --disable-crash-reporter \ - --disable-extensions \ - --disable-sync & + case "${BROWSER_ENGINE,,}" in + chromium) + log "starting Chromium (local DevTools:${CHROME_LOCAL_DEBUG_PORT})" + chromium \ + --no-sandbox \ + --disable-dev-shm-usage \ + --ozone-platform=x11 \ + --remote-debugging-port="${CHROME_LOCAL_DEBUG_PORT}" \ + --remote-debugging-address=127.0.0.1 \ + --remote-allow-origins='*' \ + --window-size=1280,720 \ + --user-data-dir="${CHROME_PROFILE_DIR}" \ + --disable-blink-features=AutomationControlled \ + --no-first-run \ + --disable-gpu \ + --mute-audio \ + --no-default-browser-check \ + --disable-software-rasterizer \ + --disable-features=site-per-process \ + --disable-crash-reporter \ + --disable-extensions \ + --disable-sync & + ;; + cloak|cloakbrowser) + log "starting CloakBrowser (local DevTools:${CHROME_LOCAL_DEBUG_PORT})" + python3 -u /src/cloak_browser_launcher.py & + ;; + *) + log "fatal: unsupported BROWSER_ENGINE=${BROWSER_ENGINE}; expected chromium or cloak" + exit 1 + ;; + esac CHROME_PID=$! wait "$CHROME_PID" || CHROME_EXIT=$? @@ -183,7 +196,7 @@ while true; do fi RESTART_COUNT=$((RESTART_COUNT + 1)) - log "Chromium exited with code=${CHROME_EXIT}; restart ${RESTART_COUNT}/${MAX_RESTARTS} in current window" + log "${BROWSER_ENGINE} exited with code=${CHROME_EXIT}; restart ${RESTART_COUNT}/${MAX_RESTARTS} in current window" if [ "$RESTART_COUNT" -ge "$MAX_RESTARTS" ]; then log "fatal: too many Chromium restarts in ${RESTART_WINDOW_SEC}s" @@ -194,4 +207,3 @@ while true; do unset CHROME_EXIT unset CHROME_PID done -