標籤:

如何基於Docker進行開發?

最近嘗試使用Docker,但是苦惱於怎麼在項目中使用Docker來進行開發。官方文檔讀了一部分,但還沒有找到相關的,懇請熟手指導下。

比如我有一個項目,需要依賴mysql, tomcat, 和LLVM(一個第三方函數庫), tensorflow(一個關於 ai的庫)。

那麼我從網上下了4 images, 每個image都是只包含一個依賴的,那麼這種情況下我需要如何去開發呢? 

感覺應該是我自己新建一個docker, 用來存儲我自己的應用,然後使用4個下載下來的docker images. 這種方式不知道怎麼搞, 尤其是這種跨docker之間的依賴。

--------------------------------------------------------

我覺得我之前的問題可能描述不是特別清楚,因此再更新下:

我的問題是: 當一個library(比如C++ so, Java的Jar)以Docker方式提供的時候,我作為開發者,在開發中需要鏈接這些library。這種情況我怎麼做? library在一個或者多個Docker images中,而我的代碼開發是在自己的機器上(不在這些依賴的docker images)。

大家說的Docker compose 更多是 each docker image is deployed as one network service, and then users will use these dockers by network connection.


一般來說Docker的組織方式是一個進程啟動一個docker容器,所以如果是進程內調用(調用第三方庫)應該在同一個容器中,進程外調用(調用外部服務如mysql)應當分到多個容器中。

進程內調用關鍵在於定製鏡像,也就是使用docker build和dockerfile,它相當於啟動一個臨時的容器,在裡面運行一組腳本,然後保存容器的存儲層級為一個新鏡像。一般從一個基礎鏡像開始,用apt-get或者yum或者curl或者maven之類下載安裝依賴項,用add命令添加本地文件,用cmd設置啟動使用的命令行。

進程外調用關鍵在於將多個容器啟動到同一網路內,一般可以使用docker compose


題主的情況,可以使用 docker + supervisord 。把 MySQL 和 tomcat 和你的腳本在docker中用前台模式運行,同時交給 supervisord 來管理,至於 llvm 和 TensorFlow 應該是你的依賴庫吧,不是要運行的服務。不過需要把 MySQL 的數據目錄映射到宿主機上,一般來說容器應該是無狀態的。

1. 開發時可以使用開發機的 MySQL 等調試

2. 測試時可以使用測試版的dockerfile,在開發機構建鏡像測試:

FROM ubuntu:16.04
# 安裝依賴
RUN install mysql, tomcat, supervisor
# 把本地文件複製進去
COPY . /opt/YOUR_PROJECT
CMD ["supervisor", "-n"]

然後 docker build, docker run 看下是否是正常的。

3. 部署的時候,首先 git 提交代碼,然後讓 jenkins 構建代碼,自動部署,dockerfile大概是這樣的:

FROM ubuntu:16.04
RUN install mysql, tomcat, supervisor
# 從 git repo clone 代碼
RUN git clone git@github.com/USER/YOUR_PROJECT /opt/YOUR_PROJECT
CMD ["supervisor", "-n"]


docker compose


最後網上找到了一個例子: Using C++ with Docker Engine

但實際上自己並不滿意這個。因為在開發寫代碼的時候,我會需要常常查看各種庫的API信息,在代碼層次。

按照這種方式,各種庫API是以image的方式來的,我沒法直接去查看。。

可能是我理解不對,或者沒有入門,期待高手來解答。


多讀官方文檔。看不懂的可以讀中文的。

容器的之間的互相通信:Legacy container links

如果你想要將MySQL, tomcat這些放在一個容器內的話,參考Dockerfile:Best practices for writing Dockerfiles

可以在Github上找一下,看有沒有其他大牛已經配置好的Dockerfile,然後clone下來,docker build


Docker 關注的問題是打包應用,可以認為一個 docker 是一個編譯出來的 image(exe)。

要說靈活的開發的話,本來用 vagrant 是更好的選擇,用戶可以快速搭建一個完整的 Linux 開發環境,之後就在這個環境里做任何操作。看最近的 vagrant 發展,未來並不明確。

猜測現在真正 viable option 還是自己建虛擬機(virtualbox / hyper-v)開發,成品打包成 docker image 部署。

當然還有另外一種做法,在一個 docker image 里打包進去編譯器工具鏈,然後把代碼全部放在 host volume,用 -v 映射進去。這樣編輯和查看代碼可以完全在 host 完成,編譯測試運行在 docker 環境里。

要做的就是從你找到的 Dockerfile 里找到需要的部分放在一個 Dockerfile 里,然後自己 docker build 一個 image 出來用。


先簡單回答一下

先說docker 解決了什麼問題:通常,一個應用會依賴很多環境,這個環境包括硬體,操作系統,函數庫,網路結構,其他通過網路的服務。。。由此而來就引起部署上面的問題,每次部署都需要保證環境先準備好。大規模部署的時候重複勞動很嚴重。當環境變化的時候,遷移很麻煩。如果還有遺留系統,最開始的開發人員都不在了,更麻煩。運維人員面對一堆應用,出了問題,會非常抓狂,因為要了解的細節太多了。

所以,docker就是來解決這些問題。docker把環境有關的依賴,全部放在一個鏡像裡面,這個鏡像不論安裝在哪裡,都是開箱可用out-of-box,需要配置的通常是網路埠,存儲位置等一些簡單的配置。

現在說說如何用docker開發

1.因為docker是主要解決部署問題,所以平時開發當中,以前怎麼開發,現在還是怎麼開發。

2.如果開發之中,需要一些服務,比如redis,那麼搞一個虛擬機,裝docker,然後docker run redis -p 6379 --always 就可以,很方便。

3.部署的話,需要把你的應用搞出一個鏡像,鏡像里裝好你的代碼和靜態庫,象llvm這些庫,還有tomcat,就應該裝在鏡像里。 如果需要依賴的網路服務,比如mysql,那麼就是啟動一個容器,docker run mysql.......需要的服務多的話,就一個個創建出容器,並且讓應用可以訪問到這些容器的服務埠。

4。有些服務對硬體也有要求,比如tensor flow要性能的話,需要gpu資源,那麼最好是安裝到裸機,把gpu資源也分配個tenserflow的容器。

5.至於docker-composer,你可以用,也可以不用,composer只是把幾個服務打包運行起來。


docker compose是正解,它的目的就是為了組合多個image,自己搜個yaml文件照著寫就好。


寫個docker compose文件做好然後直接啟這幾個環境,把需要開發的代碼用volume掛在到某個container裡面,如果在本機可以直接用編輯器開發,遠程的話裝一個ftp-sync之類的軟體。

當然也可以再啟一個c9編輯器的container,把之前的volume掛載到這個編輯器裡面,就可以實現在網頁直接編輯了。


基於docker主要是優化devops流程,本地運行鏡像和線上運行鏡像,依賴的環境變數和系統庫都一致,類似immutation的概念。

開發中使用docker可以通過用compose混編模擬其它依賴,例如mongodb,redis。這些都有別人打包好的鏡像,而免去了自己本地編譯安裝的麻煩。


推薦閱讀:

DaoCloud和雲雀到底誰家的技術比較強一些?VMware和微軟系的比較?
將JVM運行於DOCKER上,有什麼意義嗎?或者,什麼場景下,需要把JVM運行於DOCKER上?
現在國內、國際市場上有哪些docker的容器管理平台?
Docker 可以用於生產環境了嗎?
圖形化界面的 docker ?

TAG:Docker |