前端工程師學(xué)Docker?看這篇就夠了
傳統(tǒng)的虛擬機(jī),非常耗費(fèi)性能
Docker可以看成一個高性能的虛擬機(jī),并且不會浪費(fèi)資源,主要用于Linux環(huán)境的虛擬化,類似VBox這種虛擬機(jī),不同的是Docker專門為了服務(wù)器虛擬化,并支持鏡像分享等功能。前端工程師也可以用于構(gòu)建代碼等等。
目前看,Dokcer不僅帶火了GO語言,還會持續(xù)火下去。
首先,我們看看傳統(tǒng)的虛擬機(jī)和Docker的區(qū)別。
傳統(tǒng)的虛擬機(jī):
Docker:
可以看到,傳統(tǒng)的虛擬機(jī)是每開一個虛擬機(jī),相當(dāng)于運(yùn)行一個系統(tǒng),這種是非常占用系統(tǒng)資源的,但是Docker就不會。但是也做到了隔離的效果
Docker容器虛擬化的優(yōu)點(diǎn):
- 環(huán)境隔離
 
Docker實(shí)現(xiàn)了資源隔離,實(shí)現(xiàn)一臺機(jī)器運(yùn)行多個容器互不影響。
2. 更快速的交付部署
使用Docker,開發(fā)人員可以利用鏡像快速構(gòu)建一套標(biāo)準(zhǔn)的研發(fā)環(huán)境,開發(fā)完成后,測試和運(yùn)維人員可以直接通過使用相同的環(huán)境來部署代碼。
3. 更高效的資源利用
Docker容器的運(yùn)行不需要額外的虛擬化管理程序的支持,它是內(nèi)核級的虛擬化,可以實(shí)現(xiàn)更高的性能,同時對資源的額外需求很低。
4. 更易遷移擴(kuò)展
Docker容器幾乎可以在任意的平臺上運(yùn)行,包括烏力吉、虛擬機(jī)、公有云、私有云、個人電腦、服務(wù)器等,這種兼容性讓用戶可以在不同平臺之間輕松的遷移應(yīng)用。
5. 更簡單的更新管理
使用Dockerfile,只需要小小的配置修改,就可以替代以往的大量的更新工作。并且所有修改都是以增量的方式進(jìn)行分發(fā)和更新,從而實(shí)現(xiàn)自動化和高效的容器管理。
正式開始
本文撰寫于2019年10月13日
電腦系統(tǒng):Mac OS
使用最新版官網(wǎng)下載的Docker
以下代碼均手寫,可運(yùn)行
下載官網(wǎng)的Docker安裝包,然后直接安裝
Docker官網(wǎng)下載地址
安裝后直接打開
打開終端命令行,輸入docker,會出現(xiàn)以下信息,那么說明安裝成功。
下載安裝成功后,首先學(xué)習(xí)下Docker的兩個核心知識點(diǎn)
container(容器)和image(鏡像)
Docker的整個生命周期由三部分組成:鏡像(image)+容器(container)+倉庫(repository)
思維導(dǎo)圖如下:
該如何理解呢?
每臺宿主機(jī)(電腦),他下載好了Docker后,可以生成多個鏡像,每個鏡像,可以創(chuàng)建多個容器。發(fā)布到倉庫時,以鏡像為單位。可以理解成:一個容器就是一個獨(dú)立的虛擬操作系統(tǒng),互不影響,而鏡像就是這個操作系統(tǒng)的安裝包。想要生成一個容器,就用安裝包(鏡像)生成一次
上面就是Docker的核心概念,下面開始正式操作
補(bǔ)充一點(diǎn):如果想深入Docker , 還是要去認(rèn)真學(xué)習(xí)下原理,今天我們主要講應(yīng)用層面的
首先,我們回到終端命令行操作
輸入:
- docker images
 
如果你的電腦上之前有創(chuàng)建過的鏡像,會得到如下:
如果沒有的話就是空~
我們首先創(chuàng)建一個自己的鏡像
先編寫一個Node.js服務(wù)
創(chuàng)建index.js
- // index.js
 - const Koa = require('koa');
 - const app = new Koa();
 - app.use(async ctx => {
 - ctx.body = 'Hello docker';
 - });
 - app.listen(3000);
 
然后配置package.json文件
- {
 - "name": "app",
 - "version": "1.0.0",
 - "private": true,
 - "scripts": {
 - "start": "node server.js"
 - },
 - "dependencies": {
 - "koa": "^2.5.0"
 - }
 - }
 
