Shipit Node App with Docker

上面提到如何在代碼部署到 Remote Server 后,將 Sercert file link 到相應位置,然后通過 PM2 啟動服務。

但我們真實的項目,是構建 Docker 鏡像然后啟動鏡像來實現最終的發布,畢竟 Docker 有著更好的隔離性。

使用 Docker 的流程又是什么樣子呢?

  1. 將代碼放到 remote server 指定位置(已完成)。
  2. 在 remote server 上將 shared dirs/files 放到指定位置。
  3. 在代碼目錄下 build docker image。
  4. 啟動。

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::

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容