Skip to main content

Upgrading

Upgrades require a brief restart. No data is lost.

Take a full backup first

Take a complete VM snapshot before every upgrade. Back up .env separately and keep it off the server — it holds ENCRYPTION_KEY, without which no stored PBX or accounting credential can be decrypted.

Back the server up on a schedule as well, not only before upgrades.

Standard upgrade

cd /opt/vodia-billing && test -f docker-compose.yml && test -f .env && \
UPD=".vodia-billing-upd.$(date +%s)" && \
wget https://cdn.vodia.net/vodia-billing/vodia-billing.zip -O vodia-billing-update.zip && \
unzip -oq vodia-billing-update.zip -d "./$UPD" && \
test -d "./$UPD/vodia-billing" && \
cp .env .env.bak.$(date +%s) && \
cp .env /tmp/.env.vodia-billing.bak && \
cp -rf "./$UPD/vodia-billing/"* . && \
cp /tmp/.env.vodia-billing.bak .env && \
rm -rf "./$UPD" && \
rm -f vodia-billing-update.zip && \
docker compose up -d --build

.env is preserved and a timestamped copy is left beside it. Database migrations run automatically when the API starts.

Why --build and not restart

docker compose restart reuses the previously baked image. The new source would be on disk but not running, and everything would report healthy. Always up -d --build.

First start after an upgrade

New database indexes are built when the API starts. On a large database this can take a few minutes, during which the web interface and CDR ingestion are unavailable.

docker compose up -d may print dependency api failed to start while this happens. That is expected — do not interrupt it.

Watch progress:

docker compose logs -f api

Wait for the API to report that it is listening.

Verify after upgrading

curl https://your-domain/api/health

Check that version is what you expected, mongo is up, and the version shown in the bottom-left corner of the web interface matches.

Then check one finalized invoice from the previous period and confirm its totals are unchanged. Frozen detail means they should be, and confirming it takes a minute.

Do not re-run install.sh

install.sh is first-install only and refuses to run when .env exists. If it were forced, it would generate a new ENCRYPTION_KEY and every stored PBX and accounting credential would stop decrypting.

Rolling back

Restore the VM snapshot. There is no in-place downgrade, because migrations run forward only.

Manual database backup

cd /opt/vodia-billing
docker compose exec -T mongo mongodump \
--db vodia_billing --archive > billing-$(date +%Y%m%d).archive
cp .env env-$(date +%Y%m%d).bak

Keep the archive and the .env copy together and off the server. Either alone is insufficient: the database without the key cannot decrypt its stored credentials.

Restore:

docker compose exec -T mongo mongorestore --archive --drop < billing-YYYYMMDD.archive
Verify one previous invoice after upgrading

Migrations run forward only and are designed to be idempotent, but an issued invoice's totals are the thing worth checking.

Open a finalized invoice from the previous period and confirm its totals are unchanged. Frozen detail means they should be, and confirming it takes a minute.