Copyright © 2014, 2015 Sebastian Feldmann
2020.11.06
PHPBU 6.0 requires PHP 7.2, but using the latest version of PHP is highly recommended.
PHPBU requires the dom and json extensions, which are normally enabled by default.
The different backup sources may need their respective executable binary e.g. mysqldump
.
The easiest way to install PHPBU is to download a PHP Archive (PHAR) that has all the required dependencies of PHPBU bundled in a single file.
If the Suhosin extension is
enabled, you need to allow execution of PHARs in your
php.ini
:
suhosin.executor.include.whitelist = phar
To globally install the PHAR:
$
wget http://phar.phpbu.de/phpbu.phar
$
chmod +x phpbu.phar
$
sudo mv phpbu.phar /usr/local/bin/phpbu
$
phpbu --version
phpbu x.y.z by Sebastian Feldmann and Contributors.
You may also use the downloaded PHAR file directly:
$
wget https://phar.phpbu.de/phpbu.phar
$
php phpbu.phar --version
phpbu x.y.z by Sebastian Feldmann and Contributors.
If you are using Composer to manage
your dependencies, simply add phpbu/phpbu
to your
composer.json
file.
{ "require": { "phpbu/phpbu": "^6.0" } }
For a system-wide installation via Composer, just run:
composer global require phpbu/phpbu
Make sure you have ~/.composer/vendor/bin/
in your path.
The following framework integrations are available:
phpbu-laravel
Integrates phpbu with the laravel artisan command line tool. See the section called “Laravel” for details.
To use PHPBU and create your backups you first have to create a configuration file.
The configuration of PHPBU is done with a simple XML file. You can validate your config files with the respective PHPBU schema definition found at schema.phpbu.de.
You should name your configuration file phpbu.xml
or phpbu.xml.dist
so you don't have to specify the path with the --configuration
option.
The following skeleton is a good point to start and get into detail from here.
Example 2.1: XML-Configuration
<?xml version="1.0" encoding="UTF-8"?> <phpbu xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://schema.phpbu.de/6.0/phpbu.xsd"> <backups> <backup name="MyDatabase"> <!-- backup source --> <source type="mysqldump"> <option name="databases" value="mydbname"/> <option name="user" value="user.name"/> <option name="password" value="topsecret"/> </source> <!-- where should the backup be stored --> <target dirname="backup/mysql" filename="mysqldump-%Y%m%d-%H%i.sql" compress="bzip2"/> <!-- check the created backup --> <check type="SizeMin" value="10M"/> <!-- cleanup the backup location as soon as all created backups exceed 500MB remove oldest backups --> <cleanup type="Capacity"> <option name="size" value="500M"/> </cleanup> </backup> </backups> </phpbu>
The XML root element with at least xmlns:xsi and xsi:noNamespaceSchemaLocation.
Table 2.1. <phpbu> attributes
Name | Values | Required | Default | Description |
---|---|---|---|---|
bootstrap | filename | no | null | Include a PHP file to extend PHPBU |
verbose | true | false | no | false | Controls the output verbosity |
debug | true | false | no | false | Controls the debug output |
Configures a backup process. You can have as many of these as you need.
Table 2.2. <backup> attributes
Name | Values | Required | Default | Description |
---|---|---|---|---|
name | string | yes | null | A custom name for your backup used in the PHPBU output. |
stopOnError | true | false | no | false | Indicates if the execution of PHPBU should be stopped if this backup fails. |
Defines the data that is backed up.
Table 2.3. <source> attributes
Name | Values | Required | Default | Description |
---|---|---|---|---|
type | string | yes | - | Type of backup, Chapter 5 has a list of all supported source types. |
Defines where the backup is stored.
Table 2.4. <target> attributes
Name | Values | Required | Default | Description |
---|---|---|---|---|
dirname | string | yes | - | Path to the directory where the backup is stored, absolute or relative to the config file. |
filename | string | yes | - | Filename of the stored backup. |
compress | string | no | null | Type of compressor to use to compress the backup. |
Specifies what kind of tests should be performed to validate the backup.
Table 2.5. <check> attributes
Name | Values | Required | Default | Description |
---|---|---|---|---|
type | string | yes | - | Type of check, Chapter 6 has a list of all supported check types. |
value | string | yes | - | Value the backup is getting checked against. |
Specifies what type of encryption should be used to encrypt the backup.
Table 2.6. <crypt> attributes
Name | Values | Required | Default | Description |
---|---|---|---|---|
type | string | yes | - | Type of encryption, Chapter 7 has a list of all supported crypt types. |
skipOnFailure | true | false | no | false | You can still execute the encryption, even if failure(s) occurred. |
Copy the created backup to another location.
Table 2.7. <sync> attributes
Name | Values | Required | Default | Description |
---|---|---|---|---|
type | string | yes | - | Type of sync, Chapter 8 has a list of all supported sync types. |
skipOnFailure | true | false | no | false | You can still execute the sync, even if failure(s) occurred. |
Tells phpbu which files to delete after a successful backup.
Table 2.8. <cleanup> attributes
Name | Values | Required | Default | Description |
---|---|---|---|---|
type | string | yes | - | Type of cleanup, Chapter 9 has a list of all supported cleanup types. |
skipOnFailure | true | false | no | - | You can still execute the cleanup, even if failure(s) occurred. |
This is roughly the same skeleton as shown above at the XML-Section.
Example 2.2: JSON-Configuration
{ "verbose": true, "logging": [ { "type": "json", "target": "backup/json.log" } ], "backups": [ { "name": "MyDatabase", "source": { "type": "mysqldump", "options": { "databases": "mydbname", "user": "user.name", "password": "topsecret" } }, "target": { "dirname": "backup", "filename": "mysql-%Y%m%d-%H%i.sql", "compress": "bzip2" }, "checks": [ { "type": "sizemin", "value": "10M" } ], "syncs": [ { "type": "sftp", "options": { "host": "backup.example.com", "user": "user.name", "password": "topsecret", "path": "backup/someName" } } ], "cleanup": { "type": "Capacity", "options": { "size": "200M" } } } ] }
Adapters are used to include configuration settings from other configuration sources.
So with adapters you don't have to put your passwords into your PHPBU configuration file. Instead you can use environment variables or .env configuration files.
And this is how it works:
You add an adapter to your phpbu configuration like shown in the examples below.
You have to choose a type
and a name
. The name is completely up to you, but you are not allowed
to use colons.
With this done you can now reference your configured adapter for any option value in your PHPBU configuration like this.
:adapter:my-chosen-adapter-name:path.to.value:
The keyword adapter
tells PHPBU that this option value should be received from an adapter,
followed by a colon
, followed by your chosen adapter name
so PHPBU knows which adapter to use,
followed by a colon
, followed by the identifier for your value.
The identifier could be the name of a environment variable or a "path" through an configuration array like this
"db.mysql.username" completely depending on the adapter implementation.
You can use adapter values for whole configuration values, in that case you can skip the leading and trailing colons. If you want to use multiple adapter values in a single configuration value you have to use the leading and trailing colons.
Example 2.3: Adapter examples
<option name="singleValue" value="adapter:myAdp:foo"/> <option name="multipleValues" value="/foo/:adapter:myAdp:dir:/bar/:adapter:myAdp:file:.zip"/>
{"singleValue": "adapter:myAdp:foo"} {"multipleValues": "/foo/:adapter:myAdp:dir:/bar/:adapter:myAdp:file:.zip"}
For a list of available adapters and detailed documentation check out the adapter section.
Example 2.4: XML-Configuration
<?xml version="1.0" encoding="UTF-8"?> <phpbu xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://schema.phpbu.de/6.0/phpbu.xsd"> <adapters> <adapter type="dotenv" name="environment"> <option name="file" value=".env" /> </adapter> <adapters> <backups> <backup> <!-- backup source --> <source type="mysqldump"> <option name="databases" value="mydbname"/> <option name="user" value="adapter:environment:DB_USER"/> <option name="password" value="adapter:environment:DB_PASSWORD"/> </source> <!-- where should the backup be stored --> <target dirname="backup/mysql" filename="mysqldump-%Y%m%d-%H%i.sql"/> </backup> </backups> </phpbu>
Example 2.5: JSON-Configuration
{ "verbose": true, "adapters": [ { "type": "dotenv", "name": "environment", "options": { "file": ".env" } } ], "backups": [ { "source": { "type": "mysqldump", "options": { "databases": "mydbname", "user": "adapter:environment:DB_USER", "password": "adapter:environment:DB_PASSWORD" } }, "target": { "dirname": "backup", "filename": "mysql-%Y%m%d-%H%i.sql" } } ] }
Scheduling your backups is not part of PHPBU. Nevertheless here is an example how to do it with Cron. Adding one of the following lines to your crontab will execute your backup every morning at 3:10 AM.
Example 2.6: Crontab example
# +------------------------- min (0 - 59) # | +-------------------- hour (0 - 23) # | | +--------------- day of month (1 - 31) # | | | +---------- month (1 - 12) # | | | | +----- day of week (0 - 7) (Sunday=0 or 7) # | | | | | # * * * * * # this requires phpbu to be in the cron users path 10 3 * * * phpbu --configuration=/var/www/my-backup/phpbu.xml # alternatively you can specify the full path #10 3 * * * /home/user/bin/phpbu.phar --configuration=/var/www/my-backup/phpbu.xml # some systems require the full path to the PHP CLI binary #10 3 * * * /etc/php/sbin/php /home/user/bin/phpbu.phar --configuration=/var/www/my-backup/phpbu.xml
For a basic understanding why adapters are useful, have a look at the configuration documentation.
You can build your own configuration adapter. Want to know how? Have a look at the extending PHPBU section
Adapter to use .env files to load environment variables.
Example 3.3: Adapter definition
<adapter type="dotenv" name="myName"> <option name="file" value="my-dot-env-dir/.env" /> </adapter>
Adapter to use PHP array config files.
Example 3.6: Adapter definition
<adapter type="array" name="myName"> <option name="file" value="my-config-dir/config.php" /> </adapter>
Adapter to use PHP constant config files.
Example 3.9: Adapter definition
<adapter type="constant" name="myName"> <option name="file" value="my-config-dir/config.php" /> </adapter>
If you have a configuration file named phpbu.xml
in your current working directory you can execute PHPBU like this
~$ phpbu
phpbu 6.0.0 by Sebastian Feldmann and Contributors.
OK (1 backup, 0 checks, 0 encryption, 0 syncs, 0 cleanups)
If you want to use a custom name for your configuration file you have to use the --configuration
option.
~$ phpbu --configuration=MyConfig.xml
phpbu 6.0.0 by Sebastian Feldmann and Contributors.
OK (1 backup, 0 checks, 0 encryption, 0 syncs, 0 cleanups)
Here is the list of available options for the command line runner.
$ phpbu --help
phpbu 6.0.0 by Sebastian Feldmann and Contributors.
Usage: phpbu [option]
--bootstrap=<file> A "bootstrap" PHP file that is included before the backup.
--configuration=<file> A PHPBU configuration file.
--colors Use colors in output.
--debug Display debugging information during backup generation.
--generate-configuration Create a new configuration skeleton.
--limit=<subset> Limit backup execution to a subset.
--simulate Perform a simulation run with no changes made.
-h, --help Print this usage information.
-v, --verbose Output more verbose information.
-V, --version Output version information and exit.
--version-check Check whether PHPBU is up to date.
--self-update Upgrade PHPBU to the latest version.
--bootstrap
A "bootstrap" PHP file that is included before executing the backup.
--configuration
Path to the phpbu config file to use. See Chapter 2 for more details.
--colors
Use colors in output.
--debug
Display debugging information during backup generation.
--limit
Limit backup execution to a subset. See the limit section for details.
--restore
Output a guide how to restore your backup.
For this to work all your Sources
and Crypts
have to implement the Restorable
interface
--simulate
Execute PHPBU without actually executing any backup, check, encryption, sync or cleanup task. See the simulation section for details.
In order to check what actions PHPBU would perform, PHPBU supports a simulation mode where no backup is actually created and no sync and cleanup tasks are executed. In simulation mode, PHPBU will show you, what it would have done, if it would not have been a simulation run. You will get detailed output, which enables you to track every action PHPBU would have performed.
This is a great way to test if the correct backup commands will be executed and if all the right backups will be cleaned up.
If PHPBU has to use any kind of credentials executing a binary, like for example the
mysqldump
command, these credentials will be displayed in the simulation output.
If you are extending PHPBU, you can support simulation as well. You can find detailed information on this in Chapter 11.
If you don't want to execute all of your configured backups you can define a subset of backups by using the limit option.
All you have to to, is to set the limit option to a comma separated list of backup names (nameA,nameB,nameC).
If you don't define explicit backup names, PHPBU will use the source type as backup name as fallback.
You can configure multiple backups in one configuration file.
Each backup is represented by a <backup>
Tag.
To configure the data that is stored use the <source>
Tag.
Table 5.1. Supported types of backup sources:
Type | Description |
---|---|
arangodump | Backup ArangoDB with the arangodump command line tool. |
elasticdump | Backup Elasticsearch with the elasticdump command line tool. |
influxdump | Backup Influxdb with the influxd command line tool. |
ldapdump | Backup LDAP data with the ldapdump command line tool. |
mongodump | Backup MongoDB with the mongodump command line tool. |
mysqldump | Backup MySQL with the mysqldump command line tool. |
pgdump | Backup PostgreSQL with the pg_dump command line tool. |
redis | Backup redis with the redis-cli command line tool. |
rsync | Collect files via the rsync command line tool. |
tar | Backup a directory with the tar command line tool. |
xtrabackup | Backup MySQL with the Percona xtrabackup command line tool. |
Backup a ArangoDB database with arangodump.
Table 5.2. arangodump-Options
Name | Value | Required | Default | Description |
---|---|---|---|---|
endpoint | string | no | tcp://localhost:8529 | URI to your ArangoDB endpoint. |
username | string | no | null | Username for the ArangoDB authentication. |
password | string | no | null | Password for the ArangoDB authentication. |
disableAuthentication | boolean | no | false | Disable the ArangoDB authentication. |
database | string | no | _system | Database to backup. |
dumpData | boolean | no | true | Dump database data. |
includeSystemCollections | boolean | no | false | Dump system collections as well. |
collections | string | no | all | List of collections to dump. |
pathToArangoDump | string | no | Custom arangodump executable location. |
Example 5.1: arangodump XML example
<!-- source arangodump --> <source type="arangodump"> <option name="database" value="myDatabase" /> <option name="dumpData" value="true" /> <option name="collections" value="myCollection1,myCollection2" /> </source>
Example 5.2: arangodump JSON example
{ "type": "arangodump", "options": { "database": "myDatabase", "dumpData": "true", "collections": "myCollection1,myCollection2" } }
Backup a Elastic index with elasticdump.
Table 5.3. arangodump-Options
Name | Value | Required | Default | Description |
---|---|---|---|---|
host | string | no | localhost:9200 | URI to your Elastic host. |
user | string | no | null | Username for the Elastic authentication. |
password | string | no | null | Password for the Elastic authentication. |
index | string | no | all | Index name to backup. |
type | string | data | true | Elastic type to dump. |
pathToElasticDump | string | no | Custom elasticdump executable location. |
Example 5.3: elasticdump XML example
<!-- source elasticdump --> <source type="elasticdump"> <option name="index" value="myIndex" /> </source>
Backup an InfluxDB database with influxdump.
Table 5.4. influxdump-Options
Name | Value | Required | Default | Description |
---|---|---|---|---|
host | string | no | localhost:8088 | Hostname and port of your InfluxDB-Server. |
database | string | no | all | Name of database you want to backup, all by default. |
pathToInfluxdump | string | no | Custom influxdump executable location. |
Example 5.5: influxdump XML example
<!-- source influxdump --> <source type="influxdump"> <option name="host" value="localhost:8088"/> <option name="database" value="myDatabase"/> </source>
Example 5.6: influxdump JSON example
{ "type": "influxdump", "options": { "host": "localhost:8088", "database": "myDatabase" } }
Backup you LDAP data with ldapdump.
Table 5.5. ldapdump-Options
Name | Value | Required | Default | Description |
---|---|---|---|---|
host | string | no | localhost | Hostname of you LDAP server. |
port | int | no | all | Port to connect to your LDAP server. |
searchBase | string | no | LDAP search base. | |
filter | string | no | LDAP search filter. | |
attrs | string | no | LDAP search attributes. | |
pathToLdapdump | string | no | Custom path to ldapdump binary. |
Example 5.7: influxdump XML example
<!-- source ldapdump --> <source type="ldapdump"> <option name="host" value="localhost"/> <option name="searchBase" value="ou=Users,dc=fr"/> </source>
Example 5.8: influxdump JSON example
{ "type": "ldapdump", "options": { "host": "localhost", "searchBase": "ou=Users,dc=fr" } }
Backup a MongoDB database with mongodump.
Table 5.6. mongodump-Options
Name | Value | Required | Default | Description |
---|---|---|---|---|
host | string | no | localhost | Hostname of your MongoDB-Server. |
user | string | no | OS-User | Username for the MongoDB authentication. |
password | string | no | null | Password for the MongoDB authentication. |
authenticationDatabase | string | no | null | MongoDB database that holds the user credentials. |
databases | string | no | all | List of databases you want to backup, all by default. |
excludeCollections | string | no | null | List of collections you don't want to backup. |
excludeCollectionsWithPrefix | string | no | null | List of collection prefixes to exclude matching collections from backup. |
pathToMongodump | string | no | Custom mongodump executable location. |
Example 5.9: mongodump XML example
<!-- source mongodump --> <source type="mongodump"> <option name="databases" value="myDatabase"/> <option name="user" value="user.name"/> <option name="password" value="topsecret"/> <option name="excludeCollections" value="collectionFoo,collectionBar"/> </source>
Example 5.10: mongodump JSON example
{ "type": "mongodump", "options": { "databases": "myDatabase", "user": "user.name", "password": "topsecret", "excludeCollections": "collectionFoo,collectionBar" } }
Backup a MySQL database with mysqldump.
Table 5.7. mysqldump-Options
Name | Value | Required | Default | Description |
---|---|---|---|---|
host | string | no | localhost | Hostname of your MySQL-Server. |
port | integer | no | null | Port of your MySQL-Server. |
user | string | no | OS-User | Username for the MySQL authentication. |
password | string | no | null | Password for the MySQL authentication. |
databases | string | no | all | List of databases you want to backup, all by default. |
ignoreTables | string | no | null | List of tables you don't want to backup. |
filePerTable | true | false | no | false | Create directory with separate files for each table. |
structureOnly | string | no | null | List of tables where only the table structure will be stored. Can not be used with filePerTable |
hexBlob | true | false | no | false | Use the --hex-blob option to dump blob fields in hex. |
lockTables | true | false | no | null | Use the --lock-tables option to lock tables during the dump. |
singleTransaction | true | false | no | null | Use the --single-transaction option to add BEGIN SQL statement before dumping data from server. |
sslCa | string | no | Path to your ssl-ca file. | |
skipExtendedInsert | true | false | no | false | Do not use multiple-row INSERT syntax. |
skipTriggers | true | false | no | false | Do not execute triggers during backup. |
pathToMysqldump | string | no | Custom mysqldump executable location. |
Example 5.11: mysqldump XML example
<!-- source mysqldump --> <source type="mysqldump"> <option name="databases" value="myDatabase"/> <option name="user" value="user.name"/> <option name="password" value="topsecret"/> <option name="ignoreTable" value="tableFoo,tableBar"/> <option name="structureOnly" value="logTable1,logTable2"/> </source>
Example 5.12: mysqldump JSON example
{ "type": "mysqldump", "options": { "databases": "myDatabase", "user": "user.name", "password": "topsecret", "ignoreTable": "tableFoo,tableBar", "structureOnly": "logTable1,logTable2" } }
Backup a MySQL database with Percona xtrabackup.
Table 5.8. xtrabackup-options
Name | Value | Required | Default | Description |
---|---|---|---|---|
dataDir | string | no | MySQL data directory. | |
host | string | no | localhost | Host to connect to. |
user | string | no | OS-User | User to connect with. |
password | string | no | false | Password to authenticate the user. |
databases | string | no | - | List of databases to backup, all by default. |
include | string | no | - | Pattern to include databases and tables to the backup e.g. ^mydatabase[.]mytable . |
pathToXtraBackup | string | no | Custom xtrabackup executable location. |
Example 5.13: xtrabackup XML example
<!-- source xtrabackup --> <source type="xtrabackup"> <option name="databases" value="myDB1,myDB2" /> </source>
Example 5.14: xtrabackup JSON example
{ "type": "xtrabackup", "options": { "databases": "myDB1,myDB2" } }
Backup PostgreSQL databases using the pg_dump command line tool.
Table 5.9. pgdump-Options
Name | Value | Required | Default | Description |
---|---|---|---|---|
host | string | no | - | Host to connect to. |
port | integer | no | - | Port to use to connect to the PostgreSQL server. |
user | string | no | - | User to use to connect. |
password | string | no | - | Password to use to authenticate. |
database | string | yes | - | Database to backup. |
schemaOnly | bool | no | false | Dump only schema information. |
dataOnly | string | no | false | Dump no schema information. |
schemas | string | no | - | List of schemas to dump, separated by comma. |
excludeSchemas | string | no | - | List of schemas to exclude, separated by comma. |
tables | string | no | - | List of tables to backup, separated by comma. |
excludeTables | string | no | - | List of tables to exclude, separated by comma. |
excludeTableData | string | no | - | List of tables where data is not dumped, separated by comma. |
noPermissions | bool | no | false | Don't dump any permission schemas. |
noOwner | bool | no | false | Don't dump any owner changing statements. |
format | string | no | plain | Dump format, plain, custom, directory. |
encoding | string | no | - | Set the dump encoding. |
pathToPgdump | string | no | Custom pgdump executable location. |
Example 5.15: pgdump XML example
<!-- source pgdump --> <source type="pgdump"> <option name="database" value="myDstabase"/> <option name="user" value="myName"/> <option name="password" value="topSecret"/> </source>
Example 5.16: pgdump JSON example
{ "type": "pgdump", "options": { "database": "myDatabase", "user": "myName", "password": "topSecret", } }
Backup Redis data structure store using redis-cli.
Table 5.10. redis-Options
Name | Value | Required | Default | Description |
---|---|---|---|---|
pathToRedisData | string | yes | - | Path to the Redis data .rdb file. |
port | integer | no | 6379 | Port to use to connect to the redis server. |
password | string | no | - | Password to use to authenticate. |
pathToRedisCli | string | no | Custom redis-cli executable location. |
Example 5.17: redis XML example
<!-- source redis --> <source type="redis"> <option name="pathToRedisData" value="/var/lib/redis/6379/dump.rdb"/> </source>
Example 5.18: redis JSON example
{ "type": "redis", "options": { "pathToRedisData": "/var/lib/redis/6379/dump.rdb" } }
Backup files via the rsync command line tool.
Table 5.11. rsync-Options
Name | Value | Required | Default | Description |
---|---|---|---|---|
path | string | yes | - | Path to file/directory to sync. |
host | string | no | - | Host to connecto to. |
user | string | no | - | User to use to authenticate. |
delete | string | no | false | Remove deleted files locally as well. |
isDirSync | string | no | false | Keep the directory instead of archiving it at every PHPBU execution. |
pathToRsync | string | no | Custom rsync executable location. |
Example 5.19: rsync XML example
<!-- source rsync --> <source type="rsync"> <option name="path" value="/tmp/foo"/> </source>
Backup directories using tar.
Table 5.12. tar-Options
Name | Value | Required | Default | Description |
---|---|---|---|---|
path | string | yes | - | Path to the source directory. |
exclude | string | no | - | Comma separated list of paths to exclude. |
ignoreFailedRead | boolean | no | false | Ignore changing source directory. |
incrementalFile | string | no | - | Incremental cache file. |
forceLevelZeroOn | string | no | - | Force a level zero backup at specific times. |
compressProgram | string | no | - | Set custom compression program f.e. lbzip2. |
removeSourceDir | boolean | no | false | Remove the directory after compression. |
throttle | string | no | - | Throttle IO throughput via 'pv' (Linux/Unix only). |
pathToTar | string | no | Custom tar executable location. |
Example 5.21: tar XML example
<!-- source tar --> <source type="tar"> <option name="path" value="htdocs/uploads"/> </source>
Doing incremental backups with tar is also supported.
To activate incremental backups you have to specify a cache file where tar can store state information.
Tar will then only do incremental backups unless told otherwise. You can force full
backups (level zero backups) by removing the cache file manually or by using the
forceLevelZeroOn option. In the following example incremental backups are activated by
storing the backup state in a metadata.snar file and phpbu
will
force a level zero backup every Sunday and Wednesday. The backups on Monday, Tuesday, Thursday, Friday and
Saturday will only contain the changes to the day before. To for example restore a Saturday backup
you will need the backups from Wednesday, Thursday, Friday and Saturday.
Please configure your cleanup strategies accordingly to not use any data.
Example 5.23: tar XML example
<!-- source tar --> <source type="tar"> <option name="path" value="htdocs/uploads"/> <option name="incrementalFile" value="path/to/metadata.snar" /> <option name="forceLevelZeroOn" value="%D@Sun|Wed" /> </source>
date mask
@ value
[|value
]
%D
@ Sun|Web
- Level zero backups on Sunday, and Wednesday
%H
@ 3|15
- Level zero backups at 3am, and 15pm
If you want to exclude some files or directories from the created tar file.
Example 5.24: tar XML example
<!-- source tar --> <source type="tar"> <option name="path" value="htdocs/uploads"/> <option name="exclude" value="folderA,fileA.txt,folderB"/> </source>
Example 5.25: tar JSON example
{ "type": "tar", "options": { "path": "htdocs/uploads", "exclude": "folderA,fileA.txt,folderB" } }
If you are experiencing high CPU load during your backups with tar you can throttle the IO to reduce CPU load.
Example 5.26: Throttling XML example
<!-- source tar --> <source type="tar"> <option name="path" value="htdocs/uploads"/> <option name="throttle" value="5m"/> </source>
With a configuration like in the example above you make sure that you only write 5 Megabytes each second. This way your backup may take longer, but your CPU is able to handle other stuff as well.
This is done via the CLI tool pv. To use this feature you must have pv installed on your server. If you are using PHPBU on Windows, this feature is not available.
For more information on pv have a look here
You can validate your backup after creation with some simple checks.
Table 6.1. Available checks:
Type | Description |
---|---|
SizeMin | Checks if your backup is at least as big as the configured size. |
SizeDiffPreviousPercent | Checks if your backup differs more than a configured value from the previous backup. |
PHPBU can encrypt your backup using openssl
or mcrypt
.
If the choice is yours, I strongly recommend using openssl. Here is a good article explaining why.
Table 7.1. Available crypts:
Type | Description |
---|---|
mcrypt | Encrypts your backup with the mcrypt command line tool. |
openssl | Encrypts your backup with the openssl command line tool. |
Table 7.2. mcrypt options
Name | Value | Required | Default | Description |
---|---|---|---|---|
algorithm | string | yes | - | Algorithm to use to encrypt the backup. |
key | string | yes | - | Secret key to use for encryption. |
Example 7.1: mcrypt XML example
<!-- encryption --> <crypt type="mcrypt"> <option name="algorithm" value="blowfish"/> <option name="key" value="mySecretKey"/> </crypt>
Example 7.2: mcrypt JSON example
{ "type": "mcrypt", "options": { "algorithm": "blowfish", "key": "mySecretKey" } }
Please be sure to use only password
or certFile
.
Table 7.3. openssl options
Name | Value | Required | Default | Description |
---|---|---|---|---|
password | string | yes | - | Encrypt backup with 'openssl enc -pass...'. |
certFile | string | yes | - | Encrypt backup with 'openssl smime ... myCert.pem'. |
algorithm | string | yes | - |
Algorithm to use to encrypt the backup.
Attention you have to specify different algorithm names
for using password and using a cert file .
|
keepUncrypted | boolean | no | false | Don't remove the unencrypted backup. |
pathToOpenSSL | string | no | - | Used to specify a special path to the openssl command. |
Example 7.3: openssl XML example using password encryption
<!-- encryption --> <crypt type="openssl"> <option name="password" value="mySecretPassword"/> <option name="algorithm" value="aes-256-cbc"/> </crypt>
Example 7.4: openssl JSON example using password encryption
{ "type": "openssl", "options": { "password": "mySecretPassword", "algorithm": "aes-256-cbc" } }
Example 7.5: openssl XML example using SSL cert encryption
<!-- encryption --> <crypt type="openssl"> <option name="certFile" value="ssl/MyCert.pem"/> <option name="algorithm" value="aes256"/> </crypt>
Example 7.6: openssl JSON example using SSL cert encryption
{ "type": "openssl", "options": { "certFile": "ssl/MyCert.pem", "algorithm": "aes256" } }
To encrypt your backups with a cert file you have to create a private key and a certificate pem file.
$
openssl req -x509 -new -days 100000 -key private.pem -out certificate.pem
The created certificate.pem
is used to encrypt your backups
and should be referenced in your phpbu configuration as certFile
.
The private.pem
file is used to decrypt your backups.
Decrypt a cert file encoded backup
$
openssl smime -decrypt -aes256 -inform DER \ -in backup.tar.bz2.enc \ -out backup.tar.bz2 \ -inkey private.pem
Decrypt a password encoded backup
$
openssl enc -d -a -aes-256-cbc \ -in backup.tar.bz2.enc \ -out backup.tar.bz2 \ -pass pass:mySecretPassword
It's considered best practice to NOT store your backups locally, or at least not only storing them locally.
With PHPBU Sync
adapters you can copy your backups to different locations.
If you are syncing your backup to a cloud service it's advised to encrypt your backup beforehand. Especially if your backup contains personal identifiable information.
PHPBU supports cleaning up your locally stored backups by configuring a Cleanup.
Note that Cleanup
configurations do not affect remote files synced with Sync
configurations.
But some Sync
adapters support cleaning up remote files as well.
This is done by using cleanup.*
options in your Sync
configuration.
In order to better understand how remote cleanups work and how they are configured have a look at the Cleanups section.
Table 8.1. Supported types of syncs:
Type | Description | Remote Cleanup |
---|---|---|
amazon | Sync your backup to your Amazon S3 account. | yes |
Azure Blob | Sync your backup to your Azure Blob storage. | yes |
Dropbox | Sync your backup to a Dropbox account. | yes |
Google Drive | Sync your backup to a Google Drive account. | yes |
OpenStack | Sync your backups to an OpenStack storage. | yes |
rsync | Sync your backups with rsync. | no |
sftp | Sync your backup to a server via SFTP. | yes |
SoftLayer Object Storage | Sync your backup to a Softlayer Object Storage account. | no |
Yandex Disk | Sync your backup to a Yandex account. | no |
Sync your backup to an Amazon S3 account.
If you are not using the PHAR version you have to require "aws/aws-sdk-php": "^3.10"
in your Composer file.
Table 8.2. amazons3-Options
Name | Value | Required | Default | Description |
---|---|---|---|---|
key | string | yes | - | The Amazon S3 key. |
secret | string | yes | - | The Amazon S3 secret. |
bucket | string | yes | - | The bucket name where the backup is stored. |
region | string | yes | - | The region where the bucket is located e.g. 'eu-central-1'. |
path | string | no | / | Path where to store the backup in your bucket. |
useMultiPartUpload | boolean | no | false | Use Amazon S3 MultiPartUpload functionality. |
cleanup.type | string | no | - | The remote cleanup strategy (capacity|outdated|quantity|stepwise). |
cleanup.* | string | no | - | The remote cleanup strategy settings. For example "cleanup.size" if you use "cleanup.type" = "capacity". For details have a look at the corresponding Cleanup configurations. |
Example 8.1: amazons3 XML example
<!-- sync amazon s3 --> <sync type="amazons3"> <option name="key" value="myAwsKey"/> <option name="secret" value="myAwsSecret"/> <option name="bucket" value="backup"/> <option name="region" value="eu-central-1"/> <option name="path" value="/some/dir"/> </sync>
Example 8.2: amazons3 JSON example
{ "type": "amazons3", "options": { "key": "myAwsKey", "secret": "myAwsSecret", "bucket": "backup", "region": "eu-central-1", "path": "/some/dir", "useMultiPartUpload": "true" } }
Sync your backup to an Azure Blob storage.
If you are not using the PHAR version you have to require "microsoft/azure-storage-blob": "~1.4"
in your Composer file.
Table 8.3. azureblob-Options
Name | Value | Required | Default | Description |
---|---|---|---|---|
connection_string | string | yes | - | The Azure Blob storage account connection string. |
container_name | string | yes | - | A container where to store the backup. |
path | string | no | / | Path where to store the backup in your container. |
cleanup.type | string | no | - | The remote cleanup strategy (capacity|outdated|quantity|stepwise). |
cleanup.* | string | no | - | The remote cleanup strategy settings. For example "cleanup.size" if you use "cleanup.type" = "capacity". For details have a look at the corresponding Cleanup configurations. |
Example 8.3: azureblob XML example
<!-- sync azure blob --> <sync type="azureblob"> <option name="connection_string" value="DefaultEndpointsProtocol=[http|https];AccountName=[yourAccount];AccountKey=[yourKey]"/> <option name="container_name" value="backup"/> <option name="path" value="/some/dir"/> </sync>
Example 8.4: azureblob JSON example
{ "type": "azureblob", "options": { "connection_string": "DefaultEndpointsProtocol=[http|https];AccountName=[yourAccount];AccountKey=[yourKey]", "container_name": "backup", "path": "/some/dir" } }
Sync your backup to a Dropbox account.
If you are not using the PHAR version you have to require
"dropbox/dropbox-sdk": "1.1.*"
in your Composer file.
Table 8.4. Dropbox-Options
Name | Value | Required | Default | Description |
---|---|---|---|---|
token | string | yes | - | The Dropbox authentication token. Go to www.dropbox.com/developers/apps Create your app Choose: dropbox api app files and datastore yes provide some app name "my-dropbox-app" generate access token to authenticate connection to your dropbox |
path | string | yes | - | Directory where to store the backup in your Dropbox account. |
Example 8.5: Dropbox XML example
<!-- sync dropbox --> <sync type="dropbox"> <option name="token" value="myCrazyLongApiTokenThatIGotFromDropbox"/> <option name="path" value="/some/dir"/> </sync> </section>
Example 8.6: Dropbox JSON example
{ "type": "dropbox", "options": { "token": "myCrazyLongApiTokenThatIGotFromDropbox", "path": "/some/dir" } }
Sync your backup to a Google Drive account.
If you are not using the PHAR version you have to require
"google/apiclient":"^2.0"
in your Composer file.
Table 8.5. Google Drive-Options
Name | Value | Required | Default | Description |
---|---|---|---|---|
secret | string | yes | - | Google Drive authentication json file. |
access | string | yes | - | Json file containing your access token. |
parentId | string | yes | - | The Google Drive element id where your backups should be stored. |
If you are unsure on how to obtain the secret and access files or the directory ID have a look at
sebastianfeldmann/phpbu-google-drive
a utility to generate your access token and to list the files and their IDs from your Google Drive account.
Example 8.7: Google Drive XML example
<!-- sync dropbox --> <sync type="googledrive"> <option name="secret" value="config/google/secret.json"/> <option name="access" value="config/google/access.json"/> <option name="parentId" value="bkjnwqr8123njndcqw12r"/> </sync> </section>
Example 8.8: Google Drive JSON example
{ "type": "googledrive", "options": { "secret": "config/google/secret.json", "access": "config/google/access.json", "parentId": "bkjnwqr8123njndcqw12r" } }
Sync your backup to a provider supporting the OpenStack API.
Table 8.6. OpenStack-Options
Name | Value | Required | Default | Description |
---|---|---|---|---|
auth_url | string | yes | - | The remote authentication url. |
region | string | yes | - | The OpenStack region. |
user | string | yes | - | The user name for authentication. |
password | string | yes | - | The user password. |
container_name | string | yes | - | The name of the container to store the backup. |
service_name | string | no | swift | The service to use for the upload. |
path | string | no | - | Remote path to store the backup. |
Example 8.9: OpenStack XML example
<!-- sync openstack --> <sync type="openstack"> <option name="auth_url" value="www.example.com"/> <option name="region" value="my-region"/> <option name="user" value="username"/> <option name="password" value="top-secret"/> <option name="path" value="/some/path"/> </sync>
Example 8.10: OpenStack JSON example
{ "type": "openstack", "options": { "auth_url": "www.example.com", "region": "my-region", "user": "username" "password": "my-secret" "path": "/some/path", } }
Sync your backup via the rsync command.
Table 8.7. rsync-Options
Name | Value | Required | Default | Description |
---|---|---|---|---|
path | string | yes | - | The remote path where your backups should be synced to. |
host | string | yes | - | The remote host where your backups should be synced to. |
user | string | no | OS-User | The user to connect to the remote host. Make sure the user is able to connect without entering a password otherwise you get prompted for a password while executing phpbu. |
dirsync | boolean | no | false | Sync the target directory instead of syncing only the target file. |
delete | boolean | no | false | Add the --delete option to the rsync call, so locally deleted files will be deleted remotely as well. |
exclude | string | no | - | List of files to exclude from the sync separated by ":" e.g. "*.suffix:foo.bar". |
args | string | no | - | Advanced mode to use completely custom options. "rsync {args}". WARNING: phpbu is not escaping this in any way so use with caution! Use %TARGET_FILE% and %TARGET_DIR% as reference to your created backup. |
Example 8.11: rsync XML example
<!-- sync rsync --> <sync type="rsync"> <option name="path" value="/backup/some/path"/> <option name="dirsync" value="true"/> <option name="host" value="backup.example.com"/> <option name="user" value="backup"/> </sync>
Example 8.12: rsync JSON example
{ "type": "rsync", "options": { "path": "/backup/some/path", "dirsync": "true", "host": "backup.example.com", "user": "backup" } }
Copy your backup to another server via SFTP or FTP.
If you want to use SFTP and you are not using the PHAR version you have to require
"phpseclib/phpseclib": "2.0.*@dev"
in your Composer file.
For this to work you have to set the minimum-stability
to dev
.
If you want to use the FTP sync your PHP has to be compiled with --enable-ftp
.
Table 8.8. (s)ftp-Options
Name | Value | Required | Default | Description |
---|---|---|---|---|
host | string | yes | - | The host you want to copy your backups to. |
port | integer | no | 22 | The port you want to connect to. |
user | string | yes | - | The user you want to connect with. |
password | string | no | - | The password to authenticate the user. If 'key' is provided this will be used as private key password. |
key | string | no | - | Path to private key file to authenticate the user. |
path | string | yes | - | The remote path where to copy the backup. |
passive | boolean | no | false | Use passive FTP mode. |
Example 8.13: sftp XML example
<!-- sync sftp --> <sync type="sftp"> <option name="host" value="backup.example.com"/> <option name="port" value="22"/> <option name="user" value="user.name"/> <option name="password" value="topsecret"/> <option name="path" value="backup/someName"/> <option name="passive" value="true"/> </sync>
Example 8.14: sftp JSON example
{ "type": "sftp", "options": { "host": "backup.example.com", "port": 22, "user": "user.name", "password": "topsecret", "path": "backup/someName", "passive": "false" } }
If you want to use plain FTP just use ftp
as type, options stay the same.
Sync your backup to a Softlayer account.
If you are not using the PHAR version you have to require
"softlayer/objectstorage": "dev-master"
in your Composer file.
For this to work you have to set the minimum-stability
to dev
.
Table 8.9. softlayer-Options
Name | Value | Required | Default | Description |
---|---|---|---|---|
user | string | yes | - | The user you want to connect with. |
secret | string | no | - | The API key to authenticate the user. |
host | string | yes | - | The host you want to copy your backups to. |
container | string | yes | - | The Object Storage Container where the backup is stored. |
path | string | yes | - | The remote path where to copy the backup. |
Example 8.15: softlayer XML example
<!-- sync softlayer object storage --> <sync type="softlayer"> <option name="user" value="user.name"/> <option name="secret" value="topsecret"/> <option name="host" value="some.softlayer.domain.com"/> <option name="container" value="backup"/> <option name="path" value="/backup/someName"/> </sync>
Example 8.16: softlayer JSON example
{ "type": "softlayer", "options": { "user": "user.name", "secret": "topsecret", "host": "some.softlayer.domain.com", "container": "backup", "path": "/backup/someName" } }
Sync your backup to Yandex account.
If you are not using the PHAR version you have to require
"arhitector/yandex": "^2.0"
in your Composer file.
This is what you have to do:
Go to https://oauth.yandex.ru/client/new
Create your app
Check all disk permissions
Generate access token
Go to https://oauth.yandex.ru/authorize?response_type=token&client_id=APP_ID (replace APP_ID with ID given to you)
Then you should get token parameter from query parameters of opened page
Table 8.10. softlayer-Options
Name | Value | Required | Default | Description |
---|---|---|---|---|
user | string | yes | - | The user you want to connect with. |
token | string | no | - | The API token to authenticate the user. |
path | string | yes | - | The remote path where to put the backup. |
Example 8.17: Yandex XML example
<!-- sync yandex disk --> <sync type="yandex-disk"> <option name="token" value="mnahg6-1knl2l2-b1vf4"/> <option name="path" value="/backup/someName"/> </sync>
Example 8.18: Yandex JSON example
{ "type": "yandex-disk", "options": { "user": "mnahg6-1knl2l2-b1vf4", "path": "/backup/someName" } }
You can remove old backups to limit the space your backups consume on your local hard drive. It's important to note,
that only local backups will be cleaned up. So whatever kind of Sync
you are using. Cleanup
won't touch your remote files.
If you want to remove your synced backups as well, and you are not using the
Rsync sync with its delete
option.
Have a look at the remote cleanup section.
Table 9.1. Supported types of cleanup:
Type | Description |
---|---|
Capacity | Define the size your backups should occupy. If your backups start to exceed this value PHPBU will start to delete backups, starting with the oldest ones. |
Outdated | Remove backups older than a configured time-value. For example "2W" to delete all backups older than two weeks. |
Quantity | Keep only a configured amount of backups. |
Stepwise | Keep different amount of backups for different periods of time. For example keep all backups you made for the last 3 days, keep one for each week for the last 4 weeks, keep one for each month for the last 6 months and one for each year for at least 3 years. |
Remove oldest backups if all created backups exceed the configured limit.
Table 9.2. Capacity-Options
Name | Value | Required | Default | Description |
---|---|---|---|---|
size | string | yes | - | Space your backups are allowed to occupy. e.g. 500M for 500 Megabytes or 1G for one Gigabyte. |
deleteTarget | boolean | no | false | If you don't want to keep any backups locally, just specify a size of "0B", set this to "true" and even the current backup will be deleted. |
Example 9.1: capacity XML example
<!-- cleanup capacity: keep 250 Megabytes of backups --> <cleanup type="capacity"> <option name="size" value="250M"/> <option name="deleteTarget" value="false"/> </cleanup>
Example 9.2: capacity JSON example
{ "type": "capacity", "options": { "size": "250M", "deleteTarget": "false" } }
Remove backups that are older than a configured value.
Table 9.3. Outdated-Options
Name | Value | Required | Default | Description |
---|---|---|---|---|
older | string | yes | - | Time to keep backups. e.g. 1m for one month or 20d for twenty days. |
Example 9.3: outdated XML example
<!-- cleanup outdated: keep backups for 2 weeks --> <cleanup type="outdated"> <option name="older" value="2W"/> </cleanup>
Keep only a configured amount of backups.
Table 9.4. Quantity-Options
Name | Value | Required | Default | Description |
---|---|---|---|---|
amount | string | yes | - | The amount of backups to keep. |
Example 9.5: quantity XML example
<!-- cleanup quantity: keep the last 20 backups --> <cleanup type="quantity"> <option name="amount" value="20"/> </cleanup>
Keep more backups in the recent past and keep less backups for the distant past. The following table illustrates how this works.
| for x days | for x days | for x weeks | for x month keep | | keep all | keep one per day | keep one per week | keep one per month | --------+-------------+-------------------+-----------------------+--------------------+- backups | ............| . . . . . . . . . | . . . | . . |
So if you start to backup now your amount of backups will grow for the configured years to keep at least one backup. But by then the amount of your backups will be constantly the same.
Table 9.5. Stepwise-Options
Name | Value | Required | Default | Description |
---|---|---|---|---|
daysToKeepAll | integer | yes | 0 | Days to keep all backups you made. |
daysToKeepDaily | integer | yes | 0 | Days to keep at least one backup you made a day. |
weeksToKeepWeekly | integer | yes | 0 | Amount of weeks to keep at least one backup for each week. |
monthToKeepMonthly | integer | yes | 0 | Amount of month to keep at least one backup for each month. |
yearsToKeepYearly | integer | yes | 0 | Amount of years to keep at least one backup for each year. |
Example 9.7: stepwise XML example
<!-- cleanup stepwise --> <cleanup type="stepwise"> <option name="daysToKeepAll" value="2" /> <option name="daysToKeepDaily" value="5" /> <option name="weeksToKeepWeekly" value="3" /> <option name="monthToKeepMonthly" value="4" /> <option name="yearsToKeepYearly" value="10" /> </cleanup>
Example 9.8: stepwise JSON example
{ "type": "stepwise", "options": { "daysToKeepAll": 2, "daysToKeepDaily": 5, "weeksToKeepWeekly": 3, "monthToKeepMonthly": 4, "yearsToKeepYearly": 10 } }
Some sync implementations support to cleanup remote files as well. To check if the sync of your choice supports remote cleanup have a look at the sync list.
Remote cleanups are configured within your Sync configuration similar to local
cleanups. The only difference is that all options get prefixed by cleanup.
.
To better understand this have a look at the following examples.
Example 9.9: Remote cleanup XML example
<!-- cleanup stepwise --> <sync type="dropbox"> <!-- some sync relevant options --> <option name="token" value="mysecrettoken" /> <option name="path" value="/backups" /> <!-- remote cleanup options --> <option name="cleanup.type" value="quantity" /> <option name="cleanup.amount" value="10" /> </cleanup>
Example 9.10: Remote cleanup JSON example
{ "type": "dropbox", "options": { "token": "mysecrettoken", "path": "/backups", "cleanup.type": "quantity", "cleanup.amount": 10 } }
You can create a simple json logfile with PHPBU's json logger.
Example 10.1: json XML example
<!-- create a json logfile --> <log type="json" target="backup/log.json"/>
PHPBU uses SwiftMailer to send backup reports to one or more configured email addresses.
If you just want to get notified if something went wrong,
you can use the sendOnlyOnError
option to not send any email on a successful backup.
Table 10.1. Email-Options
Name | Value | Required | Default | Description |
---|---|---|---|---|
recipients | string | yes | - | List of emails separated by semicolon. |
sendOnlyOnError | string | no | false | Sending reports only if something goes wrong. |
subject | string | no | PHPBU Backup Report from $HOSTNAME | Email subject of the backup report. |
transport | string | yes | - | SwiftMailer Transport that's used to send the email (mail, sendmail, smtp, null). |
sender.mail | string | phpbu@hostname | - | The sender email address |
sender.name | string | no | OS-User | The sender name. |
sender.name | string | no | OS-User | The sender name. |
sendmail options | ||||
sendmail.path | string | no | - | Path to local sendmail binary. |
sendmail.options | string | no | - | Sendmail options (e.g. -bs). |
SMTP options | ||||
smtp.port | string | no | 25 | Port to use to connect to SMTP server. |
smtp.host | string | no | - | SMTP hostname. |
smtp.username | string | no | - | The SMTP login. |
smtp.password | string | no | - | The SMTP password. |
smtp.encryption | string | no | - | Type of encryption (e.g. ssl). |
Example 10.3: mail XML example
<!-- use mail to keep up to date with your backup creation --> <log type="mail"> <option name="transport" value="mail"/> <option name="recipients" value="user.name@example.com"/> </log>
Example 10.4: mail JSON example
{ "type": "mail", "options": { "transport": "mail", "recipients": "user.name@example.com" } }
You can log to a Telegram group or contact.
Table 10.2. Telegram-Options
Name | Value | Required | Default | Description |
---|---|---|---|---|
chat_id | string | yes | - | Telegram chat ID |
bot_id | string | no | - | Telegram bot ID. |
bot_token | string | no | - | Telegram bot authentication token. |
Example 10.5: Telegram XML example
<!-- write to Telegram chat --> <log type="telegram"> <option name="chat_id" value="YOUR_CHAT_ID"/> <option name="bot_id" value="YOUR_BOT_ID"/> <option name="bot_token" value="YOUR_BOT_TOKEN"/> </log>
Example 10.6: Telegram JSON example
{ "type": "telegram", "options": { "chat_id": "YOUR_CHAT_ID", "bot_id": "YOUR_BOT_ID", "bot_token": "YOUR_BOT_TOKEN" } }
You can call a webhook and PHPBU will send report data to the webhook.
Table 10.3. Webhook-Options
Name | Value | Required | Default | Description |
---|---|---|---|---|
uri | string | no | - | URI to call |
username | string | no | - | Basic auth user name. |
password | string | no | - | Basic auth password. |
method | string | no | get | HTTP request method (get, post). |
contentType | string | no | application/json | Post method request body content type. |
template | string | no | - | A template to use for the request body For example if you want to you xml over json. |
timeout | integer | no | - | How long until the request times out (seconds) |
Example 10.7: webhook XML example
<!-- call webhook --> <log type="webhook"> <option name="uri" value="http://example.com/hook"/> </log>
Example 10.8: webhook JSON example
{ "type": "webhook", "options": { "uri": "http://example.com/hook" } }
If you change the request method to post by default you will receive a request body in the following format.
Example 10.9: Default request body example
{ "status": 0, "timestamp": 12783781381, "duration": 234.3402, "backupCount": 1, "backupFailed": 0, "errorCount": 0, "errors": [], "backups": [ { "name": "status": "checks": { "executed": 1, "failed": 0, }, "crypt": { "executed": 1, "skipped": 0, "failed": 0, }, "syncs" => { "executed": 1, "skipped": 0, "failed": 0 }, "cleanup" => { "executed": 1, "skipped": 0, "failed": 0 } } ] }
If this format doesn't work for you, you can define your own request body with a template.
Example 10.10: Template example
<?xml version="1.0" encoding="UTF-8"?> <report> <status>%status%</status> <date>%timestamp%</date> <backups> %%backup%% <backup> <name>%name%</name> <status>%status%</status> </backup> %%backup%% </backups> <errors> %%error%% <error class="%class%" message="%message%" file="%file%" line="%line%" /> %%error%% </errors> </report>
You can create a file containing meta data which can be consumed by Prometheus.
Example 10.11: Prometheus XML example
<!-- call prometheus --> <log type="prometheus"> <option name="target" value="backup/log.prom"/> </log>
Example 10.13: Example output
# HELP phpbu_backup_success Whether or not the backup succeeded # TYPE phpbu_backup_success gauge phpbu_backup_success{name="backupName0"} 1 phpbu_backup_success{name="backupName1"} 0 # HELP phpbu_backup_duration The total time the backup took to execute # TYPE phpbu_backup_duration gauge phpbu_backup_duration{name="backupName0} 10.14783922 phpbu_backup_duration{name="backupName1} 166.72893933 # HELP phpbu_backup_last_run The unix timestamp of the last run # TYPE phpbu_backup_last_run counter phpbu_backup_last_run{name="backupName0} 1586983854 phpbu_backup_last_run{name="backupName1} 1586985773 # HELP phpbu_backup_size The size of the last successful backup # TYPE phpbu_backup_size gauge phpbu_backup_size{name="backupName0} 92474832 phpbu_backup_size{name="backupName1} 374893
You can extend PHPBU with your own Source, Check, Crypt, Sync, Cleanup, Adapter and Logger implementations.
All you have to do is to register your implementation at the PHPBU Factory. You can do this by adding you own bootstrap file.
phpbu --bootstrap=extend.php
Your extend.php file could look something like this:
Example 11.1: Extend bootstrap
<?php // make your class accessible require 'Acme/MySource.php'; // register your class as a source try { phpbu\App\Factory::register('source', 'mysource', '\\Acme\\MySource'); } catch (Exception $e) { die($e->getMessage()); }
For this to work your class Acme\MySource has to implement
the phpbu\App\Backup\Source
Interface.
After registering your Source you can use mysource
as source-type
within your XML or JSON configuration like this.
If the alias is already taken this will throw an Exception. You can force PHPBU to overwrite any previously registered class using the $force parameter. Even the PHPBU sources could be replaced with custom implementations.
Example 11.4: Overwrite default sources
<?php // make your class accessible require 'Acme/MyMysqldump.php'; // register your class as source, override already registered class phpbu\App\Factory::register('source', 'mysqldump', '\\Acme\\MyMysqldump', true);
If you are extending PHPBU you have two options. The first is to simply implement the execution interface. This way
you can execute your own Source, Check, Crypt, Sync or Cleanup tasks. The second option is to implement the
respective Simulator
interface. Choosing this option you not only have to implement the execution
part but rather implement a simulation part as well.
Simulation is supported out of the box for every implementation, but choosing option two allows you to add viable information about the actions you perform in your code within a simulation run.
Table 11.1. Types to register:
Type | Interface for execution only | Interface for execution and simulation |
---|---|---|
source | phpbu\App\Backup\Source | phpbu\App\Backup\Source\Simulator |
check | phpbu\App\Backup\Check | phpbu\App\Backup\Check\Simulator |
crypt | phpbu\App\Backup\Crypt | phpbu\App\Backup\Crypt |
sync | phpbu\App\Backup\Sync | phpbu\App\Backup\Sync\Simulator |
cleanup | phpbu\App\Backup\Cleanup | phpbu\App\Backup\Cleanup\Simulator |
adapter | phpbu\App\Adapter | - |
logger | phpbu\App\Backup\Logger | - |
A minimal custom Source class could look like this.
Example 11.5: Create a custom source
<?php namespace Acme; use \phpbu\App\Backup\Result; use \phpbu\App\Backup\Source; use \phpbu\App\Backup\Source\Status; use \phpbu\App\Backup\Target; class MySource implements Source { /** * Some data that has to be configured. */ private $someConfigValue; /** * Here you should validate the configuration and setup your class. * * @param array $conf */ public function setup(array $conf) { // here you are getting all of your configured options // $conf[ <option name> ] = <option value> $this->someConfigValue = $conf['foo'] } /** * In here you should create your backup. * * @return \phpub\App\Backup\Source\Status * @throws \phpbu\App\Backup\Source\Exception */ public function backup(Target $target, Result $result) : Status { // use these methods to store the backup at the configured location // $target->getPath() // $target->getPathname() // $target->getFilename() // to know if the backup should be compressed use // $target->shouldBeCompressed() // to get the compression settings use // $target->getCompressor() // if you want to log some debug information use // $result->debug('some message'); // anything bad happens throw a \phpbu\App\Exception // return a backup status // this is important so the runner knows if it still has to compress the backup // return Status::create()->uncompressed($pathToUncompressedFile); } }
Custom Check implementation example.
Example 11.6: Create a custom check
<?php namespace Acme; use \phpbu\App\Backup\Check; use \phpbu\App\Backup\Collector; use \phpbu\App\Backup\Target; class MyCheck implements Check { /** * Perform your check. */ public function pass(Target $target, $value, Collector $collector) : bool { // use Target to refer to the created backup // $target->getPathname() // $value is the configured value // <check type="mycheck" value="myvalue"/> // $value = "myvalue" // use the collector to get a list of previous backups array<splFileInfo> // $history = $collector->getBackups() // throw a \phpbu\App\Backup\Check\Exception if something bad is happening // finally return if the check passes or not return $boolean; } }
Implementing a custom Sync.
Example 11.7: Create a custom sync
<?php namespace Acme; use \phpbu\App\Backup\Sync; use \phpbu\App\Backup\Target; class MySync implements Sync { /** * Some data that has to be configured. */ private $someConfigValue; /** * Here you should validate the configuration and setup your class. */ public function setup(array $conf) { // here you are getting all of your configured options // $conf[ <option name> ] = <option value> $this->someConfigValue = $conf['foo'] } /** * Execute your sync. */ public function sync(Target $target, Result $result) { // use Target to refer to the created backup // $target->getPathname() // execute your sync // if you want to log some debug information use // $result->debug('some message'); // throw a \phpbu\App\Backup\Sync\Exception if something is going wrong } }
Implementing a custom cleaner.
Example 11.8: Create a custom cleaner
<?php namespace Acme; use \phpbu\App\Backup\Collector; use \phpbu\App\Backup\Sync; use \phpbu\App\Backup\Target; class MyCleaner implements Sync { /** * Some data that has to be configured. */ private $someConfigValue; /** * Here you should validate the configuration and setup your class. */ public function setup(array $conf) { // here you are getting all of your configured options // $conf[ <option name> ] = <option value> $this->someConfigValue = $conf['foo'] } /** * Execute your cleanup. */ public function cleanup(Target $target, Collector $collector, Result $result) { // use Target to refer to the created backup // $target->getPathname() // use the collector to get a list of previous backups array<splFileInfo> // delete files matching your cleanup rules // $history = $collector->getBackups() // if you want to log some debug information use // $result->debug('some message'); // throw a \phpbu\App\Backup\Cleaner\Exception if something is going wrong } }
Custom Adapter implementation example.
Example 11.9: Create a custom adapter
<?php namespace Acme; use \phpbu\App\Adapter; class MyAdapter implements Adapter { /** * Setup the adapter. * * @param array $conf * @return void */ public function setup(array $conf) { // here you will get all configured adapter options } /** * Return a value for a given path. * * @param string $path * @return string */ public function getValue(string $path) : string { // path is everything behind the second colon // adapter:name:$path return 'some_value'; } }
List of available events:
phpbu.debug
phpbu.app_start
phpbu.app_end
phpbu.backup_start
phpbu.backup_failed
phpbu.backup_end
phpbu.crypt_start
phpbu.crypt_failed
phpbu.crypt_end
phpbu.check_start
phpbu.check_failed
phpbu.check_end
phpbu.sync_start
phpbu.sync_failed
phpbu.sync_skipped
phpbu.sync_end
phpbu.cleanup_start
phpbu.cleanup_failed
phpbu.cleanup_skipped
phpbu.cleanup_end
Implementing a custom logger.
Example 11.10: Create a custom logger
<?php namespace Acme; use phpbu\App\Event; use phpbu\App\Log\Logger; class MyLogger implements Logger { /** * Logger interface requires 'getSubscribedEvents' method. * Define the events you want to get notified about. */ public static function getSubscribedEvents() { return [ 'phpbu.debug' => 'onDebug', 'phpbu.app_end' => 'onPhpbuEnd', ]; } /** * Logger interface requires 'setup' method to configure your logger. * Here you should validate the configuration and setup your class. */ public function setup(array $conf) { // here you are getting all of your configured options // $conf[ <option name> ] = <option value> } /** * Handle the debug event. */ public function onDebug(Event\Debug $event) { // use $event->getMessage() to get the debug message } /** * Handle phpbuEnd event */ public function onPhpbuEnd(Event\App\End $event) { // handle the phpbuEnd // use $event->getResult() to get the application result } }
Example 11.11: Example file structure
acme/ ├── backup/ ├── src/ | ├── bootstrap.php | ├── MyCheck.php | ├── MyCleaner.php | ├── MyCrypt.php | ├── MySource.php | └── MySync.php | ├── phpbu.phar └── phpbu.xml.dist
Example 11.12: Example bootstrap.php
<?php // use your autoloader or require your classes manually // so phpbu can find them while executing you backup // register your class as source, you may override already registered classes phpbu\App\Factory::register('source', 'mysource', '\\Acme\\MySource'); phpbu\App\Factory::register('check', 'mycheck', '\\Acme\\MyCheck'); phpbu\App\Factory::register('cleanup', 'mycleanup', '\\Acme\\MyCleaner');
Example 11.13: Example phpbu.xml.dist
<?xml version="1.0" encoding="UTF-8"?> <phpbu xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://schema.phpbu.de/6.0/phpbu.xsd"> <backups> <backup> <!-- source --> <source type="mysource"> <option name="foo" value="bar"/> </source> <!-- where should the backup be stored --> <target dirname="backup" filename="mysource-%Y%m%d-%H%i.backup" compress="bzip2"/> <!-- check the created backup --> <check type="mycheck" value="100"/> <!-- cleanup the backup location --> <cleanup type="mycleanup"> <option name="foo" value="bar"/> </cleanup> </backup> </backups> </phpbu>
The laravel-phpbu
package integrates phpbu
into the Laravel
framework so you can use the artisan
command to execute your backups
and a Laravel style PHP configuration to set them up.
PHP 7.0
Laravel 5.*
phpbu 6.0.*
Use Composer to install the package.
composer require "phpbu/phpbu-laravel"
Add the package ServiceProvider to your config/app.php
configuration file.
'providers' => [ /* * phpbu Backup Service Providers... */ phpbu\Laravel\ServiceProvider::class, ];
Finally use the Laravel artisan
command
to create a configuration skeleton by publishing the package.
php artisan vendor:publish --provider="phpbu\Laravel\ServiceProvider"
After publishing the ServiceProvider a phpbu.php
configuration file is created in your config directory.
There are two ways of configuring your backup.
Use the created phpbu.php
configuration file
Use a standard phpbu.xml
or phpbu.json
configuration file
The main difference between those two options is the implemented feature set.
While the PHPBU configuration files give you full access to all features of PHPBU the Laravel configuration file currently does not support all features of PHPBU, for example: encryption.
The main concept of configuring backups stays the same. A backup consists of a source and a target. The source represents the data you want to backup. The target represents the location where you want to store your backup. You can add checks, cleanups and syncs to a backup to validate, cleanup or sync your backup to another location.
In the Laravel configuration file you can specify two types of backups,
directories
and databases
(MySQL, PostgreSQL).
Define the directory you want to backup and the target location where to store your backup.
'directories' => [ [ 'source' => [ 'path' => storage_path('app'), 'options' => [], ], 'target' => [ 'dirname' => storage_path('/backup/app'), 'filename' => 'app-%Y%m%d-%H%i.tar', 'compression' => 'bzip2', ] ] ],
Just define the Laravel database connection configured in your databases.php
configuration
you want to backup and you are done. You can overwrite every setting defined with the specific option, for example
username
or password
in case you have to use different credentials to
backup your database.
You can use every option the mysqldump source supports for example to exclude some tables. Just use the option-name as index and the option-value as value.
'databases' => [<emphasise> [ 'source' => [ 'connection' => 'mysql', 'options' => [] ], 'target' => [ 'dirname' => storage_path('backup/db'), 'filename' => 'dump-%Y%m%d-%H%i.sql', 'compression' => 'bzip2', ] ], ],
Add check, sync and cleanup definitions to your backup configuration.
'check' => [ 'type' => 'SizeMin', 'value' => '10B', ], 'sync' => [ 'filesystem' => 's3', 'path' => '/backups/db' ], 'cleanup' => [ 'type' => 'quantity', 'options' => [ 'amount' => '20' ] ]
For a list of available checks
and cleanups
check the corresponding
documentation sections.
To sync your backups you can use every filesystem defined in your Laravel filesystems.php
configuration file.
If you want to use a PHPBU configuration file your Laravel phpbu.php configuration should look something like this.
<?php return [ /* |-------------------------------------------------- | phpbu configuration |-------------------------------------------------- | | Path to a phpbu configuration xml or json file. */ 'phpbu' => base_path('phpbu.xml'), ];
For this to work you have to setup a valid phpbu.xml configuration file in your project root.
Remember that all paths in a PHPBU configuration have to be absolute or relative to the specified PHPBU configuration file.
To execute the backup use the artisan
command line tool.
php artisan phpbu:backup
To execute a dry-run without making any changes.
php artisan phpbu:backup --phpbu-simulate
Copyright (c) 2014-2015 Sebastian Feldmann. This work is licensed under the Creative Commons Attribution 3.0 Unported License. A summary of the license is given below, followed by the full legal text. -------------------------------------------------------------------- You are free: * to Share - to copy, distribute and transmit the work * to Remix - to adapt the work Under the following conditions: Attribution. You must attribute the work in the manner specified by the author or licensor (but not in any way that suggests that they endorse you or your use of the work). * For any reuse or distribution, you must make clear to others the license terms of this work. The best way to do this is with a link to this web page. * Any of the above conditions can be waived if you get permission from the copyright holder. * Nothing in this license impairs or restricts the author's moral rights. Your fair dealing and other rights are in no way affected by the above. This is a human-readable summary of the Legal Code (the full license) below. ==================================================================== Creative Commons Legal Code Attribution 3.0 Unported CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM ITS USE. License THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS. 1. Definitions a. "Adaptation" means a work based upon the Work, or upon the Work and other pre-existing works, such as a translation, adaptation, derivative work, arrangement of music or other alterations of a literary or artistic work, or phonogram or performance and includes cinematographic adaptations or any other form in which the Work may be recast, transformed, or adapted including in any form recognizably derived from the original, except that a work that constitutes a Collection will not be considered an Adaptation for the purpose of this License. For the avoidance of doubt, where the Work is a musical work, performance or phonogram, the synchronization of the Work in timed-relation with a moving image ("synching") will be considered an Adaptation for the purpose of this License. b. "Collection" means a collection of literary or artistic works, such as encyclopedias and anthologies, or performances, phonograms or broadcasts, or other works or subject matter other than works listed in Section 1(f) below, which, by reason of the selection and arrangement of their contents, constitute intellectual creations, in which the Work is included in its entirety in unmodified form along with one or more other contributions, each constituting separate and independent works in themselves, which together are assembled into a collective whole. A work that constitutes a Collection will not be considered an Adaptation (as defined above) for the purposes of this License. c. "Distribute" means to make available to the public the original and copies of the Work or Adaptation, as appropriate, through sale or other transfer of ownership. d. "Licensor" means the individual, individuals, entity or entities that offer(s) the Work under the terms of this License. e. "Original Author" means, in the case of a literary or artistic work, the individual, individuals, entity or entities who created the Work or if no individual or entity can be identified, the publisher; and in addition (i) in the case of a performance the actors, singers, musicians, dancers, and other persons who act, sing, deliver, declaim, play in, interpret or otherwise perform literary or artistic works or expressions of folklore; (ii) in the case of a phonogram the producer being the person or legal entity who first fixes the sounds of a performance or other sounds; and, (iii) in the case of broadcasts, the organization that transmits the broadcast. f. "Work" means the literary and/or artistic work offered under the terms of this License including without limitation any production in the literary, scientific and artistic domain, whatever may be the mode or form of its expression including digital form, such as a book, pamphlet and other writing; a lecture, address, sermon or other work of the same nature; a dramatic or dramatico-musical work; a choreographic work or entertainment in dumb show; a musical composition with or without words; a cinematographic work to which are assimilated works expressed by a process analogous to cinematography; a work of drawing, painting, architecture, sculpture, engraving or lithography; a photographic work to which are assimilated works expressed by a process analogous to photography; a work of applied art; an illustration, map, plan, sketch or three- dimensional work relative to geography, topography, architecture or science; a performance; a broadcast; a phonogram; a compilation of data to the extent it is protected as a copyrightable work; or a work performed by a variety or circus performer to the extent it is not otherwise considered a literary or artistic work. g. "You" means an individual or entity exercising rights under this License who has not previously violated the terms of this License with respect to the Work, or who has received express permission from the Licensor to exercise rights under this License despite a previous violation. h. "Publicly Perform" means to perform public recitations of the Work and to communicate to the public those public recitations, by any means or process, including by wire or wireless means or public digital performances; to make available to the public Works in such a way that members of the public may access these Works from a place and at a place individually chosen by them; to perform the Work to the public by any means or process and the communication to the public of the performances of the Work, including by public digital performance; to broadcast and rebroadcast the Work by any means including signs, sounds or images. i. "Reproduce" means to make copies of the Work by any means including without limitation by sound or visual recordings and the right of fixation and reproducing fixations of the Work, including storage of a protected performance or phonogram in digital form or other electronic medium. 2. Fair Dealing Rights. Nothing in this License is intended to reduce, limit, or restrict any uses free from copyright or rights arising from limitations or exceptions that are provided for in connection with the copyright protection under copyright law or other applicable laws. 3. License Grant. Subject to the terms and conditions of this License, Licensor hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable copyright) license to exercise the rights in the Work as stated below: a. to Reproduce the Work, to incorporate the Work into one or more Collections, and to Reproduce the Work as incorporated in the Collections; b. to create and Reproduce Adaptations provided that any such Adaptation, including any translation in any medium, takes reasonable steps to clearly label, demarcate or otherwise identify that changes were made to the original Work. For example, a translation could be marked "The original work was translated from English to Spanish," or a modification could indicate "The original work has been modified."; c. to Distribute and Publicly Perform the Work including as incorporated in Collections; and, d. to Distribute and Publicly Perform Adaptations. e. For the avoidance of doubt: i. Non-waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme cannot be waived, the Licensor reserves the exclusive right to collect such royalties for any exercise by You of the rights granted under this License; ii. Waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme can be waived, the Licensor waives the exclusive right to collect such royalties for any exercise by You of the rights granted under this License; and, iii. Voluntary License Schemes. The Licensor waives the right to collect royalties, whether individually or, in the event that the Licensor is a member of a collecting society that administers voluntary licensing schemes, via that society, from any exercise by You of the rights granted under this License. The above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats. Subject to Section 8(f), all rights not expressly granted by Licensor are hereby reserved. 4. Restrictions. The license granted in Section 3 above is expressly made subject to and limited by the following restrictions: a. You may Distribute or Publicly Perform the Work only under the terms of this License. You must include a copy of, or the Uniform Resource Identifier (URI) for, this License with every copy of the Work You Distribute or Publicly Perform. You may not offer or impose any terms on the Work that restrict the terms of this License or the ability of the recipient of the Work to exercise the rights granted to that recipient under the terms of the License. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties with every copy of the Work You Distribute or Publicly Perform. When You Distribute or Publicly Perform the Work, You may not impose any effective technological measures on the Work that restrict the ability of a recipient of the Work from You to exercise the rights granted to that recipient under the terms of the License. This Section 4(a) applies to the Work as incorporated in a Collection, but this does not require the Collection apart from the Work itself to be made subject to the terms of this License. If You create a Collection, upon notice from any Licensor You must, to the extent practicable, remove from the Collection any credit as required by Section 4(b), as requested. If You create an Adaptation, upon notice from any Licensor You must, to the extent practicable, remove from the Adaptation any credit as required by Section 4(b), as requested. b. If You Distribute, or Publicly Perform the Work or any Adaptations or Collections, You must, unless a request has been made pursuant to Section 4(a), keep intact all copyright notices for the Work and provide, reasonable to the medium or means You are utilizing: (i) the name of the Original Author (or pseudonym, if applicable) if supplied, and/or if the Original Author and/or Licensor designate another party or parties (e.g., a sponsor institute, publishing entity, journal) for attribution ("Attribution Parties") in Licensor's copyright notice, terms of service or by other reasonable means, the name of such party or parties; (ii) the title of the Work if supplied; (iii) to the extent reasonably practicable, the URI, if any, that Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work; and (iv), consistent with Section 3(b), in the case of an Adaptation, a credit identifying the use of the Work in the Adaptation (e.g., "French translation of the Work by Original Author," or "Screenplay based on original Work by Original Author"). The credit required by this Section 4 (b) may be implemented in any reasonable manner; provided, however, that in the case of a Adaptation or Collection, at a minimum such credit will appear, if a credit for all contributing authors of the Adaptation or Collection appears, then as part of these credits and in a manner at least as prominent as the credits for the other contributing authors. For the avoidance of doubt, You may only use the credit required by this Section for the purpose of attribution in the manner set out above and, by exercising Your rights under this License, You may not implicitly or explicitly assert or imply any connection with, sponsorship or endorsement by the Original Author, Licensor and/or Attribution Parties, as appropriate, of You or Your use of the Work, without the separate, express prior written permission of the Original Author, Licensor and/or Attribution Parties. c. Except as otherwise agreed in writing by the Licensor or as may be otherwise permitted by applicable law, if You Reproduce, Distribute or Publicly Perform the Work either by itself or as part of any Adaptations or Collections, You must not distort, mutilate, modify or take other derogatory action in relation to the Work which would be prejudicial to the Original Author's honor or reputation. Licensor agrees that in those jurisdictions (e.g. Japan), in which any exercise of the right granted in Section 3(b) of this License (the right to make Adaptations) would be deemed to be a distortion, mutilation, modification or other derogatory action prejudicial to the Original Author's honor and reputation, the Licensor will waive or not assert, as appropriate, this Section, to the fullest extent permitted by the applicable national law, to enable You to reasonably exercise Your right under Section 3(b) of this License (right to make Adaptations) but not otherwise. 5. Representations, Warranties and Disclaimer UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. 6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. Termination a. This License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Adaptations or Collections from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License. b. Subject to the above terms and conditions, the license granted here is perpetual (for the duration of the applicable copyright in the Work). Notwithstanding the above, Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above. 8. Miscellaneous a. Each time You Distribute or Publicly Perform the Work or a Collection, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License. b. Each time You Distribute or Publicly Perform an Adaptation, Licensor offers to the recipient a license to the original Work on the same terms and conditions as the license granted to You under this License. c. If any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this agreement, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. d. No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the party to be charged with such waiver or consent. e. This License constitutes the entire agreement between the parties with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You. f. The rights granted under, and the subject matter referenced, in this License were drafted utilizing the terminology of the Berne Convention for the Protection of Literary and Artistic Works (as amended on September 28, 1979), the Rome Convention of 1961, the WIPO Copyright Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 and the Universal Copyright Convention (as revised on July 24, 1971). These rights and subject matter take effect in the relevant jurisdiction in which the License terms are sought to be enforced according to the corresponding provisions of the implementation of those treaty provisions in the applicable national law. If the standard suite of rights granted under applicable copyright law includes additional rights not granted under this License, such additional rights are deemed to be included in the License; this License is not intended to restrict the license of any rights under applicable law. Creative Commons is not a party to this License, and makes no warranty whatsoever in connection with the Work. Creative Commons will not be liable to You or any party on any legal theory for any damages whatsoever, including without limitation any general, special, incidental or consequential damages arising in connection to this license. Notwithstanding the foregoing two (2) sentences, if Creative Commons has expressly identified itself as the Licensor hereunder, it shall have all rights and obligations of Licensor. Except for the limited purpose of indicating to the public that the Work is licensed under the CCPL, Creative Commons does not authorize the use by either party of the trademark "Creative Commons" or any related trademark or logo of Creative Commons without the prior written consent of Creative Commons. Any permitted use will be in compliance with Creative Commons' then-current trademark usage guidelines, as may be published on its website or otherwise made available upon request from time to time. For the avoidance of doubt, this trademark restriction does not form part of this License. Creative Commons may be contacted at http://creativecommons.org/. ====================================================================