Skip to content

Environment variables

Lalabase is configured through environment variables — in the container installation via the .env file.

Required variables

# Base
RAILS_ENV=production
SECRET_KEY_BASE=<generated via bin/rails secret>

# Database
DATABASE_URL=postgres://lalabase:password@db:5432/lalabase_production

# Cache
REDIS_URL=redis://redis:6379/0

# Encryption of stored credentials (AI keys, repository tokens)
# Generate with: bin/rails db:encryption:init
ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY=<generated>
ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY=<generated>
ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT=<generated>
Important

Without the three ACTIVE_RECORD_ENCRYPTION_* variables Lalabase refuses to start in production. Store the values outside the server as well (e.g. in your password manager): a database backup is only partially readable without them — the encrypted columns remain ciphertext.

The operator and the legal pages are not environment variables. After your first sign-in, enter them in the admin area under System Settings → Operator and legal pages: the operator name and the addresses of your imprint, privacy policy and terms.

Lalabase shows them in the footer of the sign-in page and the pages without sign-in, in the consent when someone accepts an invitation, when AI is switched on and in the data export. With an operator, the footer shows © <year> <name>; without one, the plain text powered by Lalabase. An empty address field shows no link. Every address must be complete and start with https:// or http://, otherwise the form saves nothing.

If you have no website of your own, write the text itself instead: there is a text box under each address field. Lalabase then serves the page, at /legal/imprint, /legal/privacy and /legal/terms, and links it in the same places. Markdown is allowed (headings, lists, links); embedded HTML is stripped, because the page is publicly reachable.

An address takes precedence over the text. Two copies of the same privacy policy eventually start to differ.

With both empty there is no page and no link. For an instance only your own team uses, that is the normal case: the duty to publish an imprint begins when you offer the service publicly.

Registration through your own website (optional)

If your sign-up page runs as a separate program, it can create accounts through an endpoint. Without this variable the endpoint does not exist: it answers like any unknown address. Self-hosted instances rarely need it, because there you create users in the admin area or invite them.

# Generate with: openssl rand -hex 32
LALABASE_PROVISIONING_SECRET=<generated>

# Only during a rotation: the previous secret stays valid as well
LALABASE_PROVISIONING_SECRET_PREVIOUS=<previous value>

With the secret set, the endpoint also answers with a one-time link the website uses to sign the new user in, so they never meet the sign-in form right after choosing a password.

The secret needs at least 64 characters. A shorter one keeps the endpoint shut, and Lalabase writes a note to the log at boot: otherwise the symptom looks exactly like "not configured at all". Rotating without a gap: set the new secret, move the old one to _PREVIOUS, switch the website over, then drop _PREVIOUS.

So that /users/sign_up no longer leads anyone to this instance own form, add the address of your sign-up page as well:

LALABASE_SIGNUP_URL=https://your-site.example/signup

Without this variable nothing changes, which is the normal case for a self-hosted instance. With it, Lalabase redirects /users/sign_up there, temporarily (302), so removing the variable removes the redirect.

Two things deliberately stay here: invited guests and submitting the form. An invitation link carries a token that another sign-up page cannot redeem; it would create a new organisation instead of following the invitation. And a form somebody still has open should submit rather than lose what they typed.

The address must be complete and start with https:// or http://. Any other value is ignored, Lalabase writes a note to the log at boot, and the own form keeps answering.

Point it at an entry without a language prefix where you can: which language a visitor gets is then decided by the page that knows its own addresses.

AI keys (BYOK)

Lalabase follows the bring-your-own-key principle: you provide your own provider key, so no data ever flows through third-party accounts.

OPENAI_API_KEY=sk-...
Tip

Keep secrets out of version control. The .env belongs in .gitignore.

Email

To send notification emails, provide your SMTP credentials:

SMTP_ADDRESS=smtp.example.com
SMTP_PORT=587
SMTP_USERNAME=lalabase@example.com
SMTP_PASSWORD=<your-password>

Without working mail delivery nobody can sign up. Everyone who registers receives a confirmation email and has three days to click the link in it. After that, access is blocked until the address is confirmed — if the mail never arrives, there is no way forward. Verify delivery right after installation with a test registration.

Two groups are unaffected: users you create yourself in the admin area, and people who join through an invitation link. Both count as confirmed immediately and receive no confirmation email.

Mail authentication (SPF, DKIM, DMARC)

Correct SMTP credentials only get your mail sent. Whether it arrives is decided elsewhere: by three DNS records on your domain. Without them, Gmail and Outlook file the confirmation mail as spam or drop it silently. The registration then looks like a bug in Lalabase, even though delivery worked perfectly.

Record What it does
SPF Lists the servers allowed to send in your name
DKIM Cryptographically signs every outgoing mail
DMARC Tells recipients what to do when a check fails — and sends you reports about it

You create them at your domain's DNS provider, not in Lalabase. Most mail hosts offer a form that generates the right record for you.

The order matters, or you will lock yourself out:

  1. Enable DKIM. No risk — a missing signature can never deliver a mail, a present one can only help. Then verify the key really is in DNS yourself: dig TXT <selector>._domainkey.<your-domain>. Some hosts' status displays lag behind reality.
  2. Set SPF, at first with the neutral ?all ending. Only include servers that actually deliver. The machine running Lalabase usually does not qualify: the app hands its mail to the SMTP server from SMTP_ADDRESS, so it never faces the recipient itself. A needless authorization becomes a way in for mail sent in your name should that machine ever be compromised.
  3. Add DMARC with p=none and a rua= address. p=none changes nothing about delivery but switches the reports on. Without rua= the record is pointless — you get no feedback and never learn whether your records work. Keep the address on the same domain, otherwise the specification requires an extra authorization record over there.
  4. Measure. Send yourself a test mail to a mailbox at a major provider and read the headers (in Gmail: "Show original"). It says:
   Authentication-Results: ... spf=pass ... dkim=pass ... dmarc=pass
  1. Only once spf=pass shows up should you move the SPF ending from ?all to ~all. Doing it earlier is harmful: ?all means "no statement", while ~all and -all mean "suspicious" and "reject". Tighten before your real sending path is authorized and you reject your own mail.

After a few weeks of clean DMARC reports you can raise p=none to p=quarantine and later p=reject. Never start at reject.

Tip

Leave forensic DMARC reports (ruf=) empty. They contain full copies of other people's failed mail, and the large providers do not send them anyway.