@acuity/directus-extension-acuity-backup
v2.2.3
Published
Backup Directus collections, schema, and media files to ZIP archives. Provided free, courtesy of Acuity Consulting Inc. — we help companies build smarter systems, automate workflows with AI, and scale with confidence.
Maintainers
Readme
Directus Backup Extension
A powerful Directus bundle extension that provides full or selective backup of collections, schema, media files, and relations into ZIP archives. Backups are stored on disk under a configurable path (BACKUP_PATH), with support for automatic scheduled backups.
Provided free, courtesy of Acuity Consulting Inc. 🚀
Acuity Consulting helps companies build smarter systems, automate workflows with AI, and scale with confidence. From custom system development and integrations to intelligent automation, we turn complex technical challenges into reliable, production-grade solutions.
Features
- Full & Selective Backups — Backup all collections or choose specific ones
- Media File Export — Include binary media files from Directus Files in backups
- Schema & Relations — Capture complete schema definition and relationship mappings
- ZIP Archives — Compressed, portable backup format with metadata
- Restore Functionality — Import backups with optional data truncation
- Scheduled Backups — Automatic backups via cron expressions
- File Storage — Backups saved to a configurable local directory (
BACKUP_PATH) - Admin Dashboard — Intuitive Vue module for managing backups and schedules
Installation
⚠️ Do not run
npm install @acuity/directus-extension-acuity-backupdirectly inside/directus/extensions. That folder is a shared drop-directory, not an npm project root — installing there makes npm scan every sibling extension and can crash withCannot read properties of null (reading 'name'). This extension is not sandboxed, so it also cannot be installed from the in-app Directus Marketplace. Use one of the methods below instead.
Docker (Recommended)
On your server, inside the directory mounted to /directus/extensions, install the extension into its own subfolder. Use the package name as the folder name — do not name the folder acuity-backup, as that collides with the bundle's endpoint entry and corrupts Directus's extension registry:
mkdir directus-extension-acuity-backup && cd directus-extension-acuity-backup
npm pack @acuity/directus-extension-acuity-backup
tar -xzf *.tgz --strip-components=1
rm *.tgz
npm install --prodRestart Directus to load the extension:
docker compose restart directusDockerfile
Alternatively, bake it into a custom image:
FROM directus/directus:11
USER root
RUN corepack enable
USER node
RUN pnpm install @acuity/directus-extension-acuity-backupUpdating
Docker (subfolder install)
To upgrade to the latest published version, clear out the old files and re-extract the new package in the same subfolder:
cd /directus/extensions/directus-extension-acuity-backup
rm -rf dist node_modules package.json package-lock.json icon.png *.tgz
npm pack @acuity/directus-extension-acuity-backup
tar -xzf *.tgz --strip-components=1
rm *.tgz
npm install --prodThen restart Directus to load the new version:
docker compose restart directusTo pin a specific version instead of the latest, append @<version> to the pack command, e.g. npm pack @acuity/[email protected].
Upgrading from a release installed in a folder named
acuity-backup? Rename the folder todirectus-extension-acuity-backupfirst — the old name collides with the bundle's endpoint entry and corrupts Directus's extension registry. If the Settings → Extensions page was already returning a 500, clear the stale rows once and restart:DELETE FROM directus_extensions WHERE folder IN ('acuity-backup', 'acuity-backup-module', 'backup-endpoint');Directus rebuilds clean rows from disk on the next boot.
Dockerfile
If you baked the extension into a custom image, update by rebuilding without the cache so the latest version is pulled, then redeploy:
docker compose build --no-cache directus
docker compose up -d directusPin a version in the Dockerfile to control upgrades explicitly:
RUN pnpm install @acuity/[email protected]Check the installed version anytime with
cat /directus/extensions/directus-extension-acuity-backup/package.json | grep version, and compare against the latest release on npm.
Configuration
Environment Variables
BACKUP_PATH— Directory where backup ZIP files are stored (default:/directus/backups/). This is the single source of truth for backups; make sure it is mounted to a persistent volume.
Example .env:
BACKUP_PATH=/backupsUsage
Via Data Studio
- Log in as an administrator
- Navigate to Backup in the sidebar (cloud download icon)
- Click Run Backup to open the backup dialog
- Choose backup type:
- Full Backup — All collections, schema, and media
- Selected Collections — Choose which collections to include
- Toggle "Include Media Files" as needed
- Click Start Backup
- Monitor backup progress and download completed backups from the history table
API Endpoints
All endpoints require administrator authentication. Base path: /acuity-backup
GET /collections
List all user-created collections with item counts.
Response:
[
{
"collection": "articles",
"itemCount": 42,
"icon": "article",
"note": "Blog posts"
}
]POST /run
Trigger a backup operation.
Request body:
{
"type": "full",
"collections": [],
"includeMedia": true
}Response:
{
"id": "backup-2025-02-24-150000",
"filename": "backup-2025-02-24-150000.zip",
"timestamp": "2025-02-24T15:00:00Z",
"type": "full",
"collections": ["articles", "authors", "categories"],
"includeMedia": true,
"fileSize": 5242880,
"directusFileId": "uuid-here"
}GET /list
Retrieve all saved backups.
Response:
[
{
"id": "backup-2025-02-24-150000",
"filename": "backup-2025-02-24-150000.zip",
"timestamp": "2025-02-24T15:00:00Z",
"type": "full",
"collections": ["articles", "authors"],
"includeMedia": true,
"fileSize": 5242880
}
]POST /restore
Restore data from a backup.
Request body:
{
"backupId": "backup-2025-02-24-150000",
"truncateCollections": true,
"collections": ["articles", "authors"]
}GET /schedule
Get the current automatic backup schedule.
Response:
{
"enabled": true,
"cronExpression": "0 2 * * *",
"lastRun": "2025-02-24T02:00:00Z"
}POST /schedule
Update the automatic backup schedule.
Request body:
{
"enabled": true,
"cronExpression": "0 2 * * *"
}DELETE /:id
Delete a backup archive.
Backup Format
Backups are ZIP archives with the following structure:
backup-2025-02-24-150000.zip
├── manifest.json # Backup metadata (version 1.2.0)
├── schema.json # Complete schema definition
├── relations.json # Relationship mappings
├── views.json # Field groups & collection view settings
├── fields-meta.json # Full field metadata (interface, display, options)
├── collections/
│ ├── articles.json
│ ├── authors.json
│ └── categories.json
└── files/
├── uuid.meta.json # Media file metadata per file
└── ...Restore Behavior
- Truncate Mode — Clears collection data before inserting backup items
- Upsert Mode — Merges backup data with existing records
- Media Files — Re-uploaded to Directus Files with original metadata
- Relations — Not automatically restored; must be manually configured
Cron Expression Format
Schedule automatic backups using standard 5-field cron expressions:
┌───────────── minute (0 - 59)
│ ┌───────────── hour (0 - 23)
│ │ ┌───────────── day of month (1 - 31)
│ │ │ ┌───────────── month (1 - 12)
│ │ │ │ ┌───────────── day of week (0 - 6) (Sunday to Saturday)
│ │ │ │ │
│ │ │ │ │
* * * * *Examples:
0 2 * * *— Daily at 2:00 AM0 0 ? * 0— Weekly on Sunday at midnight0 0 1 * *— Monthly on the first day at midnight*/30 * * * *— Every 30 minutes
Permissions
This extension requires administrator privileges to:
- View the Backup module
- Create, restore, and delete backups
- Configure automatic schedules
Limitations
- System Collections —
directus_*collections are excluded from backups - Relations — Relationship metadata is captured but not automatically restored
- Media Streaming — Large media libraries may require increased timeout settings
- Storage — Backup size is limited by available disk space
Scheduled backups
- Single-instance only — the scheduler runs in-process. If Directus is deployed as multiple instances (cluster / replicated containers), each instance runs the schedule independently and a scheduled backup will fire once per instance (duplicate backups). For horizontally scaled deployments, run the backup schedule on a single designated instance, or disable the in-app schedule and trigger backups via the API (
POST /run) from an external scheduler. Manual backups and "Run now" are unaffected. - No missed-run catch-up — if the server is down at the scheduled time, that run is skipped (it is not retroactively run on restart).
Development
Build
npm run buildWatch Mode
npm run devValidate
npm run validateTypeScript
This extension is built with TypeScript. Run npm run build to compile source files in src/ to the dist/ directory.
License
MIT — Feel free to use in personal and commercial projects.
Support
For issues, feature requests, or questions, please visit: https://git.technolify.cloud/acuity/directus/backup-plugin
About Acuity Consulting Inc.
This extension is provided free of charge as a thank-you to the Directus community, courtesy of Acuity Consulting Inc.
We help companies build smarter systems, automate workflows with AI, and scale with confidence — specializing in:
- System Customization & Development — bespoke extensions, integrations, and tooling tailored to your stack
- AI Automation — intelligent workflows, agents, and automation that eliminate manual busywork
- Digital Transformation — modernizing platforms and processes to help your business move faster
Need a custom Directus extension, an AI-powered automation, or help with a complex integration? We'd love to help.
🌐 Website: acuityconsulting.net ✉️ Contact us: acuityconsulting.net/#contact
Made with ❤️ by Acuity Consulting Inc.
