---
title: "Configuration"
description: "Where slopscale finds config.yaml, how SLOPSCALE_ environment variables override its keys, and which settings live only in the file, not the database."
---

- Slopscale loads its configuration from a YAML file
- It searches for `config.yaml` in the following paths:
    - `/etc/slopscale`
    - `$HOME/.slopscale`
    - the current working directory
- To load the configuration from a different path, use:
    - the command line flag `-c`, `--config`
    - the environment variable `SLOPSCALE_CONFIG`
- Validate the configuration file with: `slopscale configtest`

:::note[Get the example configuration from the GitHub repository]

Always select the [same GitHub tag](https://github.com/aislopware/slopscale/tags) as the released version you use to
ensure you have the correct example configuration. The `main` branch might contain unreleased changes.

**View on GitHub**

- Development version: https://github.com/aislopware/slopscale/blob/main/config-example.yaml
- Version 0.36.0: https://github.com/aislopware/slopscale/blob/v0.36.0/config-example.yaml

**Download with wget**

```shell
# Development version
wget -O config.yaml https://raw.githubusercontent.com/aislopware/slopscale/main/config-example.yaml

# Version 0.36.0
wget -O config.yaml https://raw.githubusercontent.com/aislopware/slopscale/v0.36.0/config-example.yaml
```

**Download with curl**

```shell
# Development version
curl -o config.yaml https://raw.githubusercontent.com/aislopware/slopscale/main/config-example.yaml

# Version 0.36.0
curl -o config.yaml https://raw.githubusercontent.com/aislopware/slopscale/v0.36.0/config-example.yaml
```

:::

## Environment variables

Every key in the file can be overridden by an environment variable: prefix `SLOPSCALE_`, uppercase, dots
replaced by underscores, so `dns.base_domain` is `SLOPSCALE_DNS_BASE_DOMAIN` and `oidc.client_secret` is
`SLOPSCALE_OIDC_CLIENT_SECRET`. A variable wins over the file, the file over the built-in default.

- Lists are space separated: `SLOPSCALE_DNS_NAMESERVERS_GLOBAL="1.1.1.1 8.8.8.8"`.
- Maps are JSON objects: `SLOPSCALE_DNS_NAMESERVERS_SPLIT='{"example.com": ["10.0.0.53"]}'`.
- Durations take Go syntax: `SLOPSCALE_NODE_EXPIRY=720h`.
- A variable set to an empty string is an explicit empty value, not a request for the default:
  `SLOPSCALE_DERP_URLS=""` disables the public DERP map. Unset the variable to get the default back.

## Settings that live only in the file

Most of what an operator changes day to day (DNS, DERP relays, key expiry, approval, the tailnet switches) is
stored in the database and edited from the [console](/slopscale/ref/console), the CLI or the API without a restart. A few
things stay in the file, because the server needs them before it has a database or because they are about the
machine it runs on:

- `server_url`, the listen addresses, TLS and the [database](/slopscale/setup/backup).
- `oidc`, the [identity provider](/slopscale/ref/oidc), and `policy.geoip_database` for [postures](/slopscale/ref/device-trust#postures).
- `derp.paths`, the relay's key and `automatically_add_embedded_derp_region`; see [DERP](/slopscale/ref/derp).
- `ssh_recording`, `https_certificates`, `funnel` and `notifications.smtp`, which run something inside the server.
- `branding`, the name and logo the server puts on itself; the logo is a file, read once at startup. See
  [Branding](/slopscale/ref/branding).
- `client_updates`: the server reads the latest stable Tailscale release from pkgs.tailscale.com once a day and
  tells each client whether it runs it, so an older client shows Tailscale's own _update available_ warning and,
  with auto-update on, updates itself. `check: false` turns the lookup off on a server without internet access;
  `interval` is how often to look, at least one hour. See [Device management](/slopscale/ref/device-management#client-update-notices).
- `control_dial_plan`: addresses clients try for the server before resolving its name, in order of preference.
  Clients keep the plan between runs, so they reach the server through a DNS outage and fall back to the name when
  none of the addresses answers. Leave it empty to rely on DNS.

  ```yaml
  control_dial_plan:
    - 203.0.113.7
    - 2001:db8::7
  ```

- `egress`: where the server's own HTTP clients may go. Webhook receivers, log stream sinks and DERP map URLs
  may never point at a loopback, link-local or unspecified address, so an operator-supplied URL cannot reach the
  server's own services or a cloud metadata endpoint; the URL is checked when it is stored and again against the
  address it resolves to when it is dialed, so DNS rebinding does not get past it. Private ranges stay reachable,
  because a receiver on the LAN is a normal self-hosted setup. `deny_private_targets: true` refuses them too, and
  `allow_loopback_targets: true` re-allows loopback for a development server whose receivers run alongside it.
- `debug.node_api_enabled`, a [development endpoint](/slopscale/ref/debug#development-endpoints).
