概要:
本篇文章將會通過以下幾點簡要的敘述docker 在前端開發(fā)中使用場景。
1. docker 前端應用情形
2. docker 基本概念(鏡像 容器 端口映射 數(shù)據(jù)卷)介紹
3. 動手一步步搭建,前端開發(fā)環(huán)境 并生成可以團隊共享的開發(fā)鏡像以及團隊拿到鏡像后如何使用鏡像快速搭建自己的開發(fā)環(huán)境。
4. 如何通過DockerFile來搭建開發(fā)環(huán)境。
docker 功能非常強大,可以保證線上線下環(huán)境一致性,可以快速部署啟動項目,有極高的平臺遷移性,其聯(lián)合文件系統(tǒng)可以使得鏡像非常方便的迭代升級。諸多優(yōu)點,感興趣的朋友可以自己搜索下相關的教程先熟悉下docker相關概念,如果實在看不懂也不必過多的糾結docker到底是什么東西,通俗的看他就是一個虛擬機,上面跑了很多應用,應用可以是個linux系統(tǒng),也可以是實際的項目服務。其網(wǎng)絡配置方式可以將幾個不同的應用很方便的連在一起,保護你不想讓用戶通過外網(wǎng)直接訪問的應用(如Mysql數(shù)據(jù)庫)將其訪問限制在docker 虛擬的內網(wǎng)環(huán)境,對外網(wǎng)只暴露服務層。其他的部署環(huán)境配置可以多爬爬帖子。
這里筆者推薦一本書,docker入門與實踐 基礎講的很不錯,筆者買了紙質版。紙質版內容和電子版的內容差不多,紙質版會多點內容。入門的話電子版的也夠了。
本文只介紹其在前端使用情形,通過本篇文章你將了解
1.為什么我們要在前端開發(fā)中使用docker?
2.怎么用docker搭建我們自己開發(fā)環(huán)境,并共享給團隊統(tǒng)一團隊開發(fā)環(huán)境?
3.怎樣用dockerfile 記錄我們實際搭建的過程,并使用Dockerfile搭建開發(fā)環(huán)境?
這里簡要的介紹下筆者的開發(fā)環(huán)境:
Macbook Air OS系統(tǒng)
dockertool docker工具包
一、Docker在前端開發(fā)應用情形
引用自梁杰文章用 Docker 快速配置前端開發(fā)環(huán)境
今天是你入職第一天。
你起了個大早,洗漱干凈帶著材料去入職。
簽了合同,領了機器,坐到工位,泡一杯袋裝紅茶,按下開機鍵,輸入密碼,
然后,下載 Chrome、Postman、Sublime、盜版 PS、NodeJS、配置 NODE_PATH、安裝 cnpm、安裝 gulp、安裝 webpack、安裝 browserify、安裝 LessSassStylus、安裝 JadeCoffeePostCSS、安裝 BabelExpressKoa、安裝 gitpm2forever……
此處省略一萬個插件。
如果順利的話這個時候你應該已經(jīng)準備下班了,當然,通常來說都不順利。
在這個過程中,你可能會遇到網(wǎng)絡問題環(huán)境問題兼容問題權限問題配置問題配置問題配置問題配置問題配置問題配置問題配置問題。
新人第一周周報:
本周工作:配置環(huán)境,熟悉項目

