jChat LogojChat Docs
Operations & Maintenance

Database Migrations & Backups

Understanding automated zero-downtime migrations, disaster recovery procedures, and storage-conscious backup strategies.

Database Migrations

JChat manages its relational database schema with automated, transactional migrations that evolve alongside the application codebase.

Automated On-the-Go Migrations (Default)

When JChat starts or restarts:

  1. Schema Check: JChat inspects the database schema migration history to determine the current state.
  2. Transactional Migration: Any unapplied SQL migration files are executed sequentially within a safe database transaction.
  3. Traffic Readiness: Once migrations complete successfully, the Elysia HTTP server and WebSocket gateway begin accepting inbound traffic.

Manual Migrations (Maintenance & Updates)

If running in a standalone bare-metal environment or applying manual maintenance updates:

# Apply pending database migrations:
bun run db:migrate

Database Backups

Regular database backups protect your data against catastrophic hardware failure, VPS corruption, or operator error.


Select your deployment architecture to view the recommended automated backup workflow:

Execute pg_dump directly inside the running PostgreSQL container using compressed custom format (-Fc):

#!/bin/bash
set -euo pipefail

BACKUP_DIR="/var/backups/jchat"
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
mkdir -p "$BACKUP_DIR"

# Export compressed PostgreSQL database archive from Docker:
docker compose exec -T db pg_dump -U jchat -Fc jchat > "$BACKUP_DIR/jchat_$TIMESTAMP.dump"

# Retain only the last 7 days of backups to preserve VPS disk space:
find "$BACKUP_DIR" -type f -name "*.dump" -mtime +7 -delete

To automate this daily at 02:00 UTC, add a cron job via crontab -e:

0 2 * * * /path/to/backup-docker.sh >> /var/log/jchat-backup.log 2>&1

Restoring a Database Backup

Follow these steps to safely restore a database archive:

Stop the Application Container

Stop the JChat web service to prevent inbound writes while restoring:

docker compose stop jchat

Restore the PostgreSQL Dump

Restore the compressed .dump archive using pg_restore:

# For Docker Compose deployments:
docker compose exec -T db pg_restore -U jchat -d jchat --clean --if-exists < /var/backups/jchat/jchat_YYYYMMDD_HHMMSS.dump

# For Standalone Linux deployments:
pg_restore -U jchat -d jchat --clean --if-exists /var/backups/jchat/jchat_YYYYMMDD_HHMMSS.dump

Restart JChat

Restart the JChat application container. JChat will connect, verify schema integrity, and resume traffic:

docker compose start jchat

Operational Best Practices

PracticeRecommendationWhy It Matters
Pre-Upgrade SnapshotCreate an instant dump before major updatesGuarantees instant rollback if custom schema extensions conflict
Disk Space MonitoringSet alerts when host disk usage exceeds 80% (df -h)Prevents sudden PostgreSQL crashes caused by filled VPS disks
Compressed FormatsAlways use -Fc (pg_dump custom archive)Compresses database data by up to 70–80% compared to plain SQL
Offsite MirroringSync snapshots to R2, S3, or Backblaze B2Shields against total VPS provider or datacenter outage
Quarterly Restore DrillsTest restoring backups into a local staging instanceValidates that backup archives are uncorrupted and recoverable

On this page