- https://github.com/shipitjs/shipit
- https://github.com/shipitjs/shipit-deploy
- https://github.com/timkelty/shipit-shared
上面提到如何在代碼部署到 Remote Server 后,將 Sercert file link 到相應位置,然后通過 PM2 啟動服務。
但我們真實的項目,是構建 Docker 鏡像然后啟動鏡像來實現最終的發布,畢竟 Docker 有著更好的隔離性。
使用 Docker 的流程又是什么樣子呢?
- 將代碼放到 remote server 指定位置(已完成)。
- 在 remote server 上將 shared dirs/files 放到指定位置。
- 在代碼目錄下 build docker image。
- 啟動。
Symbolic link Issue
但實踐中,發現一件很麻煩的事:docker dislike symbolic link ?? 。Dokcer build 時會忽略 soft link 的文件,如果項目根目錄是 soft link,也會出現問題,接下來主要就是解決這兩個問題。
shiptit-shared-copy
首先的是,app 目錄中不能含有 soft link 文件,不然不會被 copy 到 docker 鏡像中。
像 config/application.yml 這種通過 link 方式存在的,就不行了。
所以,解決方案是直接 fork shipit-shared 項目,把 symbolic link 改成 copy。
每次都會把文件復制到 current 對應的 release 版本中。
配置文件和 shipit-shared 保持不變:
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 名。就會有
20170302110102-app-koa2
這樣的名字。而不是current-app-koa2
。
除了會構建出多個不同名的鏡像,容器也無法被銷毀,導致端口被占用。就是說,這個構建不能被重復。
解決辦法也有,就是把releases/[version]
物理復制到另一個 current 一樣的固定的位置。起名叫 deploy
。就是下面這樣的目錄結構了:
.
|-- 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 中,復制即可使用:
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']);
});
}
Docker up
解決完 Symbolic link 的問題后,終于可以將 Docker 跑起來了。通過 docker-compose.yml 文件,可以將配置都放在其中,然后,只要在相應的目錄下啟動 docker 的命令就好了。
// Docker build & run on Remote
shipit.blTask('docker-up', function () {
shipit.log('docker-compose up with build...');
return shipit.remote('cd ' + shipit.config.deployTo + '/deploy; docker-compose up -d --build');
});
REF::
- 本項目用到的完整 shipitfile.js https://github.com/lanvige/koa2-boilerplate/blob/master/shipitfile.js