As part of the new release, Webitel deb package builds have been migrated from Bamboo to GitHub Actions. Along with this, the versioning process has changed: package revision is now tied to the GitHub Actions workflow run, and packages are published to a new private S3 APT repository with a new GPG signing key.
The migration also adds support for Debian 13 alongside Debian 12 and switches part of the package builds to multi-architecture mode:
-
backend services are now built for
amd64andarm64; -
frontend packages are published as architecture-independent (all);
-
the PostgreSQL extension and FreeSWITCH modules remain amd64-only for now.
For Debian 13, the supported combination is PostgreSQL 18 and the webitel-postgresql-18 package; for Debian 12, PostgreSQL 15 and webitel-postgresql-15 remain. Upgrading from Debian 12 → Debian 13 for installations with the Webitel PostgreSQL extension must be planned together with the major PostgreSQL 15 → 18 upgrade.
There are several practical changes in the packages: some frontend packages have received the -app suffix, backend binaries and some systemd units have received the webitel- prefix, systemd units are no longer shipped via webitel-common, and service backend packages now include maintainer scripts.
Steps
Before upgrading, perform a database backup.
Stopping Webitel services
systemctl stop webitel-api webitel-app webitel-uac messages-bot messages-srv \
engine call_center storage flow_manager rabbitmq-server webitel-logger \
webitel-cases webitel-media-exporter consul freeswitch ngcp-rtpengine-daemon \
opensips grafana-server nginx
Removing the outdated Webitel repository
rm -f /etc/apt/sources.list.d/webitel.list
rm -f /etc/apt/auth.conf.d/webitel.conf
rm -f /usr/share/keyrings/webitel-repo.gpg
Dist-upgrade Debian 12 → 13
Performed only when upgrading to Debian 13.
If the installation remains on Debian 12, skip this step.
Temporarily disable custom APT repositories, switch Debian sources to trixie, perform the upgrade, and reboot the server:
find /etc/apt/sources.list.d -type f \( -name '*.list' -o -name '*.sources' \) \
-exec mv {} {}.disabled \;
sed -i 's/bookworm/trixie/g' /etc/apt/sources.list
apt update
apt upgrade --without-new-pkgs
apt full-upgrade
reboot
After rebooting, restore the custom repositories and update the codename where the repository supports Debian 13:
find /etc/apt/sources.list.d -type f -name '*.disabled' \
-exec sh -c 'for f do mv "$f" "${f%.disabled}"; done' sh {} +
find /etc/apt/sources.list.d -type f \( -name '*.list' -o -name '*.sources' \) \
-exec sed -i 's/bookworm/trixie/g' {} +
apt update
Connecting the Webitel S3 APT repository
Obtain the current AccessKeyId and SecretAccessKey.
PostgreSQL 15 → 18
Performed only after migrating to Debian 13.
Prepare the variables and check the disk before installing/running the upgrade.
export OLD_PG_MAJOR=15
export NEW_PG_MAJOR=18
export OLD_BIN_DIR="/usr/lib/postgresql/${OLD_PG_MAJOR}/bin"
export NEW_BIN_DIR="/usr/lib/postgresql/${NEW_PG_MAJOR}/bin"
export OLD_DATA_DIR="/var/lib/postgresql/${OLD_PG_MAJOR}/main"
export NEW_DATA_DIR="/var/lib/postgresql/${NEW_PG_MAJOR}/main"
du -sh "${OLD_DATA_DIR}"
df -h "${OLD_DATA_DIR}"
By default, to reduce risks, the upgrade requires free disk space approximately equal to the current PostgreSQL data directory + tablespaces, with additional headroom for WAL, auxiliary files, and temporary operations (typically x2 the size of OLD_DATA_DIR).
However, for large databases (or when disk space is insufficient), if the risks and recovery — either from a backup or via a replica — are acceptable, an upgrade mode using hard links is available. This mode does not copy files and therefore requires no additional free disk space. After a successful hard links upgrade, the old PostgreSQL 15 cluster becomes unusable.
See the following steps for details.
Installing packages
The timescaledb version in the new cluster must match the version in the old cluster at the time of the upgrade:
apt update
apt install postgresql-18 postgresql-client-18
TIMESCALEDB_VERSION=$(dpkg-query -W -f='${Version}' timescaledb-2-postgresql-${OLD_PG_MAJOR})
apt install "timescaledb-2-postgresql-${NEW_PG_MAJOR}=${TIMESCALEDB_VERSION}"
Preparing clusters
Check the existing DB clusters. If 18/main was not created automatically, create it manually.
Both clusters must be stopped before running pg_upgrade:
pg_lsclusters
OLD_LOCALE=$(su postgres -c "psql -tAc 'SHOW lc_collate' postgres" | tr -d ' ')
OLD_ENCODING=$(su postgres -c "psql -tAc 'SHOW server_encoding' postgres" | tr -d ' ')
if ! pg_lsclusters | awk '{print $1 "/" $2}' | grep -qx "${NEW_PG_MAJOR}/main"; then
pg_createcluster "${NEW_PG_MAJOR}" main -- \
--locale="${OLD_LOCALE}" \
--encoding="${OLD_ENCODING}"
fi
systemctl stop postgresql
Checking pg_upgrade
To use hard links during the upgrade, add the --link flag.
su postgres -c "${NEW_BIN_DIR}/pg_upgrade \
--old-bindir=${OLD_BIN_DIR} \
--new-bindir=${NEW_BIN_DIR} \
--old-datadir=${OLD_DATA_DIR} \
--new-datadir=${NEW_DATA_DIR} \
--check"
If --check completed with an error, do not run pg_upgrade until the cause has been resolved.
Running pg_upgrade
To use hard links during the upgrade, add the --link flag.
su postgres -c "${NEW_BIN_DIR}/pg_upgrade \
--old-bindir=${OLD_BIN_DIR} \
--new-bindir=${NEW_BIN_DIR} \
--old-datadir=${OLD_DATA_DIR} \
--new-datadir=${NEW_DATA_DIR}"
Updating PostgreSQL 18 configuration
pg_upgrade does not migrate configuration files automatically, so this must be done manually for:
-
/etc/postgresql/18/main/postgresql.conf -
/etc/postgresql/18/main/pg_hba.conf
timescaledb-tune \
--quiet --yes \
--pg-version=${NEW_PG_MAJOR} \
--conf-path=/etc/postgresql/${NEW_PG_MAJOR}/main/postgresql.conf
Starting PostgreSQL 18 and updating TimescaleDB
systemctl disable postgresql@${OLD_PG_MAJOR}-main
systemctl enable postgresql@${NEW_PG_MAJOR}-main
systemctl start postgresql@${NEW_PG_MAJOR}-main
pg_lsclusters
su postgres -c "psql webitel -c 'ALTER EXTENSION timescaledb UPDATE;'"
Updating PostgreSQL 18 statistics
Before starting the services:
su postgres -c "vacuumdb --all --analyze-in-stages --missing-stats-only --jobs=$(nproc)"
Updating Webitel packages
apt update
apt upgrade
apt install webitel-postgresql-18 webitel-postgresql-migrations-18 \
webitel-supervisor-workspace-app webitel-web-widget-app \
webitel-flow-diagram-app webitel-agent-workspace-app
apt reinstall webitel-admin-app webitel-audit-app webitel-auth-app \
webitel-crm-app webitel-history-app webitel-meetings-app
Renaming systemd unit files and binary paths
The script saves the enabled state of the old unit files, creates a backup, renames the unit files, updates the ExecStart binary path, and adds an Alias with the old name:
After verifying the services, the backup unit files can be deleted:
find /etc/systemd/system -type f -name '*.service.pre-26.4.bak' -delete
Migrating the DB schema
The migration is taken from webitel-postgresql-migrations. PostgreSQL major is determined automatically. timescaledb.restoring is reset via trap even if the migration fails.
touch /tmp/migrate-webitel-schema.sh
chmod +x /tmp/migrate-webitel-schema.sh
tee /tmp/migrate-webitel-schema.sh <<'EOF'
#!/bin/bash
set -euo pipefail
DB="webitel"
PG_MAJOR=$(su postgres -c "psql -tAc 'SHOW server_version_num'" | awk '{print int($1/10000)}')
MIGRATION="/usr/share/postgresql/${PG_MAJOR}/webitel/migration/26.02-26.4.sql"
if [ ! -f "$MIGRATION" ]; then
echo "Migration file not found: $MIGRATION" >&2
exit 1
fi
cleanup() {
su postgres -c "psql ${DB} -qxc \"ALTER DATABASE ${DB} RESET timescaledb.restoring;\"" || true
}
trap cleanup EXIT
su postgres -c "psql ${DB} -qxc \"ALTER DATABASE ${DB} SET timescaledb.restoring='on';\""
su postgres -c "psql -v ON_ERROR_STOP=1 -1 -f ${MIGRATION} ${DB}"
EOF
/tmp/migrate-webitel-schema.sh
Reconciling configuration
Review and update according to the current configuration files:
-
OpenSIPs
-
FreeSWITCH
Cleanup and restarting services
Restart services in groups in dependency order:
apt --purge autoremove
systemctl restart consul
systemctl restart postgresql
systemctl restart rabbitmq-server
systemctl restart freeswitch ngcp-rtpengine-daemon opensips
systemctl restart webitel-engine webitel-call-center webitel-flow-manager \
webitel-storage webitel-messages-srv webitel-messages-bot webitel-api \
webitel-uac webitel-app webitel-cases webitel-logger webitel-media-exporter \
grafana-server nginx
Removing old PostgreSQL 15
Only after upgrading PostgreSQL 15 → 18 and verifying the stability of PostgreSQL 18 and Webitel.
pg_dropcluster --stop 15 main
apt --purge remove postgresql-15 postgresql-client-15 \
timescaledb-2-postgresql-15 webitel-postgresql-15
apt --purge autoremove
Updating PostgreSQL 18 statistics
After updating the services (can be run in parallel):
su postgres -c "PGOPTIONS='-c vacuum_cost_delay=0' vacuumdb --all --analyze-only --jobs=$(nproc)"