tearoom1 / kirby-ftp-backup
Kirby plugin that creates content backups and uploads them to a FTP server.
Fund package maintenance!
tearoom1
Buy Me A Coffee
Installs: 65
Dependents: 0
Suggesters: 0
Security: 0
Stars: 9
Watchers: 2
Forks: 0
Open Issues: 1
Type:kirby-plugin
pkg:composer/tearoom1/kirby-ftp-backup
Requires
- ext-ftp: *
- ext-zip: *
- getkirby/composer-installer: ^1.2
- phpseclib/phpseclib: ^3.0
Requires (Dev)
- getkirby/cms: ^4.0.0 || ^5.0.0
- phpunit/phpunit: ^10.0
This package is auto-updated.
Last update: 2025-11-05 21:33:33 UTC
README
A Kirby CMS plugin that creates backups of your site content and uploads them to an FTP server.
Features
- Create ZIP backups of your site content
- Automatic upload to FTP server
- Configurable backup retention
- Panel interface for manual backups and downloads
- Scheduled backups via cron job
Installation
Manual Installation
- Download or clone this repository
- Place the folder
kirby-ftp-backupin your site's/site/pluginsdirectory
Composer Installation
composer require tearoom1/kirby-ftp-backup
Configuration
All configuration is handled through Kirby's option system. Add the following to your site/config/config.php file:
'tearoom1.kirby-ftp-backup' => [ // Plugin Control 'enabled' => true, // Enable/disable the entire plugin 'ftpEnabled' => true, // Enable/disable FTP uploads (backups still created locally) // FTP Connection Settings 'ftpProtocol' => 'ftps', 'ftpHost' => 'your-ftp-host.com', 'ftpPort' => 21, 'ftpUsername' => 'your-username', 'ftpPassword' => 'your-password', 'ftpDirectory' => 'backups', 'ftpPassive' => true, 'ftpPrivateKey' => 'path/to/private/key.pem', 'ftpPassphrase' => 'your-passphrase', // Backup Settings 'backupDirectory' => 'content/.backups', // Local directory to store backups 'backupRetention' => 10, // Number of backups to keep when using simple retention strategy 'deleteFromFtp' => true, // Whether to delete old backups from FTP 'filePrefix' => 'backup-', // Prefix for backup filenames 'retentionStrategy' => 'simple', // Backup retention strategy: 'simple' or 'tiered' 'tieredRetention' => [ 'daily' => 10, // Keep all backups for the first 10 days 'weekly' => 4, // Then keep 1 per week for 4 weeks 'monthly' => 6 // Then keep 1 per month for 6 months ], // File Filtering (regex patterns without delimiters, case-insensitive) 'includePatterns' => [], // If not empty, only files matching these patterns are included 'excludePatterns' => [], // Files matching these patterns are always excluded ]
Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
enabled |
boolean | true |
Enable/disable the entire plugin |
ftpEnabled |
boolean | true |
Enable/disable FTP uploads (backups still created locally) |
ftpProtocol |
string | 'ftp' |
FTP protocol: 'ftp', 'ftps' or 'sftp' |
ftpHost |
string | '' |
FTP server hostname |
ftpPort |
integer | 21 |
FTP server port |
ftpUsername |
string | '' |
FTP username |
ftpPassword |
string | '' |
FTP password |
ftpDirectory |
string | '/' |
Remote directory to store backups |
ftpPassive |
boolean | true |
Use passive mode |
ftpPrivateKey |
string | '' |
Path to private key file |
ftpPassphrase |
string | '' |
Passphrase for private key |
backupDirectory |
string | 'content/.backups' |
Either absolute or relative (to Kirby base) path for local backups |
backupRetention |
integer | 10 |
Number of backups to keep when using simple retention strategy |
deleteFromFtp |
boolean | true |
Whether to delete old backups from FTP server |
filePrefix |
string | 'backup-' |
Prefix for backup filenames |
retentionStrategy |
string | 'simple' |
Backup retention strategy: 'simple' or 'tiered' |
tieredRetention |
array | see below | Settings for tiered retention strategy |
includePatterns |
array | [] |
Regex patterns (no delimiters, case-insensitive) - if not empty, only matching files are included |
excludePatterns |
array | [] |
Regex patterns (no delimiters, case-insensitive) - matching files are always excluded |
urlExecutionEnabled |
boolean | false |
Enable URL-based backup execution |
urlExecutionToken |
string | '' |
Security token required for URL-based backup execution |
Plugin Control Options
Disable Entire Plugin
To completely disable the plugin (no backups will be created):
'tearoom1.kirby-ftp-backup' => [ 'enabled' => false, ]
When disabled:
- Panel UI will not be accessible
- API routes will return error responses
- CLI commands will not execute
- URL-based execution will be blocked
Disable FTP Only
To create backups locally but skip FTP uploads:
'tearoom1.kirby-ftp-backup' => [ 'ftpEnabled' => false, ]
When FTP is disabled:
- Backups are still created and stored locally
- No FTP connection or upload attempts
- Local retention policies still apply
- Panel UI remains functional for viewing/downloading local backups
This is useful when:
- You want local backups only
- FTP server is temporarily unavailable
- Testing backup creation without uploading
- Migrating between FTP servers
Retention Strategies
The plugin supports two retention strategies for managing old backups:
Simple Retention
Keeps a fixed number of most recent backups, discarding older ones. This is controlled by the backupRetention option.
'backupRetention' => 10, // Keep 10 most recent backups
Tiered Retention
A more sophisticated approach that keeps backups with decreasing frequency as they age:
'retentionStrategy' => 'tiered', 'tieredRetention' => [ 'daily' => 10, // Keep all backups for the first 10 days 'weekly' => 4, // Then keep 1 per week for 4 weeks 'monthly' => 6 // Then keep 1 per month for 6 months ]
This strategy:
- Keeps all backups from the last X days
- Then keeps one backup per week for Y weeks
- Then keeps one backup per month for Z months
- Deletes anything older
This provides a good balance between recent recovery points and long-term archiving.
File Filtering
You can control which files are included in backups using regex patterns. This is useful for excluding large media files, temporary files, or other content you don't need to back up.
How it works
- Default behavior: All files are included
- Include patterns: If specified, only files matching these patterns are included
- Exclude patterns: Files matching these patterns are always excluded (applied after include patterns)
- Case-insensitive: All patterns are automatically case-insensitive
Examples
Exclude specific file types:
'excludePatterns' => [ '\.mp4$', // Exclude video files '\.zip$', // Exclude zip files '/cache/', // Exclude cache directory '\.tmp$', // Exclude temporary files ]
Include only specific file types:
'includePatterns' => [ '\.txt$', // Only text files '\.md$', // And markdown files ]
Exclude large media files but keep images:
'includePatterns' => [ '\.(jpg|jpeg|png|gif|svg)$', // Only image files '\.txt$', // And text files '\.md$', // And markdown files ], 'excludePatterns' => [ '/originals/', // Exclude originals folder ]
Complex filtering:
'includePatterns' => [ '\.(txt|md|json|yml)$', // Include text-based files ], 'excludePatterns' => [ '/\._', // Exclude macOS resource forks '/\.DS_Store$', // Exclude .DS_Store files '/thumbs\.db$', // Exclude Windows thumbnails ]
Note: Patterns are standard regex patterns without delimiters. The plugin automatically adds # delimiters and makes all patterns case-insensitive.
Panel Interface
The plugin adds a "FTP Backup" area to your Kirby Panel:
- View all available backups
- Create new backups manually
- Download existing backups
- View backup statistics (count, total size, latest backup)
Automatic Backups with Cron
To set up automatic backups, add a cron job to your server. The cron job should run the included run.php script:
php /path/to/site/plugins/kirby-ftp-backup/run.php
Optionally the path to the kirby root directory can be passed as the first argument:
php /path/to/site/plugins/kirby-ftp-backup/run.php /path/to/root
The root directory is the one with the kirby folder inside.
Example Crontab Entry
To run a backup every day at 2 AM:
0 2 * * * php /path/to/site/plugins/kirby-ftp-backup/run.php
Replace /path/to/site with the actual path to your Kirby installation.
Using the Run Script
The run.php script handles:
- Creating a new backup
- Uploading the backup to the configured FTP server
- Cleaning up old backups based on the retention setting
- Outputs logs to the console
URL-Based Backup Execution
As an alternative to cron jobs, you can trigger backups via HTTP requests. This is useful for:
- External monitoring services
- Webhook-based automation
- Manual triggering from remote systems
- URL based cronjob execution
Configuration
First, enable URL execution and set a secure token in your config.php:
'tearoom1.kirby-ftp-backup' => [ // ... other settings ... 'urlExecutionEnabled' => true, 'urlExecutionToken' => 'your-secure-random-token-here', ]
Usage
Once configured, you can trigger a backup by making a GET request to:
https://yoursite.com/ftp-backup/execute?token=your-secure-random-token-here
Security Features
- Token Authentication: Requires a matching token to execute
- Enable/Disable Toggle: Can be completely disabled via configuration
- Timing-Safe Comparison: Uses
hash_equals()to prevent timing attacks - Plain Text Response: Returns simple status messages for easy monitoring
Example Response
On success:
Backup created successfully: backup-2025-09-26-140236.zip
File uploaded to FTP server
On error:
Error creating backup: FTP connection failed
Security Considerations
- Store your FTP credentials securely in your
config.phpfile - Make sure your
config.phpfile is not accessible from the web - Consider using SFTP or FTP with SSL for secure transfers
- Regularly verify that your backups are being created and can be restored
Troubleshooting
If you encounter issues:
- Check that your FTP credentials and server settings are correct
- Verify that the FTP directory exists and has write permissions
- Check your server's PHP error logs for any PHP errors
- Make sure the local backup directory is writable by PHP
- Check if you have the required PHP extensions (zip, ftp)
Requirements
- Kirby 3.5+
- PHP 7.4+
- PHP ZIP extension
- PHP FTP extension
Tests
The tests can be run with:
composer update
composer test
Make sure to cleanup the vendor after running tests, to remove dev dependencies.
composer dist
License
This plugin is licensed under the MIT License
Credits
- Developed by Mathis Koblin
- Assisted by AI Claude 3.7 Sonnet
