Proxy didn't work on Google Gemini Chat Model node

Describe the problem/error/question

My n8n instance is running in a region that doesn’t have direct access to Google, so I use a proxy server to handle the connection to Google.
I added the following to Docker’s environment variables:

HTTPS_PROXY http://172.17.0.3:7890/
HTTP_PROXY http://172.17.0.3:7890/
ALL_PROXY soket5://172.17.0.3:7891

When I add a Google Gemini Chat Model node, I can add the Credential correctly and load the model list in the Node. This proves to some extent that the Proxy is working properly.
But in actual operation, Node will return a 502 error.
I looked at the proxy server’s logs, which confirmed my suspicion, when I added the Credential and selected the model list, I could see a connection message. But when the node is actually running, the proxy server’s log is empty.
Likewise, n8n’s logs don’t give any errors.

What is the error message (if any)?

Share the output returned by the last node

Information on your n8n setup

  • n8n version: 1.41.0
  • Database (default: SQLite): SQLite
  • n8n EXECUTIONS_PROCESS setting (default: own, main):
  • Running n8n via (Docker, npm, n8n cloud, desktop app): Docker
  • Operating system: Synology 7.1

After doing an extensive search, I found that this came from an Axios problem that had not been solved since 2020:

There is only one way to solve this problem, which is to use the gateway proxy model and put the whole Dcoker behind the proxy server.
Here’s a Chinese post to show you how:

But this method is too complicated.
For n8n, the temporary solution is to change Execution Order to v0 in the workflow settings.

In addition, I found that RSS Read and RSS Feed Trigger have the same problem.
Unfortunately, these two nodes do not use proxies correctly even under v0 's Execution Order.

Hey @WJXY,

Proxies are complicated and due to the issue you found already they don’t always work with Axios, We actually have a few posts about this now. If you are using an https proxy make sure the proxy is confgured to use https and that will get around the issue for now.

I encountered the problem getting no response in LLM chat using localai endpoint if http_proxy / https_proxy environment variables are set in the docker container.

The problem could be solve by clearing these env vars for n8n instance, but for other tasks in n8n I would like to use the proxy. If there’s a way to change the env vars for each task in n8n then it would be great, like setting from UI panel / fetching file from local, URL.

The provided solution using transparent proxy is not as complicated as if using docker compose. For now I managed to add a redsocks2 + mitmproxy instance to docker compose, n8n should use this instance as its default gateway.

For others reference I post my setup for n8n with transparent proxy here:

The docker compose file. Mitmproxy service should be build and up first, then build and run n8n service because mitmproxy would generate a CA certificate on the run which is needed by n8n during its build.

services:
  n8n:
    image: "my-n8n-image"
    build:
      context: .
      dockerfile: Dockerfile
      target: n8n
      args:
        - MITMPROXY_CA_CERT=./data/n8n/.mitmproxy/mitmproxy-ca-cert.pem
    environment:
      - NODE_ENV=production
    env_file:
      - .env
    volumes:
      - ./data/n8n/.n8n:/home/node/.n8n
      - ./scripts/my_init.sh:/my_init.sh:ro
    entrypoint: "/my_init.sh"
    restart: "unless-stopped"
    ports:
      - 3000:3000
    depends_on:
      - mitmproxy
    networks:
      - default
    cap_add:
      - NET_ADMIN
  mitmproxy:
    image: "my-n8n-mitmproxy-image"
    build:
      context: .
      dockerfile: Dockerfile
      target: mitmproxy
    entrypoint: "/mitmproxy_init.sh"
    restart: "unless-stopped"
    cap_add:
      - NET_ADMIN
    volumes:
      - ./scripts/mitmproxy_init.sh:/mitmproxy_init.sh:ro
      - ./data/n8n/.mitmproxy:/home/mitmproxy/.mitmproxy

my_init.sh

#!/bin/sh

python3 <<EOF
import time
import socket
import subprocess
import re

# get mitmproxy service ip address for "n8n-mitmproxy-1" using getaddrinfo
while True:
    try:
        info = socket.getaddrinfo("n8n-mitmproxy-1", 80)
        if info is None:
            time.sleep(1)
            continue
        break
    except Exception:
        time.sleep(1)
        continue

proxy_ip = info[0][4][0]

# example: "default via 172.16.30.1 dev eth0"
re_default_gateway = re.compile(r"^default.*\bvia\s+(?P<ip>\d+\.\d+\.\d+\.\d+).*\bdev\s+(?P<iface>\w+)\b.*$")

gateway_ip = None
gateway_iface = None

for l in subprocess.run(["ip", "r"], capture_output=True).stdout.decode("utf-8").split("\n"):
    m = re_default_gateway.search(l)
    if m is None:
        continue
    gateway_ip = m.group("ip")
    gateway_iface = m.group("iface")
    break

print(f"{proxy_ip=}")
print(f"{gateway_ip=}, {gateway_iface=}")

if gateway_ip is not None:
    subprocess.run(["ip", "r", "del", "default"])
    subprocess.run(["ip", "r", "add", "default", "via", proxy_ip])