大公司的思路很簡單:既然你自己搞這么麻煩,那我?guī)湍愀愫?,給你個賬號,直接登錄上去開發(fā)。
確實沒毛病,不過這個方案必須解決三個問題:
- 怎么在本機預覽網(wǎng)頁
- 怎么在本機編輯文件
- 怎么在外網(wǎng)訪問開發(fā)機
解決方法有很多,這里只說一種:Nginx + Samba + VPN。
Nginx 可以解決第一個問題。每個工程師分配一個賬號,每個賬號對應一個域名,
Nginx 會把域名解析到對應用戶的目錄下,這樣開發(fā)就可以在自己電腦上用域名預覽網(wǎng)頁
(需要配置好 host)。
舉個例子,我的賬號是 liangjie,項目的域名是 www.wisdomtmt.com,
那我訪問 liangjie.wisdomtmt.com 就可以預覽開發(fā)機中 liangjie 賬號下的項目。
Samba 可以解決第二個問題。你可以把它理解成 Windows 中的“共享文件夾”。
在開發(fā)機上配置好 Samba,然后在自己機器上連接開發(fā)機,把共享文件夾拖到編輯器中就可以寫代碼了。
VPN 可以解決第三個問題。大公司除了專用的軟件,還會配套使用硬件來提高安全系數(shù)。
VPN 硬件類似 U 盾,上面顯示一串動態(tài)數(shù)字密碼,定時刷新,每次外網(wǎng)登錄 VPN 都需要附加動態(tài)密碼。
這樣就解決了問題,開發(fā)人員可以在自己機器上寫代碼,然后在瀏覽器中
直接預覽,遇到意外情況也可以外網(wǎng)登錄開發(fā)機修復。
粗略來看,這套方案沒什么技術問題。但是對于中小型公司來說,搭建整
套開發(fā)機環(huán)境、規(guī)范開發(fā)流程、規(guī)范 VPN 使用流程、全公司切到開發(fā)機,
這一套走下來需要的時間和人力成本都不低。通常來說也只有大公司才玩得起。
那小公司呢?難道每個新員工都必須浪費時間來配置環(huán)境?
當然不是。

主角登場。
什么是 Docker?我不是 Docker 專家,所以這里不對 Docker 做專業(yè)介紹。如果你還不知道 Docker 是什么,把它看成虛擬機就可以了。
在引入 Docker 之前,我對它做了一些調研,主要想搞清楚以下幾個問題:
Docker 能否跨平臺?(畢竟你不能要求公司給所有人配 Mac)
* 如何預覽 Docker 里的網(wǎng)頁?
* 如何編輯 Docker 里的文件?
* Docker 能否實現(xiàn)一次配置多處使用?
由于 Docker 運行在每個人的機器上,因此不存在外網(wǎng)訪問問題。
經(jīng)過調研,上述問題理論上都可以解決,下面是初步確定的解決方案:
* 用端口映射預覽 Docker 里的網(wǎng)頁 (-p 8080:8080)
* 用掛載數(shù)據(jù)卷的方式映射本地文件 (-v 本地文件路徑:容器路徑)
* 配置一個通用的 Image(鏡像)用 Kitematic 客戶端實現(xiàn)跨平臺運行 Docker
二、docker幾個基本概念
Docker 中最重要的三個概念是 Container(容器)、Image(鏡像)和 Volume(卷)。
Image 是靜態(tài)內容,如果你要把某個 Image 跑起來,那就需要一個Container。
這里面有一點很重要:**Container 中所做的改動不會保存到Image**。
舉個例子,你跑起來一個 Ubuntu Image,然后 touch newfile創(chuàng)建一個新文件,這時候如果直接重啟 Container,文件就沒了。
那怎么保存改動?
很簡單,執(zhí)行docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]] 即可。
這里的 commit 和 git commit 類似,執(zhí)行之后會把當前狀態(tài)保存為一個新 Image。
有同學就要問了,如果每次做改動都要 commit,我寫起代碼來豈不是很不方便?萬一寫到一半不小心重啟 Docker 怎么辦?
這確實是個問題,Docker 也有對應的解決方法:使用 Volume。
簡單來說,Volume 就是專門存放數(shù)據(jù)的文件夾,啟動 Image 時可以通過 `-v 本地目錄:容器目錄`
映射本地路徑到容器,一個容器可以掛載一個或多個 Volume,Volume 中的數(shù)據(jù)獨立于 Image,
**重啟不會丟失**。
我們創(chuàng)建一個 Volume,掛載到系統(tǒng)的一個目錄下,然后把代碼都放進去就可以了。
最后說端口映射。前面說過,Docker 可以看做一個虛擬機,你的所有文件都在里面。如果你在 Container 中運行一個服務器,監(jiān)聽 127.0.0.1:8000,從你自己的機器上直接訪問 http://127.0.0.1:8000是不行的,因為 Container 和你的機器是兩個不同的環(huán)境。
那怎么辦呢?我們先來看一個大家都熟悉的問題。
日常開發(fā)中我們經(jīng)常需要讓同事預覽網(wǎng)頁效果,常用的方法是監(jiān)聽 0.0.0.0:8000,然后讓同事連接同一個局域網(wǎng),訪問 http://你的機器IP:8000即可。
Container 的問題非常相似,只不過我們自己變成了“同事”,需要訪問
Docker 內部的網(wǎng)頁。只需要在運行容器時,通過-p 如:`-p 8080:8080` 添加
端口映射然后在本機的瀏覽器上觀察即可。
好了,枯燥的概念講完了,理解不了也不用著急,跟著下一章走一遍流程就懂了。
三、動手搭建自己的開發(fā)環(huán)境
正式開工之前,先看看我們都要做什么。
目標:配置一個通用 Image,支持預覽網(wǎng)頁,項目文件可以在容器中開發(fā)又可以在本機上用版本管理軟件管理(如:git),預裝開發(fā)過程中可能用到的包。
過程:
1. 下載并安裝 Docker Toolbox
2. 下載并運行 Ubuntu 鏡像
3. 做常規(guī)的linux系統(tǒng)初始化工作(換源、安裝常用的linux工具)
4. 安裝前端開發(fā)工具
5. 導出鏡像
1.下載并運行Ubuntu鏡像
這里我推薦大家用Docker終端使用加速器后,再用終端下載。docker Hub 國內訪問較慢,下載實在太慢。
鏡像加速器
國內很多云服務商都提供了加速器服務,例如:
阿里云加速器
DaoCloud 加速器
靈雀云加速器
注冊用戶并且申請加速器,會獲得如 https://jxus37ad.mirror.aliyuncs.com 這樣的地址。我們需要將其配置給 Docker 引擎即可。

