# Deploying mailgoserver ## Build ```bash cd mailgoserver go build -o mailgoserver . ``` One static binary — no venv, no `pip install`, no gunicorn. ## Bind ports 25/587 without root ```bash 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: ```ini [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](LICENSE).