正常情況下 使用
npm start 或 node index.js 就可以啟動服務(wù)
可是我們這里需要打包進(jìn)Docker中,這里就需要寫一個配置文件dockerfile
vsCode有天然插件支持
在目錄下新建文件dockerfile,加入如下配置
- FROM node
 - ADD . /app/
 - EXPOSE 3000
 - WORKDIR /app
 - RUN npm install
 - CMD ["node","./index.js"]
 
解釋一下,上面這些配置的作用
FROM 是設(shè)置基礎(chǔ)鏡像,我們這里需要Node
ADD是將當(dāng)前文件夾下的哪些文件添加到鏡像中 參數(shù)是 [src,target]
這里我們使用的 . 意思是所有文件,當(dāng)然跟git一樣,可以配置ignore文件
EXPOSE是向外暴露的端口號
WORKDIR是說工作目錄,我們這里將文件添加到的是app目錄,所以配置app目錄為工作目錄,
這樣就不用在命令行前面加/app了
RUN是先要執(zhí)行的腳本命令
CMD是執(zhí)行的cmd命令
可以想一想,我們打包好鏡像后,然后啟動鏡像會發(fā)生什么?
文件編寫完,使用命令打包鏡像
使用命令打包已經(jīng)好的文件目錄
- docker image build ./ -t app
 
打包后出現(xiàn)提示:
此時我們查看Docker鏡像,使用命令:
- docker images
 
我們可以清楚看到,app鏡像已經(jīng)打包成功,下面我們啟動它
- docker run -p 8000:3000 app
 
使用上面命令即可啟動我們的鏡像,這時我們在命令中輸入
- curl 127.0.0.1:8000
 
得到返回內(nèi)容
Hello docker
瀏覽器輸入: 127.0.0.1:8000 即可訪問到頁面~
以上說明,我們的第一個Docker鏡像已經(jīng)制作成功
有人可能會覺得到這里,鏡像和容器有點(diǎn)混淆了,不是先有鏡像再有容器嗎?
其實(shí)是我們啟動的鏡像有腳本命令幫我們啟動了服務(wù),于是Docker幫我們自動創(chuàng)建了容器
查看Docker容器命令:
- docker ps -a 列出所有容器
 - 不加 -a 僅列出正在運(yùn)行的,像退出了的或者僅僅只是創(chuàng)建了的就不列出來
 - docker container ls 列出當(dāng)前運(yùn)行的容器
 
輸入上面 docker container ls
得到結(jié)果
原來Docker看我們啟動了腳本服務(wù),幫我們自動生成了容器?
下面我們來一個生成鏡像,再生成容器,最后手動啟動容器的例子
這次我們配置,加入Nginx反向代理服務(wù)器
首先,創(chuàng)建用戶需要看到的html文件
這里我們給一個普通的 hello-world內(nèi)容的index.html文件即可
然后創(chuàng)建dickerfile文件,配置如下,將index.html文件添加到對應(yīng)的位置
- FROM nginx
 - COPY ./index.html /usr/share/nginx/html/index.html
 - EXPOSE 80
 
對外暴露端口號80
這里特別提示:配置文件怎么寫,根據(jù)你的基礎(chǔ)鏡像來,百度基本都能找到,不用糾結(jié)這個
此時的文件結(jié)構(gòu):
老規(guī)矩,開始打包
- docker build ./ -t html
 
打印信息:
輸入終端命令:
- docker images
 
得到結(jié)果:
新的鏡像html已經(jīng)構(gòu)建成功,但是此時查看容器,是沒有正在運(yùn)行的
輸入命令:
docker container ls //查看正在運(yùn)行的所有容器
docker container ls -a //查看所有容器
得到結(jié)果是:
可以確認(rèn)的是,我們創(chuàng)建鏡像不會自動生成和啟動容器
我們手動生成容器
- docker container create -p 8000:80 html
 
此時命令行返回 一段值
輸入
- docker container ls
 
沒有顯示有任何啟動的容器,這時候我們手動啟動
輸入
- docker container start ***(上面那段值)
 
