# ===================================================================== # owuitools ingress gateway. # # Deliberately dumb: this is the ONLY container that joins # openwebui_default, and it holds no application logic. Its whole job is # to let open-webui reach owuitools-api, which lives on an internal-only # network and therefore cannot be reached - or reach out - any other way. # # Keeping the app off openwebui_default is the point. If the app sat # there it would have a default route, and a bug in URL validation would # put the host's other stacks one HTTP request away. # ===================================================================== worker_processes 1; # Both destinations on purpose: stderr keeps `docker compose logs` # working, the file puts it with every other component in ./logs. error_log /dev/stderr warn; error_log /logs/gateway.error.log warn; pid /tmp/nginx.pid; events { worker_connections 512; } http { access_log /dev/stdout combined; access_log /logs/gateway.access.log combined; # Read-only rootfs: everything nginx wants to write goes to tmpfs. client_body_temp_path /tmp/client_body; proxy_temp_path /tmp/proxy; fastcgi_temp_path /tmp/fastcgi; uwsgi_temp_path /tmp/uwsgi; scgi_temp_path /tmp/scgi; sendfile on; server_tokens off; # Tool responses are capped server-side but a datasheet fetch can # still be a few hundred KB before trimming. client_max_body_size 1m; proxy_buffering off; upstream owuitools_api { server owuitools-netguard:8000; keepalive 8; } server { listen 8000; server_name _; # A tool call that needs a slow origin plus a PDF parse can take a # while: at 90 s a 995-page manual was cut off mid-extraction and the # model received nginx's HTML 504 page as its tool result. The app # bounds its own slow paths (PDF extraction at 120 s) so that it, not # this gateway, is what answers. # # CORRECTION, measured on 0.11.3. This comment used to say Open WebUI # sets no tool-server timeout of its own "because AIOHTTP_CLIENT_TIMEOUT # is unset here". That is wrong, and wrong in the dangerous direction: # env.py falls AIOHTTP_CLIENT_TIMEOUT_TOOL_SERVER back to # AIOHTTP_CLIENT_TIMEOUT, which defaults to 300 when unset - not to # "no limit". So there are TWO clocks on an ordinary tool call, and # Open WebUI's is the shorter one. proxy_connect_timeout 10s; proxy_send_timeout 240s; proxy_read_timeout 240s; # The one exception. A VM session is a slow model with thinking on # driving a real machine, so it is minutes to hours rather than # seconds. This needs all three clocks raised together - this one, # OWUITOOLS_VM_WAIT_SECONDS in the app, and # AIOHTTP_CLIENT_TIMEOUT_TOOL_SERVER on the open-webui container - # and the app's is deliberately the smallest so that IT answers. # # Only this location: every other tool keeps the 240 s ceiling, # because a tool that hangs should fail rather than tie up a worker # for two hours. location = /tools/vm_agent { proxy_pass http://owuitools_api; proxy_http_version 1.1; proxy_set_header Connection ""; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_pass_request_headers on; proxy_read_timeout 7200s; proxy_send_timeout 7200s; } location / { proxy_pass http://owuitools_api; proxy_http_version 1.1; proxy_set_header Connection ""; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; # open-webui forwards these when ENABLE_FORWARD_USER_INFO_HEADERS # is on; the app keys its per-user rate limits off them, so they # must survive the hop. proxy_pass_request_headers on; } } }