Skip to content

Instantly share code, notes, and snippets.

@mrazzari
Last active December 10, 2015 23:59
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mrazzari/4513611 to your computer and use it in GitHub Desktop.
Save mrazzari/4513611 to your computer and use it in GitHub Desktop.
A script to backup a WP database and user uploads into Rackspace Cloud Files, from a cron file.

BACKUP WORDPRESS into Rackspace Cloud Files

  1. Download backup.php to your WordPress root directory (where wp-config is).
  2. Download the RS Cloud Files API and save it in a folder named php-cloudfiles-master, also in your WP root dir.
  3. Download backup.sh outside your web root, and modify it with your Cloud Files username, API key, and container name.
  4. Make sure the container already exists on the Cloud Files admin panel!
  5. Point a daily cron to backup.sh, ie: @daily /var/www/mysite/backup.sh
  6. Go home, you're done.
  7. Kidding! Go download the resulting backup, and make sure it contains what you expect.

You may run php backup.php for further help and configuration options, that you can then use in backup.sh.

<?php
$options = my_getopt("p:c:u:k:b:w:d:r", array(
"prefix:",
"container:",
"user:",
"key:",
"backupdir:",
"wpdir:",
"dateformat:",
"run_dry",
));
if (!is_array($options)){ die("Only runs on the PHP CLI.\n"); }
extract($options);
if (!isset($prefix)){ ?>
BACKUP WORDPRESS into Rackspace Cloud Files
Author: @mrazzari
Author URL: http://ConVistaAlMar.com.ar
REQUIREMENTS
Needs the RS Cloud Files API, downloadable at
https://github.com/rackspace/php-cloudfiles
Place it in a folder named "php-cloudfiles-master" next to <?php echo $argv[0] ?>.
USAGE
Basic backup
php <?php echo $argv[0] ?> --prefix=mysite
Will create mysite.04.tar.gz in your WP root folder.
Backup and upload to Cloud Files
php <?php echo $argv[0] ?> --prefix=mysite --container=mybackups --user=james --key=a1b2c3d4a1b2c3d4
Will create mysite.04.tar.gz
Backup files are named with the day number.
This is a quick hack so that backups will only be kept for 1 month.
For example, on Feb 02, the Jan 02 backup will be overwritten, and so on.
Of course you could use "Y-m-d" or any other format instead.
php <?php echo $argv[0] ?> --prefix=mysite --dateformat="Y-m-d"
Test before you execute.
You may do a "dry run", printing out the actual commands run by the script,
without actually executing any of them.
php <?php echo $argv[0] ?> --prefix=mysite --run_dry
Short options
If your server doesn't support the long options format (as in Rackspace Sites!)
you may use the short format.
php <?php echo $argv[0] ?> -p mysite -c mybackups -u james -k a1b2c3d4a1b2c3d4
[p] prefix: A prefix name for your backup files (could be 'backup', site name, etc)
[c] container: The RS Cloud Files container. You need to create it, this script won't do it.
[u] user: Your RS Cloud Files username.
[k] key: Your RS Cloud Files API key.
[b] backupdir: Where to store backups before uploading. Defaults to <?php echo $argv[0] ?>'s parent dir.
[w] wpdir: Your WP dir. Defaults to the same dir as <?php echo $argv[0] ?>.
[d] dateformat: Date formatting for the backup's date. In PHP date format.
[r] run_dry: Print out the commands as run by this script, but don't really touch anything.
<?php
return 0;
}
// Dir to store backups. Files are temporary if we're uploading to Cloud Files.
// Otherwise they're kept here. Defaults to 1 level up this dir, so that it's not
// on the public web folder.
$backupdir = isset($backupdir) ? $backupdir : dirname(dirname(__FILE__));
// WordPress directory. Defaults to the same dir as this script.
$wpdir = isset($wpdir) ? $wpdir : dirname(__FILE__);
// Filename's date. Default is that backup files are named with just the day number.
$dateformat = isset($dateformat) ? $dateformat : "d";
// More settings and filenames.
define('DRY_RUN', isset($run_dry));
$filename = $prefix . "." . date($dateformat);
$backupfile = "$backupdir/$filename";
// Set some context
set_time_limit(0);
ini_set( "memory_limit", "128M" );
// Load WordPress
$_SERVER['HTTP_HOST'] = 'localhost';
define('SHORTINIT', true);
require_once( $wpdir . '/wp-load.php');
// Cloud Files client API.
require($wpdir . "/php-cloudfiles-master/cloudfiles.php");
// Our target dir to backup. For WP, this is the wp-content/uploads dir.
$upload_dir = wp_upload_dir();
$upload_dir = $upload_dir['basedir'];
// Begin!
echo "\n";
// DB dump
$cmd = sprintf("mysqldump -u %s -h %s --password=%s %s > %s", DB_USER, DB_HOST, DB_PASSWORD, DB_NAME, "$backupfile.sql" );
cmd($cmd, "Exporting MySQL dump.");
// Zip files and DB dump
$cmd = sprintf("tar -czf %s %s %s", "$backupfile.tar.gz", $upload_dir, "$backupfile.sql");
cmd($cmd, "Compressing files and db dump.");
// Remove DB dump, no longer needed.
cmd("unlink $backupfile.sql", "Removing DB backup files.");
// UPLOAD to Cloud Files?
if (!$container || !$user || !$key){
// Don't upload. File remains on this server. We're done.
echo "# Missing Cloud Files connection info!\n";
echo "# Files were backed up but not uploaded.\n";
echo "# Your backup is at: $backupfile.tar.gz\n\n";
} else {
// Upload to Rackspace. Based on http://goo.gl/H4da8
$auth = new CF_Authentication($user, $key);
$auth->authenticate();
$conn = new CF_Connection($auth);
// Get the container we want to use
$container = $conn->get_container($container);
echo "# Uploading backup file to {$container->name}.\n";
echo "$backupfile.tar.gz\n\n";
ob_flush();
// Upload file to Rackspace
if (!DRY_RUN){
$object = $container->create_object("$filename.tar.gz");
$object->load_from_filename("$backupfile.tar.gz");
}
// Remove backup file from this server.
cmd("unlink $backupfile.tar.gz", "Removing backup files.");
}
function cmd($cmd, $title = 'Running command'){
echo "# $title\n";
echo $cmd, "\n";
ob_flush();
if (!DRY_RUN){
$out = shell_exec($cmd);
echo $out, "\n";
}
echo "\n";
}
function my_getopt($short, $long){
// Workaround for older versions of PHP that don't support long opts.
$options = @getopt($short, $long); // @ suppresses the warning
if (!$options){
$options = getopt($short);
}
return short_to_long($options, $long);
}
function short_to_long($options, $longs){
foreach ($longs as $long){
if (isset($options[$long[0]])){
$options[rtrim($long, ':')] = $options[$long[0]];
unset($options[$long[0]]);
}
}
return $options;
}
// Workaround to allow using WordPress SHORTINIT on this script.
// From wp-includes/formatting.php
function untrailingslashit($string) {
return rtrim($string, '/');
}
#!/bin/sh
# See backup.php for description/help on each option.
php /var/www/mysite/backup.php -p backup -c MyBackups -u james -k a1b2c3d4a1b2c3d4a1b2c3d4a1b2c3d4
@audvin
Copy link

audvin commented Apr 11, 2013

Great script! Will this work with https://github.com/rackspace/php-opencloud once RS Cloud Files API is appreciated in August?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment