<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.wilsoz.com/index.php?action=history&amp;feed=atom&amp;title=Services%2FSnappyMail</id>
	<title>Services/SnappyMail - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.wilsoz.com/index.php?action=history&amp;feed=atom&amp;title=Services%2FSnappyMail"/>
	<link rel="alternate" type="text/html" href="https://wiki.wilsoz.com/index.php?title=Services/SnappyMail&amp;action=history"/>
	<updated>2026-07-06T07:01:47Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.9</generator>
	<entry>
		<id>https://wiki.wilsoz.com/index.php?title=Services/SnappyMail&amp;diff=12&amp;oldid=prev</id>
		<title>Wikibot: Migrated from services/SNAPPYMAIL.md</title>
		<link rel="alternate" type="text/html" href="https://wiki.wilsoz.com/index.php?title=Services/SnappyMail&amp;diff=12&amp;oldid=prev"/>
		<updated>2026-07-05T18:16:20Z</updated>

		<summary type="html">&lt;p&gt;Migrated from services/SNAPPYMAIL.md&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;#039;&amp;#039;As of: 2026-07-05 — migrated from `services/SNAPPYMAIL.md`&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
= SnappyMail Webmail =&lt;br /&gt;
&lt;br /&gt;
== Container &amp;amp; Files ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Item&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
| Container&lt;br /&gt;
| &amp;lt;code&amp;gt;snappymail&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Compose&lt;br /&gt;
| &amp;lt;code&amp;gt;/library/snappymail-app/docker-compose.yml&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Data dir&lt;br /&gt;
| &amp;lt;code&amp;gt;/library/snappymail-app/data/&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Image&lt;br /&gt;
| &amp;lt;code&amp;gt;djmaze/snappymail:latest&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Internal port&lt;br /&gt;
| &amp;lt;code&amp;gt;8888&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| External port&lt;br /&gt;
| &amp;lt;code&amp;gt;8890&amp;lt;/code&amp;gt; → proxied via VPS nginx&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /library/snappymail-app &amp;amp;&amp;amp; docker compose up -d&lt;br /&gt;
docker logs --tail=50 snappymail 2&amp;gt;&amp;amp;1 | strings&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Architecture Note — Unified vs Multi-Account ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;SnappyMail connected accounts ≠ unified inbox.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Adding external accounts (Gmail, iCloud, SDF) in SnappyMail Settings → Accounts shows them as separate silos side-by-side. There is no combined view.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;The right approach for a unified inbox&amp;#039;&amp;#039;&amp;#039; is to use &amp;#039;&amp;#039;&amp;#039;getmail&amp;#039;&amp;#039;&amp;#039; to pull all external accounts into Stalwart, then connect SnappyMail (and phones/clients) only to Stalwart. Sieve rules on Stalwart do the filtering. This way:&lt;br /&gt;
* One IMAP server to connect to from anywhere&lt;br /&gt;
* All mail filtered by sieve on arrival&lt;br /&gt;
* SnappyMail just sees one account with well-organized folders&lt;br /&gt;
&lt;br /&gt;
Use SnappyMail&amp;#039;s &amp;quot;additional accounts&amp;quot; feature only for occasional read-only access to an external account, not as the primary mail flow mechanism.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Critical: MTU Must Be 1280 ==&lt;br /&gt;
&lt;br /&gt;
The host&amp;#039;s surfshark WireGuard VPN (surfshark_wg) has MTU 1280. All Docker bridge networks must match or large TLS packets (Server Hello + cert chain, ~4–6 KB) get silently dropped mid-handshake. &amp;#039;&amp;#039;&amp;#039;Without MTU 1280, all external IMAP SSL connections hang for ~2 minutes then reset.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;docker-compose.yml&amp;lt;/code&amp;gt; already has this fix:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
networks:&lt;br /&gt;
  default:&lt;br /&gt;
    driver: bridge&lt;br /&gt;
    driver_opts:&lt;br /&gt;
      com.docker.network.driver.mtu: 1280&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If SnappyMail is redeployed or the network is recreated, verify MTU with:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
