Guy Rutenberg

Keeping track of what I do

Improved FTP Backup for WordPress

with 56 comments

This script backups both the database and files of a WordPress blog into a remote FTP server (while keeping a local copy). It’s an update of my WordPress Backup to FTP script. The main changes are auto-detecting database settings and better support for caching plugins (specifically WP-Cache). The new version makes it easier to backup multiple WordPress blogs to the same FTP server.

Usage is pretty simple after a short initial configuration. First, save the the script and make it executable:

chmod +x wp-backup

(assuming you saved it under the name wp-backup). After saving it edit the file with your favorite editor and set the 5 configuration variable to whatever is appropriate for you. BACKUP_DIR is the folder to save the local backups to. FTP_HOST, FTP_USER, FTP_PASS control the FTP host, username and password, respectively, for the remote backup server. FTP_BACKUP_DIR sets the folder on the FTP server to save the remote backup to.

Now that the initial configuration is done, all you need to do is execute the script and give the path to the blog as an argument. For example:

./wp-backup /home/someuser/myblog

And that it, the script will backup your files (excluding cache) and database to both a local and remote locations. This allows using the same script to backup multiple WordPress blogs, unlike the previous script which had to be modified for each blog.

And now the script itself:

#!/bin/bash
 
# Copyright 2008, 2010 Guy Rutenberg <http://www.guyrutenberg.com/contact-me>
# WordPress FTP backup 2.0
#
# Easily backup wordpress instances via ftp.
#
# Change Log:
# ===========
# 2.0:
#  - Auto-detect database settings.
#  - Exclude cache data from backups.
 
BACKUP_DIR=
FTP_HOST=
FTP_USER=
FTP_PASS=
FTP_BACKUP_DIR=
 
# end of configuration - you probably don't need to touch anything bellow
 
PROG=`basename "$0"`
print_usage () {
    echo "USAGE: ${PROG} [options] BLOG_ROOT"
    echo "Backup a WordPress blog"
}
 
print_help ()  {
    print_usage
    cat << EOF
 
Options:
    -h, --help          show this help message and exit
 
EOF
}
 
TEMP=`getopt -o h --long help -n "$PROG" -- "$@"`
if (($?)); then
    print_usage
    exit 1
fi
 
eval set -- "$TEMP"
 
while true ; do
    case "$1" in
        -h|--help) print_help; exit ;;
        --) shift; break;;
    esac
done
 
if [ -z "$1" ]
then
 print_usage > /dev/stderr
 exit 1
fi
 
BLOG_DIR=$1
DB_NAME=`echo "<?php require_once(\"${BLOG_DIR}/wp-config.php\"); echo DB_NAME;" | php`
DB_USER=`echo "<?php require_once(\"${BLOG_DIR}/wp-config.php\"); echo DB_USER;" | php`
DB_PASS=`echo "<?php require_once(\"${BLOG_DIR}/wp-config.php\"); echo DB_PASSWORD;" | php`
DB_HOST=`echo "<?php require_once(\"${BLOG_DIR}/wp-config.php\"); echo DB_HOST;" | php`
 
BLOG_DIR=`dirname "$BLOG_DIR"`/`basename "$BLOG_DIR"`
BACKUP_DIR=`dirname "$BACKUP_DIR"`/`basename "$BACKUP_DIR"`
 
echo -n "dumping database... "
DUMP_NAME=${DB_NAME}-$(date +%Y%m%d).sql.bz2
mysqldump --user=${DB_USER} --password=${DB_PASS} --host=${DB_HOST} \
 --databases ${DB_NAME} \
 | bzip2 -c > ${BACKUP_DIR}/${DUMP_NAME}
if [ "$?" -ne "0" ]; then
	echo "failed!"
	exit 1
fi
echo "done"
 