然后打開mac終端,輸入以下命令拉取我們需要ubuntu鏡像:
docker search ubuntu:14.04
docker pull ubuntu:14.04
docker images
我這里用的是ubuntu:14.04 版本的鏡像而沒有用官方的Ubuntu鏡像了,官方的有很多工具都精簡了用起來不方便。在終端輸入命令后可以看到如下輸出

這里筆者本地搭建了開發(fā)環(huán)境就沒重新安裝了,用
docker images 可以看到我們本地擁有的鏡像文件。
正常的情況下你可以看到如下輸出:

看到輸出的sha256校驗值后便表示已經(jīng)下載完了。這里大家可以注意下方框闊住的區(qū)域,細心的朋友會發(fā)現(xiàn)我們下載ubuntu文件,是一段一段下載的,每段都有自己的ID.這就是Docker 的聯(lián)合文件系統(tǒng),多個鏡像可以共用公共的部分,可以使得用戶在拿到別人的鏡像后,添加配置快速生成自己的開發(fā)鏡像。
下載完后,打開kitematic 在myimages便可以看到我們剛剛下的ubuntu官方鏡像文件

點擊start后點擊exec便可進入Ubuntu系統(tǒng),或者直接在mac終端上輸入
docker exec [container] /bin/bash
就可以打開終端,我們輸入幾行簡單的shell命令看下:

