Self-hosted profile service for your own mail domains. No SaaS relay, no per-client manual setup.
4.4K
Self-hosted Outlook Autodiscover, Thunderbird Autoconfig, and Apple Mail profile service for your own mail domains.
No SaaS relay, no mailbox database, no per-client manual setup.
Full documentation, source, and issue tracker live on GitHub: github.com/solarssk/mail-autodiscover.
For any syntactically valid mailbox in an allowed domain, the service returns the configured IMAP/SMTP settings and, optionally, POP3 for Thunderbird — regardless of whether that specific mailbox actually exists, and without ever exposing the internal domain list on the landing page.
It does not:
If you want a service you can deploy behind HTTPS and mostly forget about, this is what it's for.
ALLOWED_DOMAINS or the mounted CONFIG_FILE..mobileconfig profile.Every request is stateless — no database, no mailbox-existence lookup anywhere in the flow.
| Feature | What it does | |
|---|---|---|
| 📧 | Outlook Autodiscover | POST /autodiscover/autodiscover.xml, with a neutral GET response too. |
| 🦅 | Thunderbird Autoconfig | GET /mail/config-v1.1.xml, plus the .well-known alias Thunderbird tries automatically. |
| 🍎 | Apple Mail profiles | Unsigned .mobileconfig at GET /mail/ios.mobileconfig, with stable per-mailbox identifiers so re-downloading updates instead of duplicating. |
| 🏢 | Multi-domain YAML config | One container can serve entirely different IMAP/SMTP/POP3 settings per domain via a mounted config.yaml. |
| 🚫 | No mailbox enumeration | Every syntactically valid address in an allowed domain gets the exact same response shape — verified in the test suite, not just claimed. |
| 🚦 | Defense in depth | Safe XML parsing (defusedxml), bounded in-memory rate limiting, security headers on every response, log-injection–resistant access logs. |
| Layer | Technologies | |
|---|---|---|
| 🐍 | Runtime | Python ≥ 3.12 (image built on 3.14) |
| ⚡ | Framework | FastAPI + Uvicorn |
| ⚙️ | Config | pydantic-settings — environment variables or a mounted YAML file |
| 🛡️ | CI/CD security | CodeQL, Trivy (HIGH/CRITICAL gate on every published digest), SonarCloud, pip-audit against a hash-pinned lockfile, CycloneDX SBOM per platform, and a mechanical check against our own internal engineering standard on every push |
docker run -d \
-p 8000:8000 \
-e APP_ENV=production \
-e PUBLIC_BASE_URL=https://autodiscover.example.com \
-e ALLOWED_DOMAINS=example.com \
-e MAIL_DISPLAY_NAME="Example Mail" \
-e IMAP_HOST=mail.example.com \
-e SMTP_HOST=mail.example.com \
solarssk/mail-autodiscover:latest
Put it behind an HTTPS reverse proxy and point your autodiscover./autoconfig. DNS records at it. Full environment variable reference, multi-domain YAML setup, and reverse-proxy guides (Nginx, Caddy, Nginx Proxy Manager, Synology, Cloudflare Tunnel): see the README and docs/.
solarssk/mail-autodiscover:latest # tracks the most recent main build
solarssk/mail-autodiscover:sha-<short> # exact commit, for traceability
Pinned release tags (X.Y.Z) start from the next version tagged after this image began publishing to Docker Hub — check the Releases page for the latest one, and prefer it over latest in production.
Multi-arch manifest (linux/amd64 + linux/arm64) — Docker pulls the one matching your host automatically. Every published digest passes a Trivy HIGH/CRITICAL gate before it's pushed, and the exact same image is also published to ghcr.io/solarssk/mail-autodiscover — same digest, same scan results, either registry works.
MIT
Content type
Image
Digest
sha256:3183ba5a3…
Size
61.2 MB
Last updated
5 days ago
docker pull solarssk/mail-autodiscover