Shipit Node App with Docker

上面提到如何在代码部署到 Remote Server 后,将 Sercert file link 到相应位置,然后通过 PM2 启动服务。

但我们真实的项目,是构建 Docker 镜像然后启动镜像来实现最终的发布。

这里的流程又是什么样子呢?

  1. 将代码放到 remote server 指定位置(已完成)。
  2. 在 remote server 上将 shared dirs/files 放到指定位置。
  3. 在代码目录下 build docker image。
  4. 启动。

但实践中,发现一件很麻烦的事:docker dislike symbolic link 😓

shiptit-shared-copy

首先的是,app 目录中不能含有 soft link 文件,不然不会被 copy 到 docker 镜像中。

像 config/application.yml 这种通过 link 方式存在的,就不行了。

所以,直接 fork shipit-shared 项目,把 symbolic link 改成 copy。

每次都会把文件复制到 current 对应的 release 版本中。

配置文件和 shipit-shared 保持不变:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
module.exports = function (shipit) {
require('shipit-deploy')(shipit);
require('shipit-shared')(shipit);
shipit.initConfig({
default: {
shared: {
overwrite: true,
files: [
'config/application.yml',
'config/database.yml'
],
}
}
});
};

deploy-duplicate

解决完 app 内部 soft link 的问题后,然后在 current 下用 docker-compose 构建镜像,然后启动。发现不能重复,原因是,每次构建的目录并不是 current 这个 soft link 的目录。而是 releases/[version] 这个目录。

目录名变化后,构建出的镜像就不一致了,这就导致无法重复的在一个目录下进行多次构建。

compose 构建后的镜像是用 目录名+service 名。

同时也会引发无法销毁的问题,端口被占用。

解决办法也有,就是把releases/[version] 物理复制到另一个 current 一样的固定的位置。起名叫 deploy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
.
|-- current -> releases/20170228072117
|-- deploy
| |-- app
| |-- bin
| |-- config
| |-- docker-compose.yml
| |-- Dockerfile
| |-- lib
| |-- package.json
| |-- process.yml
| |-- REVISION
| `-- yarn.lock
|-- releases
| |-- 20170228062744
| `-- 20170228072117
`-- shared
`-- config

这样,每次在 published 后,都将最新的 releases 版本复制到 deploy。然后在 deploy 下执行 docker-compose up -d --build

没有做成单独的 npm,直接放在 shipitfile 中即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
module.exports = function (shipit) {
// Docker dislike soft link
// So make a physical copy (deploy) instead of softlink (current)
shipit.blTask('deploy-clean', function () {
console.log('cp -R ' + shipit.releasePath + ' ' + shipit.config.deployTo + '/deploy');
return shipit.remote('rm -rf ' + shipit.config.deployTo + '/deploy');
});
shipit.blTask('deploy-duplicate', function () {
return shipit.remote('cp -R ' + shipit.releasePath + ' ' + shipit.config.deployTo + '/deploy');
});
shipit.on('published', function () {
shipit.start(['deploy-clean', 'deploy-duplicate']);
});
}

完美。


REF::