Visit Azul.com Support

Upgrading Your Installation

An upgrade replaces the release directory and nothing else. That works safely only because everything worth keeping lives outside it. Read this page before your first upgrade, not during it.

What Survives an Upgrade

Location Content Survives

EVENTS_DB_PATH (events/events.duckdb under /var/lib/ljvmi)

The observation dataset, and with it your inventory, its runs, its tags, its trends, and your migration waves

Yes, outside the release directory

INBOX_DIR (inbox/)

The sealed deliveries that have not been ingested yet, and the delivered files kept after ingestion

Yes, outside the release directory

APP_DB_PATH (db/)

Tenants, accounts, Forwarder registrations and tags, the delivery ledger, quota counters, wave schedules, exclusion groups, audit entries, and API tokens

Yes, outside the release directory

VULN_DATA_DIR (vuln-data/)

The active and the previous vulnerability dataset

Yes, outside the release directory

/etc/ljvmi/ljvmi.env

Your settings, including the secrets

Yes, outside the release directory

The TLS keystore (TLS_KEYSTORE_FILE)

The certificate and private key the installation serves HTTPS with

Yes, when it is kept outside the release directory

The release directory (/opt/ljvmi/<release>)

Application code

No, the upgrade adds a new one beside it

The Java of the host is not part of the release, and an upgrade does not replace it. Check that the new release’s Java minimum is met before you start.

Warning
Keep the data and /etc/ljvmi/ljvmi.env outside /opt/ljvmi/<release>. A release directory is replaced at an upgrade, and everything inside it goes with it. See Storage Locations.

Nothing else needs to move. Your Forwarders learn their write path and the storage backend from check-in, so an upgrade that changes where deliveries land needs no visit to a Forwarder host.

Before You Start

  1. Read the release notes of the version you move to. They open with the upgrade impact: required configuration changes, whether a database migration runs, whether the Java minimum changes, and whether your Forwarders need an upgrade too.

  2. Read Upgrade Notes by Version for every release between yours and the target. Some releases need a configuration change before the first start.

  3. Check that the disk that receives your backup has room for a full copy of /var/lib/ljvmi, and keep that copy off the data disk. With the default INBOX_RETAIN_AFTER_INGEST=true, the inbox can be the largest part of it.

The Procedure

The jar bundle has no upgrade script. You upgrade by hand, in these steps.

  1. Verify the new bundle and extract it beside the running release. Nothing changes yet.

     
    sha256sum -c ljvmi-<new-version>-<sha>-jar.tar.gz.sha256 sudo tar -xzf ljvmi-<new-version>-<sha>-jar.tar.gz -C /opt/ljvmi cd /opt/ljvmi/ljvmi-<new-version>-<sha>-jar sha256sum -c --quiet CHECKSUMS.txt
  2. Compare the example configuration of both releases, and add any new settings to /etc/ljvmi/ljvmi.env. You do not copy an env file into the bundle.

     
    diff /opt/ljvmi/current/ljvmi.env.example /opt/ljvmi/ljvmi-<new-version>-<sha>-jar/ljvmi.env.example

    Do not change SESSION_SECRET or FORWARDER_KEY_SECRET. A new FORWARDER_KEY_SECRET makes every stored Forwarder key unreadable.

  3. Stop the service, then take a backup. Stopping first matters, because the data files cannot be copied from under a running process. Keep the copy off the data disk. Forwarders keep delivering while the installation is down, and your installation picks the deliveries up after it starts again. With S3 storage, keep the downtime shorter than the upload grant lifetime, 15 minutes by default, because uploads stop once a Forwarder’s grant expires. Don’t restart Forwarders while your installation is down, because a Forwarder can’t start until your installation is reachable.

     
    sudo systemctl stop ljvmi sudo tar czf /backup/ljvmi-$(date +%Y%m%d).tar.gz -C /var/lib ljvmi
  4. Switch current to the new release and start the service:

     
    sudo ln -sfn /opt/ljvmi/ljvmi-<new-version>-<sha>-jar /opt/ljvmi/current sudo systemctl start ljvmi
  5. Verify before you let Forwarders back in. Readiness waits for the database migrations, so the command retries instead of failing at the first refusal:

     
    curl -fs --retry 30 --retry-delay 2 --retry-connrefused http://127.0.0.1:9000/q/health/ready journalctl -u ljvmi | grep -i flyway

    The first command shows that the application is ready. The management port serves plain HTTP in every setup, so the command needs no change for HTTPS. The second command shows which database migrations ran. Sign in at the address you normally use, https://<your-host>:8443 with direct TLS, and check that the inventory shows the estate you had before the upgrade.

Keep the previous release directory until you are sure you will not go back.

What Happens to the Observation Dataset

The dataset stays in the one DuckDB file under /var/lib/ljvmi/events, and an upgrade does not rewrite it.

The inventory list and Security Exposure read a derived table, inventory_installations. When a release changes how that table is derived, the installation rebuilds it in buckets during the ingestion passes after the start. Until that finishes, inventory reads are computed for each request, which is slower, and Security Exposure shows that it is still preparing. The release notes flag a release that does this.

A change to the rules that derive a value at ingestion, such as the license of an observation or whether an installation is system-wide, applies to observations delivered from then on. It does not rewrite the ones already stored. To apply the new rules to everything, re-ingest the kept deliveries. See Re-ingesting the kept deliveries.

What Happens to the Database

The new release compares the migrations it carries against the migrations your database already records, and applies only the ones that are missing, in order. A release that adds no migration touches nothing. The application never generates schema changes on its own, so migrations remain the only path by which the database changes.

Going Back

Migrations run forward only. Once a migration has run, starting the previous release alone does not undo it, because the older code does not understand the newer database. Without the restored data, the old version refuses to start, and the migration check stops it with Detected applied migration not resolved locally.

To go back:

  1. Stop the service: sudo systemctl stop ljvmi.

  2. Restore the backup over /var/lib/ljvmi.

  3. Point current back at the previous release directory: sudo ln -sfn /opt/ljvmi/<previous-release> /opt/ljvmi/current.

  4. Start the service: sudo systemctl start ljvmi.

That backup is the entire rollback plan, which is why the procedure takes one before it changes anything.

Upgrade Notes by Version

Read the note of every release between your version and the target, oldest first.

1.0.0 is the first release, so there are no notes yet. The 0.x versions were pre-releases, and nothing upgrades from them: install 1.0.0 on a fresh data directory.

Skipping Versions

The missing database migrations apply in order, so a later release starts on an older database in one step. A jump does not skip the notes above, though: follow the note of every release in between. Only upgrading from one release to the next is rehearsed.