ChatAI Docs

Backup and upgrades

Back up Postgres and uploads, then upgrade ChatAI safely.

What to back up

DataLocationNotes
DatabaseCompose volume chatai_pgdataAssistants, chunks, conversations, API keys
UploadsCompose volume chatai_uploadsOriginal files under /app/uploads
ConfigYour .env / secrets storeNot in the image. Keep ENCRYPTION_KEY with your backups: without it, restored per-assistant provider keys can't be decrypted
Voice recordingsYour S3-compatible bucketOnly if recording is enabled; back up with your storage provider's tools

Database dump

With Compose running:

docker compose exec -T db pg_dump -U chatai -d chatai -Fc > chatai-$(date +%Y%m%d).dump

Plain SQL:

docker compose exec -T db pg_dump -U chatai -d chatai > chatai-$(date +%Y%m%d).sql

Restore

# Example: custom format dump into a fresh volume
docker compose up -d db
docker compose exec -T db pg_restore -U chatai -d chatai --clean --if-exists < chatai-YYYYMMDD.dump

Prefer restoring into an empty database or a new volume. Coordinate with app downtime so ingest workers are not writing mid-restore.

Uploads volume

Copy the named volume or bind-mount contents. Example with a temporary Alpine container:

docker run --rm \
  -v chatai_chatai_uploads:/data \
  -v "$PWD:/backup" \
  alpine tar czf /backup/chatai-uploads-$(date +%Y%m%d).tgz -C /data .

Adjust the volume name to match docker volume ls on your host (Compose prefixes the project name).

Upgrade flow

Upgrading from 1.0? Read Upgrading to 1.1 first.

  1. Back up Postgres and uploads

  2. Pull / rebuild the app image:

    git pull
    docker compose build app
  3. Restart so the entrypoint runs migrations:

    docker compose up -d app

    Migrations run automatically via node /app/packages/database/scripts/migrate.mjs on boot. You do not need to apply 0000_*.sql by hand.

  4. Smoke health:

    curl -s http://localhost:3000/api/health
    # {"status":"ok","db":"ok"}
  5. Sign in, open an assistant playground, and send a short test message.

Existing databases

If an older install only applied the first SQL file and skipped later migrations, restarting the current image applies pending Drizzle migrations (0001–…) on boot.