1. 程式人生 > >用 Docker 快速配置前端開發環境

用 Docker 快速配置前端開發環境

文章連結:http://www.open-open.com/lib/view/open1474942351115.html

我基本上是個 Docker 新手,如果有什麼地方說得不對請大家指出~目前的方案還比較粗糙,大家有什麼改進建議也請告訴我,我多和大家學習

今天是你入職第一天。

你起了個大早,洗漱乾淨帶著材料去入職。

簽了合同,領了機器,坐到工位,泡一杯袋裝紅茶,按下開機鍵,輸入密碼,

然後,下載 Chrome、Postman、Sublime、盜版 PS、NodeJS、配置 NODE_PATH、安裝 cnpm、安裝 gulp、安裝 webpack、安裝 browserify、安裝 LessSassStylus、安裝 JadeCoffeePostCSS、安裝 BabelExpressKoa、安裝 gitpm2forever……

此處省略一萬個外掛。

如果順利的話這個時候你應該已經準備下班了,當然,通常來說都不順利。

在這個過程中,你可能會遇到網路問題環境問題相容問題許可權問題配置問題配置問題配置問題配置問題配置問題配置問題配置問題。

新人第一週週報:

  • 本週工作:配置環境,熟悉專案

大公司的解決方法

“開發機”。

大公司的思路很簡單:既然你自己搞這麼麻煩,那我幫你搞好,給你個賬號,直接登入上去開發。

確實沒毛病,不過這個方案必須解決三個問題:

  1. 怎麼在本機預覽網頁

  2. 怎麼在本機編輯檔案

  3. 怎麼在外網訪問開發機

解決方法有很多,這裡只說一種:Nginx + Samba + VPN。

Nginx 可以解決第一個問題。每個工程師分配一個賬號,每個賬號對應一個域名,Nginx 會把域名解析到對應使用者的目錄下,這樣開發就可以在自己電腦上用域名預覽網頁(需要配置好 host)。舉個例子,我的賬號是 liangjie,專案的域名是 

www.wisdomtmt.com ,那我訪問 liangjie.wisdomtmt.com 就可以預覽開發機中 liangjie 賬號下的專案。

Samba 可以解決第二個問題。你可以把它理解成 Windows 中的“共享資料夾”。在開發機上配置好 Samba,然後在自己機器上連線開發機,把共享資料夾拖到編輯器中就可以寫程式碼了。

VPN 可以解決第三個問題。大公司除了專用的軟體,還會配套使用硬體來提高安全係數。VPN 硬體類似 U 盾,上面顯示一串動態數字密碼,定時重新整理,每次外網登入 VPN 都需要附加動態密碼。

這樣就解決了問題,開發人員可以在自己機器上寫程式碼,然後在瀏覽器中直接預覽,遇到意外情況也可以外網登入開發機修復。

粗略來看,這套方案沒什麼技術問題。但是對於中小型公司來說,搭建整套開發機環境、規範開發流程、規範 VPN 使用流程、全公司切到開發機,這一套走下來需要的時間和人力成本都不低。通常來說也只有大公司才玩得起。

那小公司呢?難道每個新員工都必須浪費時間來配置環境?

當然不是。

出來吧,Docker!

主角登場。

什麼是 Docker?我不是 Docker 專家,所以這裡不對 Docker 做專業介紹。如果你還不知道 Docker 是什麼,把它看成虛擬機器就可以了。

在引入 Docker 之前,我對它做了一些調研,主要想搞清楚以下幾個問題:

  1. Docker 能否跨平臺?(畢竟你不能要求公司給所有人配 Mac)

  2. 如何預覽 Docker 裡的網頁?

  3. 如何編輯 Docker 裡的檔案?

  4. Docker 能否實現一次配置多處使用?

由於 Docker 執行在每個人的機器上,因此不存在外網訪問問題。

經過調研,上述問題理論上都可以解決,下面是初步確定的解決方案:

  1. 用 Kitematic 客戶端實現跨平臺執行 Docker

  2. 用埠對映預覽 Docker 裡的網頁

  3. 用 Samba + 埠對映編輯 Docker 裡的檔案

  4. 配置一個通用的 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 共享檔案,預裝開發過程中可能用到的包。

過程:

  1. 下載並安裝 Docker Toolbox
  2. 下載並執行 Ubuntu 映象
  3. 做常規的初始化工作(換源、安裝常用工具)
  4. 安裝前端開發工具
  5. 安裝和配置 Samba
  6. 配置埠對映
  7. 匯出映象

Let's rock!

1. 下載並安裝 Docker Toolbox

Docker Toolbox 是 Docker 官方開發的 Docker 套裝,裡面有全套 Docker 環境,也有圖形化工具 Kitematic,直接下載安裝即可。

Docker Toolbox 支援 Windows 和 Mac OS,可以到 官網 下載安裝(這一步如果沒有 VPN 會比較耗時,最好把兩個平臺的安裝包都下載好,之後直接複製給同事安裝)。

下文以 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 的配置,你可以做一些測試,看看共享資料夾和埠對映工作是否正常。

測試一:

  1. 開啟 Ubuntu 命令列,隨便 cd 到一個目錄(比如 cd /web )
  2. 執行 python -m SimpleHTTPServer ,啟動一個靜態伺服器

測試二:

  1. 如果是 Mac 系統,開啟 Finder,按下 ⌘+K,輸入 smb://192.168.99.100 ,回車,輸入 root 和 Samba 密碼,應該能看到共享資料夾(我設定的是 /web )
  2. 雙擊共享資料夾,應該能在 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。

新人使用流程

我整理的新人入職配置流程:

  1. 準備好 Docker Toolbox 安裝包和 Ubuntu Image

  2. 安裝 Docker Toolbox

  3. 開啟 Kitematic,註冊一個 Docker Hub 賬號並登陸

  4. 在 Kitematic 中點選左下角“DOCKER CLI”開啟 Docker 命令列

  5. 輸入命令 docker import ,從資料夾中直接把 ubuntu 檔案拖拽到命令列中(注意 ubuntu 檔案路徑中不能有中文,如果有,先把檔案移動到另一個純英文路徑的資料夾中)

  6. 輸入命令 docker images ,複製出映象的 IMAGE ID(類似 54184b993d46 )

  7. 輸入命令
    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 替換為上一步複製的內容

  8. 回到 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,目前沒有發現致命問題。