运维 Shell 备份目录问题

suntopo · June 06, 2016 · Last by martin91 replied at June 07, 2016 · 6743 hits

每次更新代码时,要把原来代码备份一下,关键是用户的资源文件也放到了项目根目录下面了 .

一个 cp 可以解决根目录下除了 public 目录下的备份吗?

rsync with exclude

rsync -av --progress sourcefolder destinationfolder --exclude thefoldertoexclude

你应该用 cap 部署

你可以使用 Capistrano 这个 Gem 包,可以设置链接文件,部署的时候,提前在服务器创建这些文件,cap 会自动帮你链接上

# Default value for :linked_files is []
set :linked_files, fetch(:linked_files, []).push('config/database.yml', 'config/secrets.yml')
# shared/config/database.yml

# Default value for linked_dirs is []
set :linked_dirs, fetch(:linked_dirs, []).push('log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'public/system')

接着 #3 楼 @ecloud 的回答往下补充,楼主的问题可以借鉴 capistrano 的部署机制,先上图: 图中 releasescurrentshared 是 capistrano 部署时几个重要的目录(当然还有其他目录和文件,但是由于主题无关,暂时不表),各自作用是:

  • releases: releases 目录下按照每次部署建立一个新的目录,目录名用时间戳命名,比如图中的 20160606035914,capstrano 会自动通过 git 拉取部署时指定的代码,放到这个目录下,作为一份代码的拷贝,这跟你说的第一点目的一致:每次更新代码时,要把原来代码备份一下
  • shared: shared 目录下存放在每个 version 代码间共享的文件或者目录,比如我们常见的 config/database.ymlpublic/ 等等,capistrano 会在拉取完代码后,自动执行 ln -s shared/xxxx #{last_release}/,这样就将共享文件以链接的方式挂到了每个 release 下边;
  • current: 这同样是一个文件链接,在部署完成之后,capistrano 执行 ln -s /xxx/releases/xxxxx /xxx/current,这样就将 current 指向了最后一个部署的 release。用 current 链接的好处是你可以 /xxx/current 这样的绝对路径直接访问到你的最新代码目录,也方便在 Nginx 等 HTTP 服务器中直接配置站点 root 地址。而回滚部署也很简单,只需要重新将 current 链接到前面的 release 目录就可以了。

说了这么多,给个流程图(注意:去掉了很多细节,只留下跟这次讨论有关的内容):

所以回到楼主的问题,解决你的需求很简单,方案有二:

  1. 直接集成 capistrano 或者 mina,自动化部署你的代码,你的这些需求都能轻松得到满足,相关配置楼上已经给过,不再重复;
  2. 你去仔细研究一下 capinstrao 或者 mina 机制跟流程,然后自己造一个简单轮子,哪怕只是实现上面我提到的三个目录的机制都够你用了。

个人推荐1

You need to Sign in before reply, if you don't have an account, please Sign up first.