This directory contains scripts for managing the Cloudflare D1 database.
- Node.js 20+
- Cloudflare Wrangler CLI installed
- Database configured in
wrangler.toml
npm run db:migratenpm run db:migrate:remoteCreate default projects (debug, duyet.net, blog, prod, staging, test) via the Projects API.
The seed script uses the API endpoints to create projects, ensuring proper validation and error handling. It will skip projects that already exist.
npm run db:seed # Uses http://localhost:8788/api/projectsnpm run db:seed:remote # Uses https://logs.duyet.net/api/projectsNote: The local dev server must be running (npm run dev) before seeding locally.
Backup the entire D1 database to ./backups/ directory.
npm run db:backup:localnpm run db:backupOutput files:
duyet-logs_[local|prod]_YYYYMMDD_HHMMSS.sql.gz- Compressed SQL dumpduyet-logs_[local|prod]_YYYYMMDD_HHMMSS.sql.projects.json- JSON export of projectsduyet-logs_latest.sql.gz- Symlink to latest backup
Restore database from a backup file.
npm run db:restore latest --localnpm run db:restore ./backups/duyet-logs_prod_20240101_120000.sql.gzExecute SQL queries directly.
npm run db:query "SELECT * FROM projects;"npm run db:query:remote "SELECT * FROM projects;"CREATE TABLE projects (
id TEXT PRIMARY KEY,
description TEXT NOT NULL,
created_at INTEGER NOT NULL,
last_used INTEGER
);
CREATE INDEX idx_projects_created_at ON projects(created_at DESC);Columns:
id- Project identifier (3-32 alphanumeric characters)description- Project descriptioncreated_at- Unix timestamp when project was createdlast_used- Unix timestamp of last analytics event (NULL if never used)
The seed script creates these default projects:
| ID | Description |
|---|---|
debug |
Development and debugging project |
duyet |
duyet.net personal website analytics |
blog |
Blog analytics and metrics |
prod |
Production environment |
staging |
Staging environment |
test |
Testing and QA environment |
- Production: Daily backups (automated via cron/CI)
- Local: Before major changes
Keep backups for:
- Daily: 7 days
- Weekly: 4 weeks
- Monthly: 12 months
# Daily backup at 2 AM
0 2 * * * cd /path/to/project && npm run db:backup > /dev/null 2>&1
# Weekly cleanup (keep last 30 backups)
0 3 * * 0 cd /path/to/project && ls -t ./backups/*.gz | tail -n +31 | xargs rm -fwrangler d1 execute duyet-logs --local --command "SELECT * FROM projects;"wrangler d1 execute duyet-logs --local --command "
INSERT INTO projects (id, description, created_at, last_used)
VALUES ('myproject', 'My custom project', $(date +%s)000, NULL);
"wrangler d1 execute duyet-logs --local --command "
SELECT id, description,
datetime(created_at/1000, 'unixepoch') as created,
datetime(last_used/1000, 'unixepoch') as last_used
FROM projects
ORDER BY created_at DESC;
"wrangler d1 execute duyet-logs --local --command "
UPDATE projects
SET description = 'New description'
WHERE id = 'myproject';
"wrangler d1 execute duyet-logs --local --command "
DELETE FROM projects WHERE id = 'myproject';
"Ensure database is created and bound in wrangler.toml:
[[d1_databases]]
binding = "DB"
database_name = "duyet-logs"
database_id = "your-database-id"Create database if needed:
wrangler d1 create duyet-logsRun migrations:
npm run db:migrateMake scripts executable:
chmod +x scripts/*.sh-
Check backup file integrity:
gunzip -t ./backups/backup-file.sql.gz
-
Manually extract and inspect:
gunzip -c ./backups/backup-file.sql.gz | head -n 20 -
Try restoring to local first:
./scripts/restore-d1.sh ./backups/backup-file.sql.gz --local
- Never commit backup files to version control
- Add
backups/to.gitignore - Backup files may contain sensitive project data
- Restrict production database access
- Use environment-specific credentials
- Rotate database credentials regularly
- Cloudflare D1 Documentation
- Wrangler D1 Commands
- Project main README: ../README.md