This guide covers the minimum pieces required to make simplelogin-aio work on Unraid.
You normally want:
app.example.comfor the web UImail.example.comfor inbound SMTP delivery
Set the Unraid template like this:
URL=https://app.example.comEMAIL_DOMAIN=example.comSUPPORT_EMAIL=support@example.com(use a mailbox that already exists)
EMAIL_DOMAIN becomes a SimpleLogin alias domain. Do not use an address on that same domain as the first account mailbox; register with an existing external mailbox you can already receive, then add alias-domain routing inside SimpleLogin after activation.
At minimum, add:
AorAAAArecord forapp.example.comAorAAAArecord formail.example.comMXrecord forexample.compointing tomail.example.com- SPF TXT record on
example.com - DMARC TXT record on
_dmarc.example.com
SimpleLogin will also need DKIM once the container has booted and generated its keys.
After first boot, the wrapper stores DKIM material under /appdata/dkim and symlinks the active keys into the in-container paths SimpleLogin expects.
Inbound internet mail must reach the Unraid host:
- forward TCP port
25from your router/firewall to the Unraid server
If your ISP blocks outbound port 25, choose a relay provider in the template:
brevoprotonmailgmailmailguncustom
If your ISP does not block outbound mail, direct can work.
Use the template dropdown values as-is for enum-style fields. Do not free-type custom values into fields like RELAY_MODE or ADMIN_FIDO_REQUIRED.
Advanced users can also skip the wrapper relay shortcuts and use the expanded Advanced View settings for direct upstream env overrides.
On first boot the container will:
- initialize PostgreSQL if
DB_URIis not set - start Redis if
REDIS_URLis not set - write the runtime
.env - configure Postfix
- apply
alembic upgrade head - run
init_app.pyonce
The first start can take longer than a normal restart because the internal database is being prepared.
The wrapper now validates the rendered .env before starting the web app, job runner, email handler, or Postfix. If an enum-style value is invalid, startup stops once with a fatal error instead of leaving the dependent services in wait loops.
After the container comes up:
- open the web UI on port
7777 - keep
DISABLE_REGISTRATION=true(default) to prevent public sign-up - only set
DISABLE_REGISTRATION=falsetemporarily if you need web sign-up for first boot; once your first account exists, set it back totrueand restart - confirm
/healthresponds - check the logs for any Postfix relay or DNS warnings
- check
/appdata/sland/appdata/postgreswere populated
You can point the container at external services:
- set
DB_URIto skip the internal PostgreSQL daemon - set
REDIS_URLto skip the internal Redis daemon
The template also exposes the full upstream example.env feature surface in Advanced View, including:
- alias domain behavior and onboarding controls
- social/OIDC auth providers
- hCaptcha, HIBP, SpamAssassin, Plausible, and Sentry
- AWS, Paddle, Coinbase, and file-path based advanced settings
- optional
/custom-assetsmounting for custom words files or key material
Unless you have already planned around it, leave ADMIN_FIDO_REQUIRED=none. Turning it on without intentional admin security-key enrollment just creates unnecessary lockout risk.
This keeps the Unraid template flexible without forcing beginners into a multi-container setup.
SimpleLogin's official docs also cover several features that are handled inside the app itself after deployment. These do not require extra database, cache, or helper containers in this AIO image:
- custom domains and additional alias domains
- catch-all and mailbox routing behavior
- reverse aliases and reply handling
- multiple mailboxes
- alias directories and other UI-managed account features
Those are application features, not separate infrastructure services. The AIO image already bundles the core self-hosted infrastructure pieces that normally force extra containers:
- PostgreSQL
- Redis
- Postfix
So for the normal self-hosted path, users should not need to stand up additional DB/cache/mail-routing containers unless they deliberately choose external overrides like DB_URI or REDIS_URL.