Files
2026-08-12 12:59:59 +01:00

2.6 KiB

Deploying mailgoserver

Build

cd mailgoserver
go build -o mailgoserver .

One static binary — no venv, no pip install, no gunicorn.

Bind ports 25/587 without root

sudo setcap 'cap_net_bind_service=+ep' ./mailgoserver

Same purpose as script_setup_py_environment.sh's setcap step on the Python venv, applied to the compiled binary instead.

systemd (unified process)

The Go binary runs the SMTP listeners and the web UI in one process (no GIL, so no need to split them into separate services the way script_install_service.sh split pymta-smtp.service / pymta-web.service for the Python version). One unit is enough:

[Unit]
Description=mailgoserver (SMTP + web admin)
After=network.target

[Service]
Type=simple
WorkingDirectory=/opt/mailgoserver
ExecStart=/opt/mailgoserver/mailgoserver --host 127.0.0.1 --port 5000
Restart=always
RestartSec=5
AmbientCapabilities=CAP_NET_BIND_SERVICE
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
PrivateTmp=true
ProtectSystem=strict
ReadWritePaths=/opt/mailgoserver
ProtectHome=true

[Install]
WantedBy=multi-user.target

If you do want the SMTP and web parts as separate services (matching the Python split exactly), run two units with --smtp-only and --web-only respectively — both flags exist for this.

nginx

No changes needed. script_nginx_setup.sh reverse-proxies to http://127.0.0.1:5000 and terminates its own TLS for the web UI — mailgoserver listens on the same host:port by default, so the existing nginx config works unmodified. The SMTP TLS listener still consumes ssl_certs/server.crt/server.key, same as before.

Admin dashboard login

First run seeds one account: username admin, password Password123!. Logging in with it immediately forces a username + password change before anything else in the dashboard is reachable — the default credentials can never be left in place.

Optional second factors, enabled per-account from Account in the sidebar:

  • Authenticator app (TOTP) — works anywhere, no extra config.
  • Passkeys / security keys (WebAuthn) — bound to the exact origin the dashboard is served at. Set [Auth] rp_id / rp_origin in settings.ini to your real public domain before registering passkeys in production (e.g. rp_id = mail.example.com, rp_origin = https://mail.example.com). The defaults (localhost / http://localhost:5000) only work for local testing — WebAuthn requires either HTTPS or the literal host localhost, so passkeys need the nginx+TLS setup above to work behind a real domain.

License

See LICENSE.