CMS有不少備份工具可以選擇,尤其是Wordpress這類歷史悠久的CMS,備份插件之多讓你無從入手,但是很多插件工具都不是免費讓你使用的,特別是備份到Google Cloud Storage(GCS)這類較新的空間,目前只找到一個最像樣的由UpdraftPlus提供的插件,它支援GCS的收費是每個網域$15美金,雖然價錢還算合理,但工程師的自尊不容許我沒試過便直接付錢買下去(雖然最後還是買了),所以花了點下班休息時間自己試做一下。
一﹒準備工作
這次還是用我熟悉的Node.js,沒有Node可以到這裡看看安裝方法,而且這次是直接從VM備份到GSC,所以很方便不需要credential認證
- 安裝好Node.js
- 一個Google的VM instance
- Google Cloud Platform(GCP)開放Storage服務權限
- 一個GSC Bucket
二﹒開放VM服務範圍(scope)
先到你的VM控制面版,拉到最下面查看啟動了的服務,如果顯示是這樣,表示已經啟動所有權限了,所以請跳過這步驟
如果Storage狀態是Enable
,也可跳過這步驟,但是如果跟下圖一樣只有讀取(Read Only)權限便要繼續進行設定
假設你的VM沒有開啟Storage權限,先按Stop關掉你的VM,然後按Edit編輯VM的設置
我個人是蠻怕麻煩的,反正有防火牆,所以便直接開啟所有服務權限,最後儲存再重啟你的VM便完成了
三﹒編寫備份程式
怎樣建立一個project就不多說了,可以直接到我的GitHub下載原碼
NPM模組
"dependencies": {
"@google-cloud/storage": "^0.7.0",
"adm-zip": "^0.4.7",
"archiver": "^1.3.0",
"bluebird": "^3.5.0",
"cron": "^1.2.1",
"fast-crc32c": "^1.0.4",
"moment": "^2.17.1",
"mysqldump": "^1.3.1"
}
CoffeeScript原碼
_ = require 'lodash'
fs = require 'fs'
path = require 'path'
moment = require 'moment'
archiver = require 'archiver'
mysqlDump = require 'mysqldump'
Promise = require 'bluebird'
CronJob = require('cron').CronJob
# GCP
gcs = require('@google-cloud/storage')()
bucket = gcs.bucket 'MY-GCS-BUCKET' # Your bucket name
# Params
timezone = 'Asia/Hong_Kong' # Cron job timezone
cronInterval = '0 0 4 * * *' # Run every day at 4a.m.
bak 大专栏 Wordpress備份自己做,從Google VM直接備份至Cloud Storage!Filename = "backup-#{moment().format("YYYYMMDDHH")}.zip"
# Config
config =
out: "#{__dirname}/#{bakFilename}" # Temporary zipped backup path
wordpress:
dir: '/var/www/html/wp' # Wordpress root dir
mysql:
host: 'localhost'
user: 'root'
password: ''
database: 'wp'
dest: "#{__dirname}/wp.sql" # Temporary sql dump file path
# Dump Mysql
backupMysql = ->
return new Promise (rs, rj) ->
mysqlDump config.mysql, (err) ->
return rj err if err?
rs config.mysql.dest
# Backup Wordpress with MySQL
createZip = (sqlPath) ->
return new Promise (rs, rj) ->
output = fs.createWriteStream config.out
archive = archiver 'zip',
store: true
cwd: 'wordpress'
archive.pipe output
# Listener
output.on 'close', ->
console.log "#{archive.pointer()} total bytes"
return rs()
output.on 'error', (err) ->
return rj err
# Add SQL Dump
archive.file sqlPath,
name: "#{config.mysql.database}.sql"
# Add Wordpress Directories
archive.directory config.wordpress.dir, '/wordpress'
# Finalize Zip
archive.finalize()
# Push to Google Cloud Storage
pushToGCS = ->
return new Promise (rs, rj) ->
file = bucket.file bakFilename
fs
.createReadStream config.out
.pipe file.createWriteStream({ gzip: true })
.on 'error', (err) ->
return rj err
.on 'finish', ->
console.log 'Pushed to GCS'
return rs()
# Cron Job
job = new CronJob
cronTime: cronInterval
onTick: ->
console.log 'Dumping MySQL database...'
backupMysql()
.then (sqlPath) ->
console.log 'Zipping Wordpress directory...'
return createZip sqlPath
.then ->
console.log "Pushing #{bakFilename} to Google cloud storage..."
return pushToGCS()
.then ->
console.log 'Backup success!'
.catch (err) ->
console.error err
.finally ->
console.log 'Deleting local backup files...'
try
fs.unlinkSync config.out
fs.unlinkSync config.mysql.dest
start: false
timezone: timezone
# Start Job
job.start()
console.log 'Monitoring...'
簡略說明一下,首先# GCP
用作設定GCS的bucket名稱,請預先在GCS建立一個bucket,這篇沒有包括建立bucket的教程;# Params
進行cron job的設定,預設了每天凌晨四點進行備份;而# Config
則設定了MySQL的連接資料,請自行修改這些設定,最後每次作業的先後次序是:
- 備份MySQL
- 把剛備份好的MySQL連同Wordpress壓縮到
config.out
內指定的位置 - 把壓縮檔傳送至設定好的bucket內
- 最後刪除本地的備份檔案
四﹒運行
權限設定好了,程式也有了,再來就是運行的部份了,這裡建議大家使用pm2,它是一個強大的Node管理系統
npm install pm2 -g
安裝好了以後用pm2
執行index.coffee,順便為程序命名
pm2 start index.coffee --name wp-backup
然後只要等到設定好的時間,系統便會自動進行備份了,運行的log大概是以下這樣,成功了便可以到GCS查看上傳了的備份檔案
Monitoring...
Dumping MySQL database...
Zipping Wordpress directory...
3811909 total bytes
Pushing backup-2017030900.zip to Google cloud storage...
Pushed to GCS
Backup success!
Deleting local backup files...
後記
到最後就如上面提及到,我還是買了UpdraftPlus的插件,因為我用的是最便宜VM,而沒記錯它只有0.6GB記憶體和1個共用核心,所以基本上運行了LEMP以後也沒剩多少資源讓我再運行一個Node.js的程序了,這是我花了幾小時設定好以上所有東西以後才發覺的,無奈我不是很熟悉PHP啊…