Getting started

Updating DFIRe

Move an installation to a newer release with the installer, or by replacing the bundle by hand.

Before you update

  1. Back up PostgreSQL, the file storage, and the installation's .env.
  2. Restore those backups somewhere and confirm they work.
  3. Read the release notes for the target version.
  4. Plan a maintenance window. Migrations run at startup and DFIRe is briefly unavailable while they do.

See Backup and recovery for what DFIRe backs up itself and what you own.

How versions and tags work

  • A semantic version tag such as 1.8.0 always names the same build. DFIRe never moves one.
  • A correction ships as the next patch version. No published tag, bundle, checksum or provenance file is ever replaced.
  • Each release bundle pins exact image digests, so deploying the same bundle again produces the same containers.
  • :latest follows the newest stable release.
  • Every published release upgrades directly to the current one.

Update with the installer

One command installs, adopts and updates. Run it from the installation directory.

cd /opt/dfire
curl -fsSL https://dfire.fi/install.sh -o install.sh
chmod +x install.sh
./install.sh --upgrade

--upgrade is required. Changing an existing installation is never implicit. Without the flag the installer reports the installed and the current version, changes nothing, and exits with an error. Add a version to pick a specific release:

./install.sh --upgrade 1.8.0

Run the installer as the owner of the installation directory. Deployments made by the old full installer are usually owned by root, so use sudo rather than changing ownership during an update.

What it does

The installer first identifies what it found. There are four cases: an empty directory, an installation it already manages, an intact deployment from the old full installer, or an intact manually deployed bundle. It then installs, upgrades, adopts the existing files, or reconciles an installation already at the current release.

Through all of that it keeps the Compose project, the named volumes, the database mode, the persistent secrets, the frontend binding and your host proxy configuration.

It validates and pulls the new release while the current containers keep running. It never runs docker compose down. It records the new version only after the Compose health checks and both route probes pass.

Adopting an old-installer deployment removes the obsolete Compose and HTTPS helper files, after copying them into the recovery directory. It leaves host proxy and certificate state alone.

At startup the installer checks whether a newer installer exists. An outdated copy stops before it changes anything and tells you to download the current script. If that check cannot reach the network, the installer warns and carries on.

Adopting a manual deployment. The installer can adopt an installation that runs the unmodified files of a published bundle under a matching Compose project. It adds its marker without restarting containers or replacing bundle files. A customized Compose deployment stays yours, and the installer never overwrites it.

Repairing a deployment

Run the installer at the version already installed and it reconciles the deployment with that release instead of stopping. A container that was removed or never started comes back. A stack that is already correct keeps running untouched. The installer says which of the two happened. This is the supported way to restore a deployment that has lost a container. Named volumes keep their names and contents throughout.

The installer refuses to run when the Compose project recorded for the installation is not the project the running containers belong to. Starting under a different project name would create a second, empty set of volumes and strand the real data. The run therefore stops before it touches a container.

Only one installer run works in a directory at a time. A second run starts, finds the lock, and exits without changing anything.

Recovery files

Before it replaces any control file, the installer copies the current ones into a .dfire-backup- directory beside them, named with a timestamp. These build up one per update. Delete them once you are satisfied with an update, and a later run notes the missing one and continues.

Keep your own copy of .env outside the installation directory. It holds SECRET_KEY and CREDENTIAL_ENCRYPTION_KEY, which exist nowhere else. Without them the credentials stored in the installation cannot be decrypted. If .env goes missing the installer stops and names the most recent copy it still holds.

Updating without the installer

The bundle is ordinary Compose files, so you can update with ordinary Compose commands.

  1. Download and verify the target bundle
    mkdir -p /tmp/dfire-1.8.0
    cd /tmp/dfire-1.8.0
    curl -fsSLO https://dfire.fi/release/1.8.0/dfire-1.8.0.tar.gz
    curl -fsSLO https://dfire.fi/release/1.8.0/SHA256SUMS
    grep '  dfire-1.8.0.tar.gz$' SHA256SUMS | sha256sum -c -
    tar -xzf dfire-1.8.0.tar.gz
  2. Back up and replace the release files
    cd /opt/dfire
    backup_dir="release-backup-$(date +%Y%m%d%H%M%S)"
    mkdir "$backup_dir"
    cp compose.yaml compose.internal-db.yaml compose.external-db.yaml .env-example README.md "$backup_dir/"
    cp /tmp/dfire-1.8.0/compose*.yaml /tmp/dfire-1.8.0/.env-example /tmp/dfire-1.8.0/README.md .

    Keep your existing .env. Compare it against the new .env-example and add anything the release now requires.

  3. Validate, pull and apply
    docker compose config
    docker compose pull
    docker compose up -d --wait --wait-timeout 600
  4. Check both routes
    curl -f http://127.0.0.1:8080/health
    curl -f http://127.0.0.1:8080/api/health/

Pulling an image does not update a running container. docker restart restarts the container on its old image. Only docker compose up -d replaces it with the image you pulled.

Custom Compose files on :latest

If you maintain your own Compose files against the rolling stable tag, the update is the conventional pair of commands:

docker compose pull
docker compose up -d --wait --wait-timeout 600

Read each release's Compose and environment changes first, because nothing merges them into your files for you. The published bundles pin digests instead of tracking :latest.

Air-gapped updates

An update repeats the air-gapped deployment procedure with the next bundle. Prepare and pull on a connected host, then export the images the bundle selects. Move everything through your approved media process, then load and start on the isolated host. See Docker Compose deployment for the full sequence and its constraints.

Migrations

The backend applies pending database migrations when it starts. The migration history is forward-only and retained, so any published release updates directly to the current one. Only the step from the immediately previous release is rehearsed for every release. Longer jumps follow the same migration chain.

Watch the migrations run:

docker compose logs -f backend

If startup fails before the migrations apply, fix what the log reports and run docker compose up -d --wait again. If they already applied, do not point an older release at the new schema unless the release notes say it is safe. Recovering from that means restoring the pre-update database backup together with the previous bundle.

If an update fails

docker compose ps
docker compose logs
curl -f http://127.0.0.1:8080/health
curl -f http://127.0.0.1:8080/api/health/

The running backend and frontend versions appear under Settings → License & Updates.

Keep the command output and the container logs, then write to [email protected] with the version you came from, the target version, and how the installation is deployed.

← Configuration Dashboard →