echo -n "Creating tarball... "
TAR_NAME=${BLOG_DIR##*/}-$(date +%Y%m%d).tar.bz2
tar -cjf ${BACKUP_DIR}/${BLOG_DIR##*/}-$(date +%Y%m%d).tar.bz2 --exclude cache ${BLOG_DIR}
if [ "$?" -ne "0" ]; then
	echo "failed!"
	exit 2
fi
echo "done"
 
echo -n "Uploading SQL dump and tarball to FTP... "
lftp -u ${FTP_USER},${FTP_PASS} ${FTP_HOST} <<EOF
cd "${FTP_BACKUP_DIR}"
put "${BACKUP_DIR}/${DUMP_NAME}"
put "${BACKUP_DIR}/${TAR_NAME}"
 
EOF
if [ "$?" -ne "0" ]; then
	echo "failed!"
	exit 3
fi
echo "done"

Written by Guy

February 28th, 2010 at 8:38 am

Posted in Bash,Projects,Wordpress

Tagged with , ,

56 Responses to 'Improved FTP Backup for WordPress'

Subscribe to comments with RSS or TrackBack to 'Improved FTP Backup for WordPress'.

  1. Thank you, this is an awesome script! Unfortunatley, it only allows one backup a day… how would one modify it to allow hourly backups?

    I assume it would be by modifying (date +%Y%m%d) to include the time?

    Steve

    9 Mar 10 at 11:45

  2. yes, be sure to update all occurrences or else you might encounter some strange behavior.

    Guy

    9 Mar 10 at 21:04

  3. Thanks for the great script, not sure if this is an issue with my host [GoDaddy] but I seem to get the following response:

    Set-Cookie: bb2_screener_=1268525451+; path=/
    Content-type: text/html

    when the script tries to run the DB_NAME / DB_USER assignments through the portion of the script. Not sure what I am doing wrong, and running the echo command straight from shell produces same result.

    A workaround I guess would be to manually specify the DB info [as in your old version of script] but this defeats the point of a nice “automatic” detection for multiple-WP installs.

    Thanks!

    Alex

    14 Mar 10 at 02:15

  4. Do you have a fully functional shell on your GoDaddy server? Past experience teach taught me that GoDaddy doesn’t provide a full shell access, which makes running many scripts impossible (and probably this one too).

    Guy

    14 Mar 10 at 07:35

  5. actually after some long trial and error it would seem that the following part of script (for all 4 variables)

    DB_HOST=`echo “<?php include(\"${BLOG_DIR}/wp-config.php\"); echo DB_HOST;" | php`

    the php include part was returning some kind of header information in addition to the DB_HOST variable and therefore once I stripped that out by adding the following lines underneath it seemed to work.

    DB_HOST=`echo "<?php include(\"${BLOG_DIR}/wp-config.php\"); echo DB_HOST;" | php`
    DB_HOST=`echo $DB_HOST | tr -d '\r\n'`
    DB_HOST=${DB_HOST##* }

    Now on to find lftp alternative that works with GoDaddy *sigh*

    Alex

    14 Mar 10 at 07:52

  6. [...] скрипт лежит тут. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 [...]

  7. I created an .exe file with the sript you provide and when trying to run it I got this message:

    “The version of this file is not compatible with the version of Windows you’re running. Check your computer’s system information to see whether you need an x86 (32-bit) or x64 (64-bit) version of the program and then contact the software publisher”.

    My OS is Windows 7 – x64

    Any insight and am I doing everything right?

    Thanks.

    Rafael M

    9 Apr 10 at 19:03

  8. This is a bash script, how did you turn it into an exe?
    Anyway, you’ll need bash in order to run it (which probably means you’ll need some sort of Linux or BSD).

    Guy

    10 Apr 10 at 12:54

  9. This allows using the same script to backup multiple WordPress blogs, unlike the previous script which had to be modified for each blog.

    Does this mean there’s support for WPMU and Multiple DBs?

    If so, is there any other setup info we need to do to make it work?

    Nick

    2 Jun 10 at 17:47

  10. I meant that the script can be used to backup multiple regular WP blogs. I’m not familiar enough with WPMU to be sure, but I think it might work. Just try it. I don’t think it will work with multiple dbs serving one installation.

    Guy

    4 Jun 10 at 14:46

  11. Hello Guy,

    Can you give me so direction on how to solve this error?

    dumping database… ./wp-backup: line 72: ${BACKUP_DIR}/${DUMP_NAME}: ambiguous redirect
    mysqldump: unknown option ‘-2′
    failed!

    Your previous WP FTP script is working quite well on the same server.

    Thank you.

    Ed

    17 Jun 10 at 04:50

  12. Mit dem Auto nach Guadalest…

    weil auch hier und hier über Autourlaub berich…

    Kurortmeinung.de

    8 Jul 10 at 18:41

  13. Hi Guy

    Same error
    dumping database… ./wp-backup: line 72: ${BACKUP_DIR}/${DUMP_NAME}: ambiguous redirect
    mysqldump: unknown option ‘-2′
    failed!

    Manually ran the script for the echo DB_NAME bit and it may be wordpress v3.0 call wp-settings.php then it call something else and never actually ECHO DB_NAME.

    Hope this is making sense.

    Cheers
    Eric

    Eric Tam

    30 Jul 10 at 12:05

  14. Hi Eric and Ed,

    I’ve just verified that the script does work with wordpress 3.0. What happens when you echo DB_NAME? Does the php part reports any errors when executed manually?

    Guy

    31 Jul 10 at 13:20

  15. I know this a bit of a newbie question, but can you point me in the right direction of a resource that describes how you install a script onto your host.

    I host with media temple, and have about 25 websites running, all wordpress that I would like to be backed up automatically on a monthly basis.

    This sounds like the best solution, but I don’t really know where to start, any advice?

    cheers!

    Jaclyn

    Jaclyn

    9 Aug 10 at 03:23

  16. You’ll need to copy the script and save it on your server, and then continue with the instruction in the post. If you’re having problems, please be more specific and tell which part is the problematic so I can be of better help.

    Guy

    9 Aug 10 at 22:29

  17. Where do I save it on my server? In the root directory or in the root of each website? I have many domains on the same server….

    If I am understanding correctly I can use 1 script to control the backups of all of the websites, so I would assume that if I placed the file above the other sites in the file structure then it could control them.

    Is there a particular file name I should use for the script, and can it be a regular .txt file?

    Thanks for you help!

    ;)

    Jaclyn

    Jaclyn

    11 Aug 10 at 19:16

  18. Preferably in the somewhere above all other sites (also it’s). Root directory is fine.

    The extension doesn’t matter as long it is executable. By conventions shell scripts like this have no extension or .sh extension. To make it executable see the part of the post regarding chmod.

    Guy

    12 Aug 10 at 21:47

  19. Hi Guy,

    I was running into an error similar to the one Eric and Ed were seeing. It turns out that my host’s standard php executable was probably the CGI version; it was displaying headers, so DB_NAME, etc., got mangled. My solution was to change “php” to “php -q” in all four lines:


    DB_NAME=`echo “<?php require_once(\"${BLOG_DIR}/wp-config.php\"); echo DB_NAME;" | php -q`
    DB_USER=`echo "<?php require_once(\"${BLOG_DIR}/wp-config.php\"); echo DB_USER;" | php -q`
    DB_PASS=`echo "<?php require_once(\"${BLOG_DIR}/wp-config.php\"); echo DB_PASSWORD;" | php -q`
    DB_HOST=`echo "<?php require_once(\"${BLOG_DIR}/wp-config.php\"); echo DB_HOST;" | php -q`

    Maybe this will help someone else as well?

    Thanks!

    Nate

    Nate

    13 Aug 10 at 09:00

  20. Thanks Guy.

    Had tried Nate’s suggestion to no avail.

    Moving to WP 3.01 resolved the issue for us.

    Ed

    14 Aug 10 at 20:07

  21. Guy,

    Is it possible to exclude certain directories during backup?

    One blog is on the web root but also has several non WP related directories with large files in them.

    Thank you.

    Ed

    15 Aug 10 at 21:02

  22. Hi Ed,

    I’m glad things sorted out for you. I wonder why it didn’t work for you and Eric in the first place.

    Regarding excluding certain directories, just add --exclude [dir name] to the tar tar line (it’s 2 lines below where it says “Creating tarball…”). There is already one exclude rule, which you can use as an example.

    Guy

    15 Aug 10 at 21:55

  23. Thank you Guy.

    I should have looked a little closer at the script code.

    Really appreciate your making this freely available.

    Ed

    16 Aug 10 at 18:15

  24. I’m having some issues getting this script to work…

    I’m getting a similar error as already mentioned, but the suggested fixes have no effect.

    dumping database… ./wp-backup: line 72: ${BACKUP_DIR}/${DUMP_NAME}: ambiguous redirect
    mysqldump: unknown option ‘–>′
    failed!

    Any suggestions what might be causing this? Would the symbols in the password have any effect on this? The password contains a } and a comma… Then again, the previous version of this script worked perfect with the same DB details.

    Any help would be appreciated.

    Thanks!
    Andrei

    Andrei

    29 Aug 10 at 02:14

  25. Nevermind – got this sorted out!

    Turns out one of the SuperCache files was stuck with paths from the old server, and this caused a warning to be echo’ed as well as the Constants.

    If anybody else is getting these ambigious redirects, try debugging the script by changing the first line to

    #!/bin/bash -x

    That’s how I discovered the source of my problem.

    Cheers!

    Andrei

    31 Aug 10 at 17:53

  26. I know this is a stupid question. I am sure it is ridiculously simple.
    But I am new to this and am obviously missing something basic here.
    When you say “give the path to the blog as an argument” what do you mean? Which file? where in the file? I understand the line you wrote(at least what it does, but where does it go?

    Thanks!

    Jim

    6 Oct 10 at 19:13

  27. @Jim, when I wrote “give the path to the blog as an argument” it means that you need to put after the script name the path to the directory where the blog is installed on the server. The mentioned line should be executed from a shell on the server.

    Guy

    7 Oct 10 at 00:18

  28. I guess my question is even more basic. How do I execute the line mentioned from the shell? In a separate executable text file in the same directory? Is there somewhere else to write the line in the shell to execute? I am using webshell3 in Hsphere.

    Jim

    7 Oct 10 at 07:32

  29. Hi Jim,

    I’m not familiar with Hsphere. Basically, you should put the line directly in the shell.

    Guy

    9 Oct 10 at 20:44

  30. hey there – i posted on one of your previous post (original FTP backup script), not realizing that this one was the new one. i ran into one issue with the original script, which was that the command lftp (line 42) wasn’t recognized, so i wasn’t sure how to go about troubleshooting that — backup worked though. as to this updated script, i can’t seem to get it working because i can’t seem to figure out, for the life of me, how to give the path to the blog as an argument. my script is in the same directory (root) as my wp installation, so i’ve tried a bunch of combos to execute it and just can’t get it right. i’ve tried /var/www/vhosts/mysite.com/httpdocs/ and /httpdocs, just plain / and everything in between. i know you’re probably swamped with a ton of other things — and thank you for taking the time to actually post this! — but i was hoping you could point me in the right direction!

    mk

    25 Oct 10 at 06:34

  31. 1. Install lftp using your package manager. Without it the local backups will work, but you won’t be able to preform the FTP backups.

    2. Have you looked at the example at the post (second code snippet)?

    Guy

    25 Oct 10 at 07:31

  32. Hi,
    Thanks for your script.
    I tested it on my local my machine and it was working, but one day I got the following error:
    ~/www$ sudo ./wp-backup wordpress/
    PHP Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 81 bytes) in /home/aser/www/wordpress/wp-includes/pomo/mo.php on line 204

    Any idea?
    Best regards

    Aser

    16 Nov 10 at 23:10

  33. I doubt that the error is related to the backup script, but I believe I may still be of help. Try to raise the memory limit available to your php. It can be done via the php.ini configuration file, and here should also be a programmatic way to change it.

    Guy

    17 Nov 10 at 22:11

  34. Hi,
    I had a 128mb limit in php.ini but I needed to change wp-settings also:
    define(‘WP_MEMORY_LIMIT’, ’128M’);
    Nothing to do with your script ;)

    Thanks

    Aser

    19 Nov 10 at 01:52

  35. [...] FTP Backups – How to automate backing up to a FTP server [...]

  36. Thanks for such a great script. works wonders

  37. Hi,

    Thx for this amazing script.
    I’ve a problem with FTP : my password is something like “blabla<1azd" and the "<" is a problem :

    ./wp-backup: line 17: Syntax error near to "1"
    ./wp-backup: line 17: `FTP_PASS=blabla<1azd'

    How to fix it please ?
    Thank again !

    Stéphane

    Stéphane

    5 Jul 11 at 12:45

  38. Hi Stéphane,

    Just surround it with quotes, e.g.:
    FTP_PASS="blabla<1azd"
    and it should do the trick

    Guy

    8 Jul 11 at 13:49

  39. [...] Pour ceux qui chercheraient encore un bon script de backup FTP pour leur blog WordPress, il y en a un bon par ici, [...]

  40. [...] FTP Backups [...]

  41. [...] FTP Backups [...]

  42. thanks for share. I like this

    alis morey

    18 Oct 11 at 12:51

  43. Excellent script guyrutenberg it working great with my blog! Thanks alot

    abhiz

    13 Dec 11 at 13:25

  44. [...] FTP Backups – How to automate backing up to a FTP server [...]

  45. [...] FTP Backups – How to automate backing up to a FTP server [...]

  46. Many thanks for the script… I will try and work out how to implement it… I looked at my hosting provider and it says that they have SSH Shell… I assume that this is where I should be working…

    Now what about the restore? is there another script to use?

    I am asking this becasue I want to test the whole process on a test website that I have before implementing it on the live one.

    Thank you…

    IK

    12 Dec 12 at 21:10

  47. There is no script for restoring. In order to restore the backup you need to use an ftp client to fetch the tar archive and sql dump and then unpack the archive and import the dump to your db. If you need, I guess you can easily automate it.

    Guy

    14 Dec 12 at 17:13

  48. Thank you for this – I’m having trouble with the execution. Actually, I have no clue!

    Jonathan

    15 Dec 12 at 01:16

  49. Excellent script, thx a bunch!

    Optimator

    17 Dec 12 at 19:05

  50. Awesome script, i hosted my website on a free webhost, when i tried to make a back up using their backup tool, i got an error message, and after that i was looking for another option to back up my site, and this script is most useful. thank you for such a wonderful script :)

    Timix

    24 Dec 12 at 19:11

  51. [...] I was trying to make the FTP backup for WordPress work but my CentOS webserver got stuck at ‘making data connection’ when using LFTP for [...]

  52. [...] FTP Backups - How to automate backing up to a FTP server [...]

  53. I just took it and copied the entire folder. Is that bad?

    mazafakaniga

    15 Feb 13 at 04:03

  54. You should also have a dump of your db along side it.

    Guy

    16 Feb 13 at 10:47

  55. [...] you prefer a simpler solution, and don’t care about incremental or encrypted backups, see my Improved FTP Backup for WordPress or my WordPress Backup to Amazon S3 Script. Duplicity is the magic behind all this. It’s a [...]

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>