Docs / Reference

Self-hosting

Run your own copy of signo on a server with Docker. It takes about five minutes.

You need a server with Docker, a domain for signo (for example login.example.com) whose DNS points at that server, ports 80 and 443 open, and an SMTP account to send sign-in emails.

1. Get the code and fill in three settings

git clone https://codeberg.org/egglabs/signo.git && cd signo
cp .env.example .env     # set SIGNO_DOMAIN, SMTP_URL and MAIL_FROM

2. Start it

docker compose up -d

Caddy gets the HTTPS certificate for your domain. Open https://login.example.com and sign up, to check that the email arrives.

3. Register your site

docker compose exec signo signo clients add --name "Example" --redirect-uri https://example.com/api/auth/callback/signo

This prints the issuer, a client ID and a client secret. You can also sign in at https://login.example.com/account/sites and add the site there.

4. Point your site at it

Put those three values where your site has its Google ones. The guides show the exact changes for Auth.js, Better Auth, Supabase and any other OpenID Connect library.

Managing apps

docker compose exec signo signo clients list
docker compose exec signo signo clients remove <client id>

Changes apply without a restart. Redirect URIs must use https; http is allowed only for localhost.

Settings

Variable Meaning Default
ISSUER signo's public https URL (compose sets it from SIGNO_DOMAIN) http://localhost:4100
PORT port to listen on 4100
DATA_DIR where the database and keys live ./data (/data in Docker)
SMTP_URL SMTP server for sign-in emails, e.g. smtps://user:pass@smtp.example.com:465 unset: links print in the console
MAIL_FROM sender of sign-in emails signo <no-reply@ISSUER's host>
TRUST_PROXY set behind a reverse proxy (compose sets 1) unset
CLIENT_IP_HEADER the header your proxy puts the visitor's IP address in, if it doesn't use X-Forwarded-For (alwaysdata uses x-real-ip); only for a proxy that always overwrites it unset
OPERATOR who runs this copy, shown on the privacy page and in the footer of every page unset
CONTACT email address for privacy and security reports; with it set, signo also serves /.well-known/security.txt unset

Say where your copy runs

The trust and privacy pages have a section called "Where this copy runs". Fill it in by writing a short Markdown file at DATA_DIR/hosting.md: who hosts the server and where, who sends the sign-in emails, what the host logs, and how long backups are kept. signo reads it at startup and shows it as written. For example:

- **Hosting and database:** Example Hosting, Amsterdam, the Netherlands
- **Sign-in emails:** sent through Example Mail
- **Backups:** kept for 14 days

Backups

Back up the signo-data volume, or DATA_DIR outside Docker. It holds the database and the signing keys; without the keys, everyone is signed out and sites fetch the new public key on their next sign-in.

Moving to a new domain

Passkeys belong to the domain signo runs on. If you move signo to a new domain, people sign in once with an email link and add a passkey again, and each site must be given the new issuer URL.