前端工程師,為什麼要學習Docker ?

傳統的虛拟機,非常耗費性能
Docker可以看成一個高性能的虛拟機,并且不會浪費資源,主要用于Linux環境的虛拟化,類似VBox這種虛拟機,不同的是Docker專門為了伺服器虛拟化,并支援鏡像分享等功能。前端工程師也可以用于建構代碼等等
目前看,Dokcer不僅帶火了GO語言,還會持續火下去
首先,我們看看傳統的虛拟機和Docker的差別
傳統的虛拟機:
Docker:
可以看到,傳統的虛拟機是每開一個虛拟機,相當于運作一個系統,這種是非常占用系統資源的,但是Docker就不會。但是也做到了隔離的效果
Docker容器虛拟化的優點:
1. 環境隔離
Docker實作了資源隔離,實作一台機器運作多個容器互不影響。
2. 更快速的傳遞部署
使用Docker,開發人員可以利用鏡像快速建構一套标準的研發環境,開發完成後,測試和運維人員可以直接通過使用相同的環境來部署代碼。
3. 更高效的資源利用
Docker容器的運作不需要額外的虛拟化管理程式的支援,它是核心級的虛拟化,可以實作更高的性能,同時對資源的額外需求很低。
4. 更易遷移擴充
Docker容器幾乎可以在任意的平台上運作,包括烏力吉、虛拟機、公有雲、私有雲、個人電腦、伺服器等,這種相容性讓使用者可以在不同平台之間輕松的遷移應用。
5. 更簡單的更新管理
使用Dockerfile,隻需要小小的配置修改,就可以替代以往的大量的更新工作。并且所有修改都是以增量的方式進行分發和更新,進而實作自動化和高效的容器管理。
正式開始
本文撰寫于2019年10月13日
電腦系統:Mac OS
使用最新版官網下載下傳的Docker
以下代碼均手寫,可運作
下載下傳官網的Docker安裝包,然後直接安裝
https://www.docker.com/
Docker官網下載下傳位址
安裝後直接打開
打開終端指令行,輸入docker,會出現以下資訊,那麼說明安裝成功
下載下傳安裝成功後,首先學習下Docker的兩個核心知識點
container(容器)和image(鏡像)
Docker的整個生命周期由三部分組成:鏡像(image)+容器(container)+倉庫(repository)
思維導圖如下:
該如何了解呢?
每台主控端(電腦),他下載下傳好了Docker後,可以生成多個鏡像,每個鏡像,可以建立多個容器。釋出到倉庫時,以鏡像為機關。可以了解成:一個容器就是一個獨立的虛拟作業系統,互不影響,而鏡像就是這個作業系統的安裝包。想要生成一個容器,就用安裝包(鏡像)生成一次
上面就是Docker的核心概念,下面開始正式操作
補充一點:如果想深入Docker , 還是要去認真學習下原理,今天我們主要講應用層面的
首先,我們回到終端指令行操作
輸入:
docker images
複制
如果你的電腦上之前有建立過的鏡像,會得到如下:
如果沒有的話就是空~
我們首先建立一個自己的鏡像
先編寫一個Node.js服務
建立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 就可以啟動服務
複制
可是我們這裡需要打包進Docker中,這裡就需要寫一個配置檔案dockerfile
vsCode有天然插件支援
在目錄下建立檔案dockerfile,加入如下配置
FROM node
ADD . /app/
EXPOSE 3000
WORKDIR /app
RUN npm install
CMD ["node","./index.js"]
複制
解釋一下,上面這些配置的作用
FROM 是設定基礎鏡像,我們這裡需要Node
ADD是将目前檔案夾下的哪些檔案添加到鏡像中 參數是 [src,target]
這裡我們使用的 . 意思是所有檔案,當然跟git一樣,可以配置ignore檔案
EXPOSE是向外暴露的端口号
WORKDIR是說工作目錄,我們這裡将檔案添加到的是app目錄,是以配置app目錄為工作目錄, 這樣就不用在指令行前面加/app了
RUN是先要執行的腳本指令
CMD是執行的cmd指令
可以想一想,我們打包好鏡像後,然後啟動鏡像會發生什麼?
檔案編寫完,使用指令打包鏡像
使用指令打包已經好的檔案目錄
docker image build ./ -t app
複制
打包後出現提示:
此時我們檢視Docker鏡像,使用指令:
docker images
複制
我們可以清楚看到,app鏡像已經打包成功,下面我們啟動它
docker run -p 8000:3000 app
複制
使用上面指令即可啟動我們的鏡像,這時我們在指令中輸入
curl 127.0.0.1:8000
複制
得到傳回内容
Hello docker
浏覽器輸入: 127.0.0.1:8000 即可通路到頁面~
以上說明,我們的第一個Docker鏡像已經制作成功
有人可能會覺得到這裡,鏡像和容器有點混淆了,不是先有鏡像再有容器嗎?
其實是我們啟動的鏡像有腳本指令幫我們啟動了服務,于是Docker幫我們自動建立了容器
檢視Docker容器指令:
docker ps -a 列出所有容器
不加 -a 僅列出正在運作的,像退出了的或者僅僅隻是建立了的就不列出來
docker container ls 列出目前運作的容器
複制
輸入上面 docker container ls
得到結果
原來Docker看我們啟動了腳本服務,幫我們自動生成了容器?
下面我們來一個生成鏡像,再生成容器,最後手動啟動容器的例子
這次我們配置,加入Nginx反向代理伺服器
首先,建立使用者需要看到的html檔案
這裡我們給一個普通的 hello-world内容的index.html檔案即可
然後建立dickerfile檔案,配置如下,将index.html檔案添加到對應的位置
FROM nginx
COPY ./index.html /usr/share/nginx/html/index.html
EXPOSE 80
複制
對外暴露端口号80
這裡特别提示:配置檔案怎麼寫,根據你的基礎鏡像來,百度基本都能找到,不用糾結這個
此時的檔案結構:
老規矩,開始打包
docker build ./ -t html
複制
列印資訊:
輸入終端指令:
docker images
複制
得到結果:
新的鏡像html已經建構成功,但是此時檢視容器,是沒有正在運作的
輸入指令:
docker container ls //檢視正在運作的所有容器
docker container ls -a //檢視所有容器
複制
得到結果是:
可以确認的是,我們建立鏡像不會自動生成和啟動容器
我們手動生成容器
docker container create -p 8000:80 html
複制
此時指令行傳回 一段值
輸入
docker container ls
複制
沒有顯示有任何啟動的容器,這時候我們手動啟動
輸入
docker container start ***(上面那段值)
複制
再重複 docker container ls 指令
得到結果
此時通路localhost:8000即可正常通路頁面~
至此,我們可以确定,建立鏡像隻要不啟動,不會生成容器,更不會運作容器
那怎樣将Docker用在前端的日常建構中呢?
我們使用gitHub+travis+docker來形成一套完整的自動化流水線
隻要我們push新的代碼到gitHub上,自動幫我們建構出新的代碼,然後我們拉取新的鏡像即可(gitLab也有對應的代碼更新事件鈎子,可以參考那位手動實作Jenkens的文章)
首先我們先進入 Travis CI 官網配置,注冊綁定自己的gitHub賬号
然後在左側将自己需要git push後自動建構鏡像的倉庫加入
接着在項目根目錄配置 .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 mini-react:latest .
- docker push mini-react:latest
複制
每次更新push代碼,都會下載下傳,然後執行打包指令,這樣你下載下傳的鏡像就是有最新的代碼。不再需要每個人下載下傳打開鏡像再去build
為了降低複雜度,這裡使用了Parcel打包工具,零配置
更改dockerfile内容,将parcel打包後的内容COPY進容器
FROM nginx
COPY ./index.html /usr/share/nginx/html/
COPY ./dist /usr/share/nginx/html/dist
EXPOSE 80
複制
添加好了你的庫之後,選擇這裡的設定
然後添加兩個環境變量:
DOCKER_USERNAME
和
DOCKER_PASSWORD
這裡,我将我編寫的mini-react架構源碼,放入docker中,然後使用parcel打包工具打包,再用nginx反向代理~
特别提示:這裡的Docker容器,想要背景運作,就必須有一個前台程序。容器運作的指令如果不是那些一直挂起的指令(比如tcp,ping),就是會自動退出的
通過 docker ps -a 可以看到容器關閉的原因
注意 :jinejietan/mini-react應該換成你的使用者名/包名,再push代碼
這是思維導圖:
當配置成功,代碼被推送到gitHub上後,travis-ci幫我們自動建構釋出新鏡像
一定要學會使用: docker ps -a 檢視容器的狀态
成功的提示:
至此,釋出,自動建構鏡像已經完成
正式開始拉取鏡像,啟動容器
我們剛才釋出的鏡像名稱是:jinjietan/mini-react
先使用下面幾條指令
docker中 啟動所有的容器指令
docker start $(docker ps -a | awk '{ print $1}' | tail -n +2)
複制
docker中 關閉所有的容器指令
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 表示從第二行開始讀取
清除目前主控端上面所有的鏡像,容器,依次執行
然後使用:
docker image pull jinjietan/mini-react:latest
複制
拉取鏡像,這時候需要下載下傳
拉取完成後,使用
docker images
複制
可以看到jinjietan/mini-react:latest鏡像已經存在了
我們使用docker container create -p 8000:80 jinjietan/mini-react:latest建立這個鏡像的容器,并且綁定在端口号8000上
最後輸入下面的指令,即可啟動mini-react架構的容器
docker container start ***(上面create的傳回值)
複制
浏覽器輸入 127.0.0.1:8000 發現,通路成功,架構生效。
Docker的使用,我們大緻就到這裡,個人認為,用Docker比不用好,這個技術已經快跟TypeScript一樣,到不學不行的階段了。
并不是說你非要用它,而是比如說,你如果不怎麼懂TypeScript,你就沒辦法把如今那些優秀庫的大部門的源碼搞得那麼清楚。
越來越多的技術在依賴Docker
當然,其實這個mini-react架構源碼也是不錯的,如果有興趣可以了解以下,源碼都在:
mini-react架構+鏡像配置源碼,記得切換到diff-async分支哦~
https://github.com/JinJieTan/mini-react