docker network inspect snappymail-app_default | grep -i mtu&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After changing docker-compose.yml, you must &amp;lt;code&amp;gt;docker compose down &amp;amp;&amp;amp; docker compose up -d&amp;lt;/code&amp;gt; — &amp;lt;code&amp;gt;restart&amp;lt;/code&amp;gt; alone does NOT recreate the network.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Domain Config Files ==&lt;br /&gt;
&lt;br /&gt;
Path: &amp;lt;code&amp;gt;/library/snappymail-app/data/_data_/_default_/domains/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One JSON file per domain. Controls IMAP/SMTP server settings for that domain&amp;#039;s accounts.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Ownership:&amp;#039;&amp;#039;&amp;#039; Files must be owned by &amp;lt;code&amp;gt;uid 82 / gid 82&amp;lt;/code&amp;gt; (container&amp;#039;s www-data). If created as root, SnappyMail can&amp;#039;t read them and shows &amp;quot;Domain is not allowed&amp;quot; or &amp;quot;no domain configuration&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo chown 82:82 /library/snappymail-app/data/_data_/_default_/domains/*.json&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Active domain configs:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! File&lt;br /&gt;
! Server&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;wilsoz.com.json&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;host.docker.internal&amp;lt;/code&amp;gt;&lt;br /&gt;
| Stalwart — primary account&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;craniumslows.com.json&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;host.docker.internal&amp;lt;/code&amp;gt;&lt;br /&gt;
| Stalwart — secondary address&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;gmail.com.json&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;imap.gmail.com:993&amp;lt;/code&amp;gt;&lt;br /&gt;
| Requires App Password&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;icloud.com.json&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;imap.mail.me.com:993&amp;lt;/code&amp;gt;&lt;br /&gt;
| Requires App Password&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;me.com.json&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;imap.mail.me.com:993&amp;lt;/code&amp;gt;&lt;br /&gt;
| Same server as iCloud&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;sdf.org.json&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;mx.sdf.org:993&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;shortLogin: true, lowerLogin: true&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Editing domain configs:&amp;#039;&amp;#039;&amp;#039; Do NOT bind-mount individual files — the container entrypoint does &amp;lt;code&amp;gt;sed -i&amp;lt;/code&amp;gt; substitutions on its config files, which fails with &amp;quot;Resource busy&amp;quot; on bind-mounted files. Bind-mount the whole &amp;lt;code&amp;gt;data/&amp;lt;/code&amp;gt; directory (already the case).&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Disabled Domains List ==&lt;br /&gt;
&lt;br /&gt;
Path: &amp;lt;code&amp;gt;/library/snappymail-app/data/_data_/_default_/domains/disabled&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Plain text, one domain per line. Domains listed here cannot be added as accounts.&lt;br /&gt;
&lt;br /&gt;
Current contents (as of 2026-02-22):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
outlook.com&lt;br /&gt;
qq.com&lt;br /&gt;
yahoo.com&lt;br /&gt;
hotmail.com&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;gmail.com&amp;lt;/code&amp;gt; was in here by default — removed so users can add Gmail accounts.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Stalwart Connection (wilsoz.com / craniumslows.com) ==&lt;br /&gt;
&lt;br /&gt;
SnappyMail connects to Stalwart via &amp;lt;code&amp;gt;host.docker.internal&amp;lt;/code&amp;gt; (resolves to the Docker bridge gateway → host → Stalwart port 993/587).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;IMAP&amp;quot;: { &amp;quot;host&amp;quot;: &amp;quot;host.docker.internal&amp;quot;, &amp;quot;port&amp;quot;: 993, &amp;quot;type&amp;quot;: 1 },&lt;br /&gt;
  &amp;quot;SMTP&amp;quot;: { &amp;quot;host&amp;quot;: &amp;quot;host.docker.internal&amp;quot;, &amp;quot;port&amp;quot;: 587, &amp;quot;type&amp;quot;: 2 }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;extra_hosts: [&amp;quot;host.docker.internal:host-gateway&amp;quot;]&amp;lt;/code&amp;gt; in docker-compose.yml enables this.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== External Account App Passwords ==&lt;br /&gt;
&lt;br /&gt;
For reference (these are app-specific passwords, not account passwords):&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Account&lt;br /&gt;
! IMAP Server&lt;br /&gt;
! App Password&lt;br /&gt;
|-&lt;br /&gt;
| craniumslows@gmail.com&lt;br /&gt;
| imap.gmail.com:993&lt;br /&gt;
| &amp;lt;code&amp;gt;jeuwezdxaoaysvni&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| thewilson@gmail.com&lt;br /&gt;
| imap.gmail.com:993&lt;br /&gt;
| &amp;lt;code&amp;gt;wikjuwnmklkeisid&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| marcusthewilson@me.com&lt;br /&gt;
| imap.mail.me.com:993&lt;br /&gt;
| &amp;lt;code&amp;gt;pekx-kvid-iopx-lhyy&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| mnw@sdf.org&lt;br /&gt;
| mx.sdf.org:993&lt;br /&gt;
| (SDF account password)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;quot;Can&amp;#039;t connect to host ssl://...&amp;quot;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* First check: MTU. Run &amp;lt;code&amp;gt;docker network inspect snappymail-app_default | grep -i mtu&amp;lt;/code&amp;gt; — must be 1280.&lt;br /&gt;
* Test SSL from inside container: &amp;lt;code&amp;gt;docker exec snappymail php -r &amp;quot;...stream_socket_client(&amp;#039;ssl://imap.gmail.com:993&amp;#039;...)&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
* If MTU is fine, test from host: &amp;lt;code&amp;gt;curl -v --max-time 10 imaps://imap.gmail.com:993&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;quot;Domain is not allowed&amp;quot; / &amp;quot;no domain configuration&amp;quot;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Check &amp;lt;code&amp;gt;disabled&amp;lt;/code&amp;gt; file — is the domain listed there?&lt;br /&gt;
* Check if a &amp;lt;code&amp;gt;.json&amp;lt;/code&amp;gt; file exists for that domain&lt;br /&gt;
* Check ownership: &amp;lt;code&amp;gt;sudo ls -la /library/snappymail-app/data/_data_/_default_/domains/&amp;lt;/code&amp;gt;&lt;br /&gt;
* Fix: &amp;lt;code&amp;gt;sudo chown 82:82 /library/snappymail-app/data/_data_/_default_/domains/&amp;lt;domain&amp;gt;.json&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Admin panel&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* URL: &amp;lt;code&amp;gt;http://localhost:8890/?admin&amp;lt;/code&amp;gt; (or via VPS proxy)&lt;br /&gt;
* Default admin password set on first run, stored in &amp;lt;code&amp;gt;data/_data_/_default_/configs/application.ini&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Wikibot</name></author>
	</entry>
</feed>