1. 程式人生 > >實踐在windows下用docker進行web開發

實踐在windows下用docker進行web開發

關於如何在windows下安裝docker,詳見http://blog.csdn.net/ownfire/article/details/45847939

本文著重闡述如何將docker實用起來

大家在協同開發過程中,通常會遇到各人開發環境不同,導致本地部署開發環境浪費時間、擴充套件庫有差異、甚至系統不同等問題,docker就是為了解決這些問題、快速開發環境、讓開發人員迅速進入開發狀態而生的

Docker是一個基於Go語言的開源應用容器引擎,可以自動化地部署應用到可移植的的容器中,這些容器獨立於硬體、語言、框架、打包系統。

一個標準的Docker容器包含一個軟體元件及其所有的依賴——二進位制檔案,庫,配置檔案,指令碼等等。

Docker擴充套件了LXC(Linux Container),使用高層的API,提供輕量虛擬化解決方案來實現程序間隔離。可以執行在任何支援cgroups(control groups)跟AUFS的64位Linux核心上。

LXC是docker的核心技術,藉助於namespace的隔離機制和cgroup限額功能,提供了一套統一的API和工具來建立和管理container。(類Hypervisor)
Linux Namespace (ns)
Control Groups (cgroups)

LXC 旨在提供一個共享kernel的OS級虛擬化方法,在執行時不用重複載入kernel, 且container的kernel與host共享,因此可以大大加快container的啟動過程,並顯著減少記憶體消耗。

在LXC的基礎上, Docker額外提供的Feature包括
1、標準統一的打包部署執行方案
2、歷史版本控制
3、Image的重用
4、Image共享釋出等。

下面是本文重點,安裝好docker後如何快速進入開發狀態,僅針對web開發:

開始講述之前,要再次認識到docker只是一個在虛擬機器中執行的系統底層,是連線上層宿主windows和下層開發環境容器,container(即開發環境容器)類似於子系統,是在docker虛擬機器中像應用程式一樣執行的隔離環境,和宿主系統的一切互動都要通過處於中間層的docker,並且預設都是關閉的,可以理解為好多個沙盒

web開發涉及到web伺服器和專案程式碼和資料庫,我們一項一項來解決

本文假定docker虛擬機器啟動後的繫結ip為192.168.59.103

1、web伺服器

一、安裝nginx並設定埠對映

一開始docker安裝好並且啟動container後,container內的服務埠(例如nginx啟動後監聽的80埠)是不對外暴露的,在宿主windows下用瀏覽器訪問docker虛擬機器ip是訪問不到container內的80埠的

必須做埠對映操作,只要在container啟動時,docker run命令帶上埠對映引數就可以了:

docker run -it -p 22222:33333 fe65a2781dae /bin/bash

解釋:

-it引數在啟動container為tty形式時必帶,否則無法做命令列互動

-p 22222:33333    關鍵引數,指定docker虛擬機器的22222埠,對映為container的33333埠,即對192.168.59.103:22222的訪問,統統訪問到container的33333埠。如果要對映80埠,設定-p 80:80就好

fe65a2781dae    指定docker要執行的imageid,也可以是REPOSITORY:TAG形式

/bin/bash       docker啟動container後要執行的命令,一般啟動命令列互動就用這個就好了

所以要把nginx調通,要做以下步驟:

1、docker run -it -p 80:80 fe65a2781dae /bin/bash

2、container內執行nginx

3、宿主windows瀏覽器訪問192.168.59.103

4、Welcome to nginx!

二、配置nginx在容器啟動時自動啟動

最簡單的方法:

vi /etc/bashrc

新增一行類似

/usr/sbin/nginx -c /etc/nginx/nginx.conf

儲存並推出

docker commit 儲存容器修改,下次再啟動容器時,自動就把nginx啟動起來了,要新增其他自啟動程式同樣操作

docker commit 如何使用,不在本文範圍,請自行百度

其他還有通過Dockerfile的方法,還有一種通過linux程序管理工具supervisor的方法,詳見:

http://segmentfault.com/a/1190000000755980

上文關於supervisor的部分,轉載了另一篇文章,在此也直接把連結列出來方便檢視:

http://air.googol.im/2014/03/28/supervisor-with-docker-to-manage-processes.html

2、專案程式碼

docker只是一個開發環境的容器,一般不用來做程式碼持久化的容器,如果這樣做,很容易丟程式碼,因為docker並不主動儲存在container內的修改除非你手動操作

最好的解決辦法就是,有一個共享資料夾,從宿主windows共享至container內,作為專案程式碼根目錄

過程大致如下:

一、建立virtualbox和docker虛擬機器的共享

可以參考http://jingyan.baidu.com/article/2fb0ba40541a5900f2ec5f07.html

