Vulnsy Docs
Self-hosted

Backup & Restore

Back up a self-hosted Vulnsy installation with the installer, covering the .env file, the PostgreSQL databases and the uploaded files, and restore it on the same or a new server.

install.sh backup writes a complete backup into one archive, and install.sh restore puts it back, on the same server or on a new one. A backup has three parts, which are only useful together:

PartContainsIn the archive
Configuration.env with its secrets, and your docker/Caddyfile, docker/certs/ and docker-compose.override.yml if they existconfig/
PostgreSQLvulnsy_control (installation settings, license, instance ID and AI settings), vulnsy_shared (the Vulnsy library) and vulnsy_tenant (your users, clients, projects, findings and reports)postgres.sql.gz, from pg_dumpall
Uploaded filesEvidence, report templates, images and portal documents, from the file store's volumeminio-data.tar

A database backup is incomplete without the .env it was taken with. The dump contains the database role and its password, and the secrets in .env decrypt or verify data in the database. Restored with a different .env, the app cannot connect to the database, and REST API keys and stored AI credentials stop working. See Secrets.

Back Up

sudo /opt/vulnsy/install.sh backup

The installer copies the configuration, stops the app, dumps all three databases, stops the file store and archives its volume, then starts both again. Stopping them means that the databases and the files are copied at the same point in time; Vulnsy is unavailable for that time, usually under a minute. Schedule backups outside working hours.

The archive is written to /opt/vulnsy/backups/, readable only by root, and named after the version and the time, for example vulnsy-1.4.0-backup-20261001-020000.tar.gz.

OptionEffect
--out DIRWrite the archive to DIR instead of /opt/vulnsy/backups
--no-stopKeep Vulnsy running during the backup. The databases are still dumped consistently, but files uploaded during the backup may be missing or partly copied.
--home DIRThe installation directory, if it is not /opt/vulnsy

To back up every night at 02:00 and keep two weeks of backups, add this to root's crontab (sudo crontab -e):

0 2 * * * /opt/vulnsy/install.sh backup --out /var/backups/vulnsy && find /var/backups/vulnsy -name 'vulnsy-*-backup-*.tar.gz' -mtime +14 -delete

Copy the archives to storage away from the server. They hold everything needed to read your data, including the secrets in .env, so encrypt them and restrict who can access them.

If you use the bundled Caddy with tls internal, the backup includes your docker/Caddyfile but not Caddy's local certificate authority, which lives in the vulnsy_caddy-data volume. After a restore on a new server, Caddy creates a new authority, and you distribute its root certificate again.

Retention

Suggestions:

  • Back up daily. Keep at least two weeks of daily backups and a year of monthly backups, or whatever your data retention policy requires.
  • Keep at least one copy away from the server and its location.
  • Take a backup before every upgrade, and keep it until you have confirmed that the new version works. It is the only way back to the previous version.
  • Test from time to time that your backups restore.

Restore

Restoring brings back the configuration, the databases, the files and the instance ID, so the existing license keeps working, even on a new server.

A restore replaces the configuration, databases and files of the installation it runs on. Anything created since the backup is lost. The installer asks for confirmation first, unless you pass --yes.

Get the package

Restore with the package of the version the backup was taken with, or a newer one. Vulnsy refuses to start a version older than the one recorded in the database, and the installer refuses to restore a backup from a newer version. Download the package from the link in your license email, then extract it as for a new installation:

tar xzf vulnsy-1.4.0-offline.tar.gz
cd vulnsy-1.4.0

On a new server, first set up DNS for both hostnames and open the ports, as in Install. Do not run install.sh install: the restore installs Vulnsy itself, with the backed-up .env.

Run the restore

Copy the backup archive to the server, then, from the package directory:

sudo ./install.sh restore /path/to/vulnsy-1.4.0-backup-20261001-020000.tar.gz

The installer:

  1. Checks the server and installs Docker if it is missing, as for a new installation.
  2. Verifies the package, copies its files into /opt/vulnsy and loads its images.
  3. Stops Vulnsy if it is running, and deletes the current databases and files.
  4. Restores .env and your local configuration from the backup, keeping the package's version in VULNSY_VERSION.
  5. Loads the database dump into a new PostgreSQL volume and unpacks the files into a new file store volume.
  6. Starts Vulnsy, waits until it reports healthy, and prints the instance ID.

Use --home to restore into a directory other than /opt/vulnsy.

Verify

Sign in, open a finding with evidence to check that files load, and check the License page: the instance ID is unchanged, so the license is still valid.

You can also run sudo /opt/vulnsy/install.sh restore FILE from an existing installation, for example to undo a mistake. It restores into the version that is installed, without loading a package.

The instance ID lives in the vulnsy_control database. A restore keeps it only because the databases are restored. A fresh installation, even with the backed-up .env, gets a new instance ID and needs a new license. See Licensing.

On this page