用 Docker 快速配置前端開發環境
我基本上是個 Docker 新手,如果有什么地方說得不對請大家指出~目前的方案還比較粗糙,大家有什么改進建議也請告訴我,我多和大家學習
今天是你入職第一天。
你起了個大早,洗漱干凈帶著材料去入職。
簽了合同,領了機器,坐到工位,泡一杯袋裝紅茶,按下開機鍵,輸入密碼,
然后,下載 Chrome、Postman、Sublime、盜版 PS、NodeJS、配置 NODE_PATH、安裝 cnpm、安裝 gulp、安裝 webpack、安裝 browserify、安裝 LessSassStylus、安裝 JadeCoffeePostCSS、安裝 BabelExpressKoa、安裝 gitpm2forever……
此處省略一萬個插件。
如果順利的話這個時候你應該已經準備下班了,當然,通常來說都不順利。
在這個過程中,你可能會遇到網絡問題環境問題兼容問題權限問題配置問題配置問題配置問題配置問題配置問題配置問題配置問題。
新人第一周周報:
-
本周工作:配置環境,熟悉項目
大公司的解決方法
“開發機”。
大公司的思路很簡單:既然你自己搞這么麻煩,那我幫你搞好,給你個賬號,直接登錄上去開發。
確實沒毛病,不過這個方案必須解決三個問題:
-
怎么在本機預覽網頁
-
怎么在本機編輯文件
-
怎么在外網訪問開發機
解決方法有很多,這里只說一種:Nginx + Samba + V*N。
Nginx 可以解決第一個問題。每個工程師分配一個賬號,每個賬號對應一個域名,Nginx 會把域名解析到對應用戶的目錄下,這樣開發就可以在自己電腦上用域名預覽網頁(需要配置好 host)。舉個例子,我的賬號是 liangjie,項目的域名是 www.wisdomtmt.com ,那我訪問 liangjie.wisdomtmt.com 就可以預覽開發機中 liangjie 賬號下的項目。
Samba 可以解決第二個問題。你可以把它理解成 Windows 中的“共享文件夾”。在開發機上配置好 Samba,然后在自己機器上連接開發機,把共享文件夾拖到編輯器中就可以寫代碼了。
V*N 可以解決第三個問題。大公司除了專用的軟件,還會配套使用硬件來提高安全系數。V*N 硬件類似 U 盾,上面顯示一串動態數字密碼,定時刷新,每次外網登錄 V*N 都需要附加動態密碼。
這樣就解決了問題,開發人員可以在自己機器上寫代碼,然后在瀏覽器中直接預覽,遇到意外情況也可以外網登錄開發機修復。
粗略來看,這套方案沒什么技術問題。但是對于中小型公司來說,搭建整套開發機環境、規范開發流程、規范 V*N 使用流程、全公司切到開發機,這一套走下來需要的時間和人力成本都不低。通常來說也只有大公司才玩得起。
那小公司呢?難道每個新員工都必須浪費時間來配置環境?
當然不是。
出來吧,Docker!
主角登場。
什么是 Docker?我不是 Docker 專家,所以這里不對 Docker 做專業介紹。如果你還不知道 Docker 是什么,把它看成虛擬機就可以了。
在引入 Docker 之前,我對它做了一些調研,主要想搞清楚以下幾個問題:
-
Docker 能否跨平臺?(畢竟你不能要求公司給所有人配 Mac)
-
如何預覽 Docker 里的網頁?
-
如何編輯 Docker 里的文件?
-
Docker 能否實現一次配置多處使用?
由于 Docker 運行在每個人的機器上,因此不存在外網訪問問題。
經過調研,上述問題理論上都可以解決,下面是初步確定的解決方案:
-
用 Kitematic 客戶端實現跨平臺運行 Docker
-
用端口映射預覽 Docker 里的網頁
-
用 Samba + 端口映射編輯 Docker 里的文件
-
配置一個通用的 Image(鏡像)
這里面有幾個概念需要解釋。
首先,Kitematic 是一個 Docker GUI,有了它你就不用和命令行打交道,會方便不少。
其次,Docker 中最重要的三個概念是 Container(容器)、Image(鏡像)和 Volume(卷)。
Image 是靜態內容,如果你要把某個 Image 跑起來,那就需要一個 Container。這里面有一點很重要: Container 中所做的改動不會保存到 Image 。舉個例子,你跑起來一個 Ubuntu Image,然后 touch wisdomtmt 創建一個新文件,這時候如果直接重啟 Container,文件就沒了。那怎么保存改動?很簡單,執行 docker commit ContainerID TAG 即可。這里的 commit 和 git commit 類似,執行之后會把當前狀態保存為一個新 Image。
有同學就要問了,如果每次做改動都要 commit,我寫起代碼來豈不是很不方便?萬一寫到一半不小心重啟 Docker 怎么辦?
這確實是個問題,Docker 也有對應的解決方法:使用 Volume。
簡單來說,Volume 就是專門存放數據的文件夾,啟動 Image 時可以掛載一個或多個 Volume,Volume 中的數據獨立于 Image,重啟不會丟失。我們創建一個 Volume,掛載到系統的一個目錄下,然后把代碼都放進去就可以了。
最后說端口映射。前面說過,Docker 可以看做一個虛擬機,你的所有文件都在里面。如果你在 Container 中運行一個服務器,監聽 127.0.0.1:8000 ,從你自己的機器上直接訪問 http://127.0.0.1:8000 是不行的,因為 Container 和你的機器是兩個不同的環境。
那怎么辦呢?我們先來看一個大家都熟悉的問題。
日常開發中我們經常需要讓同事預覽網頁效果,常用的方法是監聽 0.0.0.0:8000 ,然后讓同事連接同一個局域網,訪問 http://你的機器IP:8000 即可。
Container 的問題非常相似,只不過我們自己變成了“同事”,需要訪問 Docker 內部的網頁。看起來只要拿到 Container 的 IP 問題就解決了。
幸運的是,Container 確實有 IP。
通常情況下這個 IP 是 192.168.99.100,只能從 Container 的宿主機(也就是運行 Docker 的機器)訪問。不過 Container 的情況有些特別,它只關聯了 IP,沒有關聯端口。因此如果想要訪問 Container 內部的端口(比如 8000),你需要手動配置端口映射,把 Container 內部的端口映射到 IP 上。
好了,枯燥的概念講完了,理解不了也不用著急,跟著下一章走一遍流程就懂了。
動手
正式開工之前,先看看我們都要做什么。
目標:配置一個通用 Image,支持預覽網頁,支持 Samba 共享文件,預裝開發過程中可能用到的包。
過程:
- 下載并安裝 Docker Toolbox
- 下載并運行 Ubuntu 鏡像
- 做常規的初始化工作(換源、安裝常用工具)
- 安裝前端開發工具
- 安裝和配置 Samba
- 配置端口映射
- 導出鏡像
Let's rock!
1. 下載并安裝 Docker Toolbox
Docker Toolbox 是 Docker 官方開發的 Docker 套裝,里面有全套 Docker 環境,也有圖形化工具 Kitematic,直接下載安裝即可。
Docker Toolbox 支持 Windows 和 Mac OS,可以到 官網 下載安裝(這一步如果沒有 V*N 會比較耗時,最好把兩個平臺的安裝包都下載好,之后直接復制給同事安裝)。
Linux 環境配置可以參考這篇: Installation on Ubuntu 。
下文以 Mac OS 為例,Windows 操作方法類似。
安裝完畢之后打開 Kitematic,注冊一個 Docker Hub 賬號,方便之后的操作。
2. 下載并運行 Ubuntu 鏡像
Docker Hub 上有現成的 Ubuntu 鏡像,在 Kitematic 中點擊左上角的“NEW”,搜索 Ubuntu,選擇第二排第一個即可。
這個 Ubuntu 鏡像是超級精簡版,只有一百多兆,不過國內網絡下載起來還是很痛苦。沒辦法,等著吧,反正只需要下載一次。
下載完成后,在 Kitematic 左側的 Container 列表中選擇 ubuntu,然后點擊上方的“START”按鈕執行。點擊“EXEC”可以進入系統命令行,輸入 su 開啟 root 權限。這個過程下文不再贅述,統稱“打開 Ubuntu 命令行”。
打開 Ubuntu 命令行后,試著執行幾個命令看看效果,比如 ls , cd / 。玩完之后,點擊 Kitematic 右上角的“Settings”,點擊“Ports”,你會看到一個 IP 地址,通常情況下是 192.168.99.100 。打開宿主機(你自己的電腦)命令行,輸入 ping 192.168.99.100 ,應該是通的。
這樣我們就準備好了 Ubuntu 鏡像,可以開始配置了。
3. 常規初始化工作
Ubuntu 裝完系統第一件事是什么?沒錯,換源。
“源”其實就是網址,你在 Ubuntu 中用 apt-get install 安裝軟件的時候就是從“源”下載。Ubuntu 默認的源在國外,安裝起來非常慢,所以要先換成國內的源。
國內有很多 Ubuntu 源,我用的是中科大源。
你可以直接看 官方換源教程 ,也可以直接打開 Ubuntu 命令行(如果你忘了怎么做,看上一節),執行下面的命令:
sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list apt-get update
換源完畢,之后 apt-get 都會從中科大源下載軟件。
前面說過,這個 Ubuntu Image 是超級精簡版,很多不重要的工具都被刪掉了,包括常用的 vim、curl、ipconfig、ping。除此之外,Linux 最常用的 TAB 補全路徑也沒有,所以下面先安裝必要的編輯器和路徑補全:
apt-get install vim bash-completion
這樣就完成了基礎配置,Ubuntu 可以正常用了。
4. 安裝前端開發工具
首先安裝 npm:
apt-get install npm
然后安裝 cnpm,之后所有 npm 操作都改成 cnpm,從淘寶源下載,速度會快很多。
npm install -g cnpm --registry=https://registry.npm.taobao.org
接著安裝 n,TJ 大神的 NodeJS 版本管理工具,可以安裝多個版本,一鍵切換。n 需要用到 curl,所以先安裝 curl:
apt-get install curl
然后安裝 n:
cnpm install -g n
最后使用 n 安裝目前的穩定版 NodeJS:
n stable
這樣就準備好了前端開發需要的基本工具。
我們的項目目前在使用 Vue,所以我還安裝了 vue-cli、browserify、gulp、babel 以及相關的庫,你可以根據你的項目需求安裝對應的庫。
5. 安裝和配置 Samba
Samba 是文件共享工具,用于在宿主機中編輯 Docker 內部的文件。
這里有 完整配置教程 ,下面是我整理的超簡潔版。
首先安裝 Samba:
apt-get install samba
Samba 的用戶系統比較特別,簡單來說,Samba 的用戶確實是系統的用戶,但是 Samba 的密碼和系統的密碼不一樣。也就是說,同一個用戶在系統和 Samba 中密碼需要單獨設置,并沒有打通。
Docker 的 Ubuntu Image 用戶是 root,我們給 root 設置 Samba 密碼:
smbpasswd -a root
設置好密碼之后,需要創建 Samba 的配置文件,設置共享文件夾和權限:
vim /etc/samba/smb.conf
下面是我的配置示例:
[web] path = /web available = yes valid users = root read only = no browsable = yes public = yes writable = yes
這里面的重點是 path ,指定需要共享的文件夾,這里我共享了 /web 目錄,你可以選擇一個不同的目錄。我的 /web 目錄是一個 Volume,用來存放代碼,重啟 Docker 也不會丟失數據。Volume 的配置方法在后文介紹。
寫好配置之后重啟 Samba 服務:
service smbd restart service nmbd restart
這樣就完成了 Samba 的配置。
不過現在你還不能從宿主機連接共享文件夾,因為我們還沒有配置端口映射。
6. 配置端口映射
首先明確需要映射的端口。
Samba 需要用到的端口:137、138、139、445。
日常開發可能用到的端口:3000、3123(hot-reload 用)、8000、8080。
接著配置端口映射。
注意:Windows 的 Kitematic 有嚴重 bug,改動 Settings 下的任何選項都會導致所有配置項丟失,解決方法看下一節
如果你是 Mac 系統,可以直接在 Kitematic 中進行配置。
如圖所示,直接在 Settings -> Ports 中添加映射即可。
到這里就已經完成了 Docker Image 的配置,你可以做一些測試,看看共享文件夾和端口映射工作是否正常。
測試一:
- 打開 Ubuntu 命令行,隨便 cd 到一個目錄(比如 cd /web )
- 執行 python -m SimpleHTTPServer ,啟動一個靜態服務器
- 在宿主機中訪問 http://192.168.99.100:8000 ,應該能看到 /web 目錄下的所有文件
測試二:
- 如果是 Mac 系統,打開 Finder,按下 ?+K,輸入 smb://192.168.99.100 ,回車,輸入 root 和 Samba 密碼,應該能看到共享文件夾(我設置的是 /web )
- 雙擊共享文件夾,應該能在 Finder 中看到 /web 下的所有文件
這樣就完成了 Docker Image 的所有配置,下面完成最后一件事:導出鏡像,供其他人使用。
7. 導出鏡像
別忘了前面的提醒:如果不 commit,重啟之后所有改動都會丟失!
所以先 commit。點擊 Kitematic 左下角 “DOCKER CLI”,執行:
docker ps
會看到下面這樣的輸出:
? ~ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c5c131f108b1 numbbbbb/ubuntu-test "/bin/bash" 15 hours ago Up 50 seconds 0.0.0.0:137-139->137-139/tcp, 0.0.0.0:445->445/tcp, 0.0.0.0:3123->3123/tcp, 0.0.0.0:8000->8000/tcp, 0.0.0.0:8080->8080/tcp, 0.0.0.0:32773->49201/tcp dev
復制 Container ID,我這里是 c5c131f108b1 ,然后執行:
docker commit c5c131f108b1 username/imagename
username 換成你的 Docker Hub 用戶名,imagename 換成你的鏡像名稱。我這里就是 numbbbbb/ubuntu-test。
commit 之后就可以把當前 Container 導出 Image 了:
docker export c5c131f108b1 -o ubuntu
執行完后,在你的個人目錄下(Mac 上是 /Users/你的用戶名)可以找到 ubuntu 文件,這就是我們的最終目標:一個完成所有配置的 Image。
稍微松口氣,下面看看新同事入職時如何使用這個 Image。
新人使用流程
我整理的新人入職配置流程:
-
準備好 Docker Toolbox 安裝包和 Ubuntu Image
-
安裝 Docker Toolbox
-
打開 Kitematic,注冊一個 Docker Hub 賬號并登陸
-
在 Kitematic 中點擊左下角“DOCKER CLI”打開 Docker 命令行
-
輸入命令 docker import ,從文件夾中直接把 ubuntu 文件拖拽到命令行中(注意 ubuntu 文件路徑中不能有中文,如果有,先把文件移動到另一個純英文路徑的文件夾中)
-
輸入命令 docker images ,復制出鏡像的 IMAGE ID(類似 54184b993d46 )
-
輸入命令
docker run -t -i --privileged -p 137-139:137-139/tcp \
-p 445:445/tcp -p 3000:3000/tcp -p 3123:3123/tcp \
-p 8000:8000/tcp -p 8080:8080/tcp -d --name dev -v /web IMAGEID \
/bin/bash
把其中的 IMAGEID 替換為上一步復制的內容 -
回到 Kitematic,應該可以看到左側多了一個容器,此時環境已經搭建完畢
2016.08.04 Windows 的 Kitematic 有 bug,如果在界面中修改設置會導致 volume 丟失,所以不要在 Kitematic 中修改任何設置,如果要改就從命令行執行
上一節提到過,Windows 的 Kitematic 有 bug,手動添加端口映射會丟失所有配置,所以我們直接用命令添加,只要不從 Kitematic 里修改配置就沒問題。
第 7 步的命令還有一個重要內容,就是 -v /web 。這會創建并掛載一個 Volume,掛載目錄是 /web ,把代碼放到這個目錄下,就不會因為重啟 Docker 丟失數據。
沒有銀彈
說了很多優點,下面來聊聊用 Docker 做開發環境的缺點。
首先,Docker 本身還不夠成熟。
Docker 確實很強大,能支持三大操作系統,性能方面也遠超傳統虛擬機,但是仍然不夠成熟。舉一個小例子:Kitematic 在 Windows 上丟失配置的 bug 去年年底就有人報過,到現在都沒解決。
其次,Docker 這套體系使用成本并不低。
試想一下,作為一個開發人員,在寫代碼之前必須運行 Kitematic、啟動 Ubuntu 鏡像、連接共享文件夾、進入鏡像啟動靜態服務器。這個流程太重,理想的開發環境應該是透明的,打開電腦就能寫代碼。或許下一步可以考慮在這方面做一些自動化腳本來輔助開發。
小結
用 Docker 做前端開發環境確實可行 — 我們團隊已經投入使用 — 但是這套方案還遠遠談不上完美,需要繼續優化。
如果你還是不知道怎么選:
- 有人有錢有時間,上標準開發機,各大公司都這么搞,肯定沒問題
- 否則,可以試試 Docker,目前沒有發現致命問題。
來自:http://dockone.io/article/1714