技術導向的 docker 新手教學。
一日 docker 初體驗。
隨著 DevOps 的技術迭代,
目前將環境容器化的部署方式,越來越盛行。
本篇環境作業系統為 Mac,
利用最簡單的實務操作,
並且使用 node.js express 框架作為基本範例,
讓大家體驗 docker 的操作。
如果你希望先了解運作,背景歷史以及理念等等,
建議可以閱讀此篇文章「什麼是Docker · 《Docker —— 從入門到實踐》正體中文版」。
本篇建議您需要具備以下基本知識:
目錄:
一、安裝 Docker
在 Mac 中,我們使用 brew 安裝,它是用於管理 Mac 套件的一項工具。
如果你沒有安裝它,請先參考該網站進行安裝。
或是直接打開 Terminal 輸入:
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
接著開始安裝 Docker。
brew update
brew cask install docker
安裝完畢後開啟應用程式,就可以看到 Docker.app。
試著使用指令,驗證看看安裝成功與否。
docker -v
docker-compose -v
畫面結果。
二、建立 Express 專案
框架的部分就不再贅述。
首先安裝 generator。
npm install -g express-generator@4
建立專案,例如「docker-express-demo」。
express docker-express-demo
接著進入目錄。
cd docker-express-demo
安裝套件並啟動。
npm install
npm start
如果順利,應該可於 http://localhost:3000/ 看到網站。
這是基本的專案啟動,
但他執行環境是依賴於本地,而非使用 docker 容器。
如果要使用 docker,則必須撰寫腳本,
告知 docker 應該如何運作。
三、撰寫 Dockerfile
首先在專案底下建立檔案 Dockerfile。
建立好後,如果您使用 vscode,可能會自動顯示檔案的 icon 唷~
接著輸入以下內容到該檔案。
[ Dockerfile ]
FROM node:8-alpine
COPY . /workspace
WORKDIR /workspace
RUN npm install
EXPOSE 3000
CMD npm start
- FROM:這裡的 node:8-alpine,來自 Docker Hub 的 node。你想用到的容器,都可以在這邊找到,這個映像檔包含了 nodejs。
- COPY:複製當前目錄到容器中的 /workspace。用意是將程式碼,複製到容器中執行。
- WORKDIR:這邊是指容器的工作目錄,就像 cd workspace 意思一樣,因為我們把檔案複製於該目錄,所以一同切換目錄。
- RUN:執行某個腳本命令,在這邊等同於我們先前所下的 npm install(用於部署階段的指令)。
- EXPOSE:將容器的 3000 port 對外公開。
- CMD:也是執行腳本命令(用於部署完畢的指令)。
建議將剛剛 npm install 所產生的 node_module 移除。
否則會連同該目錄一併複製到容器。
四、執行 Docker
docker 的運作流程首先要建立映像檔 image,
完成後我們接著再去指定映像檔於容器中。
1. 建立映像檔
docker build -t demo/myapp .
利用 docker build 就可以建立出指定容器,
我們利用 -t 建立 tag 為 demo/myapp,
而最後面的一點「 . 」就是指目錄來源喔!
完成後的指令畫面:
2. 查看映像檔
我們可以利用 docker images 來查看現有容器映像。
docker images
這時候應該可以看到剛剛建立好的 demo/myapp,
3. 建立容器
接著就可以啟動容器了。
docker run -p 8080:3000 --name myapp -d demo/myapp
- docker run:執行某個容器使用 run。
- -p 8080:3000:是指將內部的 3000 port 映射到本地的 8080 port,因為 express 預設 3000 port。
- --name myapp:我們將此容器命名為 myapp。
- -d demo/myapp:掛載映像檔名為 demo/myapp。
4. 查看容器
我們可以查看當前運作的容器狀況。
docker ps -a
查詢結果如下:
- STATUS:如果狀態看到 Up xxxx,那就是正常運作囉~
這時候打開 http://localhost:8080/,就可以看到畫面了!
這是由安裝 node.js 容器所執行的 express 專案。
5. 停止/啟動 容器
只要使用 start 以及 stop,就能夠操作了。
停止容器。
docker stop myapp
啟動容器。
docker start myapp
6. 移除容器
如果希望重新建立容器,
則我們可以使用 rm 進行移除。
docker rm myapp
或是移除所有容器。
docker rm $(docker ps -a -q)
7. 查看日誌
如果你想查看一些運作日誌,你可以使用以下指令。
docker logs myapp
五、執行 Docker Compose
在 docker 中,一次只能命令一個容器,
如果今天前端後端都是容器化,那麼是不是要總共操作兩次 docker 了!?
因此 docker-compose 就是處理多個容器的工具。
接下來我們實作,
將專案改成由 nginx 所運行的 http server。
並且啟動 nginx 時,不再是常見的這個畫面:
而是將 nginx 預設的 80,轉到我們 node express 的容器上。
首先改造一下我們專案的擺放,
1. 移動專案放入 server 資料夾
我們建立一個資料夾 server,並將剛剛專案移入。
2. 建立 nginx 目錄與檔案
這邊的用意是要把該目錄掛載到容器中的 nginx。
將原有 nginx 的 default.conf,給取代掉,因為我們要設定轉給 node express。
在根目錄建立資料夾 nginx,裡面新增檔案 default.conf
[ default.conf ]
server {
listen 80 default_server;
listen [::]:80 default_server;
server_tokens off;
client_max_body_size 15M;
if ($http_x_forwarded_proto = "http") {
return 301 https://$host$request_uri;
}
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://node:3000;
proxy_redirect off;
}
}
內容幾乎沒變,我們新增了 proxy_pass。
如果來源請求是 / 目錄的(http://xxx/),
就會轉給 http://node:3000。
這裡的 3000 port 就不再贅述,因為 express。
而這邊的 node 其實是別名,
主要是來自 docker-compose 的設定,因此我們接著來設定吧!
3. 設定 docker-compose
在根目錄中建立檔案 docker-compose.yml。
[ docker-compose.yml ]
version: "3"
services:
nginx:
image: nginx:alpine
volumes:
- ./nginx:/etc/nginx/conf.d
links:
- node
ports:
- 80:80
node:
build:
context: ./server
- nginx:這個名字與 node 一樣,是可以自由取的。
- node:在剛剛 default.confg 中的 node 就是指此,綁定它在 nginx 容器中所分配到的 ip。
- image:我們這邊其實是又建立另一個容器為 nginx。
- volumes:掛載檔案的腳本語言法,我們將外部的 nginx: (所有) 掛載到 /etc/nginx/conf.d/ 底下所有
- links:我們將 node 容器與 nginx 關聯起來。
- port:內部的 80 port 映射到外部的 80port
- build:部署的檔案則會尋找 ./server 目錄中的 Dockerfile
整體的目錄架構如下圖:
4. 啟動 docker-compose
執行以下指令,就可以同時啟動 nginx server 以及 node express 兩個容器了。
docker-compose up -d
- -d:用意是讓指令背景執行,否則你的終端機會一直顯示 log
完成後就會顯示 done。
這時候開啟網頁,應該就可以順利看到。http://localhost/
5. 停止運作
我們可以利用 down 將容器停止運作。
docker-compose down
6. 重新部署容器
這樣的動作會重新執行 Dockerfile 的指令。
docker-compose up -d --build
以上恭喜你順利完成 docker 以及 docker-compose 的初體驗了。
剩下的就多官方複雜的文件或其他的部落格吧(X
本篇程式碼放置於 Github - docker-express-demo
有勘誤之處,不吝指教。ob'_'ov