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

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

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

将网站自动备份到 Github

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

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

由于需要备份到私密仓库,貌似 Github 的私密仓库是收费的,但是博主创建的时候没有发现要收费,可能是因为通过了 Github 学生认证
如果你发现创建私密仓库需要收费,可以尝试注册其他国外或者国内(例如码云、Coding)的 git 平台看看
再不济自建一个 git 仓库,不过这样好像还不如 FTP 自动备份

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 项目为YKilin/test

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

第三句的目的是设定当前项目的同步方式为 SSH(是的,我们准备步骤中创建的密匙就是要用在这上面),并指定了仓库地址YKilin/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,那么百度一下安装方法自行安装,此处不再赘述

首先找个你喜欢的目录,创建一个脚本例如/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折优惠码BWH1ZBPVK
①年付仅需$18电信联通直连的亚洲优化线路,1核/512M内存/10G硬盘/1000GB@1Gbps【点击购买
②年付$18的可换成CN2线路(流量会变为180G),1核/512M内存/10G硬盘/500GB@1Gbps【点击购买
③年付$28的电信CN2联通直连线路,1核/512M内存/10G硬盘/500GB@1Gbps【点击购买】(购买后请到后台切DC8机房以获得最佳体验)

我的文章对您有帮助吗?
我很可爱 请给我钱
扫一扫拿红包 → 扫商家收款码 → 转账与红包相等的金额
即可免费赞赏,又可拿支付宝奖励金!
现在支付宝超抠门的,红包只给一两分钱了
Last modification:May 21st, 2018 at 12:46 am
If you think my article is useful to you, please feel free to appreciate

Leave a Comment

14 comments

  1. 九四  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 66.0.3359.139(Google Chrome 66.0.3359.139)
      @九四

      嗯,这里只是提供了思路,你可以自由发挥

  2. 小宇宙  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去备份的一个主要原因是可以很简单的做到增量备份,这意味着你可以提升备份频率而且不需要像全部打包上传备份这样消耗这么多流量

  3. 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
      这不是静态博客

  4. 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平台看看

  5. 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

      不用,免费的

  6. 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手动备份的 ̄﹃ ̄

  7. True  Windows 10 x64 Edition(Windows 10 x64 Edition) / Google Chrome 64.0.3282.167(Google Chrome 64.0.3282.167)

    真不错,