备份脚本

使用Shell脚本backup_wordpress.sh备份VPS上wordpress整个目录、数据库、nginx和php-fpm配置文件,将所有备份内容按日期压缩成一个单独文件

#!/bin/bash

dbuser=xxxx
dbpwd=xxxxx
dbname=xxxx

today=`date '+%Y%m%d'`
bakdir=wordpress-$today

mkdir /root/$bakdir
mkdir /root/$bakdir/site
mkdir /root/$bakdir/mysql

bakfile=/root/wordpress-${today}.tar.gz
[ -f $bakfile ] && rm -rf $bakfile

cp -rf /usr/share/nginx/html/wordpress /root/$bakdir/site/
cp -rf /var/lib/mysql/wordpress /root/$bakdir/mysql/
cp /etc/nginx/nginx.conf /root/$bakdir/
cp /etc/php-fpm.conf /root/$bakdir/
mysqldump -u${dbuser} -p${dbpwd} ${dbname} > /root/$bakdir/wordpress_db.sql
tar zcvfP ${bakfile} /root/$bakdir >/dev/null
rm -rf /root/$bakdir

安装Dropbox的Python SDK

Dropbox提供了用于移动应用的Sync API、web应用的Core API并提供其多种语言的SDK,我们使用Dropbox Core API的Python SDK,VPS上已经安装Python,使用Python脚本也更方便,下载Python SDK

wget https://www.dropbox.com/static/developers/dropbox-python-sdk-1.5.1.zip

安装Python的setuptools,egg包安装工具easyinstall

wget https://pypi.python.org/packages/2.6/s/setuptools/setuptools-0.6c11-py2.6.egg#md5=bfa92100bd772d5a213eedd356d64086
sh setuptools-0.6c11-py2.6.egg

构建dropbox python sdk的egg包并安装,安装成功后就可以使用dropbox python sdk了

cd dropbox-python-sdk-1.5.1
python setup.py bdist_egg
cd dist
easy_install dropbox_python_sdk-1.5.1-py2.6.egg

创建dropbox应用

为了能在VPS上将wordpres备份数据上传到dropbox保存,须在dropbox developers网站创建使用dropbox api的第三方应用,按照特定的授权方式以访问dropbox上保存的文件。也就是说,我们在VPS上将wordpress备份文件上传到dropbox的python脚本,其实是使用dropbox开放API的一个第三方应用。应用访问类型采用app_folder。

image

创建成功后会生成App Key和App Secret

image

Python脚本

dropbox的python SDK是基于其REST API封装的几个类,使用OAuth 1.0认证方式。因此写了两个脚本,脚本login_dropbox.py按照OAuth 1.0的认证过程取得access_token,分三步,1)拿已申请的App Key、App Secret获取request token;2)用request token key手工登录生成的授权界面点击Allow获得授权;3)用request token key取得access token,将这个access token保存到文件/root/token_store.txt中。上传备份文件到dropbox的脚本put_to_dropbox.py读取保存的access token构造请求以上传。OAuth 1.0认证不在本文讨论范围呢,可google详细的认证流程、几种token的区别及其在整个认证过程中的作用。

login_dropbox.py

import cmd
import locale
import os
import pprint
import shlex

from dropbox import client, rest, session

# XXX Fill in your consumer key and secret below
# You can find these at http://www.dropbox.com/developers/apps
APP_KEY = 'xxxxxx'
APP_SECRET = 'xxxxxxxxx'
ACCESS_TYPE = 'app_folder'  # should be 'dropbox' or 'app_folder' as configured for your app

TOKEN_FILE = "/root/token_store.txt"


def main():
	sess = session.DropboxSession(APP_KEY, APP_SECRET, ACCESS_TYPE)
	request_token = sess.obtain_request_token()
	url = sess.build_authorize_url(request_token)
	print "authorize url: ", url
	print "Please authorize in the browser. After you're done, press enter."
	raw_input()
	
	access_token = sess.obtain_access_token(request_token)
	f = open(TOKEN_FILE, 'w')
	f.write(",".join([access_token.key, access_token.secret]))
	f.close()
	
	print "access token wrote into ", TOKEN_FILE

if __name__ == '__main__':
	main()

login_dropbox.py须先执行获取access token保存到文件中供脚本put_to_dropbox.py上传文件使用,输出如下
image
需要在浏览器中访问红框所示url,并点击Allow获取access token,然后回到VPS的终端上敲enter回车键脚本会继续执行获取access token并保存入文件中。如下图所示
image

 

put_to_dropbox.py脚本接收两个命令行参数,本地的备份文件全路径和远程dropbox上要生成的文件名,Usage: python put_to_dropbox.py from_path to_path。

import locale
import os
import pprint
import shlex
import sys

from dropbox import client, rest, session

# XXX Fill in your consumer key and secret below
# You can find these at http://www.dropbox.com/developers/apps
APP_KEY = 'xxxx'
APP_SECRET = 'xxxx'
ACCESS_TYPE = 'app_folder'  # should be 'dropbox' or 'app_folder' as configured for your app

TOKEN_FILE = "/root/token_store.txt"


def main():

	if len(sys.argv) < 3:
	    exit("Usage: python put_to_dropbox.py from_path to_path")

	

	from_path = sys.argv[1]
	to_path = sys.argv[2]

        sess = session.DropboxSession(APP_KEY, APP_SECRET, ACCESS_TYPE)

	try:
		stored_creds = open(TOKEN_FILE).read()
		sess.set_token(*stored_creds.split(','))
		print "[loaded access token]"
	except IOError:
		exit("please run login_dropbox.py to login and obtain access token.")

	from_file = open(os.path.expanduser(from_path), "rb")
	cli = client.DropboxClient(sess)
	response = cli.put_file("/" + to_path, from_file)
	print "uploaded: ", response
	from_file.close()

if __name__ == '__main__':
        main()

设置cron脚本以执行定时备份

至此,我们有三个脚本,backup_wordpress.sh、login_dropbox.py、put_to_dropbox.py,login_dropbox.py是要事先执行,然后才能执行put_to_dropbox.py。我们设置crontab使其每天凌晨2点执行backup_wordpress.sh备份并用put_to_dropbox.py上传至dropbox。

执行crontab -e输入

0 2 * * * (/root/backup_wordpress.sh && python /root/put_to_python.py /root/wordpress-`date '+%Y%m%d'`.tar.gz wordpress-`date '+%Y%m%d'`.tar.gz 2>&1 >> /var/log/wp_bak.log)