可以看到熟悉的linux文件系統(tǒng),太親切了,讓筆者回憶起剛畢業(yè)那會看鳥叔linux私房菜的辛酸史。
2.常規(guī)初始化工作
Ubuntu 裝完系統(tǒng)第一件事是什么?沒錯,換源。
“源”其實就是網(wǎng)址,你在 Ubuntu 中用 apt-get install 安裝軟件的時候就是從“源”下載。Ubuntu 默認的源在國外,安裝起來非常慢,所以要先換成國內的源。
國內有很多 Ubuntu 源,我用的是中科大源。
你可以直接看官方換源教程,也可以直接打開 Ubuntu 命令行,執(zhí)行下面的命令:
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 可以正常用了。
3.安裝前端工具
(1).首先安裝 npm:
apt-get install npm
然后安裝 cnpm,之后所有 npm 操作都改成 cnpm,從淘寶源下載,速度會快很多。
npm install -g cnpm --registry=https://registry.npm.taobao.org
(2).接著安裝 n
TJ 大神的 NodeJS 版本管理工具,可以安裝多個版本,一鍵切換。
n 需要用到 curl,所以先安裝 curl:
apt-get install curl
然后安裝 n:
cnpm install -g n
(3).最后使用 n 安裝目前的穩(wěn)定版 NodeJS:
n stable
這樣就準備好了前端開發(fā)需要的基本工具。
我們的項目目前在使用 Vue,所以我還安裝了 vue-cli、browserify、gulp、babel 以及相關的庫,你可以根據(jù)你的項目需求安裝對應的庫。
(4).安裝Vue-cli 等開發(fā)環(huán)境
# 全局安裝 vue-cli
$ npm install --global vue-cli
4. 導出鏡像
別忘了前面的提醒:如果不 commit,重啟之后所有改動都會丟失!
所以先 commit。輸入命令行執(zhí)行:
docker ps
會看到下面這樣的輸出:

復制 Container name,我這里是 devtest3,然后執(zhí)行:
docker commit -t registry:tag devtest3
tag 換成你想要的標簽號, registry 換成你的鏡像名稱。我這里就是 docker commit -t dev:latest devtest3
注意:這里registry貌似不支持大寫。有大寫字母會報錯
doker images查看本地鏡像

commit 之后就可以把當前 Container 導出 Image 了:
docker export > develop.tar
執(zhí)行完后,在你的個人目錄下(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 文件路徑中不能有中文,如果有,先把文件移動到另一個純英文路徑的文件夾中)
輸入命令docker images,復制出鏡像的 IMAGE ID(類似54184b993d46)
輸入命令,
docker run -t -d -p 8080:8080/tcp --name dev -v /Users/yixinmac/Desktop/dockerRegistry/ssh_ubuntu/volums:/web IMAGEID
把其中的 IMAGEID 替換為上一步復制的內容.下面對上面的幾個參數(shù)簡要的介紹下
--name 自定義容器名稱 -d 后臺運行 -p 8080:8080 本地8080端口映射到容器8080端口 -v 掛載本地ssh_ubuntu/volums 文件夾到容器 /web 路徑
回到 Kitematic,應該可以看到左側多了一個容器,如果沒有可以重啟下Kitematic,此時環(huán)境已經(jīng)搭建完畢,可以點擊Kitematic 上的Ports Volumes 標簽查看下容器的配置是否都正確,如果一部小心手快弄錯了不礙事,大膽刪,再docker run 配置正確的容器。只要鏡像文件在,我們可以很方便的重新再建一個新的容器。 如果說新的容器配置了新的東西,不想刪掉后重新配,沒關系,commit 后再新建一個新的容器,原有的鏡像可以通過docker rmi imgaeID刪除,不過推薦大家平時在啟動容器的時候就養(yǎng)成 -t (防止容器沒任務時自動退出) -v -p 的好習慣。
刪除指令
1.docker rm container
即可刪除
有時候容器正在運行時刪除會報錯,可以通過
dcoker stop container 后再刪除
2.docker rm $(docker ps -a -q)
刪除所有已停止的容器
查看下相關配置:


接下來我們將在容中新建一個vue 工程然后查看本地文件系統(tǒng)變化,最后在本地訪問vue-cli 提供的nginx服務網(wǎng)頁。
exec進入容器

輸入如下命令:
su
ls
cd web/
vue init webpack myproject
cd myproject
npm install
npm run dev

本地訪問localhost:8080 ,熟悉的vue歡迎頁。
我們再進入本地文件系統(tǒng)看一下,


