Self-Hosting n8n + Baserow with Docker: The Networking Bug Nobody Documents

If you're running n8n and Baserow together in the same docker-compose.yml, you'll likely hit this exact error the first time n8n's Baserow node tries to talk to Baserow: the credential test fails, or you get a raw 404 Server Error / "Site not found" page when hitting http://baserow/api/... from inside the n8n container.

The cause isn't what most guides assume.

What's actually happening

Baserow's all-in-one Docker image ships its own internal Caddy reverse proxy in front of the Django backend and the frontend. That proxy only forwards /api/* requests to the backend for hostnames it explicitly recognizes. Any other Host header — like the internal Docker network name baserow that n8n uses to reach it — gets routed to the frontend instead, which doesn't know what to do with an API call and returns a 404.

Two environment variables look like they should fix this, and don't:

The actual fix

Add the internal hostname to BASEROW_EXTRA_PUBLIC_URLS:

services:
  baserow:
    image: baserow/baserow:latest
    environment:
      - BASEROW_PUBLIC_URL=http://localhost:8080
      - BASEROW_CADDY_ADDRESSES=:80
      - BASEROW_EXTRA_PUBLIC_URLS=http://baserow,http://127.0.0.1:8080
      - BASEROW_EXTRA_ALLOWED_HOSTS=baserow,127.0.0.1

BASEROW_EXTRA_PUBLIC_URLS is what Caddy's internal matcher actually checks before proxying /api/* to the backend. List every hostname another container will use to reach Baserow here — including the plain Docker Compose service name (baserow) that other containers on the same network use by default.

After adding this and restarting the stack, the n8n Baserow credential test (and any HTTP request from another container) starts working immediately — no other change needed.

How to verify it yourself

From inside any other container on the same Docker network:

curl -s http://baserow/api/settings/

If you get back JSON instead of an HTML 404 page, the routing is fixed.