PHPackages                             tearoom1/kirby-ftp-backup - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [File &amp; Storage](/categories/file-storage)
4. /
5. tearoom1/kirby-ftp-backup

ActiveKirby-plugin[File &amp; Storage](/categories/file-storage)

tearoom1/kirby-ftp-backup
=========================

Kirby plugin that creates content backups and uploads them to a FTP server.

1.6.1(3w ago)13144[2 issues](https://github.com/tearoom1/kirby-ftp-backup/issues)MITPHPCI passing

Since Jul 30Pushed 3w ago2 watchersCompare

[ Source](https://github.com/tearoom1/kirby-ftp-backup)[ Packagist](https://packagist.org/packages/tearoom1/kirby-ftp-backup)[ Docs](https://github.com/tearoom1/kirby-ftp-backup)[ Fund](https://www.buymeacoffee.com/tearoom1)[ GitHub Sponsors](https://github.com/tearoom1)[ RSS](/packages/tearoom1-kirby-ftp-backup/feed)WikiDiscussions main Synced today

READMEChangelog (10)Dependencies (16)Versions (52)Used By (0)

Kirby FTP Backup
================

[](#kirby-ftp-backup)

A Kirby CMS plugin that creates backups of your site content and uploads them to an FTP server.

[![Screenshot](screenshot.jpg)](https://github.com/tearoom1/kirby-content-watch)

---

Features
--------

[](#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
------------

[](#installation)

### Manual Installation

[](#manual-installation)

1. Download or clone this repository
2. Place the folder `kirby-ftp-backup` in your site's `/site/plugins` directory

### Composer Installation

[](#composer-installation)

```
composer require tearoom1/kirby-ftp-backup
```

Configuration
-------------

[](#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',
    'ftpTimeout' => 30,
    'ftpKeepAlive' => 0,

    // 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
    'excludePaths' => [],                    // Relative paths or fnmatch patterns to exclude
    'excludeContentWatch' => false,          // Exclude .content-watch.json history files
    'excludeDrafts' => false,                // Exclude Kirby _drafts folders
]
```

### Configuration Options

[](#configuration-options)

OptionTypeDefaultDescription`enabled`boolean`true`Enable/disable the entire plugin`allowedRoles`array`[]`Additional Kirby roles allowed to use the plugin. Admins always have access (see Access Control)`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`ftpTimeout`integer`30`Socket response timeout in seconds (see Advanced Options)`ftpKeepAlive`integer`0`SFTP only. SSH keepalive interval in seconds, `0` = disabled (see Advanced Options)`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`arraysee belowSettings 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`excludePaths`array`[]`Relative paths or fnmatch patterns to exclude before regex filtering`excludeContentWatch`boolean`false`Exclude `.content-watch.json` files from backups`excludeDrafts`boolean`false`Exclude all Kirby `_drafts` directories from backups`urlExecutionEnabled`boolean`false`Enable URL-based backup execution`urlExecutionToken`string`''`Security token required for URL-based backup execution### Plugin Control Options

[](#plugin-control-options)

#### Disable Entire Plugin

[](#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

#### Access Control

[](#access-control)

By default, **only users with the `admin` role** can access the plugin — that includes the panel area, the menu entry, the stats view, listing/creating/cancelling backups, and downloading backup files. Non-admins will not see the menu item at all, and any direct API call returns `403 Forbidden`.

If you want to grant access to additional Kirby roles (for example, an `editor` or a dedicated `backup-operator` role), list them in `allowedRoles`:

```
'tearoom1.kirby-ftp-backup' => [
    'allowedRoles' => ['editor', 'backup-operator'],
]
```

Notes:

- Admins are **always** allowed; you do not need to include `'admin'` in the list.
- Users with any of the listed roles get **full** access — there is no read-only mode. They can create backups, download archives (which contain your entire site), and cancel running jobs. Only grant this to roles you fully trust.
- The `allowedRoles` option does **not** apply to the URL-based `/ftp-backup/execute` endpoint — that endpoint is protected by its own token and is intended for unauthenticated cron-style use (see [URL-Based Backup Execution](#url-based-backup-execution)).

#### Disable FTP Only

[](#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

[](#retention-strategies)

The plugin supports two retention strategies for managing old backups:

#### Simple Retention

[](#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

[](#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:

1. Keeps all backups from the last X days
2. Then keeps one backup per week for Y weeks
3. Then keeps one backup per month for Z months
4. Deletes anything older

This provides a good balance between recent recovery points and long-term archiving.

### File Filtering

[](#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

[](#how-it-works)

1. **Default behavior**: All files are included
2. **Include patterns**: If specified, only files matching these patterns are included
3. **Dedicated excludes**: `excludeContentWatch`, `excludeDrafts` and `excludePaths` are applied before regex patterns
4. **Exclude patterns**: Files matching these patterns are always excluded
5. **Case-insensitive**: Regex patterns are automatically case-insensitive

#### Examples

[](#examples)

**Exclude specific file types:**

```
'excludePatterns' => [
    '\.mp4$',           // Exclude video files
    '\.zip$',           // Exclude zip files
    '/cache/',          // Exclude cache directory
    '\.tmp$',           // Exclude temporary files
]
```

**Exclude Content Watch history and drafts:**

```
'excludeContentWatch' => true,
'excludeDrafts' => true,
```

**Exclude specific relative paths:**

```
'excludePaths' => [
    '.backups',
    'private',
    '*/_versions/*',
]
```

**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
---------------

[](#panel-interface)

The plugin adds a "FTP Backup" area to your Kirby Panel:

- View all available backups
- Create new backups manually with live progress indication
- Cancel a running backup
- Download existing backups
- View backup statistics (count, total size, latest backup)
- View FTP server stats and file listing

Automatic Backups with Cron
---------------------------

[](#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

[](#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

[](#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
--------------------------

[](#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

[](#configuration-1)

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',
]
```

> **⚠️ Security: the token is the only thing protecting this endpoint.**The `/ftp-backup/execute` URL is publicly reachable whenever `urlExecutionEnabled` is `true` — it is not behind the panel login, only behind the token. The plugin does **not** rate-limit failed attempts, so a weak token can be brute-forced.
>
> **You must:**
>
> - Generate a long, high-entropy token (at least 32 random characters), e.g. `openssl rand -hex 32` or `php -r "echo bin2hex(random_bytes(32));"`. Never use a guessable string.
> - Treat the token like a password: do not commit it to public repos, do not share it in chats, rotate it if exposed.
> - Prefer HTTPS so the token is not sent in the clear.
> - For defense in depth, add rate limiting / IP allow-listing at the web server level (e.g. `fail2ban`, nginx `limit_req`, Cloudflare rules). The plugin itself does not throttle requests.
> - If you don't need URL execution, leave `urlExecutionEnabled` set to `false`.

### Usage

[](#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

[](#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

**Not provided by the plugin:** rate limiting on the `execute` endpoint. Token strength and any throttling are entirely your responsibility — see the warning above.

### Example Response

[](#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

```

Advanced Options
----------------

[](#advanced-options)

### `ftpTimeout`

[](#ftptimeout)

How long to wait for the server to respond to each individual packet, in seconds. This is **not** a total transfer timeout — large files will transfer for as long as needed as long as the connection stays active. The default of `30` seconds is appropriate for most servers. Increase it only if uploads fail on very slow or high-latency connections.

### `ftpKeepAlive` (SFTP only)

[](#ftpkeepalive-sftp-only)

Sends an SSH keepalive packet every N seconds to prevent firewalls or load balancers from dropping idle connections during large uploads. Disabled by default (`0`).

> **Note:** Some OpenSSH servers respond to keepalives with a `hostkeys-00@openssh.com` global request that phpseclib cannot handle mid-transfer, which can interrupt the upload. Only enable this if you have confirmed that idle-timeout drops are the cause of your upload failures.

Security Considerations
-----------------------

[](#security-considerations)

- Store your FTP credentials securely in your `config.php` file
- Make sure your `config.php` file 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
---------------

[](#troubleshooting)

If you encounter issues:

1. Check that your FTP credentials and server settings are correct
2. Verify that the FTP directory exists and has write permissions
3. Check your server's PHP error logs for any PHP errors
4. Make sure the local backup directory is writable by PHP
5. Check if you have the required PHP extensions (zip, ftp)
6. If uploads fail on slow or high-latency connections, increase `ftpTimeout` — see Advanced Options
7. If you get a 504 Gateway Timeout when creating backups from the Panel, increase your web server's proxy/fastcgi read timeout to match or exceed `max_execution_time` in your `php.ini`

Requirements
------------

[](#requirements)

- Kirby 4+
- PHP 7.4+
- PHP ZIP extension
- PHP FTP extension

Tests
-----

[](#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
-------

[](#license)

This plugin is licensed under the [MIT License](LICENSE)

Credits
-------

[](#credits)

- Developed by Mathis Koblin
- Assisted by AI Claude Sonnet 4.6

[!["Buy Me A Coffee"](https://camo.githubusercontent.com/9f44ce2dc3b3eecdd02598900866ffc518801df1932849703dae1e5ce5031070/68747470733a2f2f7777772e6275796d6561636f666665652e636f6d2f6173736574732f696d672f637573746f6d5f696d616765732f6f72616e67655f696d672e706e67)](https://coff.ee/tearoom1)

###  Health Score

45

—

FairBetter than 91% of packages

Maintenance92

Actively maintained with recent releases

Popularity18

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity50

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~6 days

Total

51

Last Release

24d ago

Major Versions

0.5.4 → 1.0.02025-08-06

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/188788687?v=4)[Tearoom One](/maintainers/tearoom1)[@tearoom1](https://github.com/tearoom1)

---

Top Contributors

[![morja](https://avatars.githubusercontent.com/u/29610198?v=4)](https://github.com/morja "morja (183 commits)")

---

Tags

backupftpftpskirbykirby-cmskirby-pluginkirby4kirby5sftpftpbackupkirbypanel

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/tearoom1-kirby-ftp-backup/health.svg)

```
[![Health](https://phpackages.com/badges/tearoom1-kirby-ftp-backup/health.svg)](https://phpackages.com/packages/tearoom1-kirby-ftp-backup)
```

###  Alternatives

[league/flysystem

File storage abstraction for PHP

13.6k679.9M2.5k](/packages/league-flysystem)[getkirby/cms

The Kirby core

1.5k584.8k474](/packages/getkirby-cms)[bnomei/kirby3-janitor

Kirby Plugin for running commands like cleaning the cache from within the Panel, PHP code or a cronjob

9342.8k2](/packages/bnomei-kirby3-janitor)[league/flysystem-ftp

FTP filesystem adapter for Flysystem.

2823.7M148](/packages/league-flysystem-ftp)[bnomei/kirby-janitor

Kirby Plugin for running commands like cleaning the cache from within the Panel, PHP code or a cronjob

935.5k2](/packages/bnomei-kirby-janitor)[medienbaecker/kirby-modules

Easily add modules to your pages

895.5k1](/packages/medienbaecker-kirby-modules)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
