Repository navigation
Deployment
npm run build
NODE_ENV=production PORT=3000 node dist-server/index.mjsdeploy/goodmail.service is an example systemd unit. Keep the process on 127.0.0.1 and put a TLS reverse proxy in front.
The page and the API are both served by the Node process. A minimal HTTPS virtual host:
<VirtualHost *:443>
ServerName goodmail.example.com
ProxyPreserveHost On
ProxyPass /.well-known/acme-challenge/ !
ProxyPass / http://127.0.0.1:3000/ timeout=120
ProxyPassReverse / http://127.0.0.1:3000/
RequestHeader set X-Forwarded-Proto "https"
LimitRequestBody 52428800
Header always set Strict-Transport-Security "max-age=31536000"
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/goodmail.example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/goodmail.example.com/privkey.pem
</VirtualHost>-
ProxyPreserveHost Onis required: login by host and passkeys depend on the originalHost. - Set
GOODMAIL_TRUST_PROXY=trueso rate limits see the real client address. -
LimitRequestBodycaps attachment size (here 50 MB). - For several domains on one install see Several Domains and
deploy/apache-multidomain.conf. -
ServerTokens ProdandServerSignature Offkeep the Apache version out of headers and error pages.
When the Node process is stopped or restarting, Apache answers 502/503/504. deploy/unavailable.html is a self-contained "We'll be right back" page in seven languages that retries every five seconds and opens the mailbox as soon as it answers. Copy it to a folder outside the web root that deploys replace, and add inside the HTTPS virtual host, before the general ProxyPass /:
Alias /goodmail-errors/ /var/www/goodmail/errors/
<Directory /var/www/goodmail/errors>
Require all granted
</Directory>
ProxyPass /goodmail-errors/ !
ErrorDocument 502 /goodmail-errors/unavailable.html
ErrorDocument 503 /goodmail-errors/unavailable.html
ErrorDocument 504 /goodmail-errors/unavailable.html
Header always set Retry-After "10" "expr=%{REQUEST_STATUS} == 503"The status stays a real 503 with a Retry-After header, so monitoring still sees the outage.
git pull
npm install
npm run build
sudo systemctl restart goodmailKeep the previous dist/ and dist-server/ so you can roll back. Signed-in sessions survive a restart: the login cookie is sealed with the server key (secret.key), so goodmail rebuilds the session from it. Keep secret.key unchanged between versions.
goodmail needs nothing special from the mail server beyond IMAP and SMTP. Optional extras: ManageSieve for Mail Rules, and the helper commands for Passwords and Administration (ops/ in the repository).
goodmail
Using it
Security
Running it