鑑因而公司的項目,項目源碼很差公開,就專門講踩坑的經歷好了,我之前沒有接觸過docker,一直覺得它是個輕量化的虛擬機,但在看了《docker - 從入門到實踐》前言與介紹後,我意識到個人認識是不全面的,準確來講,docker是一個基於操做系統內核的虛擬化技術,可以低消耗地封裝你想要的進程。以往的虛擬機都是在系統上又構建了一個完整的系統,天然耗費巨大,而docker則提供了一個可讓你爲所欲爲地稱王的果殼,讓每一個進程在這個果殼中都能享有一個本身的宇宙,而這個果殼又立足於真正的宇宙--操做系統內核上。mysql
docker有三個重要概念:鏡像,容器,倉庫。按個人理解:linux
鏡像就是劇本,這個劇本描述了全部的場景佈置(系統環境),演員結構(軟件依賴),劇情設計(運行程序)等等,是果殼裏這場戲的根本,沒有劇本,就沒有戲。nginx
容器就是實際演出,是劇本的實現,你做爲導演,若是看的不爽,能夠闖入進去,進行各類調整與改變,當你調整改變完了,你想沿用下來,那就commit做爲新劇本。(但官方推薦使用Dockerfile,由於能夠完整地再現一個劇本的創做,至關於給劇本做說明,要否則劇本就成爲了黑盒子)git
倉庫就是劇本存放箱子,各類各樣的劇本都在這裏,有的是同一場戲的,可是分新舊版本,你須要給劇本打上標籤,標明它是哪一個版本的,最近版本就叫latest,倉庫的公開服務可讓你向全天下分享你的劇本,別人也能夠拿過來就演,也能夠改完再演,也能夠改完變成新劇本,說到這裏,感受docker跟github的思想很是相近。github
不得不說linux下的docker安裝真是輕鬆+寫意,而windows下的docker安裝簡直就是災難!雖然官方出了toolbox等一系列工具,作了不少兼容工做,但仍是會偶爾出現一些問題(尤爲是各類管理工具不能用),安裝完docker後,我推薦使用docker管理工具DockerFly,做者helyho是個很不錯的人哦。(實際上我是到都快整完了,才發現的。。。唉!早點發現能省多少事!)web
個人項目是使用Django框架開發,現階段暫時是Django + uwsgi + nginx + mysql,根據一些好的建議,我使用了多容器部署,這樣可使服務與數據分離,有極大的好處,但相對的,對於我這樣的小白,就意味着要有更多的坑要踩。sql
我按照這個教程來進行,但一開始就遇到麻煩,個人開發環境是使用conda管理的,其中一些conda找不到的包使用pip安裝的,不得已就得本身在鏡像中安裝miniconda,可是在Dockerfile中安裝miniconda真是坑多多,由於miniconda必需要經過sh腳本安裝,它途中會各類亂七八糟地問你是否許可這個那個的,致使Docker build不能自動地運行下去,當時沒有想到好的解決辦法,只好去找miniconda的專門鏡像,找到了continuumio/miniconda,但如今我知道,當時能夠在運行容器中裝好,而後從新生成新鏡像。docker
有了教程的幫助,我省了很多的力氣,因而我在Dockerfile中亂寫一氣,把本該用bash腳本寫的用來「臨場指揮」的一些命令也全都用 RUN 寫到了Dockerfile中,使得Dockerfile成了一鍋雜燴,直到後來,我才知道,Dockerfile中有下面的東西,讓你「臨場指揮」用,例如啓動nginx。數據庫
ENTRYPOINT [ "/usr/src/run.sh"] CMD [ "/bin/bash" ]
個人web容器要與mysql容器連通,才能讓web操做數據庫的數據,但即使在教程的幫助下,我依然沒法將這兩個牽到一塊兒,像這樣的代碼django
docker run --name mysql \ -p 3309:3306 \ -d daocloud.io/mysql:5.6.30 \
-p是將mysql的端口映射到本地,我覺得讓web程序訪問3309的端口,就能鏈接到數據庫,但事實是死活不通,我變換了各類接口,發現172.17.0.×是通的,原來那是docker容器的ip,頓時感受找到但願和光明,但隨即又想到,這是根據容器順序配給的,mysql容器若是中止重啓了,ip改變,難道還要去改程序不成?通過一連串的百度與論壇諮詢,(開源中國回答個人技術問題的人實在不算多,也許是太low了),我才知道,我想要的,在docker中叫作容器互聯,在個人代碼中
docker run --name django \ --link mysql:mysql \ -p 2000:8000 \ -d mine/django-app \
--link就是幹這個用的,host就是mysql,而-p映射的端口是給你在本地鏈接查看用的,不能用做容器互聯。
web容器終於運行起來了,但奇怪的是,容器運行不過幾秒就自動退出,這令我倍感驚訝,百度後發現,docker的機制是這樣的,docker容器是進程的容器,一個容器裏能夠運行多個進程,但最後一個運行的進程不能退出,不然進程退出後,容器也就退出了。在容器啓動運行run.sh,進程的缺省設置是後臺運行,這樣致使run.sh運行結束,容器跟着run.sh退出而退出。所以,在run.sh中,最後的進程應強制採用前臺運行,例如crond -f。這樣run.sh就不會退出, docker run -d 運行時就能夠保持容器後臺運行。還有同志建議寫個死循環
$ sudo docker run -d ubuntu:14.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"
不過,我以爲不太好,我採用了tail -f ×××.log。
最後應該將web落到nginx上了,但nginx要定位static靜態文件,但我又不肯意將static目錄從web中抽出,放到nginx中(這樣是否是好的?若是讀者感受很差,請在評論中指出),怎麼好呢,docker的數據卷及時救援了我,docker的數據卷能夠有效地解決多容器共享目錄的問題,而且數據卷的更新,不會影響到容器,使用-v標記建立數據卷掛載到容器裏,也能夠掛載一個本地目錄到容器,因而我
docker run --name django \ -v /usr/src/backend \ -v /usr/src/backend/static \ -d mine/django-app \
而nginx則使用 --volumes-from django 從而能夠訪問到靜態文件與web目錄。
通過這一週的踩坑,我對docker有了初步的瞭解,有很多心得體會,也還有好多不足,要學習一項新的技術,果真要走很多彎路,docker虛擬化技術的前途,可見其光明。