dbdock 1.1.15 → 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 +287 -610
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,116 +1,116 @@
|
|
|
1
1
|
# DBDock
|
|
2
2
|
|
|
3
|
-
|
|
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
|
[](https://www.npmjs.com/package/dbdock)
|
|
6
6
|
[](LICENSE)
|
|
7
7
|
[](https://nodejs.org)
|
|
8
8
|
[](https://dbdock.mintlify.app)
|
|
9
9
|
|
|
10
|
-
|
|
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
|
-
|
|
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
|
|
16
|
-
npx dbdock backup
|
|
17
|
-
npx dbdock restore
|
|
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
|
-
|
|
29
|
+
That's it. No shell scripts. No manual uploads. No config files for `copydb`.
|
|
21
30
|
|
|
22
|
-
|
|
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
|
-
##
|
|
33
|
+
## Install
|
|
33
34
|
|
|
34
|
-
**
|
|
35
|
+
**Use directly with npx (no install needed):**
|
|
35
36
|
|
|
36
37
|
```bash
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
dbdock init # Use directly
|
|
40
|
-
dbdock backup
|
|
41
|
-
dbdock status
|
|
38
|
+
npx dbdock backup
|
|
42
39
|
```
|
|
43
40
|
|
|
44
|
-
**Or
|
|
41
|
+
**Or install globally:**
|
|
45
42
|
|
|
46
43
|
```bash
|
|
47
|
-
|
|
48
|
-
npx dbdock backup
|
|
49
|
-
npx dbdock status
|
|
44
|
+
npm install -g dbdock
|
|
50
45
|
```
|
|
51
46
|
|
|
52
|
-
|
|
47
|
+
**Prerequisites:** Node.js 18+ and PostgreSQL client tools (`pg_dump`, `pg_restore`, `psql`).
|
|
53
48
|
|
|
54
|
-
|
|
49
|
+
```bash
|
|
50
|
+
# macOS
|
|
51
|
+
brew install postgresql
|
|
55
52
|
|
|
56
|
-
|
|
53
|
+
# Ubuntu/Debian
|
|
54
|
+
sudo apt-get install postgresql-client
|
|
55
|
+
```
|
|
57
56
|
|
|
58
|
-
|
|
59
|
-
- Storage provider (Local, S3, R2, Cloudinary)
|
|
60
|
-
- Encryption/compression settings
|
|
61
|
-
- Email and Slack alerts (optional)
|
|
57
|
+
---
|
|
62
58
|
|
|
63
|
-
|
|
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
|
|
61
|
+
### `dbdock init` — Set up in 30 seconds
|
|
69
62
|
|
|
70
|
-
|
|
63
|
+
Run once. It walks you through everything interactively:
|
|
71
64
|
|
|
72
65
|
```bash
|
|
73
|
-
npx dbdock
|
|
66
|
+
npx dbdock init
|
|
74
67
|
```
|
|
75
68
|
|
|
76
|
-
|
|
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
|
-
|
|
75
|
+
---
|
|
79
76
|
|
|
80
|
-
|
|
77
|
+
### `dbdock backup` — One command, full backup
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
npx dbdock backup
|
|
81
|
+
```
|
|
81
82
|
|
|
82
83
|
```
|
|
83
|
-
████████████████████ | 100% | 45.23
|
|
84
|
+
████████████████████ | 100% | 45.23 MB | Speed: 12.50 MB/s | Uploading to S3
|
|
84
85
|
✔ Backup completed successfully
|
|
85
86
|
```
|
|
86
87
|
|
|
87
|
-
|
|
88
|
+
Real-time progress. Streams directly to your storage provider. Done.
|
|
88
89
|
|
|
89
|
-
|
|
90
|
-
npx dbdock backup --encrypt --compress --compression-level 9
|
|
91
|
-
```
|
|
90
|
+
**Options:**
|
|
92
91
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
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
|
-
**
|
|
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
|
|
105
|
+
**Backup formats:** `custom` (default binary), `plain` (SQL text), `directory`, `tar`
|
|
105
106
|
|
|
106
|
-
|
|
107
|
-
- `plain` - Plain SQL text format (.sql)
|
|
108
|
-
- `directory` - Directory format (.dir)
|
|
109
|
-
- `tar` - Tar archive format (.tar)
|
|
107
|
+
---
|
|
110
108
|
|
|
111
|
-
### `
|
|
109
|
+
### `dbdock restore` — Interactive restore with smart filtering
|
|
112
110
|
|
|
113
|
-
|
|
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
|
-
|
|
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
|
-
|
|
129
|
-
- Date range (24h, 7d, 30d, 90d, custom)
|
|
130
|
-
- Search by keyword/ID
|
|
159
|
+
**Environment consolidation:**
|
|
131
160
|
|
|
132
|
-
|
|
161
|
+
```bash
|
|
162
|
+
# Refresh staging with production data
|
|
163
|
+
npx dbdock copydb "prod_url" "staging_url"
|
|
133
164
|
|
|
134
|
-
|
|
165
|
+
# Promote staging to production
|
|
166
|
+
npx dbdock copydb "staging_url" "prod_url"
|
|
135
167
|
|
|
136
|
-
|
|
137
|
-
|
|
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
|
-
|
|
171
|
+
# Align schema across environments without touching data
|
|
172
|
+
npx dbdock copydb --schema-only "prod_url" "staging_url"
|
|
173
|
+
```
|
|
142
174
|
|
|
143
|
-
|
|
175
|
+
---
|
|
144
176
|
|
|
145
|
-
|
|
177
|
+
### `dbdock list` — See all your backups
|
|
146
178
|
|
|
147
179
|
```bash
|
|
148
|
-
npx dbdock list #
|
|
180
|
+
npx dbdock list # Everything
|
|
149
181
|
npx dbdock list --recent 10 # Last 10
|
|
150
|
-
npx dbdock list --search keyword #
|
|
182
|
+
npx dbdock list --search keyword # Find specific backup
|
|
151
183
|
npx dbdock list --days 7 # Last 7 days
|
|
152
184
|
```
|
|
153
185
|
|
|
154
|
-
|
|
186
|
+
Auto-filters when you have 50+ backups so the output stays clean.
|
|
155
187
|
|
|
156
|
-
|
|
188
|
+
---
|
|
157
189
|
|
|
158
|
-
|
|
190
|
+
### `dbdock delete` — Remove backups
|
|
159
191
|
|
|
160
192
|
```bash
|
|
161
|
-
npx dbdock delete # Interactive
|
|
162
|
-
npx dbdock delete --key <id> #
|
|
163
|
-
npx dbdock delete --all #
|
|
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
|
-
|
|
198
|
+
---
|
|
167
199
|
|
|
168
|
-
|
|
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 #
|
|
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
|
|
208
|
+
Shows you exactly what gets deleted and how much space you reclaim before doing anything.
|
|
177
209
|
|
|
178
|
-
|
|
210
|
+
---
|
|
179
211
|
|
|
180
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
**
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
244
|
+
npx dbdock test
|
|
284
245
|
```
|
|
285
246
|
|
|
286
|
-
|
|
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
|
-
|
|
249
|
+
---
|
|
293
250
|
|
|
294
|
-
|
|
251
|
+
### `dbdock migrate-config` — Fix legacy configs
|
|
295
252
|
|
|
296
253
|
```bash
|
|
297
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
261
|
+
## Storage Providers
|
|
370
262
|
|
|
371
|
-
|
|
263
|
+
Pick your storage during `dbdock init`, or set it in `dbdock.config.json`:
|
|
372
264
|
|
|
373
|
-
|
|
265
|
+
### Local
|
|
374
266
|
|
|
375
267
|
```json
|
|
376
268
|
{ "storage": { "provider": "local", "local": { "path": "./backups" } } }
|
|
377
269
|
```
|
|
378
270
|
|
|
379
|
-
|
|
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
|
-
|
|
287
|
+
Needs IAM permissions: `s3:PutObject`, `s3:GetObject`, `s3:ListBucket`, `s3:DeleteObject`
|
|
400
288
|
|
|
401
|
-
|
|
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
|
-
|
|
304
|
+
Same env vars as S3 above.
|
|
417
305
|
|
|
418
|
-
|
|
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
|
-
|
|
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
|
-
###
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
391
|
+
## Alerts
|
|
466
392
|
|
|
467
|
-
|
|
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
|
-
|
|
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
|
-
|
|
416
|
+
SMTP credentials go in env vars (`DBDOCK_SMTP_USER`, `DBDOCK_SMTP_PASS`).
|
|
475
417
|
|
|
476
|
-
|
|
418
|
+
**Works with:** Gmail, SendGrid, AWS SES, Mailgun — anything that speaks SMTP.
|
|
477
419
|
|
|
478
|
-
|
|
420
|
+
> For Gmail, use an [App Password](https://support.google.com/accounts/answer/185833), not your regular password.
|
|
479
421
|
|
|
480
|
-
|
|
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
|
-
|
|
424
|
+
---
|
|
485
425
|
|
|
486
|
-
|
|
426
|
+
## Programmatic Usage
|
|
487
427
|
|
|
488
|
-
DBDock
|
|
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
|
-
|
|
491
|
-
|
|
492
|
-
|
|
430
|
+
```bash
|
|
431
|
+
npm install dbdock
|
|
432
|
+
```
|
|
493
433
|
|
|
494
|
-
|
|
434
|
+
Make sure `dbdock.config.json` exists (run `npx dbdock init` first).
|
|
495
435
|
|
|
496
|
-
###
|
|
436
|
+
### Create a Backup
|
|
497
437
|
|
|
498
438
|
```javascript
|
|
499
439
|
const { createDBDock, BackupService } = require('dbdock');
|
|
500
440
|
|
|
501
|
-
async function
|
|
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',
|
|
446
|
+
format: 'plain',
|
|
507
447
|
compress: true,
|
|
508
448
|
encrypt: true,
|
|
509
449
|
});
|
|
510
450
|
|
|
511
|
-
console.log(`
|
|
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
|
-
|
|
454
|
+
backup();
|
|
519
455
|
```
|
|
520
456
|
|
|
521
|
-
**
|
|
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
|
-
###
|
|
459
|
+
### List Backups
|
|
529
460
|
|
|
530
461
|
```javascript
|
|
531
462
|
const { createDBDock, BackupService } = require('dbdock');
|
|
532
463
|
|
|
533
|
-
async function
|
|
464
|
+
async function list() {
|
|
534
465
|
const dbdock = await createDBDock();
|
|
535
|
-
const
|
|
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
|
-
|
|
470
|
+
list();
|
|
556
471
|
```
|
|
557
472
|
|
|
558
|
-
###
|
|
473
|
+
### Get Backup Info
|
|
559
474
|
|
|
560
475
|
```javascript
|
|
561
476
|
const { createDBDock, BackupService } = require('dbdock');
|
|
562
477
|
|
|
563
|
-
async function
|
|
478
|
+
async function info(id) {
|
|
564
479
|
const dbdock = await createDBDock();
|
|
565
|
-
const
|
|
566
|
-
|
|
567
|
-
|
|
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
|
-
|
|
485
|
+
info('your-backup-id');
|
|
586
486
|
```
|
|
587
487
|
|
|
588
|
-
|
|
488
|
+
Restore is CLI-only for now (`npx dbdock restore`). Programmatic restore is coming.
|
|
589
489
|
|
|
590
|
-
###
|
|
490
|
+
### Schedule Backups with node-cron
|
|
591
491
|
|
|
592
|
-
DBDock
|
|
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
|
|
608
|
-
// Initialize DBDock
|
|
502
|
+
async function start() {
|
|
609
503
|
const dbdock = await createDBDock();
|
|
610
504
|
const backupService = dbdock.get(BackupService);
|
|
611
505
|
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
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
|
-
|
|
514
|
+
start();
|
|
637
515
|
```
|
|
638
516
|
|
|
639
|
-
|
|
517
|
+
---
|
|
640
518
|
|
|
641
|
-
|
|
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
|
-
|
|
812
|
-
sudo apt-get install postgresql-client
|
|
521
|
+
**First step, always:**
|
|
813
522
|
|
|
814
|
-
|
|
815
|
-
|
|
523
|
+
```bash
|
|
524
|
+
npx dbdock test
|
|
816
525
|
```
|
|
817
526
|
|
|
818
|
-
|
|
527
|
+
This tests your database, storage, and alert config in one go.
|
|
819
528
|
|
|
820
|
-
|
|
529
|
+
### pg_dump / pg_restore / psql not found
|
|
821
530
|
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
**pg_dump not found:**
|
|
531
|
+
You need PostgreSQL client tools installed:
|
|
825
532
|
|
|
826
533
|
```bash
|
|
827
|
-
# macOS
|
|
828
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
547
|
+
**S3:** Check credentials, bucket name, region. IAM user needs `s3:PutObject`, `s3:GetObject`, `s3:ListBucket`, `s3:DeleteObject`.
|
|
850
548
|
|
|
851
|
-
|
|
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
|
-
|
|
551
|
+
**Cloudinary:** Verify cloud name, API key, API secret. Make sure the account is active.
|
|
857
552
|
|
|
858
|
-
|
|
859
|
-
- Check your Cloudinary account is active
|
|
860
|
-
- Ensure API credentials have media library access
|
|
553
|
+
### Encryption key issues
|
|
861
554
|
|
|
862
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
893
|
-
- 🐛 **[Issues](https://github.com/naheemolaide/dbdock-support/issues)** - Report bugs and request features
|
|
568
|
+
---
|
|
894
569
|
|
|
895
570
|
## Links
|
|
896
571
|
|
|
897
|
-
-
|
|
898
|
-
-
|
|
899
|
-
-
|
|
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
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dbdock",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.16",
|
|
4
4
|
"description": "Enterprise-grade PostgreSQL backup and restore in under 60 seconds. CLI-first tool with encryption, compression, and multi-cloud storage.",
|
|
5
5
|
"author": "Naheem Olaide <naheemolaide@gmail.com>",
|
|
6
6
|
"private": false,
|