> ## Documentation Index
> Fetch the complete documentation index at: https://docs.asobeast.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Web app configuration

> The web app reads API_INTERNAL_URL at runtime and proxies browser traffic to it, so one image can target any API without a rebuild.

The web app reads two variables, both at runtime. Nothing about the API address is baked into the image, so the same image can point at a different API by changing an environment variable and restarting.

## Variables

| Variable               | Default                 | Required | Effect                                                                                                                 |
| ---------------------- | ----------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------- |
| `API_INTERNAL_URL`     | `http://localhost:4000` | No       | API base URL. Server rendered pages call it directly, and browser requests reach it through the `/api/backend/*` proxy |
| `API_PROXY_TIMEOUT_MS` | `30000`                 | No       | Upper bound for a single proxied request. A timeout returns a `504` error envelope instead of hanging                  |

Compose sets `API_INTERNAL_URL` to `http://api:4000`, which resolves on the Docker network rather than on your machine.

## How the proxy works

The browser only ever talks to the web origin. A call to `/api/backend/apps` is handled by a Next.js route handler, which forwards the request, the session cookie and any bearer header to `API_INTERNAL_URL` and streams the answer back.

Two consequences follow from that, and both are the reason it works this way.

* There is no CORS configuration and no cross site cookie handling, because the browser never makes a cross origin request.
* The API never needs to be published. In the Compose stack it stays on a private network and only port 3000 is exposed.

See [How asobeast works](/concepts/architecture).

## What a timeout looks like

When the API does not answer within `API_PROXY_TIMEOUT_MS`, the proxy returns a `504` in the standard error envelope rather than leaving the request open. Raise the value if you run a slow upstream, but a proxy timeout usually points at a saturated API rather than at a bound that is too tight.

## Related

<CardGroup cols={2}>
  <Card title="Configuration reference" icon="sliders" href="/configuration/reference">
    Every API variable with its default.
  </Card>

  <Card title="Hosting behind TLS and a reverse proxy" icon="shield" href="/security/hosting">
    What to set before exposing port 3000.
  </Card>
</CardGroup>