開啟virtualbox並且選擇到boot2docker-vm虛擬機器,右鍵點設定

  1. 點選共享資料夾設定框,右上角的新增按鈕

    http://f.hiphotos.baidu.com/exp/w=480/sign=107cd686ad51f3dec3b2b86ca4eff0ec/241f95cad1c8a786447d54426509c93d70cf5022.jpg
  2. 選擇之前本機設定的共享資料夾,此時一定不可以勾選自動掛載

    http://c.hiphotos.baidu.com/exp/w=480/sign=3badb02c4dc2d562f208d1e5d71090f3/18d8bc3eb13533fa001e8d62aad3fd1f40345bd5.jpg
  3. 設定好共享名後,進入docker虛擬機器系統,開啟終端,先執行命令,在掛載點目錄新增“bdshare”目錄,接著執行"mount -t vboxsf BaiduShare /mnt/bdshare/",就能完成共享資料夾的設定。請記住mount命令一定要帶上引數-t vboxsf,BaiduShare就是共享資料夾名稱,/mnt/bdshare/就是要在docker虛擬機器中掛載的絕對路徑

  4. docker虛擬機器系統預設使用docker使用者,可能會遇到Permission denied錯誤,即許可權不足,需要切換到root賬戶操作,只要輸入“sudo su”命令即可,無需密碼

二、docker容器掛載docker虛擬機器的目錄

可以參考http://my.oschina.net/piorcn/blog/324202

docker可以支援把一個宿主機上的目錄掛載到映象裡。

docker run -it -v /home/dock/Downloads:/usr/Downloads ubuntu64 /bin/bash

通過-v引數,冒號前為宿主機目錄,必須為絕對路徑,冒號後為映象內掛載的路徑。

現在映象內就可以共享宿主機裡的檔案了。


此處要掛載上一步virtualbox和docker虛擬機器共享的資料夾,就在docker啟動container時加上引數:

-v /mnt/bdshare/:/data

命令類似:

docker run -it -p 80:80 -v /mnt/bdshare/:/bdshare fe65a2781dae /bin/bash

這樣就把宿主windows的K:\BaiduShare目錄,掛載到了container的/bdshare目錄

3、資料庫

同樣因為docker只是一個容器,不具備主動持久化的原因,所有會記錄狀態的資料(例如資料庫)都無法被儲存下來

解決的方法還是通過使用掛載的共享目錄,將所有需要持久化的資料儲存目錄都放在共享目錄中即可,下次container啟動的時候掛載上共享目錄,資料保持原樣

4、docker虛擬機器和container的持久化

我們可能想對docker虛擬機器本身做些配置,以便在虛擬機器啟動時自動啟動一些程式,比如自動掛載共享目錄,正常的linux系統只要往/etc/fstab檔案或者/etc/rc.local檔案裡寫執行語句,系統啟動時就會自動執行

但是往docker虛擬機器的自啟動檔案裡寫語句的話,下次啟動就不見了,這是為什麼呢,是因為:

docker虛擬機器裡面跑的是TinyCoreLinux,這個OS的rootfs是臨時性的(放在記憶體的,實際上就是boot2docker.iso檔案裡面的一個rootfs),因此其根目錄/下的東西(包括/home)根本不會持久化,只有/mnt/sda1這個目錄下的才能持久化。如果你放在/home目錄下,只要VM一重啟,就會丟失的,/mnt/sda1則不會,實際上就是那個~/.boot2docker-vm.vmdk檔案掛載到了/mnt/sda1目錄下

docker裡跑的container只是docker系統底層的上層隔離沙盒,container裡持久化的一切內容,最終都持久化到docker虛擬機器裡

這樣方法就清楚了,沒辦法針對docker虛擬機器做自啟動配置,但是可以寫好自啟動的sh指令碼,放在/mnt/sda1這個目錄下,下次啟動虛擬機器時,手動切換到這個目錄下執行sh指令碼。目前沒有找到更好的方法, 如果有更好的方法,歡迎告訴我謝謝

而container的持久化,除了掛載宿主windows的共享目錄外,還有就是對映的目錄設定到虛擬機器的/mnt/sda1目錄下,這兩種方法一個是持久化到宿主系統中,一個是持久化到虛擬機器的虛擬磁碟中。兩種方法都可以,就看自己選擇了

舉例,我的/mnt/sda1/的sh指令碼內容是:

sudo mount -t vboxsf sync /mnt/sync/      #掛載宿主windows的共享目錄
docker run -it -p 80:80 -v /mnt/sync:/sync -v /mnt/sda1/data:/data centos:centos6 /bin/bash        #對映共享目錄,和虛擬機器磁碟