# Environment variables

Set these in **Settings → Environment Variables** in the menu-bar
tray.

## On/off values

Every Fregata on/off switch below accepts the same values, and **case
doesn't matter** — `1`, `true`, `True`, `TRUE`, `yes`, `y`, `on`, and `t`
all mean on; `0`, `false`, `no`, `n`, `off`, and `f` all mean off.
Surrounding spaces are ignored. Leaving a variable unset, or setting it to
an empty value, keeps the documented default.

If you set one to something else entirely (say `enable`), Fregata keeps the
default and writes a warning naming the value to the log — so a typo tells
you rather than silently doing nothing.

:::note
Environment variable changes take effect when Frigate **starts**. After
editing them, restart Fregata from the menu bar.
:::

## Frigate+

### `PLUS_API_KEY`

| Default | Effect |
| --- | --- |
| unset | Frigate+ Subscription not enabled |
| `Frigate+ API Key` | Frigate+ Subscription enabled |

Needed to take advantage of a Frigate+ subscription, if you have one.

## Fregata-specific

These are the env vars introduced by the Fregata port itself.

### `FRIGATE_CACHE_SIZE_MB`

| Default | Effect |
| --- | --- |
| computed | Ceiling for the **Basic RAM disk** size in megabytes (1024 MB max). Default is a per-camera-config formula; set explicitly to lock a value. Does **not** apply to the Smart memory (tmpfs) cache backing &mdash; that one has a fixed 1 GB sparse cap that's not user-tunable. See [Performance &rarr; RAM-disk cache](/guides/performance/#ram-disk-cache) for the two modes and how you picked one in the welcome wizard. |

### `FREGATA_EXPOSE_INTERNAL_PORT`

| Default | Effect |
| --- | --- |
| unset | Port 5000 bound to `127.0.0.1` only (loopback). |
| `1` | Port 5000 bound to all interfaces (`0.0.0.0`), reachable from your LAN. |

:::danger[No authentication on port 5000]
Port 5000 has **no authentication middleware**. Any device on your network that can reach it gets full admin API access — no login required. Only set this on a network you fully trust (home LAN behind a router, not a shared office or open Wi-Fi).

