Docker(六): 用Docker-compose建立與實作Web專案

LUFOR129
Sep 27, 2021

一個專案由多個container組成,如前幾天的Web,前端由apache、後端由express、伺服器由postgres組成。但是基本上每個Container都各自更新為政,彼此的DockerNet連結依靠著Docker自動生成IP。每次都要寫docker run去輸入一堆參數。有沒有辦法讓這些參數寫成文件化更方便控管呢? 有! 就是Docker-compose!!

直接看Code連結: Github

Docker-compose你可以如封面,理解成一個章魚小幫手,幫你把許許多多的Container建立起來。當我們程式修改後執行docker-compose命令可以自動抓到哪一個image改變,並專門為其重新build、run,大大增加了部屬的效率。

docker-compose.yml

我們直接來看看Day14的Node前後端分離該怎麼改成用Docker-compose,在根目錄下建立一個docker-compose.yml,docker-compose.yml寫法範例如下:

version: "3.9"
services:
frontend:
build: ./html
image: myweb:latest
ports:
- 8085:80
container_name: run_myweb
backend:
build: ./app
image: mynode:latest
ports:
- 4200:3000
container_name: run_mynode
db:
image: postgres
ports:
- 5432:5432
container_name: my_postgres
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
PGDATA: /var/lib/postgresql/data/pgdata
volumes:
- pgdata:/var/lib/postgresql/data/
volumes:
pgdata:

docker-compose是為了取代過去docker run冗長的參數輸入過程,在service下每一個都是一個container。如上建立了run_myweb、run_mynode、my_postgres三個container。

docker-compose.yml該如何撰寫呢?詳細的文件在這裡。但是太多了,如下列出一些比較重要的參數:

  • build: 輸入一個dockerfile的位置,更多資訊參考這裡
  • image: 決定了一個container的base image,如果沒有build將會從遠端拉下來,如果有build會是build後的image名稱。
  • container_name: container的名稱
  • environment: build與container的參數類似ENV,接受MAP(- K:V)、ARRAY(K=V)寫法
  • env_file: 傳入.env的路徑讓建構的參數更方便修改,多個則用MAP寫法
  • ports: 用MAP寫法寫上對內對外PORT
  • volumes: 決定volumes

假如你的docker-compose.yml有很多環境變數,你可以加入.env檔(裡面VAR=VALUE)在與docker-compose.yml檔同一個目錄下,默認會自動抓取變數。

docker-compose指令:

寫好docker-compose.yml檔後該如何執行呢? 以下為執行命令

  • docker-compose up 這是建構,會直接掃描當前目錄下的docker-compose.yml檔並進行build 所有的image並建立好container。
  • -d 背景執行,我們通常會加上這一個參數
  • -f <path.yml> 指定yml
  • --force-rm 強制刪除所有container再重run
  • --no-cache 強制重新buiild所有image
  • docker-compose stop/rm/restart/down 停止、刪除、重新啟動、停止並刪除

執行完後會出現三個container包再一起,他們彼此網路是互相連接的,我們稱做docker stack

成功抓取網頁:

詳細程式碼可以參考Github

--

--