再重復(fù) docker container ls 命令
得到結(jié)果
此時訪問localhost:8000即可正常訪問頁面~
至此,我們可以確定,創(chuàng)建鏡像只要不啟動,不會生成容器,更不會運(yùn)行容器
那怎樣將Docker用在前端的日常構(gòu)建中呢?
我們使用gitHub+travis+docker來形成一套完整的自動化流水線
只要我們push新的代碼到gitHub上,自動幫我們構(gòu)建出新的代碼,然后我們拉取新的鏡像即可(gitLab也有對應(yīng)的代碼更新事件鉤子,可以參考那位手動實(shí)現(xiàn)Jenkens的文章)
首先我們先進(jìn)入 Travis CI 官網(wǎng)配置,注冊綁定自己的gitHub賬號
然后在左側(cè)將自己需要git push后自動構(gòu)建鏡像的倉庫加入
接著在項(xiàng)目根目錄配置 .travis.yml 文件
- language: node_js
 - node_js:
 - - '12'
 - services:
 - - docker
 - before_install:
 - - npm install
 - - npm install -g parcel-bundler
 - script:
 - - parcel build ./index.js
 - - echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin
 - - docker build -t jinjietan/mini-react:latest .
 - - docker push jinjietan/mini-react:latest
 
每次更新push代碼,都會下載,然后執(zhí)行打包命令,這樣你下載的鏡像就是有最新的代碼。不再需要每個人下載打開鏡像再去build
為了降低復(fù)雜度,這里使用了Parcel打包工具,零配置
更改dockerfile內(nèi)容,將parcel打包后的內(nèi)容COPY進(jìn)容器
- FROM nginx
 - COPY ./index.html /usr/share/nginx/html/
 - COPY ./dist /usr/share/nginx/html/dist
 - EXPOSE 80
 
添加好了你的庫之后,選擇這里的設(shè)置
然后添加兩個環(huán)境變量:
DOCKER_USERNAME和DOCKER_PASSWORD
這里,我將我編寫的mini-react框架源碼,放入docker中,然后使用parcel打包工具打包,再用nginx反向代理~
特別提示:這里的Docker容器,想要后臺運(yùn)行,就必須有一個前臺進(jìn)程。容器運(yùn)行的命令如果不是那些一直掛起的命令(比如tcp,ping),就是會自動退出的
通過 docker ps -a 可以看到容器關(guān)閉的原因
注意 :jinejietan/mini-react應(yīng)該換成你的用戶名/包名,再push代碼
這是思維導(dǎo)圖:
當(dāng)配置成功,代碼被推送到gitHub上后,travis-ci幫我們自動構(gòu)建發(fā)布新鏡像
一定要學(xué)會使用: docker ps -a 查看容器的狀態(tài)
成功的提示:
至此,發(fā)布,自動構(gòu)建鏡像已經(jīng)完成
正式開始拉取鏡像,啟動容器
我們剛才發(fā)布的鏡像名稱是:jinjietan/mini-react
先使用下面幾條命令
- docker中 啟動所有的容器命令
 - docker start $(docker ps -a | awk '{ print $1}' | tail -n +2)
 - docker中 關(guān)閉所有的容器命令
 - docker stop $(docker ps -a | awk '{ print $1}' | tail -n +2)
 - docker中 刪除所有的容器命令
 - docker rm $(docker ps -a | awk '{ print $1}' | tail -n +2)
 - docker中 刪除所有的鏡像
 - docker rmi $(docker images | awk '{print $3}' |tail -n +2)
 - tail -n +2 表示從第二行開始讀取
 
清除當(dāng)前宿主機(jī)上面所有的鏡像,容器,依次執(zhí)行
然后使用:
- docker image pull jinjietan/mini-react:latest
 
拉取鏡像,這時候需要下載
拉取完成后,使用
- docker images
 
可以看到j(luò)injietan/mini-react:latest鏡像已經(jīng)存在了
我們使用
- docker container create -p 8000:80 jinjietan/mini-react:latest
 
創(chuàng)建這個鏡像的容器,并且綁定在端口號8000上
最后輸入下面的命令,即可啟動mini-react框架的容器
- docker container start ***(上面create的返回值)
 
瀏覽器輸入 127.0.0.1:8000 發(fā)現(xiàn),訪問成功,框架生效。
Docker的使用,我們大致就到這里,個人認(rèn)為,用Docker比不用好,這個技術(shù)已經(jīng)快跟TypeScript一樣,到不學(xué)不行的階段了。
并不是說你非要用它,而是比如說,你如果不怎么懂TypeScript,你就沒辦法把如今那些優(yōu)秀庫的大部門的源碼搞得那么清楚。
越來越多的技術(shù)在依賴Docker
當(dāng)然,其實(shí)這個mini-react框架源碼也是不錯的,如果有興趣可以了解以下,源碼都在:
mini-react框架+鏡像配置源碼,記得切換到diff-async分支哦~





































 
 
 









 
 
 
 