Reverse proxy & SSL
SubsiMail can serve HTTPS on its own, or sit behind Nginx or Apache the way most self-hosted apps do. This page covers both, plus Certbot for the reverse-proxy paths, and how to change the port SubsiMail listens on either way.
Do you need one?
- Fresh server, just SubsiMail, one domain — use built-in HTTPS. Nothing else to install or patch.
- You already run other sites/services on this box, or already manage certificates for everything with Nginx/Apache + Certbot — put SubsiMail behind that same setup so it slots into what you have.
Don't run both at once. SubsiMail's built-in Let's Encrypt support and a reverse proxy both want ports 80 and 443 for themselves — pick one path per server.
Built-in HTTPS (no reverse proxy)
SubsiMail can provision and renew its own certificate via Let's Encrypt (using rustls-acme, built into the binary — no Certbot needed for this path). It's the same three environment variables on every install method, covered in detail on the Docker install page:
ACME_DOMAIN=mail.yourdomain.com
ACME_EMAIL=you@yourdomain.com
ACME_PRODUCTION=true
- Point the domain's
Arecord at your server first, and open ports 80 (for the Let's Encrypt HTTP-01 challenge) and 443 in your firewall — both are needed, not just 443. - Leave
ACME_PRODUCTIONunset (orfalse) while you're first getting the domain/DNS/firewall right — that uses Let's Encrypt's staging environment, which issues browser-untrusted test certs but has no rate limits. Flip it totrueonce a staging cert comes through cleanly, to get a real, browser-trusted one. - The trade-off: this claims ports 80/443 on the host for SubsiMail alone. If you want to host anything else on the same IP later, you'd need to move SubsiMail behind a reverse proxy at that point anyway.
Nginx + Certbot
Assumes SubsiMail is already running in plain-HTTP mode on port 3000 (leave ACME_DOMAIN/ACME_EMAIL/ACME_PRODUCTION unset) and Nginx is installed on the same host:
sudo apt update && sudo apt install nginx
Create /etc/nginx/sites-available/subsimail:
server {
listen 80;
server_name mail.yourdomain.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Enable the site and reload:
sudo ln -s /etc/nginx/sites-available/subsimail /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
http://mail.yourdomain.com should now reach SubsiMail. Next, get a certificate with Certbot's Nginx plugin, which edits this same config file for you — adding the ssl_certificate lines and an HTTP→HTTPS redirect:
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d mail.yourdomain.com
Certbot's Debian/Ubuntu package installs a systemd timer that renews automatically before the 90-day certificate expires — nothing to schedule yourself. Confirm it's there and that a renewal would succeed:
systemctl list-timers | grep certbot
sudo certbot renew --dry-run
Set TRUSTED_PROXY=true in SubsiMail's own environment once it's behind Nginx (or Apache, below). Without it, every request looks like it came from 127.0.0.1 — with it, SubsiMail reads the real visitor IP from the X-Forwarded-For header the config above sends, which is what shows up in login history and the audit trail.
Apache + Certbot
Same idea, Apache's module system instead of Nginx's config blocks:
sudo apt update && sudo apt install apache2
sudo a2enmod proxy proxy_http ssl headers
Create /etc/apache2/sites-available/subsimail.conf:
<VirtualHost *:80>
ServerName mail.yourdomain.com
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:3000/
ProxyPassReverse / http://127.0.0.1:3000/
RequestHeader set X-Forwarded-Proto "http"
</VirtualHost>
Enable the site and reload:
sudo a2ensite subsimail
sudo apache2ctl configtest
sudo systemctl reload apache2
Then Certbot's Apache plugin, which edits this vhost the same way the Nginx plugin does — SSL directives and an HTTPS redirect added automatically:
sudo apt install certbot python3-certbot-apache
sudo certbot --apache -d mail.yourdomain.com
Renewal works the same way as the Nginx path above — a systemd timer installed alongside Certbot, verifiable with sudo certbot renew --dry-run. And the same TRUSTED_PROXY=true setting applies here too, so SubsiMail sees real client IPs instead of Apache's own address.
Changing the default port
Yes — it's the PORT environment variable, same name on every install method (already covered per-platform on the Linux and Windows install pages). It defaults to 3000.
- Docker: simplest is to leave
PORTalone and just change the host side of the port mapping indocker-compose.yml, e.g."8080:3000"to expose it on 8080 instead. Only set thePORTenv var too if you specifically need the container's internal port to differ — in that case both sides of the mapping need to match it, e.g.PORT: "8080"with"8080:8080". - Linux binary:
PORT=8080 ./subsimail - Windows:
$env:PORT = "8080"before running.\subsimail.exe
If you're using a reverse proxy from this page, just point it at the new port — change proxy_pass http://127.0.0.1:3000 (Nginx) or ProxyPass / http://127.0.0.1:3000/ (Apache) to match. Nothing else changes.
Which should I use?
| Approach | Best when | Trade-off |
|---|---|---|
| Built-in HTTPS | Single-purpose server, just SubsiMail | Owns ports 80/443 outright; nothing else can share them |
| Nginx + Certbot | You already run Nginx, or want the most common self-hosted stack | One more service to keep patched and configured |
| Apache + Certbot | You already standardized on Apache | Same as Nginx, slightly more verbose config syntax |
Nginx and Apache are functionally equivalent here — both just forward requests to SubsiMail's port and let Certbot handle the certificate. Use whichever one you already run elsewhere rather than introducing a second proxy to maintain.