本地文件系統(tǒng)有了我們剛創(chuàng)建的工程文件,這部分文件我們交給git或svn管理即可。
這樣前端環(huán)境就算搭建完成了,建好的鏡像你可以直接通過鏡像文件直接發(fā)給團隊,也可以搭建docker私有倉庫進行管理,推薦后者,docker私有倉庫和git一樣,可以很方便對現(xiàn)有的鏡像迭代提交,具體步驟docker 入門與實踐一書第十四章有,大家也可以百度下。
四、使用dockerfile 創(chuàng)建開發(fā)環(huán)境
這時候大家心里可能有個疑問:
既然我們可以通過上面的方式創(chuàng)建開發(fā)環(huán)境,為什么我們還需要使用dockerfile?
開發(fā)環(huán)境一旦搭建完后,后期我們基本上很少會懂了,久而久之可能自己都忘了對開發(fā)環(huán)境做了哪些事情。
團隊分享的時候,怎么樣讓其他人知道你環(huán)境配置了什么而不會重復做已有的工作?
時間久了,有些服務要映射哪些端口不記得了怎么辦?
這就是dockerfile的作用了。
dockerfile 和 上面的方式差不多,只是用一個文件用docker 指定的方式把我們的做的操作寫在了一個文件里而已。
現(xiàn)在我們打開終端,進入我們指定的文件目錄,新建Dockerfile 文件

新建完后我們把我們上面做過的指令,全部寫下來前面 加個 RUN,不同的是apt-get install 后面多加了一個 -y 這個指令的意思是在之后需要交互的地方全部默認Yes.需要加上這樣一個參數(shù) 否者在之后的建立鏡像中,linux apt-get會因為得不到用戶相應而自動退出。
最終得到的Dockerfile文件如下:
FROM ubuntu:14.04
MAINTAINER “niwanglongDevUbuntu”
#apt-get 換源
RUN sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
RUN apt-get update
#安裝linux基本軟件
RUN apt-get install -y vim bash-completion
#安裝前端開發(fā)環(huán)境
RUN apt-get install -y npm
RUN npm install -g cnpm --registry=https://registry.npm.taobao.org
RUN apt-get install -y curl
RUN npm install -g -y n
RUN n stable
RUN npm install -y --global vue-cli
#開放Vue-Cli端口
EXPOSE 8080
使用Dockerfile 建立鏡像。

注意箭頭 所指的地方 "."表示dockerfile所在的目錄。
五、坑匯總
1.CMD 總是提醒command not found 導致容器直接退出。

可以看到“”有明顯的區(qū)別,換成vim 編輯后,問題解決。
2.windows下修改設置,丟失volume
2016.08.04 Windows 的 Kitematic 有 bug,如果在界面中修改設置會導致 volume 丟失,所以不要在 Kitematic 中修改任何設置,如果要改就從命令行執(zhí)行
上一節(jié)提到過,Windows 的 Kitematic 有 bug,手動添加端口映射會丟失所有配置,所以我們直接用命令添加,只要不從 Kitematic 里修改配置就沒問題。
有銀彈
說了很多優(yōu)點,下面來聊聊用 Docker 做開發(fā)環(huán)境的缺點。
首先,Docker 本身還不夠成熟。
Docker 確實很強大,能支持三大操作系統(tǒng),性能方面也遠超傳統(tǒng)虛擬機,但是仍然不夠成熟。舉一個小例子:Kitematic 在 Windows 上丟失配置的 bug 去年年底就有人報過,到現(xiàn)在都沒解決。
其次,Docker 這套體系使用成本并不低。
試想一下,作為一個開發(fā)人員,在寫代碼之前必須運行 Kitematic、啟動 Ubuntu 鏡像、連接共享文件夾、進入鏡像啟動靜態(tài)服務器。這個流程太重,理想的開發(fā)環(huán)境應該是透明的,打開電腦就能寫代碼?;蛟S下一步可以考慮在這方面做一些自動化腳本來輔助開發(fā)。