Mailnib docs v1.0.0

Install

Install on a VPS

Outcome: Mailnib running on your own server at https://your-domain, with its database, automatic HTTPS and automatic restarts, set up by one command.

This works on any provider that gives you a fresh Linux server: Hetzner, DigitalOcean, Vultr, Linode, AWS Lightsail and others.

Before you start

  • A new server running Ubuntu 22.04 or 24.04, or Debian 12, on an x86-64 (Intel or AMD) processor. ARM servers, such as Hetzner's CAX plans, are not supported.
  • At least 1 GB of memory; 2 GB is comfortable. The installer adds swap on small servers.
  • The server's IP address and root password or SSH key, from your provider's dashboard.
  • Optional: a domain name. Point its DNS A record at the server's IP address before you start. Without a domain, the installer gives you a free temporary address, and you can switch to your own later.
  • Your download, the ZIP file you downloaded after your purchase. It holds the installer (install.sh) and the prebuilt app (runtime/).

1. Upload the download

Use any SFTP program, such as FileZilla or WinSCP:

FieldValue
Hostyour server's IP address
ProtocolSFTP, port 22
Userroot
Passwordthe root password or your SSH key

Upload the whole download ZIP, unchanged, into /root. It is one file; do not unzip it on your computer.

2. Unzip and run the installer

Open a terminal on the server. Your provider's dashboard has a Console button, or connect with ssh root@YOUR-IP from your computer. A new server may not have unzip, so install it, unpack the download and run the installer from inside it:

apt-get update && apt-get install -y unzip
unzip mailnib-*.zip
cd mailnib
bash install.sh

The folder name mailnib is the one inside the ZIP. If your ZIP has a different file name, use that name in the unzip line.

The installer asks two questions:

  1. Domain. Enter it, for example mail.example.com, or press Enter to use a temporary address.
  2. Email. Optional; the certificate authority uses it to warn you before a certificate expires.

It then installs Node.js, PostgreSQL and Caddy, creates the database with a random password, copies runtime/ to /opt/mailnib and runs it as a service that restarts on its own, and sets up HTTPS. This takes about five minutes. It finishes by printing your address and a setup token.

3. Finish in the browser

  1. Open the https://…/install address the installer printed.
  2. Paste the setup token.
  3. Follow the web installer to create your operator account and connect email.

Failed-payment reminders

If you take card payments, add a cron job that calls the reminder endpoint, as described in Payment providers. Set CRON_SECRET in /opt/mailnib/.env, restart, then run crontab -e and add the curl line from that page.

Everyday commands

ToRun
See the live logjournalctl -u mailnib -f
Restartsystemctl restart mailnib
Change a settingedit /opt/mailnib/.env, then restart
Updateupload the new download, unzip it, and run bash install.sh from inside its folder

An update keeps your settings and uploads. The unzipped download can be deleted once the installer has finished; the running copy lives in /opt/mailnib. The previous version stays in /opt/mailnib.previous until the next update, and the installer prints the command to go back to it if the new version does not start.

Switch from the temporary address to your domain

  1. Point your domain's A record at the server.
  2. In /opt/mailnib/.env, set PUBLIC_APP_URL=https://your-domain.
  3. In /etc/caddy/Caddyfile, replace the temporary address with your domain.
  4. Run systemctl restart mailnib && systemctl reload caddy.

If something goes wrong

  • "this build is for x86-64 servers": you created an ARM server. Create an Intel or AMD one instead.
  • "HTTPS is not answering yet": the domain does not point at this server yet, or your provider's firewall blocks ports 80 and 443. Fix that; Caddy retries on its own. journalctl -u caddy -n 50 shows why the certificate failed.
  • "did not answer its health check": run journalctl -u mailnib -n 50 and see Troubleshooting.
  • The full installer log is in /var/log/mailnib-install.log.

PostgreSQL role privileges

Use a dedicated login role that owns this application's tables and functions. It needs CONNECT and CREATE on the database, USAGE and CREATE on the application schema (public), and permission to create the drizzle migration schema. Migrations need to create and alter tables, indexes, policies, triggers and functions; normal operation reads and writes those tables and executes the shipped functions. Use the same role for the installer, migrations and DATABASE_URL.

NOSUPERUSER NOBYPASSRLS is supported and recommended. Neither superuser nor BYPASSRLS nor permission to create roles is required. Tenant tables retain FORCE ROW LEVEL SECURITY even for their owner. Verified webhooks, the authenticated operator console and the secret-authenticated dunning scheduler discover workspaces through fixed, read-only functions, then enter a workspace scope for tenant data and writes. Never share the application's database credentials with tenants or browser code. Test setup creates roles to verify isolation; those privileges are needed only by the test administrator.

On managed PostgreSQL, use the database/schema owner supplied by the provider, or have the provider grant the schema creation privileges above. On cPanel, ask the host to grant these privileges if the control-panel database user cannot create schemas or functions. No elevated RLS-bypass role is needed.

Mailnib 1.0.0 · These pages open from your download with no server and no internet connection.