[inhalt]
Projekt BISO 3 - Handbuch

Backup and Restore

Deutsche Version

Overview

A BISO installation consists of three logically independent areas that must be backed up and restored separately:

Area Path / Source Content
Webroot <biso-webroot> PHP backend, frontend (ExtJS), templates, migrations, components
Data-Dir Config::get('datadir') Attachments, letter templates, invoices, import inbox, help texts, FOP/phpdocx configuration, customer-specific fonts, help topics
Database PostgreSQL DB (biso) All business data (counseling cases, persons, appointments, reports, parameterization, logs, etc.)

Together, all three areas form a complete, restorable BISO instance.

What needs to be backed up?

Backup

Prerequisites

1. Webroot Backup (Application)

The webroot contains the executable application code including all components (Gaia, phpdocx, FOP) and configurations. It only changes with updates — accordingly, the backup frequency here is typically lower than for the data dir or the DB.

Customer-specific configuration files are to be excluded (see above).

rsync -a \
    --exclude='data' \
    /PATH/TO/WEBROOT/ \
    /var/backups/biso/webroot/

Note: The excluded paths correspond exactly to the rsync pattern from the update guide (see Installation), so that the state of a backup is always comparable to that of an update.

2. Data-Dir Backup (User Data)

The datadir (see Config::set('datadir', ...) in config.php) contains all user-generated files. In production installations this area grows continuously and must be backed up accordingly often.

Not to be backed up:

# Determine / set the datadir:
DATADIR=/var/www/biso-webroot/data

rsync -a \
    --exclude='tmp/' \
    --exclude='*.log' \
    --exclude='maintenance.on' \
    "$DATADIR/" \
    /var/backups/biso/data/

3. Database Dump (Plain SQL)

The database dump is created as plain SQL (as specified). This makes it inspectable and version-controllable without additional tools.

# Configuration of the database parameters, see config.php, Config::set('gaia.db',[ ....]))
DB_HOST=db.host
DB_NAME=biso_db
DB_USER=biso_user

pg_dump \
    -h "$DB_HOST" \
    -U "$DB_USER" \
    -d "$DB_NAME" \
    --no-owner \
    --no-privileges \
    --clean \
    --if-exists \
    | gzip > /var/backups/biso/db/biso_$(date +%Y%m%d_%H%M%S).sql.gz

Note: If the optional log database biso_log is also operated (see Configuration), it must be backed up separately.

The three backup steps are ideally executed consistently in sequence. For production systems the following is recommended:

  1. Briefly stop the web server / PHP workers or switch BISO into maintenance mode (php biso-cli maintenance on), so that no write operations take place during the backup.
  2. Create the DB dump.
  3. Back up the data dir.
  4. Back up the webroot.
  5. Deactivate maintenance mode again (php biso-cli maintenance off).

Restore (Disaster Recovery)

Prerequisites

Order

1. Restore webroot
2. Provide config.php
3. Restore data dir
4. Restore database
5. Configuration & migrations
6. Verification

The order is important: without webroot code the BISO application cannot interpret the DB. Without config.php the application does not know where the data dir and DB are. Without a DB schema every request will fail.

1. Restore Webroot

The webroot is restored from the backup to the intended location:

rsync -a /var/backups/biso/webroot/ /PATH/TO/WEBROOT/

2. Restore Data-Dir

Restore from the data dir backup to the path configured in config.php (Config::set('datadir', ...)). Check path permissions (see Installation):

rsync -a /var/backups/biso/data/ "$DATADIR/"
chown -R www-data:www-data "$DATADIR"
chmod -R u+rwX "$DATADIR"

3. Restore Database

Prepare the target database (if it does not already exist) and import the dump:

# on the DB server or on a client with psql installed:
# Prepare database (possibly drop the old one):
psql -U biso -d postgres -c "DROP DATABASE biso;"
psql -U biso -d postgres -c "CREATE DATABASE biso OWNER biso ENCODING 'UTF8' LC_COLLATE='de_CH.utf8' LC_CTYPE='de_CH.utf8';"

# Execute restore
gunzip -c /var/backups/biso/db/biso_YYYYMMDD_HHMMSS.sql.gz | psql -U biso -d biso

4. Configuration and Migrations

  1. Copy config.php from the backup to the correct path, if it is not part of the webroot backup

  2. Verify that Config::set('env', 'PROD') and the DB connection data are correct.

  3. Execute pending DB migrations so that the DB schema matches the application code:

    cd /PATH/TO/WEBROOT
    php biso-cli migration exec
    

    For Docker setups:

    docker compose exec web83 php biso-cli migration exec
    
  4. Crunz scheduler cron job and queue runner are set up (see Configuration).

  5. Restart PHP workers / web server.

Verification

Data Refresh (Production → Test)

Goal

The test environment should contain a data set that is as realistic as possible so that tests, bug reproductions, and trainings can be performed with production-like data. This is not a disaster recovery — the production state remains untouched.

Prerequisites

Procedure

# 1. Switch test system into maintenance mode
php biso-cli maintenance on

# 2. Stop test web server / PHP workers
# Depending on the system, here shown using the example of Debian with apache and fpm:
systemctl stop apache2 php-fpm

# 3. Fetch fresh prod DB dump (or create it beforehand)
rsync -a prod:/var/backups/biso/db/biso_latest.sql.gz /tmp/

# 4. Empty test DB and recreate it
docker compose exec db psql -U biso -d postgres \
    -c "DROP DATABASE biso_test;"
docker compose exec db psql -U biso -d postgres \
    -c "CREATE DATABASE biso_test OWNER biso ENCODING 'UTF8' LC_COLLATE='de_CH.utf8' LC_CTYPE='de_CH.utf8';"
gunzip -c /tmp/biso_latest.sql.gz | docker compose exec -T db psql -U biso -d biso_test

# 5. Empty test data dir and fill with prod state
rm -rf "$TEST_DATADIR"/
rsync -a prod:/var/backups/biso/data/ "$TEST_DATADIR/"

# 6. Execute test DB migrations
php biso-cli migration exec

# 7. Restart test workers
systemctl start apache2 php-fpm

# 8. Remove maintenance mode
php biso-cli maintenance off

Note on customer parameters: The params table contains customer-specific settings (including the kunde column). As a rule, these should be carried over to the test instance — otherwise they must be manually adjusted after the restore (see Installation).

Note on session / login data: Sessions do not belong in the prod dump — the refresh formally copies them, but they become invalid after the DB restore. Users must log in again on the test instance.

Personal data (client data, counselor notes, counseling cases, attachments) is not automatically anonymized during the refresh. Before a test environment that is accessed by external persons (e.g. developers, training participants, support staff), anonymization must be performed.

Procedure according to Anonymization:

# Make sure in config.php of the test system:
#   Config::set('env', 'dev');

php biso-cli anonymizer anonymize --do-it

Important: For safety reasons, the anonymizer is only active in env = dev and must never be executed on a production system.

Among others, the tables person, beratungsfall, bf_termin, bf_termin_protokoll, bf_notiz, bf_log are anonymized. Files in the data dir are not anonymized — attachments deliberately carried over during the refresh in $TEST_DATADIR/attachments/ still contain the original files. Under strict data protection requirements, the data dir restore must be restricted accordingly, or the attachments must be cleaned up separately beforehand.

Cleanup

After a successful refresh: