神代綺凛

每日自动将你的网站备份到Github 告别数据丢失
最近听到许多数据丢失的惨况,有人提议为何不用 Github 去备份网站?而且这样还能看到每次 commit 的更改...
扫描右侧二维码阅读全文
28
2018/03

每日自动将你的网站备份到Github 告别数据丢失

最近听到许多数据丢失的惨况,有人提议为何不用 Github 去备份网站?而且这样还能看到每次 commit 的更改情况,随时任意回档。一拍大腿,亲自试验,做出成品,写下文章,一气呵成(

Head Pic: 「レイマリなプレイマット」/「望月椎那」[pixiv]

将网站自动备份到 Github

Github 已经允许免费用户创建无限量的私有 repo,皆大欢喜

本文将会给具体实现步骤,以及过程中用到的所有命令的解释

步骤是死的,人是活的,在一些不需要完全遵守的地方(比如各种使用的路径之类的)可以根据自己的需要和习惯自行改变

1. 一点微小的事先准备

首先的首先,你当然需要一个 Github 账户(

然后接下来是在服务器上的操作:

进入一个你喜欢的安全的目录,此处直接以/root为例

参考下命令创建一个 RSA 密匙

cd /root
ssh-keygen -t rsa

然后根据提示输入生成密匙的文件名,此处举例输入github,要你输入 passphrase 的时候直接不输入回车就行

完成后会有类似这样的显示,并且你会在当前目录下得到githubgithub.pub这两个文件

接着用cat命令查看github.pub文件的内容,并复制下来

cat github.pub

还没完,回到你的 Github 页面,点右上角头像,Settings,左边“SSH and GPG keys”,右上角“New SSH key”

然后将刚才复制的内容粘贴到“Key”输入框中,上方的“Tittle”自己随意输入,然后“Add SSH key”

这样事前准备就完成了,嗯,其实就是加一个 SSH 密匙到 Github,这样可以方便后续 Github 项目的同步

2. 创建一个私密 Github 项目

要备份当然首先得有一个 Github 项目啦

直接右上角新建项目

记得选成私密(Private)就行,不然你整个网站就被别人盗走了……

3. 在你的站点目录下初始化你的 Github 项目

进入你的站点所在目录,并执行一系列 git 初始化命令,参考以下代码

假设我的网站在/www/wwwroot/xxx.com,Github 项目为Tsuk1ko/test

cd /www/wwwroot/xxx.com
git init
git remote add origin git@github.com:Tsuk1ko/test.git

第三句的目的是设定当前项目的同步方式为 SSH(是的,我们准备步骤中创建的密匙就是要用在这上面),并指定了仓库地址Tsuk1ko/test

为什么用 SSH 方式而不用 HTTPS 方式?

HTTPS 方式是要你输入用户名密码的,虽然你可以直接将用户名密码输入到链接中,像这样https://yourname:password@github.com/name/project.git,但是在链接中明文输入用户名密码是极不安全的,容易被监听窃取

另外还有一种办法是使用git config --global credential.helper store,这样会在.git中生成一个配置文件来储存你的用户名密码,但是你要意识到你现在所处的目录是一个网站,如果你忘了在网站配置中禁止对.git的访问,那么你的用户名密码也会很容易泄露

所以,SSH 还是最为稳妥的一种方式

4. 尝试同步当前站点到 Github 项目

cd /www/wwwroot/xxx.com
git add -A
git commit -m "backup"
ssh-agent bash
ssh-add /root/github
git push -u origin master

命令解释

  1. 进入网站目录
  2. 把目录下所有文件变化(增、删、改)提交到暂存区
    如果你想只增、改而不删,那么可以用git add .命令代替
  3. 提交所有更改,这个"backup"可以随意填写,没有影响,其实就是你提交改动的时候的说明,但是 commit 的时候必须要有这个说明
  4. 启动 SSH 密钥管理器
  5. 将之前我们创建的github密匙文件添加到密匙管理器中
  6. 推送所有更改到 Github 项目

执行完后你应该能看到文件上传进度等回显,等待执行完毕,然后去自己的私密项目刷新一下,你的网站是不是整个被上传上去了?(好耶!

5. 设定每天自动同步

实际上就是使用 crontab 定时任务每天git push一次,但是操作与上面略有不同,并且有一些需要注意的点

如果你没有安装 crontab,那么百度一下安装方法自行安装,此处不再赘述

当然,如果你使用宝塔面板等自带 crontab 管理功能的就更方便了,接下来的步骤请自行灵性应对

首先找个你喜欢的目录,创建一个脚本例如/root/backup_website.sh,然后写入以下内容并保存

#!/bin/bash
cd /www/wwwroot/xxx.com
git add -A
git commit -m "backup"
ssh-add /root/github
git push -u origin master

接着编辑 crontab 的配置文件,一般是/var/spool/cron/crontabs/root,在最下面加入这行,然后保存退出

30 3 * * * ssh-agent bash /root/backup_website.sh

这条 crontab 命令代表每天凌晨3:30分执行ssh-agent bash /root/backup_website.sh命令

接着重启一下 crontab 使新配置文件生效

# CentOS6 系列及以下
service crond restart
# CentOS7 系列
systemctl restart crond.service
# Ubuntu / Debian 系列
/etc/init.d/cron restart

搞定,这样每天凌晨3:30的时候就会自动备份你的网站到 Github 了,想改成其他时间也可以,自行更改 crontab 命令即可

不过这只是备份了网站目录,数据库之类的也要记得勤备份,或者你也可以仿照这样的方式每天自动把数据库导出到一个地方然后同步到另外一个 Github 项目

注意点解释

细心的你肯定注意到了此步骤和上一步骤中命令的不同,关键就在于ssh-agent

我们是使用 SSH 去同步 git 的,因此在同步之前,服务器上也必须先添加 SSH 密匙(ssh-add)才能连接到 Github

你可以试一下,重开一个 SSH 窗口,直接使用ssh-add /root/github命令,是无法添加密匙的,会报Could not open a connection to your authentication agent.,因为密匙管理器ssh-agent并没有运行

但是如果你使用以下这样的脚本内容

#!/bin/bash
cd /www/wwwroot/xxx.com
git add -A
git commit -m "backup"
ssh-agent bash              #加上这句
ssh-add /root/github
git push -u origin master

然后直接bash /root/backup_website.sh运行,你会发现目录切换到了/www/wwwroot/xxx.com,然后,什么事也没发生

这是为什么呢

因为当你直接运行ssh-agent bash的时候,实际上是相当于使用ssh-agent新建了一个bash窗口,然后……就没有然后了,后面的命令并没有在这个新建的窗口中运行

大概像这样

#!/bin/bash
# 以下命令在原本的 bash 窗口中运行
cd /www/wwwroot/xxx.com
git add -A
git commit -m "backup"

# 当运行到这一句的时候,ssh-agent 新建了一个 bash 窗口
# 而你也看到了这个窗口
ssh-agent bash

# 但是下面这两句仍然是在原本的 bash 窗口中运行的
ssh-add /root/github
git push -u origin master
# 只是因为你执行完 ssh-agent bash 之后,切换到了新的 bash 窗口
# 所以你并不会看到这两句命令执行的回显
# 实际上 ssh-add 将会因为我前面说过的原因而不能添加密匙
# 所以 git push 自然会因为没有密匙而失败

所以我才不在脚本中执行ssh-agent,而是放到了最外层的 crontab 命令上

ssh-agent bash /root/backup_website.sh

这样执行,相当于用ssh-agent创建了一个bash,而这个bash会接收参数/root/backup_website.sh,运行这个脚本,也就是在ssh-agent运行的情况下执行了后续的ssh-add等命令

这样才可以成功实现 SSH 访问 git 并同步

我一开始也是碰到了这个坑,不过弄明白之后感觉对命令行有了更深的理解,总归是没有白忙活

搬瓦工VPS优惠套餐,建站稳如狗,支持支付宝,循环出账94折优惠码BWH3HYATVBJW
年付$47CN2线路,1核/1G内存/20G硬盘/1T@1Gbps【点击购买
季付$47CN2 GIA线路,1核/1G内存/20G硬盘/1T@2.5Gbps【点击购买
Last modification:January 12th, 2019 at 12:32 pm
If you think my article is useful to you, please feel free to appreciate

Leave a Comment

25 comments

  1. 寒夜方舟  Windows 10 x64 Edition(Windows 10 x64 Edition) / Google Chrome 77.0.3865.120(Google Chrome 77.0.3865.120)
    如果用面板会简单点,自动打包所有网站文件和数据库,或者阿里云快照,超级便宜一个月也才一块钱
    1. 神代綺凜  Mac OS X(Mac OS X) / Safari(Safari)
      @寒夜方舟 他们的适用场景不同

      这个方法的优势在于利用 git 做到增量备份,因此可以以很高的频率进行备份,而且能随时回退到某个时间点

      比如一个有几G大的站点,你选择打包备份,每次都要传输这么多内容,所以备份频率还不能太高,如果用的还是国内小水管机器那不是直接没了

      目前我会综合使用你说的面板备份和git进行备份,备份数据库是面板方便而且也不大可以每天备份,博客每天git备份,每周面板打包传七牛

  2. 巡璃  Windows 10 x64 Edition(Windows 10 x64 Edition) / Google Chrome 76.0.3809.100(Google Chrome 76.0.3809.100)
    感谢教程,十分实用
    在下有两个问题,在琢磨git的时候,记得先是要git pull origin master 把本地仓库的变化连接到远程仓库主分支,然后再git push -u origin master。奇怪的是有时候需要这个有时候不需要,不太明白。
    还有就是ssh-add 之后需要手动输入passphrase,不知有没有可选项能自动输入passphrase
    再次感谢
    1. 神代綺凜  Mac OS X 10.14.6(Mac OS X 10.14.6) / Google Chrome 76.0.3809.100(Google Chrome 76.0.3809.100)
      @巡璃 1、https://www.zhihu.com/question/20019419

      2、需要 passphrase 是因为你生成密钥的时候设定了,如果不想要就在生成的时候直接回车不要输入 passphrase 就行
      如果你一定需要的话,可以利用<<<来预先设置交互输入内容,具体请自行搜索bash <<<

      1. 巡璃  Windows 10 x64 Edition(Windows 10 x64 Edition) / Google Chrome 76.0.3809.100(Google Chrome 76.0.3809.100)
        @神代綺凜 感谢!
  3. Jockie  Windows 10 x64 Edition(Windows 10 x64 Edition) / Firefox 68.0(Firefox 68.0)
    还有一个方案。
    挂载存储桶或者NAS,通过rsync命令可以实现增量备份。
  4. 会飞的猫  Windows 10 x64 Edition(Windows 10 x64 Edition) / Google Chrome 72.0.3626.109(Google Chrome 72.0.3626.109)
    ssh-agent 原来是这样,我说计划任务一直不成功
  5. Hannes  Windows 10 x64 Edition(Windows 10 x64 Edition) / Google Chrome 70.0.3538.77(Google Chrome 70.0.3538.77)
    一个更方便的方法:

    1. 用宝塔面板的计划任务 - 自动备份功能,每天定时把网站和数据库自动备份到服务器磁盘的/www/backup/目录
    2. 在上述目录手动建个本地repo,写个shell脚本commit
    3. 用宝塔面板的计划任务功能,在自动备份时间半小时后运行这个脚本
      完毕
    1. 神代綺凜  Windows 10 x64 Edition(Windows 10 x64 Edition) / Google Chrome 71.0.3578.98(Google Chrome 71.0.3578.98)
      @Hannes 宝塔的备份由于是压缩打包,并不能利用git增量备份的优势,跟宝塔的七牛备份之类的没差别了
      至于数据库备份可以这样利用,先备份再复制到网站某目录,随网站一起用git备份,不过注意 nginx 等做好防护措施禁止访问数据库存放的目录
  6. 九四  Windows 10 x64 Edition(Windows 10 x64 Edition) / Google Chrome 66.0.3359.170(Google Chrome 66.0.3359.170)
    何不加上这一句备份数据库?
    mysqldump -uroot -ppassword sql> sql.sql
    1. 梦酱  Windows 10 x64 Edition(Windows 10 x64 Edition) / Google Chrome 80.0.3987.132(Google Chrome 80.0.3987.132)
      @九四 老哥,这个数据库备份具体应该怎么操作可以稍微说一下吗OωO
      1. 梦酱  Windows 10 x64 Edition(Windows 10 x64 Edition) / Google Chrome 80.0.3987.132(Google Chrome 80.0.3987.132)
        @梦酱 嗷,不好意思,按照老哥的思路已经解决了。。
    2. 神代綺凜  Windows 10 x64 Edition(Windows 10 x64 Edition) / Google Chrome 66.0.3359.139(Google Chrome 66.0.3359.139)
      @九四 嗯,这里只是提供了思路,你可以自由发挥
  7. 小宇宙  Windows 10 x64 Edition(Windows 10 x64 Edition) / Google Chrome 65.0.3325.146(Google Chrome 65.0.3325.146)
    这种备份只是备份了网站文件,数据库没有备份吧
    假设网站崩了用备份的文件也恢复不了网站 没有数据库文件
    1. 神代綺凜  Windows 7(Windows 7) / Google Chrome 65.0.3325.181(Google Chrome 65.0.3325.181)
      @小宇宙 恩,我这里只是提供了一个思路,数据库当然也可以如法炮制,用脚本定时从mysql导出成sql文件然后备份到github仓库,不过我自己是直接用的宝塔的七牛备份脚本所以没有去考虑这么多复杂的问题
      另外使用git去备份的一个主要原因是可以很简单的做到增量备份,这意味着你可以提升备份频率而且不需要像全部打包上传备份这样消耗这么多流量
  8. Civin  Mac OS X 10.13.4(Mac OS X 10.13.4) / Safari 11.1(Safari 11.1)
    老哥,你的博客是用hexo搭建的吧,那你是怎么做到把网站放到云主机上还能在本地实时更新的呢?
    1. 神代綺凜  Mac OS X(Mac OS X) / Safari(Safari)
      @Civin 是Typecho
      这不是静态博客
  9. dark  Windows 10 x64 Edition(Windows 10 x64 Edition) / Google Chrome 65.0.3325.181(Google Chrome 65.0.3325.181)
    1. 神代綺凜  Windows 10 x64 Edition(Windows 10 x64 Edition) / Google Chrome 65.0.3325.162(Google Chrome 65.0.3325.162)
      @dark 这,难道是因为我通过了github学生认证的原因?
      或者你也可以去gitlab,国内的码云、coding之类的git平台看看
  10. dark  Windows 10 x64 Edition(Windows 10 x64 Edition) / Google Chrome 65.0.3325.181(Google Chrome 65.0.3325.181)
    在GitHub上创建隐私项目还要收费的是吧
    1. 神代綺凜  Mac OS X(Mac OS X) / Safari(Safari)
      @dark 不用,免费的
  11. Mashiro  Windows 10 x64 Edition(Windows 10 x64 Edition) / Firefox 59.0(Firefox 59.0)
    关键还有数据库备份,MySQL导出挺麻烦的
    1. 神代綺凜  Windows 10 x64 Edition(Windows 10 x64 Edition) / Google Chrome 65.0.3325.162(Google Chrome 65.0.3325.162)
      @Mashiro mysql自动导出用命令应该不难实现吧,不过我用的是宝塔的自动备份所以就不用想这些了
      (同是真白厨
      1. Mashiro  Windows 10 x64 Edition(Windows 10 x64 Edition) / Firefox 59.0(Firefox 59.0)
        @神代綺凜 一直用phpMyAdmin手动备份的 ̄﹃ ̄
  12. True  Windows 10 x64 Edition(Windows 10 x64 Edition) / Google Chrome 64.0.3282.167(Google Chrome 64.0.3282.167)
    真不错,