EOF

su node -c "/usr/bin/env -u HTTP_PROXY -u http_proxy -u HTTPS_PROXY -u https_proxy -u NO_PROXY -u NODE_EXTRA_CA_CERTS=/usr/local/share/ca-certificates/mitmproxy-ca-cert.pem TINI_SUBREAPER=true tini -- /docker-entrypoint.sh"

mitmproxy_init.sh

#!/bin/sh

REDSOCKS_PORT=${REDSOCKS_PORT:-21542}
MINIPROXY_PORT=${MINIPROXY_PORT:-1002}
MITMPROXY_PORT=8080

python3 <<EOF
import re
re_scheme = re.compile(r"(https?://)?(?P<ip_port>(\d+\.){3}\d+:\d+)")

UPSTREAM_PROXY="${HTTP_PROXY}" if len("${http_proxy}") == 0 else "${http_proxy}"
m = re_scheme.search(UPSTREAM_PROXY)
if m is not None:
    UPSTREAM_PROXY = m.group("ip_port")
print(f"{UPSTREAM_PROXY=}")


UPSTREAM_BYPASS_DICT = dict()
UPSTREAM_BYPASS = list(filter(lambda h: len(h) > 0, 
    [h.strip() for h in "${NO_PROXY}".split(",")]))
for i, h in enumerate(UPSTREAM_BYPASS):
    if h.startswith("*"):
        UPSTREAM_BYPASS[i] = h[1:]
    UPSTREAM_BYPASS_DICT[UPSTREAM_BYPASS[i]] = UPSTREAM_BYPASS[i]

with open("/tmp/tinyproxy.conf", "w") as f:
    f.write("\n".join([
        "Port ${MINIPROXY_PORT}",
        "Upstream none \".localai_default\"",
    ]))
    f.write("\n")
    f.write("\n".join(map(lambda h: f"Upstream none \"{h}\"", UPSTREAM_BYPASS_DICT.keys())))
    if len(UPSTREAM_PROXY) > 0:
        f.write("\n")
        f.write(f"Upstream http {UPSTREAM_PROXY}\n")
    f.write("\n")
    f.write("LogLevel Critical")
    f.write("\n")
    f.write("MaxClients 2000")
    f.write("\n")
    f.write("StartServers 10")
    f.write("\n")
    f.write("MaxSpareServers 10")
EOF

python3 <<EOF
cfg = """base {
  log_debug = off;
  log_info = off;
  log = stderr;
  daemon = off;
  redirector = iptables;
  reuseport = off;
}

redsocks {
  bind = "0.0.0.0:${REDSOCKS_PORT}";
  relay = "127.0.0.1:${MITMPROXY_PORT}";
  type = direct;
}
"""

with open("/tmp/redsocks.conf", "w") as f:
    f.write(cfg)
EOF

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port ${REDSOCKS_PORT}
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j REDIRECT --to-port ${REDSOCKS_PORT}

/usr/bin/env \
    -u HTTP_PROXY \
    -u http_proxy \
    -u HTTPS_PROXY \
    -u https_proxy \
    -u NO_PROXY \
    -u no_proxy \
    tinyproxy -d -c /tmp/tinyproxy.conf &
redsocks2 -c /tmp/redsocks.conf &

docker-entrypoint.sh \
    mitmdump \
    --mode upstream:http://127.0.0.1:${MINIPROXY_PORT} \
    --quiet

A custom docker image with python3.12 and iptables is needed

Dockerfile

FROM mitmproxy/mitmproxy as mitmproxy

RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
    --mount=type=cache,target=/var/lib/apt,sharing=locked \
    apt-get -q update && \
    DEBIAN_FRONTEND=noninteractive \
        apt-get -q install --no-install-recommends -y \
        tinyproxy iptables procps \
        libevent-dev libssl-dev build-essential git

RUN git clone https://github.com/semigodking/redsocks.git /tmp/redsocks
RUN cd /tmp/redsocks/ && \
    make distclean && \
    make -j DISABLE_SHADOWSOCKS=true redsocks2 && \
    cp /tmp/redsocks/redsocks2 /usr/local/bin/redsocks2 && \
    rm -rf /tmp/redsocks/

FROM n8nio/n8n:latest as n8n

USER root

ARG MITMPROXY_CA_CERT

COPY ${MITMPROXY_CA_CERT} /usr/local/share/ca-certificates/mitmproxy-ca-cert.pem
RUN cat /usr/local/share/ca-certificates/mitmproxy-ca-cert.pem \
    >> /etc/ssl/certs/ca-certificates.crt

RUN --mount=type=cache,target=/var/cache/apk \
    && apk update \
    && apk add --update --no-cache python3=~3.12 py3-pip curl iptables ca-certificates \
    && ln -sf python3 /usr/bin/python

COPY ${MITMPROXY_CA_CERT} /usr/local/share/ca-certificates/mitmproxy-ca-cert.pem
RUN update-ca-certificates

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.