dbdock 1.1.14 → 1.1.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,116 +1,116 @@
1
1
  # DBDock
2
2
 
3
- Enterprise-grade PostgreSQL backup and restore. Beautiful CLI with real-time progress tracking.
3
+ Stop writing backup scripts. Stop losing sleep over database migrations. DBDock handles PostgreSQL backups, restores, and database copies in one command.
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/dbdock.svg)](https://www.npmjs.com/package/dbdock)
6
6
  [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
7
7
  [![Node.js](https://img.shields.io/badge/node-%3E%3D18-brightgreen)](https://nodejs.org)
8
8
  [![Documentation](https://img.shields.io/badge/docs-dbdock.mintlify.app-blue)](https://dbdock.mintlify.app)
9
9
 
10
- 📚 **[Full Documentation](https://dbdock.mintlify.app)** | 💬 **[Discussions](https://github.com/naheemolaide/dbdock-support/discussions)** | 🐛 **[Issues](https://github.com/naheemolaide/dbdock-support/issues)**
10
+ [Full Docs](https://dbdock.mintlify.app) [Discussions](https://github.com/naheemolaide/dbdock-support/discussions) [Report a Bug](https://github.com/naheemolaide/dbdock-support/issues)
11
11
 
12
- ## Quick Start
12
+ ---
13
+
14
+ ## The Problem
15
+
16
+ Every time you need to backup a database, copy it to staging, or restore before a migration — it's the same boring steps. Connect, dump, upload, move files around, remember the right flags. Sure, you could ask AI to write you a script. But then you're maintaining that script, handling errors, adding encryption, switching storage providers, doing it again next week.
17
+
18
+ It's not hard. It's just repetitive. And repetitive stuff should be one command.
19
+
20
+ ## The Fix
13
21
 
14
22
  ```bash
15
- npx dbdock init # Interactive setup
16
- npx dbdock backup # Create backup
17
- npx dbdock restore # Restore backup
23
+ npx dbdock init # One-time setup (takes 30 seconds)
24
+ npx dbdock backup # Backup with encryption + compression
25
+ npx dbdock restore # Restore from any backup
26
+ npx dbdock copydb "db_url_1" "db_url_2" # Copy entire database, zero config
18
27
  ```
19
28
 
20
- ## Features
29
+ That's it. No shell scripts. No manual uploads. No config files for `copydb`.
21
30
 
22
- - **Beautiful CLI** - Real-time progress bars, speed tracking, smart filtering
23
- - **Multiple Storage** - Local, AWS S3, Cloudflare R2, Cloudinary
24
- - **Security First** - Hybrid config (env vars for secrets), AES-256 encryption, credential masking, .pgpass support
25
- - **Retention Policies** - Automatic cleanup by count/age with safety nets
26
- - **Smart UX** - Intelligent filtering for 100+ backups, clear error messages
27
- - **Alerts** - Email (SMTP) and Slack notifications for backups (CLI & Programmatic)
28
- - **TypeScript Native** - Full type safety for programmatic usage
29
- - **Automation** - Cron schedules, auto-cleanup after backups
30
- - **Migration Tool** - One command to migrate legacy configs to secure env vars
31
+ ---
31
32
 
32
- ## Installation
33
+ ## Install
33
34
 
34
- **Global Installation (Recommended):**
35
+ **Use directly with npx (no install needed):**
35
36
 
36
37
  ```bash
37
- npm install -g dbdock
38
-
39
- dbdock init # Use directly
40
- dbdock backup
41
- dbdock status
38
+ npx dbdock backup
42
39
  ```
43
40
 
44
- **Or use with npx (No installation needed):**
41
+ **Or install globally:**
45
42
 
46
43
  ```bash
47
- npx dbdock init
48
- npx dbdock backup
49
- npx dbdock status
44
+ npm install -g dbdock
50
45
  ```
51
46
 
52
- ## CLI Commands
47
+ **Prerequisites:** Node.js 18+ and PostgreSQL client tools (`pg_dump`, `pg_restore`, `psql`).
53
48
 
54
- ### `dbdock init`
49
+ ```bash
50
+ # macOS
51
+ brew install postgresql
55
52
 
56
- Interactive setup wizard that creates secure configuration:
53
+ # Ubuntu/Debian
54
+ sudo apt-get install postgresql-client
55
+ ```
57
56
 
58
- - Database connection (host, port, credentials)
59
- - Storage provider (Local, S3, R2, Cloudinary)
60
- - Encryption/compression settings
61
- - Email and Slack alerts (optional)
57
+ ---
62
58
 
63
- **Security-first approach:**
64
- - Saves non-sensitive config to `dbdock.config.json` (safe for git)
65
- - Saves secrets to `.env` (automatically gitignored)
66
- - Auto-updates `.gitignore` to exclude sensitive files
59
+ ## Commands
67
60
 
68
- ### `dbdock migrate-config`
61
+ ### `dbdock init` — Set up in 30 seconds
69
62
 
70
- Migrate existing configurations with embedded secrets:
63
+ Run once. It walks you through everything interactively:
71
64
 
72
65
  ```bash
73
- npx dbdock migrate-config
66
+ npx dbdock init
74
67
  ```
75
68
 
76
- Extracts secrets from `dbdock.config.json`, creates `.env`, and updates your config to use environment variables.
69
+ It asks for your database connection, picks your storage (Local, S3, R2, Cloudinary), sets up encryption if you want it, and optionally configures Slack/Email alerts.
70
+
71
+ **What happens under the hood:**
72
+ - Config (safe stuff) goes to `dbdock.config.json` — commit this
73
+ - Secrets go to `.env` — never committed, `.gitignore` updated automatically
77
74
 
78
- ### `npx dbdock backup`
75
+ ---
79
76
 
80
- Creates database backup with real-time progress tracking:
77
+ ### `dbdock backup` One command, full backup
78
+
79
+ ```bash
80
+ npx dbdock backup
81
+ ```
81
82
 
82
83
  ```
83
- ████████████████████ | 100% | 45.23/100 MB | Speed: 12.50 MB/s | ETA: 0s | Uploading to S3
84
+ ████████████████████ | 100% | 45.23 MB | Speed: 12.50 MB/s | Uploading to S3
84
85
  ✔ Backup completed successfully
85
86
  ```
86
87
 
87
- **Options:**
88
+ Real-time progress. Streams directly to your storage provider. Done.
88
89
 
89
- ```bash
90
- npx dbdock backup --encrypt --compress --compression-level 9
91
- ```
90
+ **Options:**
92
91
 
93
- - `--encrypt` / `--no-encrypt` - Toggle encryption
94
- - `--compress` / `--no-compress` - Toggle compression
95
- - `--encryption-key <key>` - 64-char hex key (must be exactly 64 hexadecimal characters)
96
- - `--compression-level <1-11>` - Compression level (default: 6)
92
+ | Flag | What it does |
93
+ |------|------|
94
+ | `--encrypt` / `--no-encrypt` | Toggle AES-256 encryption |
95
+ | `--compress` / `--no-compress` | Toggle Brotli compression |
96
+ | `--encryption-key <key>` | Custom 64-char hex key |
97
+ | `--compression-level <1-11>` | Compression intensity (default: 6) |
97
98
 
98
- **Generate encryption key:**
99
+ **Need an encryption key?**
99
100
 
100
101
  ```bash
101
102
  node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
102
103
  ```
103
104
 
104
- **Backup Formats:**
105
+ **Backup formats:** `custom` (default binary), `plain` (SQL text), `directory`, `tar`
105
106
 
106
- - `custom` (default) - PostgreSQL custom binary format (.sql)
107
- - `plain` - Plain SQL text format (.sql)
108
- - `directory` - Directory format (.dir)
109
- - `tar` - Tar archive format (.tar)
107
+ ---
110
108
 
111
- ### `npx dbdock restore`
109
+ ### `dbdock restore` — Interactive restore with smart filtering
112
110
 
113
- Interactive restore with smart filtering and multi-step progress:
111
+ ```bash
112
+ npx dbdock restore
113
+ ```
114
114
 
115
115
  ```
116
116
  Progress:
@@ -123,282 +123,170 @@ Progress:
123
123
  ✔ All steps completed in 8.42s
124
124
  ```
125
125
 
126
- **Smart filtering** (auto-enabled for 20+ backups):
126
+ Got 200+ backups? It auto-enables smart filtering — search by date, keyword, or just grab the most recent ones. No scrolling through walls of text.
127
+
128
+ You can also restore to a completely different database. Pick "New Database Instance (Migrate)" when prompted and enter the target connection details.
129
+
130
+ ---
131
+
132
+ ### `dbdock copydb` — Copy a database with just two URLs
133
+
134
+ This is the one people love. No config files. No setup. Just paste two PostgreSQL URLs:
135
+
136
+ ```bash
137
+ npx dbdock copydb "postgresql://user:pass@source:5432/mydb" "postgresql://user:pass@target:5432/mydb"
138
+ ```
139
+
140
+ It tests both connections, shows you the source DB size and table count, warns you if the target has existing data, and asks for confirmation before doing anything. Then it streams `pg_dump` directly into `pg_restore` — no temp files, no waiting.
141
+
142
+ **Options:**
143
+
144
+ | Flag | What it does |
145
+ |------|------|
146
+ | `--schema-only` | Copy tables, indexes, constraints — no data |
147
+ | `--data-only` | Copy data only (schema must exist on target) |
148
+ | `--verbose` | Show detailed pg_dump/pg_restore output |
149
+
150
+ ```bash
151
+ npx dbdock copydb --schema-only "source_url" "target_url"
152
+ npx dbdock copydb --data-only "source_url" "target_url"
153
+ ```
154
+
155
+ **Perfect for:**
156
+ - Moving between Neon, Supabase, Railway, RDS, or any Postgres host
157
+ - Migrating cloud providers without the headache
127
158
 
128
- - Show recent (last 10)
129
- - Date range (24h, 7d, 30d, 90d, custom)
130
- - Search by keyword/ID
159
+ **Environment consolidation:**
131
160
 
132
- **Migration Support:**
161
+ ```bash
162
+ # Refresh staging with production data
163
+ npx dbdock copydb "prod_url" "staging_url"
133
164
 
134
- You can choose to restore to a **New Database Instance** during the restore process. This is perfect for migrating data between servers (e.g., from staging to production or local to cloud).
165
+ # Promote staging to production
166
+ npx dbdock copydb "staging_url" "prod_url"
135
167
 
136
- 1. Run `npx dbdock restore`
137
- 2. Select a backup
138
- 3. Choose "New Database Instance (Migrate)"
139
- 4. Enter connection details for the target database
168
+ # Pull production to local for debugging
169
+ npx dbdock copydb "prod_url" "postgresql://postgres:pass@localhost:5432/myapp"
140
170
 
141
- Shows database stats and requires confirmation before restore.
171
+ # Align schema across environments without touching data
172
+ npx dbdock copydb --schema-only "prod_url" "staging_url"
173
+ ```
142
174
 
143
- ### `npx dbdock list`
175
+ ---
144
176
 
145
- View backups with smart filtering:
177
+ ### `dbdock list` See all your backups
146
178
 
147
179
  ```bash
148
- npx dbdock list # All backups
180
+ npx dbdock list # Everything
149
181
  npx dbdock list --recent 10 # Last 10
150
- npx dbdock list --search keyword # Search
182
+ npx dbdock list --search keyword # Find specific backup
151
183
  npx dbdock list --days 7 # Last 7 days
152
184
  ```
153
185
 
154
- **Auto-filtering** for 50+ backups with interactive prompts.
186
+ Auto-filters when you have 50+ backups so the output stays clean.
155
187
 
156
- ### `npx dbdock delete`
188
+ ---
157
189
 
158
- Delete backups interactively or by key:
190
+ ### `dbdock delete` Remove backups
159
191
 
160
192
  ```bash
161
- npx dbdock delete # Interactive
162
- npx dbdock delete --key <id> # Specific backup
163
- npx dbdock delete --all # All (with confirmation)
193
+ npx dbdock delete # Interactive picker
194
+ npx dbdock delete --key <id> # Delete specific backup
195
+ npx dbdock delete --all # Nuke everything (with confirmation)
164
196
  ```
165
197
 
166
- ### `npx dbdock cleanup`
198
+ ---
167
199
 
168
- Clean up old backups based on retention policy:
200
+ ### `dbdock cleanup` Auto-clean old backups
169
201
 
170
202
  ```bash
171
203
  npx dbdock cleanup # Interactive with preview
172
- npx dbdock cleanup --dry-run # Preview only
204
+ npx dbdock cleanup --dry-run # See what would be deleted
173
205
  npx dbdock cleanup --force # Skip confirmation
174
206
  ```
175
207
 
176
- Shows detailed preview of what will be deleted and space to reclaim.
208
+ Shows you exactly what gets deleted and how much space you reclaim before doing anything.
177
209
 
178
- ### `dbdock status`
210
+ ---
179
211
 
180
- Quick view of all schedules and service status:
212
+ ### `dbdock status` Check schedules and service health
181
213
 
182
214
  ```bash
183
- dbdock status
215
+ npx dbdock status
184
216
  ```
185
217
 
186
- **Output:**
187
-
188
218
  ```
189
- 📅 Scheduled Backups:
190
-
191
219
  ┌─────┬──────────────┬─────────────────┬──────────┐
192
220
  │ # │ Name │ Cron Expression │ Status │
193
221
  ├─────┼──────────────┼─────────────────┼──────────┤
194
222
  │ 1 │ daily │ 0 * * * * │ ✓ Active │
195
223
  │ 2 │ weekly │ 0 0 * * 0 │ ✗ Paused │
196
224
  └─────┴──────────────┴─────────────────┴──────────┘
197
-
198
- Total: 2 schedule(s) - 1 active, 1 paused
199
-
200
- 🚀 Service Status:
201
-
202
- 🟢 Running (PM2)
203
- PID: 12345
204
- Uptime: 2d 5h
205
- Memory: 45.23 MB
206
225
  ```
207
226
 
208
- ### `dbdock test`
209
-
210
- Validates database, storage, and email configuration.
227
+ ---
211
228
 
212
- ### `dbdock schedule`
213
-
214
- Manage backup schedules in configuration:
229
+ ### `dbdock schedule` — Manage cron schedules
215
230
 
216
231
  ```bash
217
- dbdock schedule
232
+ npx dbdock schedule
218
233
  ```
219
234
 
220
- **Features:**
221
-
222
- - View current schedules with status
223
- - Add new schedule with cron expression presets
224
- - Remove or toggle (enable/disable) schedules
225
- - Saves to `dbdock.config.json`
226
-
227
- **Schedule Presets:**
228
-
229
- - Every hour: `0 * * * *`
230
- - Every day at midnight: `0 0 * * *`
231
- - Every day at 2 AM: `0 2 * * *`
232
- - Every week (Sunday): `0 0 * * 0`
233
- - Every month (1st): `0 0 1 * *`
234
- - Custom cron expression
235
-
236
- **⚠️ Important:** Schedules only execute when DBDock is integrated into your Node.js application (see Programmatic Usage below). The CLI is for configuration only.
237
-
238
- ## Security Best Practices
239
-
240
- ### Secure Configuration Management
241
-
242
- DBDock uses a **hybrid configuration approach** to keep your secrets safe:
243
-
244
- - **Non-sensitive settings** → `dbdock.config.json` (safe for version control)
245
- - **Sensitive secrets** → Environment variables (NEVER commit to git)
246
-
247
- When you run `npx dbdock init`, DBDock automatically:
248
- - Saves credentials to `.env` (not committed)
249
- - Saves only non-sensitive config to `dbdock.config.json`
250
- - Updates `.gitignore` to exclude `.env`
235
+ Add, remove, or toggle backup schedules. Comes with presets (hourly, daily at midnight, daily at 2 AM, weekly, monthly) or use a custom cron expression.
251
236
 
252
- **Note:** DBDock reads environment variables from both `.env` and `.env.local` files (with `.env.local` taking priority for local overrides). You can use either file depending on your workflow.
237
+ **Heads up:** Schedules only run when DBDock is integrated into your Node.js app (see [Programmatic Usage](#programmatic-usage) below). The CLI just manages the config.
253
238
 
254
- ### Environment Variables
255
-
256
- Set these environment variables for secure credential management:
257
-
258
- ```bash
259
- # Database password (Required)
260
- DBDOCK_DB_PASSWORD=your-database-password
261
-
262
- # Storage credentials (Required for cloud storage)
263
- DBDOCK_STORAGE_ACCESS_KEY=your-access-key
264
- DBDOCK_STORAGE_SECRET_KEY=your-secret-key
265
-
266
- # Encryption key (Required if encryption enabled)
267
- # Generate with: openssl rand -hex 32
268
- DBDOCK_ENCRYPTION_SECRET=64-char-hex-string
239
+ ---
269
240
 
270
- # Email alerts (Optional)
271
- DBDOCK_SMTP_USER=your-email@example.com
272
- DBDOCK_SMTP_PASS=your-app-password
273
-
274
- # Slack alerts (Optional)
275
- DBDOCK_SLACK_WEBHOOK=https://hooks.slack.com/services/...
276
- ```
277
-
278
- ### Migration from Legacy Config
279
-
280
- If you have an existing configuration with secrets in `dbdock.config.json`:
241
+ ### `dbdock test` — Verify everything works
281
242
 
282
243
  ```bash
283
- npx dbdock migrate-config
244
+ npx dbdock test
284
245
  ```
285
246
 
286
- This command will:
287
- 1. Extract all secrets from your config file
288
- 2. Create/update `.env` with the secrets
289
- 3. Remove secrets from `dbdock.config.json`
290
- 4. Update `.gitignore` automatically
247
+ Tests your database connection, storage provider, and alert config. Run this first if something feels off.
291
248
 
292
- ### Using .pgpass for PostgreSQL
249
+ ---
293
250
 
294
- For enhanced security, use `.pgpass` instead of environment variables:
251
+ ### `dbdock migrate-config` Fix legacy configs
295
252
 
296
253
  ```bash
297
- # Create the file
298
- touch ~/.pgpass
299
- chmod 600 ~/.pgpass
300
-
301
- # Add your connection (format: host:port:database:username:password)
302
- echo "localhost:5432:myapp:postgres:my-secure-password" >> ~/.pgpass
254
+ npx dbdock migrate-config
303
255
  ```
304
256
 
305
- DBDock will automatically use `.pgpass` when available, which is more secure than `PGPASSWORD` environment variables.
257
+ Got secrets sitting in `dbdock.config.json` from an older version? This extracts them to `.env`, cleans up your config, and updates `.gitignore`. One command, done.
306
258
 
307
- ### Security Features
308
-
309
- - **Automatic credential masking** - All passwords and keys are masked in logs
310
- - **File permission checking** - Warns about insecure config file permissions
311
- - **Encryption at rest** - AES-256-GCM encryption for backups
312
- - **Strict mode** - Optional enforcement of env-only secrets (`DBDOCK_STRICT_MODE=true`)
313
-
314
- 📖 **[Read the full Security Guide](SECURITY.md)** for deployment best practices, compliance guidelines, and incident response procedures.
315
-
316
- ## Configuration
317
-
318
- After running `npx dbdock init`, a `dbdock.config.json` file is created (without sensitive data):
319
-
320
- ```json
321
- {
322
- "_comment": "Secrets (passwords, keys) are set via environment variables",
323
- "database": {
324
- "type": "postgres",
325
- "host": "localhost",
326
- "port": 5432,
327
- "username": "postgres",
328
- "database": "myapp"
329
- },
330
- "storage": {
331
- "provider": "s3",
332
- "s3": {
333
- "bucket": "my-backups",
334
- "region": "us-east-1"
335
- }
336
- },
337
- "backup": {
338
- "format": "custom",
339
- "compression": {
340
- "enabled": true,
341
- "level": 6
342
- },
343
- "encryption": {
344
- "enabled": true
345
- },
346
- "retention": {
347
- "enabled": true,
348
- "maxBackups": 100,
349
- "maxAgeDays": 30,
350
- "minBackups": 5,
351
- "runAfterBackup": true
352
- }
353
- },
354
- "alerts": {
355
- "email": {
356
- "enabled": true,
357
- "smtp": {
358
- "host": "smtp.gmail.com",
359
- "port": 587,
360
- "secure": false
361
- },
362
- "from": "backups@yourapp.com",
363
- "to": ["admin@yourapp.com"]
364
- }
365
- }
366
- }
367
- ```
259
+ ---
368
260
 
369
- **Note:** SMTP credentials (`user`, `pass`) and storage secrets are set via environment variables for security.
261
+ ## Storage Providers
370
262
 
371
- ### Storage Providers
263
+ Pick your storage during `dbdock init`, or set it in `dbdock.config.json`:
372
264
 
373
- **Local:**
265
+ ### Local
374
266
 
375
267
  ```json
376
268
  { "storage": { "provider": "local", "local": { "path": "./backups" } } }
377
269
  ```
378
270
 
379
- **AWS S3:**
271
+ ### AWS S3
380
272
 
381
273
  ```json
382
274
  {
383
275
  "storage": {
384
276
  "provider": "s3",
385
- "s3": {
386
- "bucket": "my-backups",
387
- "region": "us-east-1"
388
- }
277
+ "s3": { "bucket": "my-backups", "region": "us-east-1" }
389
278
  }
390
279
  }
391
280
  ```
392
281
 
393
- Set credentials via environment variables:
394
282
  ```bash
395
283
  DBDOCK_STORAGE_ACCESS_KEY=your-access-key
396
284
  DBDOCK_STORAGE_SECRET_KEY=your-secret-key
397
285
  ```
398
286
 
399
- Required IAM permissions: `s3:PutObject`, `s3:GetObject`, `s3:ListBucket`, `s3:DeleteObject`
287
+ Needs IAM permissions: `s3:PutObject`, `s3:GetObject`, `s3:ListBucket`, `s3:DeleteObject`
400
288
 
401
- **Cloudflare R2:**
289
+ ### Cloudflare R2
402
290
 
403
291
  ```json
404
292
  {
@@ -413,32 +301,70 @@ Required IAM permissions: `s3:PutObject`, `s3:GetObject`, `s3:ListBucket`, `s3:D
413
301
  }
414
302
  ```
415
303
 
416
- Set credentials via environment variables (same as S3 above).
304
+ Same env vars as S3 above.
417
305
 
418
- **Cloudinary:**
306
+ ### Cloudinary
419
307
 
420
308
  ```json
421
309
  {
422
310
  "storage": {
423
311
  "provider": "cloudinary",
424
- "cloudinary": {
425
- "cloudName": "your-cloud"
426
- }
312
+ "cloudinary": { "cloudName": "your-cloud" }
427
313
  }
428
314
  }
429
315
  ```
430
316
 
431
- Set credentials via environment variables:
432
317
  ```bash
433
318
  DBDOCK_CLOUDINARY_API_KEY=your-api-key
434
319
  DBDOCK_CLOUDINARY_API_SECRET=your-api-secret
435
320
  ```
436
321
 
437
- All cloud backups stored in `dbdock_backups/` folder with format: `backup-YYYY-MM-DD-HH-MM-SS-BACKUPID.sql`
322
+ ---
323
+
324
+ ## Security
325
+
326
+ DBDock splits your config into two parts by design:
327
+
328
+ | What | Where | Git safe? |
329
+ |------|-------|-----------|
330
+ | Host, port, bucket names, settings | `dbdock.config.json` | Yes |
331
+ | Passwords, API keys, secrets | `.env` | No (auto-gitignored) |
438
332
 
439
- ### Retention Policy
333
+ ### Environment Variables
334
+
335
+ ```bash
336
+ DBDOCK_DB_PASSWORD=your-database-password # Required
337
+ DBDOCK_STORAGE_ACCESS_KEY=your-access-key # For cloud storage
338
+ DBDOCK_STORAGE_SECRET_KEY=your-secret-key # For cloud storage
339
+ DBDOCK_ENCRYPTION_SECRET=64-char-hex-string # If encryption enabled
340
+ DBDOCK_SMTP_USER=your-email@example.com # For email alerts
341
+ DBDOCK_SMTP_PASS=your-app-password # For email alerts
342
+ DBDOCK_SLACK_WEBHOOK=https://hooks.slack.com/... # For Slack alerts
343
+ ```
440
344
 
441
- Automatic cleanup to prevent storage bloat from frequent backups:
345
+ Reads from both `.env` and `.env.local` (`.env.local` takes priority).
346
+
347
+ ### .pgpass Support
348
+
349
+ If you prefer `.pgpass` over env vars for the database password, DBDock detects and uses it automatically:
350
+
351
+ ```bash
352
+ touch ~/.pgpass && chmod 600 ~/.pgpass
353
+ echo "localhost:5432:myapp:postgres:my-secure-password" >> ~/.pgpass
354
+ ```
355
+
356
+ ### What's Built In
357
+
358
+ - AES-256 encryption at rest
359
+ - Automatic credential masking in all logs
360
+ - File permission warnings for insecure configs
361
+ - Strict mode (`DBDOCK_STRICT_MODE=true`) — enforces env-only secrets
362
+
363
+ ---
364
+
365
+ ## Retention Policy
366
+
367
+ Backups pile up fast. Retention handles it automatically:
442
368
 
443
369
  ```json
444
370
  {
@@ -454,449 +380,200 @@ Automatic cleanup to prevent storage bloat from frequent backups:
454
380
  }
455
381
  ```
456
382
 
457
- **How it works:**
383
+ - Keeps at least `minBackups` recent backups (safety net — these never get deleted)
384
+ - Removes anything over `maxBackups` (oldest first)
385
+ - Removes anything older than `maxAgeDays`
386
+ - Runs automatically after each backup if `runAfterBackup` is on
387
+ - Or run manually: `npx dbdock cleanup`
458
388
 
459
- - Keeps most recent `minBackups` (safety net, never deleted)
460
- - Deletes backups exceeding `maxBackups` limit (oldest first)
461
- - Deletes backups older than `maxAgeDays` (respecting minBackups)
462
- - Runs automatically after each backup (if `runAfterBackup: true`)
463
- - Manual cleanup: `npx dbdock cleanup`
389
+ ---
464
390
 
465
- **Safety features:**
391
+ ## Alerts
466
392
 
467
- - Always preserves `minBackups` most recent backups
468
- - Shows preview before deletion
469
- - Detailed logging of what was deleted
470
- - Error handling for failed deletions
393
+ Get notified on Slack or Email when backups succeed or fail. Set it up during `dbdock init` or add to your config:
471
394
 
472
- ## Programmatic Usage
395
+ ```json
396
+ {
397
+ "alerts": {
398
+ "email": {
399
+ "enabled": true,
400
+ "smtp": {
401
+ "host": "smtp.gmail.com",
402
+ "port": 587,
403
+ "secure": false
404
+ },
405
+ "from": "backups@yourapp.com",
406
+ "to": ["admin@yourapp.com"]
407
+ },
408
+ "slack": {
409
+ "enabled": true,
410
+ "webhookUrl": "https://hooks.slack.com/services/..."
411
+ }
412
+ }
413
+ }
414
+ ```
473
415
 
474
- Use DBDock in your Node.js application to create backups programmatically. You don't need to understand NestJS internals - DBDock provides a simple API that works with any Node.js backend.
416
+ SMTP credentials go in env vars (`DBDOCK_SMTP_USER`, `DBDOCK_SMTP_PASS`).
475
417
 
476
- ### Basic Setup
418
+ **Works with:** Gmail, SendGrid, AWS SES, Mailgun — anything that speaks SMTP.
477
419
 
478
- First, install DBDock:
420
+ > For Gmail, use an [App Password](https://support.google.com/accounts/answer/185833), not your regular password.
479
421
 
480
- ```bash
481
- npm install dbdock
482
- ```
422
+ Alerts fire automatically on both CLI and programmatic backups. They include backup ID, database name, size, duration, and storage location. Failure alerts include the error message and troubleshooting tips.
483
423
 
484
- Make sure you have `dbdock.config.json` configured (run `npx dbdock init` first). DBDock reads all configuration from this file automatically.
424
+ ---
485
425
 
486
- ### How It Works
426
+ ## Programmatic Usage
487
427
 
488
- DBDock uses a simple initialization pattern:
428
+ Don't just use the CLI — drop DBDock into your Node.js app and trigger backups from code. Works with any backend (Express, Fastify, NestJS, whatever).
489
429
 
490
- 1. Call `createDBDock()` to initialize DBDock (reads from `dbdock.config.json`)
491
- 2. Get the `BackupService` from the returned context using `.get(BackupService)`
492
- 3. Use the service methods to create backups, list backups, etc.
430
+ ```bash
431
+ npm install dbdock
432
+ ```
493
433
 
494
- Think of `createDBDock()` as a factory function that sets up everything for you based on your config file.
434
+ Make sure `dbdock.config.json` exists (run `npx dbdock init` first).
495
435
 
496
- ### Creating Backups
436
+ ### Create a Backup
497
437
 
498
438
  ```javascript
499
439
  const { createDBDock, BackupService } = require('dbdock');
500
440
 
501
- async function createBackup() {
441
+ async function backup() {
502
442
  const dbdock = await createDBDock();
503
443
  const backupService = dbdock.get(BackupService);
504
444
 
505
445
  const result = await backupService.createBackup({
506
- format: 'plain', // 'custom' (binary), 'plain' (sql), 'directory', 'tar'
446
+ format: 'plain',
507
447
  compress: true,
508
448
  encrypt: true,
509
449
  });
510
450
 
511
- console.log(`Backup created: ${result.metadata.id}`);
512
- console.log(`Size: ${result.metadata.formattedSize}`); // e.g. "108.3 KB"
513
- console.log(`Path: ${result.storageKey}`);
514
-
515
- return result;
451
+ console.log(`Done: ${result.metadata.id} (${result.metadata.formattedSize})`);
516
452
  }
517
453
 
518
- createBackup().catch(console.error);
454
+ backup();
519
455
  ```
520
456
 
521
- **Backup Options:**
522
-
523
- - `compress` - Enable/disable compression (default: from config)
524
- - `encrypt` - Enable/disable encryption (default: from config)
525
- - `format` - Backup format: `'custom'` (default), `'plain'`, `'directory'`, `'tar'`
526
- - `type` - Backup type: `'full'` (default), `'schema'`, `'data'`
457
+ **Options:** `compress`, `encrypt`, `format` (`'custom'` | `'plain'` | `'directory'` | `'tar'`), `type` (`'full'` | `'schema'` | `'data'`)
527
458
 
528
- ### Listing Backups
459
+ ### List Backups
529
460
 
530
461
  ```javascript
531
462
  const { createDBDock, BackupService } = require('dbdock');
532
463
 
533
- async function listBackups() {
464
+ async function list() {
534
465
  const dbdock = await createDBDock();
535
- const backupService = dbdock.get(BackupService);
536
-
537
- const backups = await backupService.listBackups();
538
-
539
- console.log(`Found ${backups.length} backups:`);
540
- backups.forEach(
541
- (backup: {
542
- id: string;
543
- formattedSize: string;
544
- startTime: string | Date;
545
- }) => {
546
- console.log(
547
- `- ${backup.id} (${backup.formattedSize}, created: ${backup.startTime})`
548
- );
549
- }
550
- );
551
-
552
- return backups;
466
+ const backups = await dbdock.get(BackupService).listBackups();
467
+ backups.forEach(b => console.log(`${b.id} — ${b.formattedSize} — ${b.startTime}`));
553
468
  }
554
469
 
555
- listBackups().catch(console.error);
470
+ list();
556
471
  ```
557
472
 
558
- ### Getting Backup Metadata
473
+ ### Get Backup Info
559
474
 
560
475
  ```javascript
561
476
  const { createDBDock, BackupService } = require('dbdock');
562
477
 
563
- async function getBackupInfo(backupId) {
478
+ async function info(id) {
564
479
  const dbdock = await createDBDock();
565
- const backupService = dbdock.get(BackupService);
566
-
567
- const metadata = await backupService.getBackupMetadata(backupId);
568
-
569
- if (!metadata) {
570
- console.log('Backup not found');
571
- return null;
572
- }
573
-
574
- console.log('Backup details:', {
575
- id: metadata.id,
576
- size: metadata.size,
577
- created: metadata.startTime,
578
- encrypted: !!metadata.encryption,
579
- compressed: metadata.compression.enabled,
580
- });
581
-
582
- return metadata;
480
+ const metadata = await dbdock.get(BackupService).getBackupMetadata(id);
481
+ if (!metadata) return console.log('Not found');
482
+ console.log({ id: metadata.id, size: metadata.size, encrypted: !!metadata.encryption });
583
483
  }
584
484
 
585
- getBackupInfo('your-backup-id').catch(console.error);
485
+ info('your-backup-id');
586
486
  ```
587
487
 
588
- **Note:** Restore functionality is currently only available via CLI (`npx dbdock restore`). Programmatic restore will be available in a future release.
488
+ Restore is CLI-only for now (`npx dbdock restore`). Programmatic restore is coming.
589
489
 
590
- ### Scheduling Backups
490
+ ### Schedule Backups with node-cron
591
491
 
592
- DBDock doesn't include a built-in scheduler (to keep the package lightweight), but it's easy to schedule backups using `node-cron`.
593
-
594
- First, install `node-cron`:
492
+ DBDock stays lightweight no built-in daemon. Use `node-cron` to schedule:
595
493
 
596
494
  ```bash
597
495
  npm install node-cron
598
- npm install --save-dev @types/node-cron
599
496
  ```
600
497
 
601
- Then create a scheduler script (e.g., `scheduler.ts`):
602
-
603
498
  ```typescript
604
499
  import { createDBDock, BackupService } from 'dbdock';
605
500
  import * as cron from 'node-cron';
606
501
 
607
- async function startScheduler() {
608
- // Initialize DBDock
502
+ async function start() {
609
503
  const dbdock = await createDBDock();
610
504
  const backupService = dbdock.get(BackupService);
611
505
 
612
- console.log('🚀 Backup scheduler started. Running every minute...');
613
-
614
- // Schedule task to run every minute ('* * * * *')
615
- // For every 5 minutes use: '*/5 * * * *'
616
- // For every hour use: '0 * * * *'
617
- cron.schedule('* * * * *', async () => {
618
- try {
619
- console.log('\n⏳ Starting scheduled backup...');
620
-
621
- const result = await backupService.createBackup({
622
- format: 'plain', // Use 'plain' for SQL text, 'custom' for binary
623
- compress: true,
624
- encrypt: true,
625
- });
626
-
627
- console.log(`✅ Backup successful: ${result.metadata.id}`);
628
- console.log(`📦 Size: ${result.metadata.formattedSize}`);
629
- console.log(`📂 Path: ${result.storageKey}`);
630
- } catch (error) {
631
- console.error('❌ Backup failed:', error);
632
- }
506
+ cron.schedule('0 2 * * *', async () => {
507
+ const result = await backupService.createBackup({ compress: true, encrypt: true });
508
+ console.log(`Backup done: ${result.metadata.id}`);
633
509
  });
510
+
511
+ console.log('Scheduler running — daily at 2 AM');
634
512
  }
635
513
 
636
- startScheduler().catch(console.error);
514
+ start();
637
515
  ```
638
516
 
639
- **Note:** The CLI `dbdock schedule` command manages configuration for external schedulers but does not run a daemon itself. Using `node-cron` as shown above is the recommended way to run scheduled backups programmatically.
517
+ ---
640
518
 
641
- ### Alerts
642
-
643
- DBDock can send notifications when backups complete (success or failure) via Email and Slack. Alerts work with both **programmatic usage** and **CLI commands**.
644
-
645
- **Configuration in `dbdock.config.json`:**
646
-
647
- ```json
648
- {
649
- "database": { ... },
650
- "storage": { ... },
651
- "backup": { ... },
652
- "alerts": {
653
- "email": {
654
- "enabled": true,
655
- "smtp": {
656
- "host": "smtp.gmail.com",
657
- "port": 587,
658
- "secure": false,
659
- "auth": {
660
- "user": "your-email@gmail.com",
661
- "pass": "your-app-password"
662
- }
663
- },
664
- "from": "backups@yourapp.com",
665
- "to": ["admin@yourapp.com", "devops@yourapp.com"]
666
- },
667
- "slack": {
668
- "enabled": true,
669
- "webhookUrl": "https://hooks.slack.com/services/..."
670
- }
671
- }
672
- }
673
- ```
674
-
675
- **Slack Configuration:**
676
-
677
- 1. Create a Slack App or use an existing one.
678
- 2. Enable "Incoming Webhooks".
679
- 3. Create a new Webhook URL for your channel.
680
- 4. Run `npx dbdock init` and paste the URL when prompted.
681
-
682
- **SMTP Provider Examples:**
683
-
684
- _Gmail:_
685
- ```json
686
- {
687
- "smtp": {
688
- "host": "smtp.gmail.com",
689
- "port": 587,
690
- "secure": false,
691
- "auth": {
692
- "user": "your-email@gmail.com",
693
- "pass": "your-app-password"
694
- }
695
- }
696
- }
697
- ```
698
-
699
- > **Note:** For Gmail, you need to [create an App Password](https://support.google.com/accounts/answer/185833) instead of using your regular password.
700
-
701
- _SendGrid:_
702
- ```json
703
- {
704
- "smtp": {
705
- "host": "smtp.sendgrid.net",
706
- "port": 587,
707
- "secure": false,
708
- "auth": {
709
- "user": "apikey",
710
- "pass": "YOUR_SENDGRID_API_KEY"
711
- }
712
- }
713
- }
714
- ```
715
-
716
- _AWS SES:_
717
- ```json
718
- {
719
- "smtp": {
720
- "host": "email-smtp.us-east-1.amazonaws.com",
721
- "port": 587,
722
- "secure": false,
723
- "auth": {
724
- "user": "YOUR_SMTP_USERNAME",
725
- "pass": "YOUR_SMTP_PASSWORD"
726
- }
727
- }
728
- }
729
- ```
730
-
731
- _Mailgun:_
732
- ```json
733
- {
734
- "smtp": {
735
- "host": "smtp.mailgun.org",
736
- "port": 587,
737
- "secure": false,
738
- "auth": {
739
- "user": "postmaster@your-domain.mailgun.org",
740
- "pass": "YOUR_MAILGUN_SMTP_PASSWORD"
741
- }
742
- }
743
- }
744
- ```
745
-
746
- **Using Alerts Programmatically:**
747
-
748
- Once configured in `dbdock.config.json`, alerts are sent automatically when you create backups programmatically:
749
-
750
- ```javascript
751
- const { createDBDock, BackupService } = require('dbdock');
752
-
753
- async function createBackupWithAlerts() {
754
- const dbdock = await createDBDock();
755
- const backupService = dbdock.get(BackupService);
756
-
757
- // Alerts will be sent automatically after backup completes
758
- const result = await backupService.createBackup({
759
- compress: true,
760
- encrypt: true,
761
- });
762
-
763
- console.log(`Backup created: ${result.metadata.id}`);
764
- // Alerts sent to configured channels
765
- }
766
-
767
- createBackupWithAlerts().catch(console.error);
768
- ```
769
-
770
- **Alert Content:**
771
-
772
- Success alerts include:
773
- - Backup ID
774
- - Database name
775
- - Size (original and compressed)
776
- - Duration
777
- - Storage location
778
- - Encryption status
779
-
780
- Failure alerts include:
781
- - Error message
782
- - Database details
783
- - Timestamp
784
- - Helpful troubleshooting tips
785
-
786
- **Testing Alert Configuration:**
787
-
788
- Run `npx dbdock test` to validate your configuration without creating a backup.
789
-
790
- **Important Notes:**
791
-
792
- - ✅ Alerts work with programmatic usage (`createBackup()`)
793
- - ✅ Alerts work with scheduled backups (cron jobs in your app)
794
- - ✅ Alerts work with CLI commands (`npx dbdock backup`)
795
- - Configuration is read from `dbdock.config.json` automatically
796
- - Multiple recipients supported in the `to` array for email
797
- - Alerts are sent asynchronously (won't block backup completion)
798
-
799
- ## Requirements
800
-
801
- - Node.js 18 or higher
802
- - PostgreSQL 12+
803
- - PostgreSQL client tools (`pg_dump`, `pg_restore`, `psql`)
804
-
805
- **Installing PostgreSQL client tools:**
806
-
807
- ```bash
808
- # macOS
809
- brew install postgresql
519
+ ## Troubleshooting
810
520
 
811
- # Ubuntu/Debian
812
- sudo apt-get install postgresql-client
521
+ **First step, always:**
813
522
 
814
- # Windows
815
- # Download from https://www.postgresql.org/download/windows/
523
+ ```bash
524
+ npx dbdock test
816
525
  ```
817
526
 
818
- ## Troubleshooting
527
+ This tests your database, storage, and alert config in one go.
819
528
 
820
- Run `npx dbdock test` to verify your configuration.
529
+ ### pg_dump / pg_restore / psql not found
821
530
 
822
- ### Common Issues
823
-
824
- **pg_dump not found:**
531
+ You need PostgreSQL client tools installed:
825
532
 
826
533
  ```bash
827
- # macOS
828
- brew install postgresql
829
-
830
- # Ubuntu/Debian
831
- sudo apt-get install postgresql-client
534
+ brew install postgresql # macOS
535
+ sudo apt-get install postgresql-client # Ubuntu/Debian
832
536
  ```
833
537
 
834
- **Database connection errors:**
835
-
836
- - Verify `host`, `port`, `username`, `password`, `database` in config
837
- - Test connection: `psql -h HOST -p PORT -U USERNAME -d DATABASE`
838
- - Check PostgreSQL server is running
839
- - Verify network/firewall allows connection
840
-
841
- **Storage errors:**
538
+ ### Can't connect to database
842
539
 
843
- _AWS S3:_
540
+ - Double-check `host`, `port`, `username`, `password`, `database` in config
541
+ - Test manually: `psql -h HOST -p PORT -U USERNAME -d DATABASE`
542
+ - Make sure the PostgreSQL server is actually running
543
+ - Check firewalls / security groups if it's a remote database
844
544
 
845
- - Verify credentials are correct
846
- - Ensure IAM user has permissions: `s3:PutObject`, `s3:GetObject`, `s3:ListBucket`, `s3:DeleteObject`
847
- - Check bucket name and region
545
+ ### Storage errors
848
546
 
849
- _Cloudflare R2:_
547
+ **S3:** Check credentials, bucket name, region. IAM user needs `s3:PutObject`, `s3:GetObject`, `s3:ListBucket`, `s3:DeleteObject`.
850
548
 
851
- - Verify API token is correct
852
- - Check endpoint URL format: `https://ACCOUNT_ID.r2.cloudflarestorage.com`
853
- - Ensure bucket exists and is accessible
854
- - Verify R2 credentials have read/write permissions
549
+ **R2:** Check endpoint format (`https://ACCOUNT_ID.r2.cloudflarestorage.com`), verify API token and bucket exist.
855
550
 
856
- _Cloudinary:_
551
+ **Cloudinary:** Verify cloud name, API key, API secret. Make sure the account is active.
857
552
 
858
- - Verify cloud name, API key, and secret are correct
859
- - Check your Cloudinary account is active
860
- - Ensure API credentials have media library access
553
+ ### Encryption key issues
861
554
 
862
- **Encryption key errors:**
555
+ Key must be exactly 64 hex characters. Generate a valid one:
863
556
 
864
557
  ```bash
865
- # Generate a valid 64-character hex key
866
558
  node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
867
-
868
- # Must be exactly 64 hexadecimal characters (0-9, a-f, A-F)
869
559
  ```
870
560
 
871
- **R2 restore not working:**
872
-
873
- - Ensure backups are in `dbdock_backups/` folder
874
- - Verify backup files are named with `.sql` extension
875
- - Check endpoint configuration matches R2 account ID
876
-
877
- **No backups found:**
878
-
879
- - Local: Check files exist in configured path
880
- - S3/R2: Verify files are in `dbdock_backups/` folder
881
- - Cloudinary: Check Media Library for `dbdock_backups` folder
882
- - Ensure files match pattern: `backup-*.sql`
883
-
884
- DBDock shows clear, actionable error messages for all issues with specific troubleshooting steps.
885
-
886
- ## Documentation
887
-
888
- 📚 **[Full Documentation](https://dbdock.mintlify.app)** - Comprehensive guides, API reference, and examples
561
+ ### No backups found during restore
889
562
 
890
- ## Support
563
+ - **Local:** Check the configured path has files
564
+ - **S3/R2:** Files should be in `dbdock_backups/` folder
565
+ - **Cloudinary:** Check Media Library for `dbdock_backups` folder
566
+ - Files should match: `backup-*.sql`
891
567
 
892
- - 💬 **[Discussions](https://github.com/naheemolaide/dbdock-support/discussions)** - Ask questions and share ideas
893
- - 🐛 **[Issues](https://github.com/naheemolaide/dbdock-support/issues)** - Report bugs and request features
568
+ ---
894
569
 
895
570
  ## Links
896
571
 
897
- - 📦 **[npm Package](https://www.npmjs.com/package/dbdock)**
898
- - 📖 **[Documentation](https://dbdock.mintlify.app)**
899
- - 💻 **[GitHub Repository](https://github.com/naheemolaide/dbdock-support)**
572
+ - [npm Package](https://www.npmjs.com/package/dbdock)
573
+ - [Full Documentation](https://dbdock.mintlify.app)
574
+ - [GitHub](https://github.com/naheemolaide/dbdock-support)
575
+ - [Discussions](https://github.com/naheemolaide/dbdock-support/discussions)
576
+ - [Report Issues](https://github.com/naheemolaide/dbdock-support/issues)
900
577
 
901
578
  ## License
902
579