From c7ffe46771f0c1eb0b344100766ddf22154b811d Mon Sep 17 00:00:00 2001 From: Christian Coleman Date: Sun, 22 Jun 2025 02:39:20 -0400 Subject: [PATCH] Added a warning for people that try to run a non-headless browser in a docker container. It errors in a very unhelpful way, and so this code tells the user in the output what's happening and also forces headless = True. If a user actually means to run a non-headless browser and view via X11 or something then the warning/output will lead them to the right place that they need to tweak. --- api.py | 44 ++++++++++++++++++++++++++++++++++++++++++-- sources/browser.py | 5 +++++ 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/api.py b/api.py index 425fc72..288e108 100755 --- a/api.py +++ b/api.py @@ -27,6 +27,22 @@ from dotenv import load_dotenv load_dotenv() +def is_running_in_docker(): + """Detect if code is running inside a Docker container.""" + # Method 1: Check for .dockerenv file + if os.path.exists('/.dockerenv'): + return True + + # Method 2: Check cgroup + try: + with open('/proc/1/cgroup', 'r') as f: + return 'docker' in f.read() + except: + pass + + return False + + from celery import Celery api = FastAPI(title="AgenticSeek API", version="0.1.0") @@ -52,7 +68,25 @@ def initialize_system(): stealth_mode = config.getboolean('BROWSER', 'stealth_mode') personality_folder = "jarvis" if config.getboolean('MAIN', 'jarvis_personality') else "base" languages = config["MAIN"]["languages"].split(' ') - + + # Force headless mode in Docker containers + headless = config.getboolean('BROWSER', 'headless_browser') + if is_running_in_docker() and not headless: + # Print prominent warning to console (visible in docker-compose output) + print("\n" + "*" * 70) + print("*** WARNING: Detected Docker environment - forcing headless_browser=True ***") + print("*** INFO: To see the browser, run 'python cli.py' on your host machine ***") + print("*" * 70 + "\n") + + # Flush to ensure it's displayed immediately + sys.stdout.flush() + + # Also log to file + logger.warning("Detected Docker environment - forcing headless_browser=True") + logger.info("To see the browser, run 'python cli.py' on your host machine instead") + + headless = True + provider = Provider( provider_name=config["MAIN"]["provider_name"], model=config["MAIN"]["provider_model"], @@ -62,7 +96,7 @@ def initialize_system(): logger.info(f"Provider initialized: {provider.provider_name} ({provider.model})") browser = Browser( - create_driver(headless=config.getboolean('BROWSER', 'headless_browser'), stealth_mode=stealth_mode, lang=languages[0]), + create_driver(headless=headless, stealth_mode=stealth_mode, lang=languages[0]), anticaptcha_manual_install=stealth_mode ) logger.info("Browser initialized") @@ -251,6 +285,12 @@ async def process_query(request: QueryRequest): interaction.save_session() if __name__ == "__main__": + # Print startup info + if is_running_in_docker(): + print("[AgenticSeek] Starting in Docker container...") + else: + print("[AgenticSeek] Starting on host machine...") + envport = os.getenv("BACKEND_PORT") if envport: port = int(envport) diff --git a/sources/browser.py b/sources/browser.py index 639eaec..eff6bf7 100644 --- a/sources/browser.py +++ b/sources/browser.py @@ -121,6 +121,11 @@ def create_undetected_chromedriver(service, chrome_options) -> webdriver.Chrome: def create_driver(headless=False, stealth_mode=True, crx_path="./crx/nopecha.crx", lang="en") -> webdriver.Chrome: """Create a Chrome WebDriver with specified options.""" + # Warn if trying to run non-headless in Docker + if not headless and os.path.exists('/.dockerenv'): + print("[WARNING] Running non-headless browser in Docker may fail!") + print("[WARNING] Consider setting headless=True or headless_browser=True in config.ini") + chrome_options = Options() chrome_path = get_chrome_path()