Configuration
Serelane is configured entirely through the environment, so a container needs no configuration file and nothing mounted to hold one.
Every setting is validated at boot, and every problem is reported at once rather than one restart at a time. A container with no environment at all boots on the defaults below.
| Variable | Default | What it does |
|---|---|---|
SERELANE_BASE_URL |
derived from the Host header |
The absolute URL this instance is reachable at. It goes into emails and link previews, which a relative address cannot serve. Must be an absolute http or https URL, and a trailing slash is trimmed. Behind a proxy that does not set Host, the guess is wrong, so set this. |
SERELANE_DATA_DIR |
./data |
Where the database, the uploads and the generated secret key live. The only path Serelane writes to. The container image sets this to /data. |
SERELANE_LOG_LEVEL |
info |
One of debug, info, warn or error. |
SERELANE_PORT |
8080 |
The TCP port to listen on. Between 1 and 65535. |
SERELANE_SECRET_KEY |
generated into the data directory | Signs sessions, sign-in links and anonymous cookies. At least 32 characters. Left unset, one is generated into secret.key and the instance says so loudly at boot: back that file up, because losing it signs everyone out and invalidates every pending sign-in link. |
SERELANE_TRUSTED_PROXIES |
empty | Comma-separated CIDR blocks, or bare addresses for a single host. Only these networks’ X-Forwarded-For is believed. Unset means the header is ignored entirely, so every visitor appears to come from the proxy, which collapses anonymous vote deduplication and rate limiting onto one address. |
Database
Section titled “Database”| Variable | Default | What it does |
|---|---|---|
SERELANE_DB_DRIVER |
sqlite |
The only accepted value today. Postgres is a planned driver, not a shipped one, and any other value fails at boot. |
SERELANE_DB_DSN |
serelane.db inside the data directory |
Where the database lives. Defaulting inside the data directory is what makes moving that directory move the database with it. |
Mail is optional.
With no SERELANE_SMTP_HOST, sign-in links and notifications are written to the log instead of sent, so magic-link identity does not work and nobody is notified of anything.
| Variable | Default | What it does |
|---|---|---|
SERELANE_SMTP_FROM |
none | The envelope sender. Required once SERELANE_SMTP_HOST is set; the instance refuses to boot without it. |
SERELANE_SMTP_HOST |
empty | The relay. Setting it is what turns mail on. |
SERELANE_SMTP_PASSWORD |
empty | The password for the relay. |
SERELANE_SMTP_PORT |
587 |
The relay’s port. |
SERELANE_SMTP_TLS |
starttls |
One of starttls (port 587, a plaintext session upgraded), implicit (port 465, TLS from the first byte) or none (in the clear, which is only ever right for a relay on localhost). true, 1 and yes are accepted as synonyms for starttls, and false, 0 and no for none, because this setting used to be a boolean. |
SERELANE_SMTP_USERNAME |
empty | The username for the relay. |
Spam and abuse
Section titled “Spam and abuse”The challenge is instance configuration because the keys are per deployment and because it decides whether the process can verify a solution at all. Which boards actually use it is a per-project setting, in the database.
| Variable | Default | What it does |
|---|---|---|
SERELANE_CAPTCHA_PROVIDER |
empty | altcha, turnstile, or empty for none. Altcha is a self-hosted proof of work and involves no third party, which is why it is the one to reach for first on a self-hosted instance. |
SERELANE_CAPTCHA_SECRET |
the instance secret key | Signs altcha challenges and authenticates to Turnstile. Required for turnstile. In altcha mode it falls back to SERELANE_SECRET_KEY, so the privacy-preserving option needs no configuration beyond switching it on. |
SERELANE_CAPTCHA_SITE_KEY |
empty | The public half a third-party widget renders with. Required for turnstile. |
Sign-in
Section titled “Sign-in”Both providers below require the same assertion: the id token’s email_verified claim has to be present and true.
A provider that omits the claim entirely, which Azure AD and SAML-bridged identity providers do, is refused exactly as if it had sent false — omitting an assertion is not making one.
This applies to the admin console provider and the board provider alike.
Admin console
Section titled “Admin console”Configures the OIDC provider the operator console signs in through.
This is separate from the board provider below: setting one never configures the other, so an instance can require a second factor of its operators without requiring one of every visitor who votes on a roadmap.
The client secret is optional here too, since every authorisation request carries a PKCE S256 challenge.
Register <base URL>/api/v1/admin/auth/callback as the redirect URI with the provider, using the instance’s own base URL in place of <base URL>.
This is a different path from the board provider’s callback below, so a provider can tell the two sign-ins apart.
| Variable | Default | What it does |
|---|---|---|
SERELANE_ADMIN_OIDC_CLIENT_ID |
empty | The application registered with the provider. Required once SERELANE_ADMIN_OIDC_ISSUER is set. |
SERELANE_ADMIN_OIDC_CLIENT_SECRET |
empty | Optional. Every authorisation request carries a PKCE S256 challenge, so a public client is a complete configuration on its own. |
SERELANE_ADMIN_OIDC_ISSUER |
empty | The provider’s base URL, the one its discovery document hangs off. Required once SERELANE_ADMIN_OIDC_CLIENT_ID is set. |
SERELANE_ADMIN_OIDC_LABEL |
empty | What the sign-in button says. |
SERELANE_ADMIN_OIDC_SCOPES |
empty | Space-separated. Empty means the default set. |
Board provider
Section titled “Board provider”Configures one OIDC provider for every board on the instance. It is optional, and when it is set it replaces whatever a project has stored, because a deployment that names its provider here should not have that quietly overridden from a form.
Register <base URL>/api/v1/public/auth/callback as the redirect URI with the provider, using the instance’s own base URL in place of <base URL>.
Identities are joined on the verified email address, not on the provider.
Pointing an instance at a different provider lets anyone who controls that same address there sign in as the existing identity.
They inherit its votes, comments and subscriptions.
Only repoint SERELANE_OIDC_ISSUER at a provider you trust to guard the same addresses as the one it replaces.
| Variable | Default | What it does |
|---|---|---|
SERELANE_OIDC_CLIENT_ID |
empty | The application registered with the provider. Required once SERELANE_OIDC_ISSUER is set. |
SERELANE_OIDC_CLIENT_SECRET |
empty | Optional. Serelane always sends a PKCE challenge, so a public client is a complete configuration on its own, and some providers will not issue a secret for one. |
SERELANE_OIDC_ISSUER |
empty | The provider’s base URL, the one its discovery document hangs off. Required once SERELANE_OIDC_CLIENT_ID is set. |
SERELANE_OIDC_LABEL |
empty | What the sign-in button says. |
SERELANE_OIDC_SCOPES |
empty | Space-separated. Empty means the default set. |
First run
Section titled “First run”These are read on every invocation but only used by serelane bootstrap, which creates the first admin account without a browser.
They live here rather than in flags so that an operator provisioning from a compose file finds them beside every other setting.
| Variable | Default | What it does |
|---|---|---|
SERELANE_BOOTSTRAP_DEMO |
on for a dev instance, otherwise off | Fills the example board with content. |
SERELANE_BOOTSTRAP_EMAIL |
none | The first admin account’s address. Must contain an @. |
SERELANE_BOOTSTRAP_NAME |
none | The display name on that account. |
SERELANE_BOOTSTRAP_PASSWORD |
none | That account’s password. Checked for length up front, so a typo fails the command rather than creating an account nobody can sign in to. Not trimmed: leading and trailing spaces are a legitimate part of a password, and silently changing what you set would lock you out. |
Without both an email and a password, serelane bootstrap refuses rather than inventing credentials.
Create the account through the setup form instead, at /setup.
Development
Section titled “Development”| Variable | Default | What it does |
|---|---|---|
SERELANE_DEV |
off | Set to 1 to serve the frontend by proxying to the Vite dev server instead of from the embedded copy, and to allow serelane bootstrap to fall back to built-in credentials. Never set this on an instance anyone else can reach. |