2016-09-12 29 views
13

我不確定我的問題是否相關,因爲我可能會嘗試混合不應混用的工具(Capistrano和Docker)。如何整合Capistrano與Docker進行部署?

我最近dockerized與Capistrano部署的應用程序。 Docker compose用於開發環境和登臺環境。

這是我的項目看起來像(未顯示的應用程序文件):

Capfile 
docker-compose.yml 
docker-compose.staging.yml 
config/ 
    deploy.rb 
    deploy 
     staging.rb 

泊塢窗撰寫文件創建所有必需的容器(Nginx的,PHP,MongoDB的,Elasticsearch等)運行在開發或登臺環境中的應用程序(因此在docker-compose.staging.yml中定義了一些特定參數)。

的應用程序部署到暫存環境中使用此命令:

cap staging deploy 

服務器上的文件夾結構是斯特拉努的一個:

current 
releases 
    20160912150720 
    20160912151003 
    20160912153905 
shared 

下面的命令已在已經運行current登臺服務器的目錄實例化所有必要的容器來運行應用程序:

docker-compose -f docker-compose.yml -f docker-compose.staging.yml up -d 

到目前爲止好。事情變得對未來部署更加複雜:在current符號鏈接將指向releases目錄的新目錄:

  • 如果deploy.rb定義了需要的容器(如docker-compose exec php composer install爲PHP)內要執行的命令,碼頭工人告訴容器還不存在(因爲現有的容器是在以前的發佈文件夾中創建的)。
  • 如果在Capistrano部署過程中執行了docker-compose up -d命令,由於端口衝突(之前的容器仍然存在),我得到一些錯誤。

你對如何解決這個問題有想法嗎?我應該離開Capistrano並做一些不同的事情嗎?

這個想法是保持Capistrano爲Docker容器的靈活性(例如在同一臺服務器上爲各種應用程序提供幾個PHP版本)所提供的零宕機時間部署。

回答

12

據我所知,您在主機上使用capistrano來重新部署整個應用程序堆棧,意味着容器。因此,您正在使用capistrano來編排建築,容器創建和部署。

當你做,你基本上運行帽當部署

  • 構建應用程序(根據你的主機上拉電流基地) - 甚至可能包括一飲而盡/咕嚕/建設任務
  • 然後你「包」到你的容器中使用「卷安裝」在你開始
  • /更換容器

你如願拿到了「幾乎」零停機時間部署。

如果你真正關心的停機時間和有關正式部署過程多,你應該正確使用適當的管道實施

  • 包裝/ CI
  • 部署/分佈

我不認爲capistrano可以/應該成爲您在此策略中可以使用的工具之一。 Capistrano意味着直接在服務器上使用ssh和git作爲傳輸來部署應用程序。使用上限在目標服務器上構建完整映像,然後將這些映像作爲容器啓動,實際上超過了頂端,恕我直言。

包裝/建築

要麼使用CI/CD服務器像詹金斯/竹/ gocd構建一個版本圖像爲你的應用程序。假設只有應用程序是根據'發佈'來定製的,可以說你有db和app作爲容器/服務,應用程序將包含你的源代碼並且在發佈期間會定期更改。

因此,它的CD/CI進程在CI服務器上異地構建新的應用程序鏡像(發行版)。使用COPY,然後使用任何RUN語句來編譯您的資源(npm/gulp/grunt),將應用程序的源代碼打包到圖像中。這一切都不是發生在生產服務器上,而是發生在CI/CD代理上。

然後你推這個release-image,讓這個圖像yourregistry.com/yourapp成爲你的private registry作爲一個新的部署版本。

部署

與停機時間(容易)

要部署到生產或分期停機的服務器,你會簡單地做一個docker-composer stop && docker-composer up - 這會自動將更新的圖像,然後在您的堆棧啓動 - 您的應用已升級

服務器當然應該能夠從您的私有存儲庫中提取。

withou停機時間(更多的努力)

實現零停機時間的部署,你應該使用blue-green deployment concept。因此,您可以將代理添加到您的設置中,並不再從應用程序中公開端口,而是使用此代理公共端口。您當前的實時系統可能在隨機端口21231上運行,代理從443轉發到21231。

我們使用隨機端口來避免在部署「第二」系統期間發生衝突,其中包括您提到的一個問題。

當重新部署時,除了舊版應用程序之外,您將只啓動一個基於新應用程序映像的「新」容器,它會得到一個新的隨機端口12312 - 如果您願意,可以再次運行集成測試12312直接(不要使用代理)。如果你已經完成並開心,重新配置代理現在轉發到12312 - 然後刪除舊的容器(21231)。

如果你喜歡自動代理重新配置,這詳細超出範圍了這個問題,你可以使用服務發現和registrator這使得隨機端口更實用,可以很容易地重新配置你代理,讓它在運行時成爲nginx/haproxy。工具將是,例如。

+0

謝謝你的回答! 我可能應該將Capistrano從主機部署到服務器。 我已經有了應用程序作爲容器,所以這應該是沒問題的爲它建立一個圖像。由於它不會使用卷共享(對開發環境有用),我是否需要特定的Dockerfile來添加COPY/RUN語句?我想我必須確保應用程序中的上傳目錄仍然是裝入的卷,以便在部署新的應用程序映像時不會重置它們。 對於整個部署過程的設置是否有很好的教程? (簡單的)。 –

+0

正如上面提到的那樣,在編譯期間添加COPY以將代碼部署到您的映像中。 –

4

我不認爲Capistrano是這項工作的正確工具。這是最近在爲Capistrano提供基礎的SSHKit公關中討論的。

https://github.com/capistrano/sshkit/pull/368

@EugenMayer做了解釋使用泊塢窗的「正常」的方式更好的工作。

+0

感謝您的回答,它證實我不應該在此dockerized架構中使用Capistrano。我沒有找到任何解釋整個過程(從安裝私人註冊表)到準備(樣本)應用程序以部署爲圖像的好教程,但我會盡快獲得更多信息。 –

+1

獲取DevOps 2.0的書,它涵蓋了所有這些主題,def。值得一讀 –

+0

編寫DevOps 2.0視頻的Victor Farcic https://www.youtube.com/watch?v=QhPEOhKXm-s –