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:
| Part | Contains | In the archive |
|---|---|---|
| Configuration | .env with its secrets, and your docker/Caddyfile, docker/certs/ and docker-compose.override.yml if they exist | config/ |
| PostgreSQL | vulnsy_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 files | Evidence, report templates, images and portal documents, from the file store's volume | minio-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 backupThe 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.
| Option | Effect |
|---|---|
--out DIR | Write the archive to DIR instead of /opt/vulnsy/backups |
--no-stop | Keep Vulnsy running during the backup. The databases are still dumped consistently, but files uploaded during the backup may be missing or partly copied. |
--home DIR | The 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 -deleteCopy 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.0On 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.gzThe installer:
- Checks the server and installs Docker if it is missing, as for a new installation.
- Verifies the package, copies its files into
/opt/vulnsyand loads its images. - Stops Vulnsy if it is running, and deletes the current databases and files.
- Restores
.envand your local configuration from the backup, keeping the package's version inVULNSY_VERSION. - Loads the database dump into a new PostgreSQL volume and unpacks the files into a new file store volume.
- 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.