This script performs two operations:
- Backup Creation - Dumps a database (PostgreSQL or MySQL) to a local SQL file
- Cloud Upload - Queues the backup for upload to DigitalOcean Spaces, then deletes the local file
The backup and upload are decoupled via a Redis-backed job queue (BullMQ), allowing the worker to run on a different machine or at a different time.
┌─────────────────┐ ┌─────────────┐ ┌─────────────────┐
│ Create Backup │────▶│ Redis │────▶│ Worker │
│ (pg_dump or │ │ (Queue) │ │ (S3 Upload) │
│ mysqldump) │ │ │ │ │
└─────────────────┘ └─────────────┘ └─────────────────┘
│ │
▼ ▼
local .sql file DigitalOcean
Spaces
npm installCopy .env.example to .env and configure the following variables:
| Variable | Description |
|---|---|
DATABASE_CONNECTION |
Database type: postgresql or mysql (default: postgresql) |
DB_HOST |
Database host |
DB_PORT |
Database port (default: 5432 for PostgreSQL, 3306 for MySQL) |
DB_NAME |
Database name to backup |
DB_USER |
Database username |
DB_PASSWORD |
Database password |
| Variable | Description |
|---|---|
RD_HOST |
Redis host |
RD_PORT |
Redis port (default: 6379) |
| Variable | Description |
|---|---|
DO_SPACES_KEY |
Spaces access key |
DO_SPACES_SECRET |
Spaces secret key |
DO_SPACES_BUCKET |
Spaces bucket name |
DO_SPACES_REGION |
Spaces region (e.g., nyc3) |
DO_SPACES_ENDPOINT |
Spaces endpoint URL |
| Variable | Description |
|---|---|
BACKUP_STORAGE_DIR |
Local directory for temp backup files (default: src/storage) |
CRON_SCHEDULE |
Cron schedule expression (default: 0 2 * * * - daily at 2:00 AM) |
Starts the backup script with a cron schedule. The process runs continuously and executes backups according to CRON_SCHEDULE:
npm run backupAn initial backup runs immediately on startup.
| Schedule | Description |
|---|---|
* * * * * |
Every minute (for testing) |
0 * * * * |
Every hour |
0 2 * * * |
Daily at 2:00 AM |
0 */6 * * * |
Every 6 hours |
Processes queued backup jobs (upload to Spaces + local cleanup):
npm run workerFor simple setups, run both in the background or as separate processes:
npm run backup & # Start backup first
npm run worker # Then start workerSet DATABASE_CONNECTION in your .env file:
# For PostgreSQL
DATABASE_CONNECTION=postgresql
DB_PORT=5432
# For MySQL
DATABASE_CONNECTION=mysql
DB_PORT=3306Make sure the corresponding command-line tool is installed:
- PostgreSQL:
pg_dumpmust be available - MySQL:
mysqldumpmust be available
npm testRuns syntax validation on all JavaScript files.
src/
├── app.js # Main entry point - creates backup + dispatches job
├── config/
│ ├── env.js # Environment variable exports
│ ├── db-connection.js # PostgreSQL client
│ ├── redis-connection.js # Redis client
│ └── space-client.js # DigitalOcean Spaces (S3) client
├── queue/
│ ├── backup-queue.js # BullMQ queue setup
│ └── constants.js # Queue name constant
├── services/
│ └── create-backup.js # Local database dump execution (routes to pg-dump or mysql-dump)
├── worker/
│ └── worker.js # Job processor - uploads to Spaces
└── utils/
├── backup-paths.js # Path generation for backup files
├── env.js # Environment validation
├── log-cleanup.js # Log file cleanup utility
├── logger.js # File-based logging
├── pg-dump.js # pg_dump wrapper
└── mysql-dump.js # mysqldump wrapper
Backups are organized by database type, database name, and date. This allows multiple databases to be stored in the same DigitalOcean Space with a clean, hierarchical structure.
{BACKUP_STORAGE_DIR}/{database_type}/{database_name}/{YYYY-MM-DD}/{dbName}-{timestamp}.sql
Example:
storage/postgresql/mydrive/2026-06-18/mydrive-2026-06-18T08-00-00-024Z.sql
storage/mysql/database1/2026-06-18/database1-2026-06-18T08-30-00-025Z.sql
backups/{database_type}/{database_name}/{YYYY-MM-DD}/{dbName}-{timestamp}.sql
Example:
backups/postgresql/mydrive/2026-06-18/mydrive-2026-06-18T08-00-00-024Z.sql
backups/mysql/database1/2026-06-18/database1-2026-06-18T08-30-00-025Z.sql
storage/
├── mysql/
│ └── {database_name}/
│ └── {YYYY-MM-DD}/
│ └── {dbName}-{timestamp}.sql
└── postgresql/
└── {database_name}/
└── {YYYY-MM-DD}/
└── {dbName}-{timestamp}.sql
backups/ (in DigitalOcean Spaces)
├── mysql/
│ └── {database_name}/
│ └── {YYYY-MM-DD}/
│ └── {dbName}-{timestamp}.sql
└── postgresql/
└── {database_name}/
└── {YYYY-MM-DD}/
└── {dbName}-{timestamp}.sql
This structure enables:
- Multiple databases of different types in one Space
- Easy navigation and manual file retrieval
- Clear organization by database type, name, and date
Logs are stored in the logs/ directory with automatic cleanup (7-day retention):
logs/backup-{date}.log- Backup process logslogs/worker-{date}.log- Worker process logslogs/queue-{date}.log- Queue eventslogs/log-cleanup-{date}.log- Log cleanup process
Ensure the PostgreSQL or MySQL client tools are installed on your system:
# Ubuntu/Debian
sudo apt install postgresql-client
# or
sudo apt install mysql-client
# macOS
brew install postgresql
# or
brew install mysqlEnsure Redis is running:
redis-serverCheck your Spaces credentials in .env and ensure the bucket exists.
ISC