For most use cases, port **8971** with a Bearer token or `auth.enabled: false` in `config.yml` is a safer path. See [Using the API from local automation tools](/guides/network-and-remote-access/#using-the-api-from-local-automation-tools).
:::

See [On/off values](#onoff-values) for the accepted values — case doesn't matter. Unset keeps the default loopback binding. A warning is written to the Fregata log at startup whenever this is active.

If port 5000 is already bound by something else — most commonly macOS's
**AirPlay Receiver**, which holds it permanently whenever enabled — Fregata
detects the conflict and automatically serves the same unauthenticated
endpoint on port `5050` instead, leaving port 5000 itself loopback-only.
You don't need to disable AirPlay Receiver; check the Fregata log at
startup to confirm which port is active. See
[Port 5000 already in use?](/guides/network-and-remote-access/#using-the-api-from-local-automation-tools)
for details.

:::caution[Use `127.0.0.1:5000`, not `localhost:5000`]
That conflict detection only runs when this variable is set to expose
port 5000 to your LAN. In the default loopback-only mode there's no bind
conflict to catch, because AirPlay Receiver binds all interfaces
(IPv4 *and* IPv6) while Fregata binds only `127.0.0.1`. Since `localhost`
often resolves to the IPv6 loopback address (`::1`) before the IPv4 one on
macOS, `http://localhost:5000/...` can silently land on AirPlay Receiver
instead of Fregata. Always use `http://127.0.0.1:5000/...` explicitly.
:::

### `FREGATA_INTERNAL_PORT_FALLBACK`

| Default | Effect |
| --- | --- |
| `5050` | Port used for LAN-exposed unauthenticated access when port 5000 can't be bound (see `FREGATA_EXPOSE_INTERNAL_PORT` above). |
| `<port>` | Use this port instead, e.g. if `5050` is also taken on your network. |

Only relevant when `FREGATA_EXPOSE_INTERNAL_PORT=1` **and** port 5000 is
unavailable. Has no effect otherwise. Same no-authentication warning as
`FREGATA_EXPOSE_INTERNAL_PORT` applies to whichever port ends up active.

Can't be set to a port Fregata already uses internally — `5000`, `5001`,
`5002`, `8082`, `8971`, `1984`, `8554`, or `8555`. An override matching one
of those is ignored (with a warning in the log) and the default (`5050`)
is used instead.

### `FREGATA_EXPOSE_GO2RTC_PORT`

| Default | Effect |
| --- | --- |
| unset | Port 1984 (go2rtc's admin API) bound to `127.0.0.1` only (loopback). |
| `1` | Port 1984 bound to all interfaces (`0.0.0.0`), reachable from your LAN. |

:::danger[No authentication on port 1984]
go2rtc's admin API has **no authentication of its own**. Any device on your network that can reach it can read and change stream/restream configuration and pull RTSP/WebRTC feeds directly — bypassing Frigate's auth entirely. Only set this on a network you fully trust.
:::

See [On/off values](#onoff-values) for the accepted values — case doesn't matter. Unset keeps the default loopback binding. A warning is written to the Fregata log at startup whenever this is active.

Unlike `FREGATA_EXPOSE_INTERNAL_PORT`, there's no conflict fallback here — go2rtc is its own process, so a failed bind only stops go2rtc, not the rest of Fregata, and port 1984 isn't known to collide with anything on macOS. If you've set `go2rtc.api.listen` explicitly in your own `config.yml`, that takes precedence over this env var.

### `FREGATA_EXPOSE_RTSP_PORT`

| Default | Effect |
| --- | --- |
| unset | Port 8554 (go2rtc's RTSP restream) bound to all interfaces (`0.0.0.0`), reachable from your LAN. |
| `0` | Port 8554 bound to `127.0.0.1` only (loopback) — locks the RTSP restream down to the same Mac. |

:::danger[No authentication on port 8554, by default]
The RTSP restream has **no authentication of its own by default**. Any device on your network that can reach it can watch — and for cameras with two-way talk configured, potentially control — your camera streams directly. If you don't need the RTSP feed from another device (VLC, Home Assistant's RTSP camera platform, another NVR), set `FREGATA_EXPOSE_RTSP_PORT=0` to restrict it to loopback-only. If you do need LAN access, add a username/password instead (see below).
:::

Set it to an off value (`0`, `false`, `no`, `off` — see [On/off values](#onoff-values); case doesn't matter) to disable LAN exposure. Unset keeps the default LAN-open binding. A warning is written to the Fregata log at startup whenever the port is locked to loopback, so you always have a visible reminder that it's disabled.

Unlike `FREGATA_EXPOSE_INTERNAL_PORT`, there's no conflict fallback here — go2rtc is its own process, so a failed bind only stops go2rtc, not the rest of Fregata, and port 8554 isn't known to collide with anything on macOS. If you've set `go2rtc.rtsp.listen` explicitly in your own `config.yml`, that takes precedence over this env var.

To require a login instead of relying on network exposure alone, set `go2rtc.rtsp.username`/`password` in `config.yml`:

```yaml
go2rtc:
  rtsp:
    username: "admin"
    password: "pass"
```

Clients then connect with `rtsp://admin:pass@<mac-ip>:8554/<camera_name>`. This is go2rtc's own credential check — independent of `FREGATA_EXPOSE_RTSP_PORT`, independent of Frigate's `auth.enabled`, and separate from whatever username/password your cameras use upstream.

### `FREGATA_TELEMETRY_DISABLED`

| Default | Effect |
| --- | --- |
| unset | Privacy-respecting Telemetry included in license check. |
| `1` | Telemetry omitted. |

The contents of the telemetry are listed at
[Privacy & telemetry](/reference/privacy-and-telemetry/). Setting
this to `1` is a complete opt-out — nothing telemetry-shaped leaves
the Mac.

## go2rtc

### `GO2RTC_ALLOW_ARBITRARY_EXEC`

| Default | Effect |
| --- | --- |
| unset | `echo:`, `expr:`, and `exec:` go2rtc stream sources are **rejected** — dropped from the generated go2rtc config (and from the `PUT /go2rtc/streams` admin API), with an error written to the log. |
| `true` | Those sources are allowed. |

An upstream Frigate switch — note the `GO2RTC_` prefix, not `FREGATA_` or
`FRIGATE_`. go2rtc's `exec:`/`echo:`/`expr:` sources run arbitrary local
commands, so Fregata disables them by default, matching upstream Frigate.
Turn it on only if you deliberately use a custom `exec:` restream — a split
fisheye, a `drawtext` overlay, a GPU rotation pipeline.

Unlike Fregata's own on/off switches above, this one accepts a **narrower**
set of values: only `true`, `1`, or `yes` turns it on (case doesn't matter).
Anything else — including `on`, `y`, or `enable` — leaves it off, matching
upstream Frigate's parser exactly.

Fregata's own internal `exec:` streams — the birdseye restream and the
adaptive-live rungs — are never affected by this switch; it gates only the
sources you write into `go2rtc.streams` yourself.

See [Custom go2rtc stream sources](/guides/network-and-remote-access/#custom-go2rtc-stream-sources)
for the full behavior, the `{{output}}` token, and brace-doubling.

## Optional Frigate config wiring

These are read by `config.yml` via the `{}` YAML tag, not by
Fregata or the launcher. They exist because writing secrets in
plaintext into a file is generally a bad habit.

### `FRIGATE_MQTT_PASSWORD`

Conventional name for the MQTT broker password. Reference in
`config.yml`:

```yaml
mqtt:
  password: {FRIGATE_MQTT_PASSWORD}
```

You're free to use any other name, as long as it starts with
`FRIGATE_` — Frigate's config loader only substitutes env vars with
that prefix. Pick a convention and stick with it.

### Other secrets

The same pattern works for any secret your config references:
`FRIGATE_GENAI_KEY`, `FRIGATE_HOMEASSISTANT_TOKEN`,
`FRIGATE_MQTT_PASSWORD`, etc. Set them in the in-app editor and
reference them with `{NAME}` in `config.yml`, using the `FRIGATE_`
prefix.
