[GH-ISSUE #100] [Bug]: Screenshot functionality #56

Closed
opened 2026-06-06 22:08:50 -04:00 by yindo · 11 comments
Owner

Originally created by @adriaanvermaak on GitHub (Feb 13, 2026).
Original GitHub issue: https://github.com/vxcontrol/pentagi/issues/100

Originally assigned to: @asdek on GitHub.

Affected Component

Core Services (Frontend UI/Backend API)

Describe the bug

Hi @asdek and Team,

i have enabled duckduckgo, also provided the google and tavily api keys to the environment, however screenshots dont happen. from the terminal logs we can see that it attempts to use npm/selenium to download and attempt an install of those tools.

why doesnt it use te tools that are their like the scrapping service and the enabled google and tavily api's?is this an issue
with the prompting perhaps as the default sys prompts are all default.

also how best would we setup a serxing environment for this? an suggestions?

i also also noticed that the kali image is a bit like, the curl isnt even part of the image? should we opt to have the full image pulled with all tools by default? as the kali containers are in a closed env.

looking forward to your response

Steps to Reproduce

na

System Configuration

na

Logs and Artifacts

No response

Screenshots or Recordings

No response

Verification

  • I have checked that this issue hasn't been already reported
  • I have provided all relevant configuration files (with sensitive data removed)
  • I have included relevant logs and error messages
  • I am running the latest version of PentAGI
Originally created by @adriaanvermaak on GitHub (Feb 13, 2026). Original GitHub issue: https://github.com/vxcontrol/pentagi/issues/100 Originally assigned to: @asdek on GitHub. ### Affected Component Core Services (Frontend UI/Backend API) ### Describe the bug Hi @asdek and Team, i have enabled duckduckgo, also provided the google and tavily api keys to the environment, however screenshots dont happen. from the terminal logs we can see that it attempts to use npm/selenium to download and attempt an install of those tools. why doesnt it use te tools that are their like the scrapping service and the enabled google and tavily api's?is this an issue with the prompting perhaps as the default sys prompts are all default. also how best would we setup a serxing environment for this? an suggestions? i also also noticed that the kali image is a bit like, the curl isnt even part of the image? should we opt to have the full image pulled with all tools by default? as the kali containers are in a closed env. looking forward to your response ### Steps to Reproduce na ### System Configuration na ### Logs and Artifacts _No response_ ### Screenshots or Recordings _No response_ ### Verification - [ ] I have checked that this issue hasn't been already reported - [ ] I have provided all relevant configuration files (with sensitive data removed) - [ ] I have included relevant logs and error messages - [ ] I am running the latest version of PentAGI
yindo added the bug label 2026-06-06 22:08:50 -04:00
yindo closed this issue 2026-06-06 22:08:50 -04:00
Author
Owner

@asdek commented on GitHub (Feb 13, 2026):

hey @adriaanvermaak

let me address your questions one by one:

  • All requests to Tavily, Google, and DuckDuckGo are available on the Searches tab in the UI. If you connect Searxng, those queries will also appear there.

  • Based on our experience, Searxng is necessary when working in a closed network environment where you don't want to configure HTTP Proxy for the PentAGI installation. You can separate the deployment so that the Searxng VM has internet access while the worker machine doesn't.

  • Screenshots are created via the Browser tool, which is a component called scraper in the deployment. It's a separate Docker container that runs from this image and is deployed alongside PentAGI in the same docker-compose.yml file.

  • Why screenshots aren't being created: This is either a configuration error OR the AI agents simply don't need screenshots for their current tasks. Typically, you can explicitly ask the agent in your initial prompt to use the browser for conducting attacks, and it will create a screenshot for each action. Obviously, this is more relevant for client-side attacks.

  • Regarding tools in Kali containers: We have a pre-built Kali Linux image available at Docker Hub that's best to download in advance on the worker node. You can do this via docker pull or through the installer's Maintenance section using either "Download Worker Image" or "Update Worker Image" (depending on whether it's already been downloaded).

  • To separate the main node from the worker node (for enhanced security and isolation), please follow this guide.

  • For the system to choose this image, the initial task that starts the flow must be related to pentesting, vulnerability research, or anything similar to cybersecurity topics. Also, the DOCKER_DEFAULT_IMAGE_FOR_PENTEST environment variable should be either empty or set to vxcontrol/kali-linux. At this stage, internet access is required on the worker node.

  • To check which Docker image the worker container is actually running from, execute docker ps while the flow is active. The value for the pentagi-terminal-* container should be vxcontrol/kali-linux:latest. Unfortunately, this isn't exposed in the UI yet.

  • This image already includes everything necessary for agent operations. However, if there's no internet access, you should explicitly mention this in the initial prompt to the agent. This will save a lot of money and time as the agent will only use out-of-the-box tools.

Also, without the PentAGI container logs, it's hard to determine if the issue is in the logic or configuration. Please feel free to share your logs in a follow-up message, and we can investigate together to find the best solution

<!-- gh-comment-id:3896843808 --> @asdek commented on GitHub (Feb 13, 2026): hey @adriaanvermaak let me address your questions one by one: * All requests to Tavily, Google, and DuckDuckGo are available on the **Searches** tab in the UI. If you connect Searxng, those queries will also appear there. * Based on our experience, Searxng is necessary when working in a closed network environment where you don't want to configure HTTP Proxy for the PentAGI installation. You can separate the deployment so that the Searxng VM has internet access while the worker machine doesn't. * Screenshots are created via the **Browser tool**, which is a component called `scraper` in the deployment. It's a separate Docker container that runs from [this image](https://hub.docker.com/r/vxcontrol/scraper) and is deployed alongside PentAGI in the same docker-compose.yml file. * **Why screenshots aren't being created**: This is either a configuration error OR the AI agents simply don't need screenshots for their current tasks. Typically, you can explicitly ask the agent in your initial prompt to use the browser for conducting attacks, and it will create a screenshot for each action. Obviously, this is more relevant for client-side attacks. * **Regarding tools in Kali containers**: We have a pre-built [Kali Linux image](https://hub.docker.com/r/vxcontrol/kali-linux) available at Docker Hub that's best to download in advance on the worker node. You can do this via `docker pull` or through the installer's **Maintenance** section using either "Download Worker Image" or "Update Worker Image" (depending on whether it's already been downloaded). * To separate the main node from the worker node (for enhanced security and isolation), please follow [this guide](https://github.com/vxcontrol/pentagi/blob/master/examples/guides/worker_node.md). * For the system to choose this image, the initial task that starts the flow must be related to pentesting, vulnerability research, or anything similar to cybersecurity topics. Also, the `DOCKER_DEFAULT_IMAGE_FOR_PENTEST` environment variable should be either empty or set to `vxcontrol/kali-linux`. At this stage, internet access is required on the worker node. * To check which Docker image the worker container is actually running from, execute `docker ps` while the flow is active. The value for the `pentagi-terminal-*` container should be `vxcontrol/kali-linux:latest`. Unfortunately, this isn't exposed in the UI yet. * This image already includes everything necessary for agent operations. However, if there's no internet access, you should explicitly mention this in the initial prompt to the agent. This will save a lot of money and time as the agent will only use out-of-the-box tools. Also, without the PentAGI container logs, it's hard to determine if the issue is in the logic or configuration. Please feel free to share your logs in a follow-up message, and we can investigate together to find the best solution
Author
Owner

@adriaanvermaak commented on GitHub (Feb 13, 2026):

hi there @asdek

once the env is updated with keys or parameters, do we need to just have the containers restarted or re-create?
here are some of the logs i could find

time="2026-02-13T13:47:36Z" level=info msg="SELECT * FROM "users" WHERE (id = '1') LIMIT 1" component=pentagi-gorm duration="624.884µs" rows_returned=1 src="pentagi/pkg/server/services/auth.go:744" type=sql values="[1]"
time="2026-02-13T13:47:36Z" level=info msg="SELECT * FROM "roles" WHERE ("id" = '1')" component=pentagi-gorm duration="280.117µs" rows_returned=1 src="pentagi/pkg/server/services/auth.go:744" type=sql values="[1]"
time="2026-02-13T13:47:36Z" level=info msg="SELECT name FROM "privileges" WHERE (role_id = '1')" component=pentagi-gorm duration="261.086µs" rows_returned=0 src="pentagi/pkg/server/services/auth.go:753" type=sql values="[1]"
2026/02/13 13:48:06 Trying to get content from http://1server:8080/
time="2026-02-13T13:48:06Z" level=error msg="browser tool failed" error="failed to fetch content by url 'http://server:8080/': failed to fetch data by scraper 'https://someuser:somepass@scraper/html?url=http%3A%2F%server%3A8080%2F': Get "https://someuser:***@scraper/html?url=http%3A%2F%server%3A8080%2F": dial tcp server:443: connect: connection refused" result= screen= tool=browser url="http://server:8080/"

Scraper URLs and settings

SCRAPER_PUBLIC_URL=
SCRAPER_PRIVATE_URL=https://someuser:somepass@scraper/
LOCAL_SCRAPER_USERNAME=someuser
LOCAL_SCRAPER_PASSWORD=somepass
LOCAL_SCRAPER_MAX_CONCURRENT_SESSIONS=10

<!-- gh-comment-id:3897357738 --> @adriaanvermaak commented on GitHub (Feb 13, 2026): hi there @asdek once the env is updated with keys or parameters, do we need to just have the containers restarted or re-create? here are some of the logs i could find time="2026-02-13T13:47:36Z" level=info msg="SELECT * FROM \"users\" WHERE (id = '1') LIMIT 1" component=pentagi-gorm duration="624.884µs" rows_returned=1 src="pentagi/pkg/server/services/auth.go:744" type=sql values="[1]" time="2026-02-13T13:47:36Z" level=info msg="SELECT * FROM \"roles\" WHERE (\"id\" = '1')" component=pentagi-gorm duration="280.117µs" rows_returned=1 src="pentagi/pkg/server/services/auth.go:744" type=sql values="[1]" time="2026-02-13T13:47:36Z" level=info msg="SELECT name FROM \"privileges\" WHERE (role_id = '1')" component=pentagi-gorm duration="261.086µs" rows_returned=0 src="pentagi/pkg/server/services/auth.go:753" type=sql values="[1]" 2026/02/13 13:48:06 Trying to get content from http://1server:8080/ time="2026-02-13T13:48:06Z" level=error msg="browser tool failed" error="failed to fetch content by url 'http://server:8080/': failed to fetch data by scraper 'https://someuser:somepass@scraper/html?url=http%3A%2F%server%3A8080%2F': Get \"https://someuser:***@scraper/html?url=http%3A%2F%server%3A8080%2F\": dial tcp server:443: connect: connection refused" result= screen= tool=browser url="http://server:8080/" ## Scraper URLs and settings SCRAPER_PUBLIC_URL= SCRAPER_PRIVATE_URL=https://someuser:somepass@scraper/ LOCAL_SCRAPER_USERNAME=someuser LOCAL_SCRAPER_PASSWORD=somepass LOCAL_SCRAPER_MAX_CONCURRENT_SESSIONS=10
Author
Owner

@adriaanvermaak commented on GitHub (Feb 13, 2026):

do you also have a sample of a prompt where you would stpulate the screenshotting and tool assignment for the example you gave?
searxng has inernet access as well

i just dont see anything happening in the search taps as well when applying a simple browser tool call in the prompt.

Based on our experience, Searxng is necessary when working in a closed network environment where you don't want to configure HTTP Proxy for the PentAGI installation. You can separate the deployment so that the Searxng VM has internet access while the worker machine doesn't.

Screenshots are created via the Browser tool, which is a component called scraper in the deployment. It's a separate Docker container that runs from this image and is deployed alongside PentAGI in the same docker-compose.yml file.

Why screenshots aren't being created: This is either a configuration error OR the AI agents simply don't need screenshots for their current tasks. Typically, you can explicitly ask the agent in your initial prompt to use the browser for conducting attacks, and it will create a screenshot for each action. Obviously, this is more relevant for client-side attacks.

<!-- gh-comment-id:3897392554 --> @adriaanvermaak commented on GitHub (Feb 13, 2026): do you also have a sample of a prompt where you would stpulate the screenshotting and tool assignment for the example you gave? searxng has inernet access as well i just dont see anything happening in the search taps as well when applying a simple browser tool call in the prompt. Based on our experience, Searxng is necessary when working in a closed network environment where you don't want to configure HTTP Proxy for the PentAGI installation. You can separate the deployment so that the Searxng VM has internet access while the worker machine doesn't. Screenshots are created via the Browser tool, which is a component called scraper in the deployment. It's a separate Docker container that runs from [this image](https://hub.docker.com/r/vxcontrol/scraper) and is deployed alongside PentAGI in the same docker-compose.yml file. Why screenshots aren't being created: This is either a configuration error OR the AI agents simply don't need screenshots for their current tasks. Typically, you can explicitly ask the agent in your initial prompt to use the browser for conducting attacks, and it will create a screenshot for each action. Obviously, this is more relevant for client-side attacks.
Author
Owner

@asdek commented on GitHub (Feb 13, 2026):

Thank you for details,

When you update .env with new keys or parameters, you generally need to restart the containers for changes to take effect:

docker compose restart pentagi

for more significant changes (like adding new services), you may need to recreate:

docker compose up -d --force-recreate

Regarding the error in your logs, there's a masked error in your log. Please check the original log line carefully - does it refer to your target server or the scraper container?

dial tcp server:443: connect: connection refused

If this refers to the scraper container:

  • Check if the scraper container is running: docker ps | grep scraper
  • Verify there are no Docker network issues on your VM

If this refers to the target server, there are two options to resolve this:

  1. Move scraper to the worker node where the target server is accessible. In the installer, there's a choice between Embedded or External scraper - in your case, use External with a separate Docker Compose deployment on the worker node.

  2. Configure network access from the main node (where PentAGI container runs) to the target server.

In any case, this is a configuration error that needs to be fixed either by:

  • Directly editing the .env file
  • Using the Installer settings

Based on your use of the default someuser credentials, it appears you did a manual installation - is that correct?

Regarding the screenshot prompt example, there's no explicit instruction needed in the prompt to "take screenshots". Screenshot creation is a side effect of using the Browser tool. When agents use it for testing, you'll see results on the Screenshots tab - this uses a local browserless instance with Chrome engine and Puppeteer API.

Here's a general web pentest prompt example.

Agents autonomously decide which method to use for testing, but if you give clear instructions in the prompt to use a specific approach, they will follow it during automation or in assistant mode.

To test tool functionality directly, refer to the documentation

for your example, use:

docker exec -it pentagi /opt/pentagi/bin/ftester -flow 1 browser -action markdown -url http://server:8080

(replace 1 with your actual flow ID)

for interactive field completion

docker exec -it pentagi /opt/pentagi/bin/ftester -flow 1 browser
<!-- gh-comment-id:3897743229 --> @asdek commented on GitHub (Feb 13, 2026): Thank you for details, When you update `.env` with new keys or parameters, you generally need to **restart** the containers for changes to take effect: ```bash docker compose restart pentagi ``` for more significant changes (like adding new services), you may need to recreate: ```bash docker compose up -d --force-recreate ``` Regarding the error in your logs, there's a masked error in your log. Please check the original log line carefully - does it refer to your target server or the scraper container? `dial tcp server:443: connect: connection refused` If this refers to the scraper container: - Check if the scraper container is running: `docker ps | grep scraper` - Verify there are no Docker network issues on your VM If this refers to the target server, there are two options to resolve this: 1. Move scraper to the worker node where the target server is accessible. In the installer, there's a choice between Embedded or External scraper - in your case, use External with a separate Docker Compose deployment on the worker node. 2. Configure network access from the main node (where PentAGI container runs) to the target server. In any case, this is a configuration error that needs to be fixed either by: - Directly editing the `.env` file - Using the Installer settings Based on your use of the default `someuser` credentials, it appears you did a manual installation - is that correct? Regarding the screenshot prompt example, there's no explicit instruction needed in the prompt to "take screenshots". Screenshot creation is a **side effect** of using the Browser tool. When agents use it for testing, you'll see results on the **Screenshots** tab - this uses a local browserless instance with Chrome engine and Puppeteer API. Here's a general web [pentest prompt example](https://github.com/vxcontrol/pentagi/blob/master/examples/prompts/base_web_pentest.md). Agents autonomously decide which method to use for testing, but if you give clear instructions in the prompt to use a specific approach, they will follow it during automation or in assistant mode. To test tool functionality directly, [refer to the documentation](https://github.com/vxcontrol/pentagi?tab=readme-ov-file#-function-testing-with-ftester) for your example, use: ```bash docker exec -it pentagi /opt/pentagi/bin/ftester -flow 1 browser -action markdown -url http://server:8080 ``` (replace `1` with your actual flow ID) for interactive field completion ```bash docker exec -it pentagi /opt/pentagi/bin/ftester -flow 1 browser ```
Author
Owner

@adriaanvermaak commented on GitHub (Feb 13, 2026):

hi @asdek

thanks for the quick response.

we dont have a worker setup they are running on the same docker instance, pentagi, all services.

the docker instance is in a restricted network but have limited access out.

time="2026-02-13T13:47:36Z" level=info msg="SELECT * FROM "users" WHERE (id = '1') LIMIT 1" component=pentagi-gorm duration="624.884µs" rows_returned=1 src="pentagi/pkg/server/services/auth.go:744" type=sql values="[1]"
time="2026-02-13T13:47:36Z" level=info msg="SELECT * FROM "roles" WHERE ("id" = '1')" component=pentagi-gorm duration="280.117µs" rows_returned=1 src="pentagi/pkg/server/services/auth.go:744" type=sql values="[1]"
time="2026-02-13T13:47:36Z" level=info msg="SELECT name FROM "privileges" WHERE (role_id = '1')" component=pentagi-gorm duration="261.086µs" rows_returned=0 src="pentagi/pkg/server/services/auth.go:753" type=sql values="[1]"
2026/02/13 13:48:06 Trying to get content from http://targetserver:8080/
time="2026-02-13T13:48:06Z" level=error msg="browser tool failed" error="failed to fetch content by url 'http://targetserver:8080/': failed to fetch data by scraper 'https://someuser:somepass@scraper/html?url=http%3A%2F%2Ftargetserver%3A8080%2F': Get "https://someuser:***@scraper/html?url=http%3A%2F%2Ftargetserver%3A8080%2F": dial tcp 10.89.6.94:443: connect: connection refused" result= screen= tool=browser url="http://targetserver:8080/"

here is my compose
volumes:
pentagi-data:
driver: local
pentagi-ssl:
driver: local
scraper-ssl:
driver: local
pentagi-postgres-data:
driver: local

networks:
pentagi-network:
driver: bridge
name: pentagi-network
observability-network:
driver: bridge
name: observability-network
langfuse-network:
driver: bridge
name: langfuse-network

services:

pentagi:
image: vxcontrol/pentagi:latest
restart: unless-stopped
container_name: pentagi
hostname: pentagi
expose:
- 8443/tcp
ports:
#- "8443:8443"
- ${PENTAGI_LISTEN_IP:-127.0.0.1}:${PENTAGI_LISTEN_PORT:-8443}:8443
depends_on:
- pentagi-pgvector
environment:
- DOCKER_GID=998
- CORS_ORIGINS=${CORS_ORIGINS:-}
- COOKIE_SIGNING_SALT=${COOKIE_SIGNING_SALT:-}
- INSTALLATION_ID=${INSTALLATION_ID:-}
- LICENSE_KEY=${LICENSE_KEY:-}
- ASK_USER=${ASK_USER:-false}
- OPEN_AI_KEY=${OPEN_AI_KEY:-}
- OPEN_AI_SERVER_URL=${OPEN_AI_SERVER_URL:-}
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:-}
- ANTHROPIC_SERVER_URL=${ANTHROPIC_SERVER_URL:-}
- GEMINI_API_KEY=${GEMINI_API_KEY:-}
- GEMINI_SERVER_URL=${GEMINI_SERVER_URL:-}
- BEDROCK_REGION=${BEDROCK_REGION:-}
- BEDROCK_ACCESS_KEY_ID=${BEDROCK_ACCESS_KEY_ID:-}
- BEDROCK_SECRET_ACCESS_KEY=${BEDROCK_SECRET_ACCESS_KEY:-}
- BEDROCK_SERVER_URL=${BEDROCK_SERVER_URL:-}
- LLM_SERVER_URL=${LLM_SERVER_URL:-}
- LLM_SERVER_KEY=${LLM_SERVER_KEY:-}
- LLM_SERVER_MODEL=${LLM_SERVER_MODEL:-}
- LLM_SERVER_CONFIG_PATH=${LLM_SERVER_CONFIG_PATH:-}
- LLM_SERVER_LEGACY_REASONING=${LLM_SERVER_LEGACY_REASONING:-}
- OLLAMA_SERVER_URL=${OLLAMA_SERVER_URL:-}
- OLLAMA_SERVER_CONFIG_PATH=${OLLAMA_SERVER_CONFIG_PATH:-}
- EMBEDDING_URL=${EMBEDDING_URL:-}
- EMBEDDING_KEY=${EMBEDDING_KEY:-}
- EMBEDDING_MODEL=${EMBEDDING_MODEL:-}
- EMBEDDING_PROVIDER=${EMBEDDING_PROVIDER:-}
- EMBEDDING_BATCH_SIZE=${EMBEDDING_BATCH_SIZE:-}
- EMBEDDING_STRIP_NEW_LINES=${EMBEDDING_STRIP_NEW_LINES:-}
- SUMMARIZER_PRESERVE_LAST=${SUMMARIZER_PRESERVE_LAST:-}
- SUMMARIZER_USE_QA=${SUMMARIZER_USE_QA:-}
- SUMMARIZER_SUM_MSG_HUMAN_IN_QA=${SUMMARIZER_SUM_MSG_HUMAN_IN_QA:-}
- SUMMARIZER_LAST_SEC_BYTES=${SUMMARIZER_LAST_SEC_BYTES:-}
- SUMMARIZER_MAX_BP_BYTES=${SUMMARIZER_MAX_BP_BYTES:-}
- SUMMARIZER_MAX_QA_SECTIONS=${SUMMARIZER_MAX_QA_SECTIONS:-}
- SUMMARIZER_MAX_QA_BYTES=${SUMMARIZER_MAX_QA_BYTES:-}
- SUMMARIZER_KEEP_QA_SECTIONS=${SUMMARIZER_KEEP_QA_SECTIONS:-}
- ASSISTANT_USE_AGENTS=${ASSISTANT_USE_AGENTS:-}
- ASSISTANT_SUMMARIZER_PRESERVE_LAST=${ASSISTANT_SUMMARIZER_PRESERVE_LAST:-}
- ASSISTANT_SUMMARIZER_LAST_SEC_BYTES=${ASSISTANT_SUMMARIZER_LAST_SEC_BYTES:-}
- ASSISTANT_SUMMARIZER_MAX_BP_BYTES=${ASSISTANT_SUMMARIZER_MAX_BP_BYTES:-}
- ASSISTANT_SUMMARIZER_MAX_QA_SECTIONS=${ASSISTANT_SUMMARIZER_MAX_QA_SECTIONS:-}
- ASSISTANT_SUMMARIZER_MAX_QA_BYTES=${ASSISTANT_SUMMARIZER_MAX_QA_BYTES:-}
- ASSISTANT_SUMMARIZER_KEEP_QA_SECTIONS=${ASSISTANT_SUMMARIZER_KEEP_QA_SECTIONS:-}
- PROXY_URL=${PROXY_URL:-}
- EXTERNAL_SSL_CA_PATH=${EXTERNAL_SSL_CA_PATH:-}
- EXTERNAL_SSL_INSECURE=${EXTERNAL_SSL_INSECURE:-}
- SCRAPER_PUBLIC_URL=${SCRAPER_PUBLIC_URL:-}
- SCRAPER_PRIVATE_URL=${SCRAPER_PRIVATE_URL:-}
- PUBLIC_URL=${PUBLIC_URL:-}
- STATIC_DIR=${STATIC_DIR:-}
- STATIC_URL=${STATIC_URL:-}
#- SERVER_PORT=${SERVER_PORT:-8443}
- SERVER_PORT=8443
#- SERVER_HOST=${SERVER_HOST:-0.0.0.0}
- SERVER_HOST=0.0.0.0
- SERVER_SSL_CRT=${SERVER_SSL_CRT:-}
- SERVER_SSL_KEY=${SERVER_SSL_KEY:-}
- SERVER_USE_SSL=${SERVER_USE_SSL:-true}
- OAUTH_GOOGLE_CLIENT_ID=${OAUTH_GOOGLE_CLIENT_ID:-}
- OAUTH_GOOGLE_CLIENT_SECRET=${OAUTH_GOOGLE_CLIENT_SECRET:-}
- OAUTH_GITHUB_CLIENT_ID=${OAUTH_GITHUB_CLIENT_ID:-}
- OAUTH_GITHUB_CLIENT_SECRET=${OAUTH_GITHUB_CLIENT_SECRET:-}
- DATABASE_URL=postgres://${PENTAGI_POSTGRES_USER:-postgres}:${PENTAGI_POSTGRES_PASSWORD:-postgres}@pgvector:5432/${PENTAGI_POSTGRES_DB:-pentagidb}?sslmode=disable
- DUCKDUCKGO_ENABLED=${DUCKDUCKGO_ENABLED:-}
- SEARXNG_URL=${SEARXNG_URL:-}
- SEARXNG_CATEGORIES=${SEARXNG_CATEGORIES:-}
- SEARXNG_LANGUAGE=${SEARXNG_LANGUAGE:-}
- SEARXNG_SAFESEARCH=${SEARXNG_SAFESEARCH:-}
- SEARXNG_TIME_RANGE=${SEARXNG_TIME_RANGE:-}
- GOOGLE_API_KEY=${GOOGLE_API_KEY:-}
- GOOGLE_CX_KEY=${GOOGLE_CX_KEY:-}
- GOOGLE_LR_KEY=${GOOGLE_LR_KEY:-}
- TRAVERSAAL_API_KEY=${TRAVERSAAL_API_KEY:-}
- TAVILY_API_KEY=${TAVILY_API_KEY:-}
- PERPLEXITY_API_KEY=${PERPLEXITY_API_KEY:-}
- PERPLEXITY_MODEL=${PERPLEXITY_MODEL:-sonar}
- PERPLEXITY_CONTEXT_SIZE=${PERPLEXITY_CONTEXT_SIZE:-low}
- LANGFUSE_BASE_URL=${LANGFUSE_BASE_URL:-}
- LANGFUSE_PROJECT_ID=${LANGFUSE_PROJECT_ID:-}
- LANGFUSE_PUBLIC_KEY=${LANGFUSE_PUBLIC_KEY:-}
- LANGFUSE_SECRET_KEY=${LANGFUSE_SECRET_KEY:-}
- OTEL_HOST=${OTEL_HOST:-}
- DOCKER_HOST=${DOCKER_HOST:-unix:///var/run/docker.sock}
- DOCKER_TLS_VERIFY=${DOCKER_TLS_VERIFY:-}
- DOCKER_CERT_PATH=${DOCKER_CERT_PATH:-}
- DOCKER_INSIDE=${DOCKER_INSIDE:-false}
- DOCKER_NET_ADMIN=${DOCKER_NET_ADMIN:-false}
- DOCKER_SOCKET=${DOCKER_SOCKET:-}
- DOCKER_NETWORK=${DOCKER_NETWORK:-}
- DOCKER_PUBLIC_IP=${DOCKER_PUBLIC_IP:-}
- DOCKER_WORK_DIR=${DOCKER_WORK_DIR:-}
- DOCKER_DEFAULT_IMAGE=${DOCKER_DEFAULT_IMAGE:-}
- DOCKER_DEFAULT_IMAGE_FOR_PENTEST=${DOCKER_DEFAULT_IMAGE_FOR_PENTEST:-}
- HTTP_PROXY=
- HTTPS_PROXY=
- http_proxy=
- https_proxy=
- ALL_PROXY=
- all_proxy=
logging:
options:
max-size: 50m
max-file: '7'
volumes:
- ${PENTAGI_DATA_DIR:-pentagi-data}:/opt/pentagi/data
- ${PENTAGI_SSL_DIR:-pentagi-ssl}:/opt/pentagi/ssl
- ${PENTAGI_DOCKER_SOCKET:-/var/run/docker.sock}:/var/run/docker.sock
#- ${PENTAGI_LLM_SERVER_CONFIG_PATH:-./example.provider.yml}:${PENTAGI_LLM_SERVER_CONFIG_PATH:-/opt/pentagi/conf/example.provider.yml}
- ${PENTAGI_LLM_SERVER_CONFIG_PATH}:/opt/pentagi/conf/litellm.provider.yml
- ${DOCKER_CERT_PATH:-./docker-ssl}:${DOCKER_CERT_PATH:-/opt/pentagi/docker-ssl}
dns:
- 10.33.249.90
- 10.33.249.91
user: root:root # while using docker.sock
networks:
pentagi-network:
driver: bridge
name: pentagi-network
ipam:
config:
- subnet: 10.89.6.0/24
gateway: 10.89.6.1
observability-network:
driver: bridge
name: observability-network
langfuse-network:
driver: bridge
name: langfuse-network

pentagi-pgvector:
image: vxcontrol/pgvector:latest
restart: unless-stopped
container_name: pgvector
hostname: pgvector
expose:
- 5432/tcp
ports:
- 127.0.0.1:5432:5432
environment:
POSTGRES_USER: ${PENTAGI_POSTGRES_USER:-postgres}
POSTGRES_PASSWORD: ${PENTAGI_POSTGRES_PASSWORD:-postgres}
POSTGRES_DB: ${PENTAGI_POSTGRES_DB:-pentagidb}
logging:
options:
max-size: 50m
max-file: '7'
volumes:
- pentagi-postgres-data:/var/lib/postgresql/data
networks:
- pentagi-network

pentagi-pgexporter:
image: quay.io/prometheuscommunity/postgres-exporter:v0.16.0
restart: unless-stopped
depends_on:
- pentagi-pgvector
container_name: pgexporter
hostname: pgexporter
expose:
- 9187/tcp
ports:
- 127.0.0.1:9187:9187
environment:
- DATA_SOURCE_NAME=postgresql://${PENTAGI_POSTGRES_USER:-postgres}:${PENTAGI_POSTGRES_PASSWORD:-postgres}@pgvector:5432/${PENTAGI_POSTGRES_DB:-pentagidb}?sslmode=disable
logging:
options:
max-size: 50m
max-file: '7'
dns:
- 10.33.249.90
- 10.33.249.91
networks:
- pentagi-network

pentagi-scraper:
image: vxcontrol/scraper:latest
restart: unless-stopped
container_name: scraper
hostname: scraper
expose:
- 443/tcp
ports:
- 127.0.0.1:9443:443
environment:
- MAX_CONCURRENT_SESSIONS=${LOCAL_SCRAPER_MAX_CONCURRENT_SESSIONS:-10}
- USERNAME=${LOCAL_SCRAPER_USERNAME:-someuser}
- PASSWORD=${LOCAL_SCRAPER_PASSWORD:-somepass}
logging:
options:
max-size: 50m
max-file: '7'
volumes:
- scraper-ssl:/usr/src/app/ssl
networks:
- pentagi-network
shm_size: 2g

pentagi-litellm:
image: ghcr.io/berriai/litellm:main-stable
container_name: pentagi-litellm
hostname: litellm
restart: unless-stopped
env_file:
- ./litellm/litellm.env
environment:
- TIKTOKEN_CACHE_DIR=/root/.cache/tiktoken
- NO_PROXY=localhost,127.0.0.1,pentagi,pgvector,litellm,scraper,pgexporter,proxy,searxng
- no_proxy=localhost,127.0.0.1,pentagi,pgvector,litellm,scraper,pgexporter,proxy,searxng
command: ["--config", "/app/config.yaml", "--port", "${LITELLM_PROXY_PORT:-4000}", "--host", "0.0.0.0"]
volumes:
- ./litellm/litellm-config.yaml:/app/config.yaml:ro
- ./litellm/litellm-config.yaml:/app/proxy_server_config.yaml:ro
- ./litellm/cache:/root/.cache/tiktoken
expose:
- "${LITELLM_PROXY_PORT:-4000}/tcp"
ports:
- ${LITELLM_LISTEN_IP:-127.0.0.1}:${LITELLM_PROXY_PORT:-4000}:${LITELLM_PROXY_PORT:-4000}
networks:
- pentagi-network

pentagi-proxy:
image: nginx:alpine
container_name: pentagi-proxy
hostname: proxy
restart: unless-stopped
# expose proxy to users
ports:
- "0.0.0.0:8444:8444"
# IMPORTANT: ensure this container itself does not try use corp proxy
environment:
- HTTP_PROXY=
- HTTPS_PROXY=
- http_proxy=
- https_proxy=
- ALL_PROXY=
- all_proxy=
- NO_PROXY=localhost,127.0.0.1,pentagi,pgvector,litellm,scraper,pgexporter,proxy,searxng
- no_proxy=localhost,127.0.0.1,pentagi,pgvector,litellm,scraper,pgexporter,proxy,searxng
# nginx config + certs
volumes:
- ./pentagi-proxy/pentagi-nginx.conf:/etc/nginx/nginx.conf:ro
#- ./pentagi-proxy/certs:/etc/nginx/certs:ro
depends_on:
- pentagi
networks:
- pentagi-network

searxng:
image: docker.io/searxng/searxng:latest
container_name: searxng
hostname: searxng
restart: unless-stopped

# LAN access on host:8888
ports:
  - "0.0.0.0:8888:8080"

volumes:
  - ./searxng/config:/etc/searxng:Z
  - ./searxng/data:/var/cache/searxng:Z

environment:
  - FORCE_OWNERSHIP=true
  - NO_PROXY=localhost,127.0.0.1,pentagi,pgvector,litellm,scraper,pgexporter,proxy,searxng
  - no_proxy=localhost,127.0.0.1,pentagi,pgvector,litellm,scraper,pgexporter,proxy,searxng
networks:
  - pentagi-network
<!-- gh-comment-id:3897845663 --> @adriaanvermaak commented on GitHub (Feb 13, 2026): hi @asdek thanks for the quick response. we dont have a worker setup they are running on the same docker instance, pentagi, all services. the docker instance is in a restricted network but have limited access out. time="2026-02-13T13:47:36Z" level=info msg="SELECT * FROM \"users\" WHERE (id = '1') LIMIT 1" component=pentagi-gorm duration="624.884µs" rows_returned=1 src="pentagi/pkg/server/services/auth.go:744" type=sql values="[1]" time="2026-02-13T13:47:36Z" level=info msg="SELECT * FROM \"roles\" WHERE (\"id\" = '1')" component=pentagi-gorm duration="280.117µs" rows_returned=1 src="pentagi/pkg/server/services/auth.go:744" type=sql values="[1]" time="2026-02-13T13:47:36Z" level=info msg="SELECT name FROM \"privileges\" WHERE (role_id = '1')" component=pentagi-gorm duration="261.086µs" rows_returned=0 src="pentagi/pkg/server/services/auth.go:753" type=sql values="[1]" 2026/02/13 13:48:06 Trying to get content from http://targetserver:8080/ time="2026-02-13T13:48:06Z" level=error msg="browser tool failed" error="failed to fetch content by url 'http://targetserver:8080/': failed to fetch data by scraper 'https://someuser:somepass@scraper/html?url=http%3A%2F%2Ftargetserver%3A8080%2F': Get \"https://someuser:***@scraper/html?url=http%3A%2F%2Ftargetserver%3A8080%2F\": dial tcp 10.89.6.94:443: connect: connection refused" result= screen= tool=browser url="http://targetserver:8080/" here is my compose volumes: pentagi-data: driver: local pentagi-ssl: driver: local scraper-ssl: driver: local pentagi-postgres-data: driver: local networks: pentagi-network: driver: bridge name: pentagi-network observability-network: driver: bridge name: observability-network langfuse-network: driver: bridge name: langfuse-network services: pentagi: image: vxcontrol/pentagi:latest restart: unless-stopped container_name: pentagi hostname: pentagi expose: - 8443/tcp ports: #- "8443:8443" - ${PENTAGI_LISTEN_IP:-127.0.0.1}:${PENTAGI_LISTEN_PORT:-8443}:8443 depends_on: - pentagi-pgvector environment: - DOCKER_GID=998 - CORS_ORIGINS=${CORS_ORIGINS:-} - COOKIE_SIGNING_SALT=${COOKIE_SIGNING_SALT:-} - INSTALLATION_ID=${INSTALLATION_ID:-} - LICENSE_KEY=${LICENSE_KEY:-} - ASK_USER=${ASK_USER:-false} - OPEN_AI_KEY=${OPEN_AI_KEY:-} - OPEN_AI_SERVER_URL=${OPEN_AI_SERVER_URL:-} - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:-} - ANTHROPIC_SERVER_URL=${ANTHROPIC_SERVER_URL:-} - GEMINI_API_KEY=${GEMINI_API_KEY:-} - GEMINI_SERVER_URL=${GEMINI_SERVER_URL:-} - BEDROCK_REGION=${BEDROCK_REGION:-} - BEDROCK_ACCESS_KEY_ID=${BEDROCK_ACCESS_KEY_ID:-} - BEDROCK_SECRET_ACCESS_KEY=${BEDROCK_SECRET_ACCESS_KEY:-} - BEDROCK_SERVER_URL=${BEDROCK_SERVER_URL:-} - LLM_SERVER_URL=${LLM_SERVER_URL:-} - LLM_SERVER_KEY=${LLM_SERVER_KEY:-} - LLM_SERVER_MODEL=${LLM_SERVER_MODEL:-} - LLM_SERVER_CONFIG_PATH=${LLM_SERVER_CONFIG_PATH:-} - LLM_SERVER_LEGACY_REASONING=${LLM_SERVER_LEGACY_REASONING:-} - OLLAMA_SERVER_URL=${OLLAMA_SERVER_URL:-} - OLLAMA_SERVER_CONFIG_PATH=${OLLAMA_SERVER_CONFIG_PATH:-} - EMBEDDING_URL=${EMBEDDING_URL:-} - EMBEDDING_KEY=${EMBEDDING_KEY:-} - EMBEDDING_MODEL=${EMBEDDING_MODEL:-} - EMBEDDING_PROVIDER=${EMBEDDING_PROVIDER:-} - EMBEDDING_BATCH_SIZE=${EMBEDDING_BATCH_SIZE:-} - EMBEDDING_STRIP_NEW_LINES=${EMBEDDING_STRIP_NEW_LINES:-} - SUMMARIZER_PRESERVE_LAST=${SUMMARIZER_PRESERVE_LAST:-} - SUMMARIZER_USE_QA=${SUMMARIZER_USE_QA:-} - SUMMARIZER_SUM_MSG_HUMAN_IN_QA=${SUMMARIZER_SUM_MSG_HUMAN_IN_QA:-} - SUMMARIZER_LAST_SEC_BYTES=${SUMMARIZER_LAST_SEC_BYTES:-} - SUMMARIZER_MAX_BP_BYTES=${SUMMARIZER_MAX_BP_BYTES:-} - SUMMARIZER_MAX_QA_SECTIONS=${SUMMARIZER_MAX_QA_SECTIONS:-} - SUMMARIZER_MAX_QA_BYTES=${SUMMARIZER_MAX_QA_BYTES:-} - SUMMARIZER_KEEP_QA_SECTIONS=${SUMMARIZER_KEEP_QA_SECTIONS:-} - ASSISTANT_USE_AGENTS=${ASSISTANT_USE_AGENTS:-} - ASSISTANT_SUMMARIZER_PRESERVE_LAST=${ASSISTANT_SUMMARIZER_PRESERVE_LAST:-} - ASSISTANT_SUMMARIZER_LAST_SEC_BYTES=${ASSISTANT_SUMMARIZER_LAST_SEC_BYTES:-} - ASSISTANT_SUMMARIZER_MAX_BP_BYTES=${ASSISTANT_SUMMARIZER_MAX_BP_BYTES:-} - ASSISTANT_SUMMARIZER_MAX_QA_SECTIONS=${ASSISTANT_SUMMARIZER_MAX_QA_SECTIONS:-} - ASSISTANT_SUMMARIZER_MAX_QA_BYTES=${ASSISTANT_SUMMARIZER_MAX_QA_BYTES:-} - ASSISTANT_SUMMARIZER_KEEP_QA_SECTIONS=${ASSISTANT_SUMMARIZER_KEEP_QA_SECTIONS:-} - PROXY_URL=${PROXY_URL:-} - EXTERNAL_SSL_CA_PATH=${EXTERNAL_SSL_CA_PATH:-} - EXTERNAL_SSL_INSECURE=${EXTERNAL_SSL_INSECURE:-} - SCRAPER_PUBLIC_URL=${SCRAPER_PUBLIC_URL:-} - SCRAPER_PRIVATE_URL=${SCRAPER_PRIVATE_URL:-} - PUBLIC_URL=${PUBLIC_URL:-} - STATIC_DIR=${STATIC_DIR:-} - STATIC_URL=${STATIC_URL:-} #- SERVER_PORT=${SERVER_PORT:-8443} - SERVER_PORT=8443 #- SERVER_HOST=${SERVER_HOST:-0.0.0.0} - SERVER_HOST=0.0.0.0 - SERVER_SSL_CRT=${SERVER_SSL_CRT:-} - SERVER_SSL_KEY=${SERVER_SSL_KEY:-} - SERVER_USE_SSL=${SERVER_USE_SSL:-true} - OAUTH_GOOGLE_CLIENT_ID=${OAUTH_GOOGLE_CLIENT_ID:-} - OAUTH_GOOGLE_CLIENT_SECRET=${OAUTH_GOOGLE_CLIENT_SECRET:-} - OAUTH_GITHUB_CLIENT_ID=${OAUTH_GITHUB_CLIENT_ID:-} - OAUTH_GITHUB_CLIENT_SECRET=${OAUTH_GITHUB_CLIENT_SECRET:-} - DATABASE_URL=postgres://${PENTAGI_POSTGRES_USER:-postgres}:${PENTAGI_POSTGRES_PASSWORD:-postgres}@pgvector:5432/${PENTAGI_POSTGRES_DB:-pentagidb}?sslmode=disable - DUCKDUCKGO_ENABLED=${DUCKDUCKGO_ENABLED:-} - SEARXNG_URL=${SEARXNG_URL:-} - SEARXNG_CATEGORIES=${SEARXNG_CATEGORIES:-} - SEARXNG_LANGUAGE=${SEARXNG_LANGUAGE:-} - SEARXNG_SAFESEARCH=${SEARXNG_SAFESEARCH:-} - SEARXNG_TIME_RANGE=${SEARXNG_TIME_RANGE:-} - GOOGLE_API_KEY=${GOOGLE_API_KEY:-} - GOOGLE_CX_KEY=${GOOGLE_CX_KEY:-} - GOOGLE_LR_KEY=${GOOGLE_LR_KEY:-} - TRAVERSAAL_API_KEY=${TRAVERSAAL_API_KEY:-} - TAVILY_API_KEY=${TAVILY_API_KEY:-} - PERPLEXITY_API_KEY=${PERPLEXITY_API_KEY:-} - PERPLEXITY_MODEL=${PERPLEXITY_MODEL:-sonar} - PERPLEXITY_CONTEXT_SIZE=${PERPLEXITY_CONTEXT_SIZE:-low} - LANGFUSE_BASE_URL=${LANGFUSE_BASE_URL:-} - LANGFUSE_PROJECT_ID=${LANGFUSE_PROJECT_ID:-} - LANGFUSE_PUBLIC_KEY=${LANGFUSE_PUBLIC_KEY:-} - LANGFUSE_SECRET_KEY=${LANGFUSE_SECRET_KEY:-} - OTEL_HOST=${OTEL_HOST:-} - DOCKER_HOST=${DOCKER_HOST:-unix:///var/run/docker.sock} - DOCKER_TLS_VERIFY=${DOCKER_TLS_VERIFY:-} - DOCKER_CERT_PATH=${DOCKER_CERT_PATH:-} - DOCKER_INSIDE=${DOCKER_INSIDE:-false} - DOCKER_NET_ADMIN=${DOCKER_NET_ADMIN:-false} - DOCKER_SOCKET=${DOCKER_SOCKET:-} - DOCKER_NETWORK=${DOCKER_NETWORK:-} - DOCKER_PUBLIC_IP=${DOCKER_PUBLIC_IP:-} - DOCKER_WORK_DIR=${DOCKER_WORK_DIR:-} - DOCKER_DEFAULT_IMAGE=${DOCKER_DEFAULT_IMAGE:-} - DOCKER_DEFAULT_IMAGE_FOR_PENTEST=${DOCKER_DEFAULT_IMAGE_FOR_PENTEST:-} - HTTP_PROXY= - HTTPS_PROXY= - http_proxy= - https_proxy= - ALL_PROXY= - all_proxy= logging: options: max-size: 50m max-file: '7' volumes: - ${PENTAGI_DATA_DIR:-pentagi-data}:/opt/pentagi/data - ${PENTAGI_SSL_DIR:-pentagi-ssl}:/opt/pentagi/ssl - ${PENTAGI_DOCKER_SOCKET:-/var/run/docker.sock}:/var/run/docker.sock #- ${PENTAGI_LLM_SERVER_CONFIG_PATH:-./example.provider.yml}:${PENTAGI_LLM_SERVER_CONFIG_PATH:-/opt/pentagi/conf/example.provider.yml} - ${PENTAGI_LLM_SERVER_CONFIG_PATH}:/opt/pentagi/conf/litellm.provider.yml - ${DOCKER_CERT_PATH:-./docker-ssl}:${DOCKER_CERT_PATH:-/opt/pentagi/docker-ssl} dns: - 10.33.249.90 - 10.33.249.91 user: root:root # while using docker.sock networks: pentagi-network: driver: bridge name: pentagi-network ipam: config: - subnet: 10.89.6.0/24 gateway: 10.89.6.1 observability-network: driver: bridge name: observability-network langfuse-network: driver: bridge name: langfuse-network pentagi-pgvector: image: vxcontrol/pgvector:latest restart: unless-stopped container_name: pgvector hostname: pgvector expose: - 5432/tcp ports: - 127.0.0.1:5432:5432 environment: POSTGRES_USER: ${PENTAGI_POSTGRES_USER:-postgres} POSTGRES_PASSWORD: ${PENTAGI_POSTGRES_PASSWORD:-postgres} POSTGRES_DB: ${PENTAGI_POSTGRES_DB:-pentagidb} logging: options: max-size: 50m max-file: '7' volumes: - pentagi-postgres-data:/var/lib/postgresql/data networks: - pentagi-network pentagi-pgexporter: image: quay.io/prometheuscommunity/postgres-exporter:v0.16.0 restart: unless-stopped depends_on: - pentagi-pgvector container_name: pgexporter hostname: pgexporter expose: - 9187/tcp ports: - 127.0.0.1:9187:9187 environment: - DATA_SOURCE_NAME=postgresql://${PENTAGI_POSTGRES_USER:-postgres}:${PENTAGI_POSTGRES_PASSWORD:-postgres}@pgvector:5432/${PENTAGI_POSTGRES_DB:-pentagidb}?sslmode=disable logging: options: max-size: 50m max-file: '7' dns: - 10.33.249.90 - 10.33.249.91 networks: - pentagi-network pentagi-scraper: image: vxcontrol/scraper:latest restart: unless-stopped container_name: scraper hostname: scraper expose: - 443/tcp ports: - 127.0.0.1:9443:443 environment: - MAX_CONCURRENT_SESSIONS=${LOCAL_SCRAPER_MAX_CONCURRENT_SESSIONS:-10} - USERNAME=${LOCAL_SCRAPER_USERNAME:-someuser} - PASSWORD=${LOCAL_SCRAPER_PASSWORD:-somepass} logging: options: max-size: 50m max-file: '7' volumes: - scraper-ssl:/usr/src/app/ssl networks: - pentagi-network shm_size: 2g pentagi-litellm: image: ghcr.io/berriai/litellm:main-stable container_name: pentagi-litellm hostname: litellm restart: unless-stopped env_file: - ./litellm/litellm.env environment: - TIKTOKEN_CACHE_DIR=/root/.cache/tiktoken - NO_PROXY=localhost,127.0.0.1,pentagi,pgvector,litellm,scraper,pgexporter,proxy,searxng - no_proxy=localhost,127.0.0.1,pentagi,pgvector,litellm,scraper,pgexporter,proxy,searxng command: ["--config", "/app/config.yaml", "--port", "${LITELLM_PROXY_PORT:-4000}", "--host", "0.0.0.0"] volumes: - ./litellm/litellm-config.yaml:/app/config.yaml:ro - ./litellm/litellm-config.yaml:/app/proxy_server_config.yaml:ro - ./litellm/cache:/root/.cache/tiktoken expose: - "${LITELLM_PROXY_PORT:-4000}/tcp" ports: - ${LITELLM_LISTEN_IP:-127.0.0.1}:${LITELLM_PROXY_PORT:-4000}:${LITELLM_PROXY_PORT:-4000} networks: - pentagi-network pentagi-proxy: image: nginx:alpine container_name: pentagi-proxy hostname: proxy restart: unless-stopped # expose proxy to users ports: - "0.0.0.0:8444:8444" # IMPORTANT: ensure this container itself does not try use corp proxy environment: - HTTP_PROXY= - HTTPS_PROXY= - http_proxy= - https_proxy= - ALL_PROXY= - all_proxy= - NO_PROXY=localhost,127.0.0.1,pentagi,pgvector,litellm,scraper,pgexporter,proxy,searxng - no_proxy=localhost,127.0.0.1,pentagi,pgvector,litellm,scraper,pgexporter,proxy,searxng # nginx config + certs volumes: - ./pentagi-proxy/pentagi-nginx.conf:/etc/nginx/nginx.conf:ro #- ./pentagi-proxy/certs:/etc/nginx/certs:ro depends_on: - pentagi networks: - pentagi-network searxng: image: docker.io/searxng/searxng:latest container_name: searxng hostname: searxng restart: unless-stopped # LAN access on host:8888 ports: - "0.0.0.0:8888:8080" volumes: - ./searxng/config:/etc/searxng:Z - ./searxng/data:/var/cache/searxng:Z environment: - FORCE_OWNERSHIP=true - NO_PROXY=localhost,127.0.0.1,pentagi,pgvector,litellm,scraper,pgexporter,proxy,searxng - no_proxy=localhost,127.0.0.1,pentagi,pgvector,litellm,scraper,pgexporter,proxy,searxng networks: - pentagi-network
Author
Owner

@asdek commented on GitHub (Feb 13, 2026):

@adriaanvermaak

Your docker-compose.yml file has several configuration problems:

  1. Duplicate network declaration - the pentagi-network is declared twice: once at the beginning of the file (basic configuration) and again at the end with ipam settings. This can cause conflicts.

  2. If you're not using Langfuse and Observability stacks, the langfuse-network and observability-network declarations should be removed from the file.

  3. From the error dial tcp 10.89.6.94:443: connect: connection refused, we can see that DNS resolution is working (the name scraper resolved to IP 10.89.6.94), but the scraper container itself is either not running or not listening on port 443.

possible solution:

  1. Remove the duplicate declaration at the end of the file, keep only one at the beginning with full configuration:

    networks:
      pentagi-network:
        driver: bridge
        name: pentagi-network
        ipam:
          config:
            - subnet: 10.89.6.0/24
              gateway: 10.89.6.1
    
  2. Remove unused networks langfuse-network and observability-network if you're not using these stacks.

  3. Recreate containers:

    docker compose down
    docker compose up -d
    
  4. Check scraper status and logs:

    docker compose ps
    docker logs scraper
    docker exec -it scraper ps aux
    
  5. Verify connectivity to scraper:

    # From scraper container
    docker exec -it scraper wget -O- --no-check-certificate "https://someuser:somepass@127.0.0.1:443/html?url=http://example.com"
    
    # From pentagi container
    docker exec -it pentagi wget -O- --no-check-certificate "https://someuser:somepass@scraper/html?url=http://example.com"
    
  6. Use ftester to test the browser tool:

    docker exec -it pentagi /opt/pentagi/bin/ftester -flow 1 browser -action markdown -url "http://example.com"
    

from the pentagi container logs, we can see it successfully connected to the pgvector database (successful SQL queries), which means DNS resolution and networking are working. the problem is specifically with the availability of the scraper container on port 443.

<!-- gh-comment-id:3898615382 --> @asdek commented on GitHub (Feb 13, 2026): @adriaanvermaak Your `docker-compose.yml` file has several configuration problems: 1. Duplicate network declaration - the `pentagi-network` is declared twice: once at the beginning of the file (basic configuration) and again at the end with `ipam` settings. This can cause conflicts. 2. If you're not using Langfuse and Observability stacks, the `langfuse-network` and `observability-network` declarations should be removed from the file. 3. From the error `dial tcp 10.89.6.94:443: connect: connection refused`, we can see that DNS resolution is working (the name `scraper` resolved to IP 10.89.6.94), but the scraper container itself is either not running or not listening on port 443. possible solution: 1. Remove the duplicate declaration at the end of the file, keep only one at the beginning with full configuration: ```yaml networks: pentagi-network: driver: bridge name: pentagi-network ipam: config: - subnet: 10.89.6.0/24 gateway: 10.89.6.1 ``` 2. Remove unused networks `langfuse-network` and `observability-network` if you're not using these stacks. 3. Recreate containers: ```bash docker compose down docker compose up -d ``` 4. Check scraper status and logs: ```bash docker compose ps docker logs scraper docker exec -it scraper ps aux ``` 5. Verify connectivity to scraper: ```bash # From scraper container docker exec -it scraper wget -O- --no-check-certificate "https://someuser:somepass@127.0.0.1:443/html?url=http://example.com" # From pentagi container docker exec -it pentagi wget -O- --no-check-certificate "https://someuser:somepass@scraper/html?url=http://example.com" ``` 6. Use ftester to test the browser tool: ```bash docker exec -it pentagi /opt/pentagi/bin/ftester -flow 1 browser -action markdown -url "http://example.com" ``` from the `pentagi` container logs, we can see it successfully connected to the `pgvector` database (successful SQL queries), which means DNS resolution and networking are working. the problem is specifically with the availability of the `scraper` container on port 443.
Author
Owner

@adriaanvermaak commented on GitHub (Feb 16, 2026):

thanks @asdek

i have cleaned up with the compose

however

sudo podman logs scraper
service ssl crt and key already exist
2026/02/16 11:21:46 Starting server on 0.0.0.0:443 TLS true
2026/02/16 11:21:46 listen tcp 0.0.0.0:443: bind: permission denied
INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
INFO: Started parent process [4]
INFO: Started server process [28]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Started server process [27]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Started server process [29]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Started server process [30]
INFO: Waiting for application startup.
INFO: Application startup complete.
2026-02-16T11:21:47.021Z browserless:server Using configuration:
2026-02-16T11:21:47.023Z browserless:server {
CONNECTION_TIMEOUT: 60000,
MAX_CONCURRENT_SESSIONS: 10,
QUEUE_LENGTH: 10,
SINGLE_RUN: false,
CHROME_REFRESH_TIME: 1800000,
KEEP_ALIVE: false,
DEFAULT_BLOCK_ADS: false,
DEFAULT_HEADLESS: 'new',
DEFAULT_LAUNCH_ARGS: [],
DEFAULT_IGNORE_DEFAULT_ARGS: false,
DEFAULT_IGNORE_HTTPS_ERRORS: false,
DEFAULT_DUMPIO: false,
DEFAULT_STEALTH: false,
DEFAULT_USER_DATA_DIR: undefined,
PREBOOT_CHROME: false,
PREBOOT_QUANTITY: 0,
PRINT_GET_STARTED_LINKS: true,
PRINT_NETWORK_INFO: true,
DEBUG: 'browserless*',
DISABLED_FEATURES: [],
ENABLE_CORS: false,
ENABLE_API_GET: false,
TOKEN: null,
ENABLE_HEAP_DUMP: false,
ALLOW_FILE_PROTOCOL: false,
DISABLE_AUTO_SET_DOWNLOAD_BEHAVIOR: false,
FUNCTION_BUILT_INS: [ 'url' ],
FUNCTION_ENV_VARS: [],
FUNCTION_ENABLE_INCOGNITO_MODE: false,
FUNCTION_EXTERNALS: [ 'lighthouse', 'node-pdftk', 'sharp' ],
WORKSPACE_DIR: '/usr/src/app/workspace',
WORKSPACE_DELETE_EXPIRED: false,
WORKSPACE_EXPIRE_DAYS: 30,
FAILED_HEALTH_URL: null,
QUEUE_ALERT_URL: null,
REJECT_ALERT_URL: null,
TIMEOUT_ALERT_URL: null,
ERROR_ALERT_URL: null,
SESSION_CHECK_FAIL_URL: null,
PRE_REQUEST_HEALTH_CHECK: false,
EXIT_ON_HEALTH_FAILURE: false,
MAX_CPU_PERCENT: 99,
MAX_MEMORY_PERCENT: 99,
METRICS_JSON_PATH: null,
HOST: '0.0.0.0',
PORT: 3000,
SOCKET_CLOSE_METHOD: 'http',
PROXY_URL: undefined,
MAX_PAYLOAD_SIZE: '5mb'
}
2026-02-16T11:21:47.024Z browserless:server

Running on port 3000
Localhost ws:localhost:3000
Local network ws:10.89.6.230:3000
2026-02-16T11:21:47.024Z browserless:server
Get started at https://www.browserless.io/docs/start
Get a license at https://www.browserless.io/sign-up?type=commercial
Get support at https://www.browserless.io/contact

Happy coding!

sudo podman exec -it scraper wget -O- --no-check-certificate "https://someuser:somepass@127.0.0.1:443/html?url=http://example.com"
--2026-02-16 11:24:02-- https://someuser:password@127.0.0.1/html?url=http://example.com
Connecting to 127.0.0.1:443... failed: Connection refused.

sudo podman exec -it pentagi wget -O- --no-check-certificate "https://someuser:somepass@scraper/html?url=http://example.com"
Connecting to scraper (10.89.6.230:443)
wget: can't connect to remote host (10.89.6.230): Connection refused

sudo podman exec -it pentagi /opt/pentagi/bin/ftester -flow 1 browser -action markdown -url "http://example.com"
2026/02/16 11:24:53 Warning: Error loading .env file: open .env: no such file or directory
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x1629dca]

goroutine 1 [running]:
main.main()
pentagi/cmd/ftester/main.go:63 +0x42a

<!-- gh-comment-id:3907949240 --> @adriaanvermaak commented on GitHub (Feb 16, 2026): thanks @asdek i have cleaned up with the compose however sudo podman logs scraper service ssl crt and key already exist 2026/02/16 11:21:46 Starting server on 0.0.0.0:443 TLS true 2026/02/16 11:21:46 listen tcp 0.0.0.0:443: bind: permission denied INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit) INFO: Started parent process [4] INFO: Started server process [28] INFO: Waiting for application startup. INFO: Application startup complete. INFO: Started server process [27] INFO: Waiting for application startup. INFO: Application startup complete. INFO: Started server process [29] INFO: Waiting for application startup. INFO: Application startup complete. INFO: Started server process [30] INFO: Waiting for application startup. INFO: Application startup complete. 2026-02-16T11:21:47.021Z browserless:server Using configuration: 2026-02-16T11:21:47.023Z browserless:server { CONNECTION_TIMEOUT: 60000, MAX_CONCURRENT_SESSIONS: 10, QUEUE_LENGTH: 10, SINGLE_RUN: false, CHROME_REFRESH_TIME: 1800000, KEEP_ALIVE: false, DEFAULT_BLOCK_ADS: false, DEFAULT_HEADLESS: 'new', DEFAULT_LAUNCH_ARGS: [], DEFAULT_IGNORE_DEFAULT_ARGS: false, DEFAULT_IGNORE_HTTPS_ERRORS: false, DEFAULT_DUMPIO: false, DEFAULT_STEALTH: false, DEFAULT_USER_DATA_DIR: undefined, PREBOOT_CHROME: false, PREBOOT_QUANTITY: 0, PRINT_GET_STARTED_LINKS: true, PRINT_NETWORK_INFO: true, DEBUG: 'browserless*', DISABLED_FEATURES: [], ENABLE_CORS: false, ENABLE_API_GET: false, TOKEN: null, ENABLE_HEAP_DUMP: false, ALLOW_FILE_PROTOCOL: false, DISABLE_AUTO_SET_DOWNLOAD_BEHAVIOR: false, FUNCTION_BUILT_INS: [ 'url' ], FUNCTION_ENV_VARS: [], FUNCTION_ENABLE_INCOGNITO_MODE: false, FUNCTION_EXTERNALS: [ 'lighthouse', 'node-pdftk', 'sharp' ], WORKSPACE_DIR: '/usr/src/app/workspace', WORKSPACE_DELETE_EXPIRED: false, WORKSPACE_EXPIRE_DAYS: 30, FAILED_HEALTH_URL: null, QUEUE_ALERT_URL: null, REJECT_ALERT_URL: null, TIMEOUT_ALERT_URL: null, ERROR_ALERT_URL: null, SESSION_CHECK_FAIL_URL: null, PRE_REQUEST_HEALTH_CHECK: false, EXIT_ON_HEALTH_FAILURE: false, MAX_CPU_PERCENT: 99, MAX_MEMORY_PERCENT: 99, METRICS_JSON_PATH: null, HOST: '0.0.0.0', PORT: 3000, SOCKET_CLOSE_METHOD: 'http', PROXY_URL: undefined, MAX_PAYLOAD_SIZE: '5mb' } 2026-02-16T11:21:47.024Z browserless:server Running on port 3000 Localhost ws:localhost:3000 Local network ws:10.89.6.230:3000 2026-02-16T11:21:47.024Z browserless:server Get started at https://www.browserless.io/docs/start Get a license at https://www.browserless.io/sign-up?type=commercial Get support at https://www.browserless.io/contact Happy coding! sudo podman exec -it scraper wget -O- --no-check-certificate "https://someuser:somepass@127.0.0.1:443/html?url=http://example.com" --2026-02-16 11:24:02-- https://someuser:*password*@127.0.0.1/html?url=http://example.com Connecting to 127.0.0.1:443... failed: Connection refused. sudo podman exec -it pentagi wget -O- --no-check-certificate "https://someuser:somepass@scraper/html?url=http://example.com" Connecting to scraper (10.89.6.230:443) wget: can't connect to remote host (10.89.6.230): Connection refused sudo podman exec -it pentagi /opt/pentagi/bin/ftester -flow 1 browser -action markdown -url "http://example.com" 2026/02/16 11:24:53 Warning: Error loading .env file: open .env: no such file or directory panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x1629dca] goroutine 1 [running]: main.main() pentagi/cmd/ftester/main.go:63 +0x42a
Author
Owner

