Run and maintain
Updating and backups
Outcome: you have a backup you could restore from, and you can move to a new version without losing anything.
What to back up
Everything your customers make lives in two places. Back up both, together, on a schedule.
- The PostgreSQL database. Accounts, workspaces, designs and their history, brand kits, plans, subscriptions, invoices, settings and the audit log.
- The
storage/folder (or whereverSTORAGE_ROOTpoints), which holds uploaded images, generated files and the installer's "installed" marker. If you use S3-compatible storage, uploads are in your bucket instead; turn on versioning or backups there.
Also keep a copy of your .env file (or your host's environment variables), and above all APP_KEY, somewhere safe and private. If you rotate APP_KEY, replace the saved copy at once.
Back up the database
Most hosts have a backup button: cPanel → Backup or PostgreSQL Databases, and automatic backups on Render and on hosted PostgreSQL providers. To make one yourself:
pg_dump --format=custom --file=mailnib-$(date +%F).dump "$DATABASE_URL"
Restore
Stop the app.
Restore the database into an empty database:
pg_restore --no-owner --dbname="$DATABASE_URL" mailnib-2026-09-25.dumpPut the matching copy of the
storage/folder back.Start the app and open
/api/health.
A backup you have never restored is a hope, not a backup. Try a restore on a spare database once.
Updating to a new version
Updating is a manual step that takes a few minutes. Read the changelog for the version first. Then:
- Back up the database and
storage/, as above. - Keep your
.envfile and yourstorage/folder. Do not overwrite either. - Replace the application files with the new version:
- VPS: upload the new download, unzip it, and run
bash install.shfrom inside its folder. It keeps.envandstorage/, and the previous version stays in/opt/mailnib.previous. - cPanel: stop the app in Setup Node.js App. In File Manager, delete everything in the
runtimeapplication folder except.envandstorage/, upload the new download, extract it, and copy the newruntimefolder's contents in. - Render or Vercel: replace the files in your repository with the new
source/folder (keep your.gitfolder), commit and push. The environment variables and the Render disk are kept. - Your computer: replace the
source/files, then runpnpm install --frozen-lockfileandpnpm build.
- VPS: upload the new download, unzip it, and run
- Start the app. With
MIGRATE_ON_START=true(cPanel and Render), pending database migrations run automatically on start. On Vercel they run during the build. Elsewhere, runpnpm db:migratebefore starting. - Check
/api/healthsays"migrations":"up to date", then sign in.
Migrations only ever move forward and never delete your data. Running them twice is safe: applied ones are skipped.
Your changes and updates
Replacing the application files replaces anything you edited inside them, such as a template in templates/ or a line of source code. The code you edit is the code in source/; to run a change on a VPS or cPanel you build it yourself and deploy that build instead of runtime/. Keep your own changes in a separate copy, or in your own Git branch, and re-apply them after updating. Settings made in the operator console and everything your customers made are in the database and are not affected.