@Muitamax commented on GitHub (Feb 23, 2026):

(Recommended for Podman): Use Non-Privileged Port

Modify scraper service:
pentagi-scraper:
image: vxcontrol/scraper:latest
ports:
- "127.0.0.1:9443:3000"
Then change environment:
SCRAPER_PRIVATE_URL=http://someuser:somepass@scraper:3000/

Notice:
Use HTTP
Use port 3000
Do NOT use 443

Then:
docker compose down
docker compose up -d --force-recreate

Test:
podman exec -it pentagi wget -O- "http://someuser:somepass@scraper:3000/html?url=http://example.com"

If this works → screenshots will work.

<!-- gh-comment-id:3943022462 --> @Muitamax commented on GitHub (Feb 23, 2026): (Recommended for Podman): Use Non-Privileged Port Modify scraper service: pentagi-scraper: image: vxcontrol/scraper:latest ports: - "127.0.0.1:9443:3000" Then change environment: SCRAPER_PRIVATE_URL=http://someuser:somepass@scraper:3000/ Notice: Use HTTP Use port 3000 Do NOT use 443 Then: docker compose down docker compose up -d --force-recreate Test: podman exec -it pentagi wget -O- "http://someuser:somepass@scraper:3000/html?url=http://example.com" If this works → screenshots will work.
Author
Owner

@Muitamax commented on GitHub (Feb 23, 2026):

Run Scraper Privileged
Not recommended but possible:
pentagi-scraper:
user: root
cap_add:
- NET_BIND_SERVICE

But Podman rootless still blocks privileged port binding.
So you'd need rootful Podman or Docker.

<!-- gh-comment-id:3943023711 --> @Muitamax commented on GitHub (Feb 23, 2026): Run Scraper Privileged Not recommended but possible: pentagi-scraper: user: root cap_add: - NET_BIND_SERVICE But Podman rootless still blocks privileged port binding. So you'd need rootful Podman or Docker.
Author
Owner

@asdek commented on GitHub (Feb 23, 2026):

@Muitamax thanks for this guide, we'll add it into the readme file

<!-- gh-comment-id:3944609289 --> @asdek commented on GitHub (Feb 23, 2026): @Muitamax thanks for this guide, we'll add it into the readme file
Author
Owner

@asdek commented on GitHub (Feb 23, 2026):

this issue will be closed by #144

<!-- gh-comment-id:3948521039 --> @asdek commented on GitHub (Feb 23, 2026): this issue will be closed by #144
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: vxcontrol/pentagi#56