Your cart is currently empty!
docker-compose 一次建立多個 Container
當一次運行多個 Container 時,這個 docker-compose 就派上用場了,他可以在一個文件中定義多個 container,不論是從當前的相對目錄裡面的 Dockerfile build image,還是直接從 repository pull image 然後放在一起跑。
定義你的 Dockerfile
Dockerfile,建議在瀏覽前先知道設定單一 Container 怎麼做,看這篇:Docker container intro。
這個部分很簡單,但先有一個從你的程式資料夾複製到 image 資料夾的概念,你可以整包 COPY . .,也就是從 Dockerfile 所在資料夾,複製到 image 的資料夾,只是 image 會很巨。
以下介紹幾個常用的:
- FROM:使用的作業系統,通常 alpine 是空間最小的(Google Artifact Repository 限制 500MB)
- COPY:就是把 Dockerfile 的相對位置複製到 image(這邊是 package*.json 移動到 image 最高路徑)
- WORKDIR:可以定義 RUN COPY CMD 在哪個 Folder 運行,但因為我只有一個階層 . 複製到 .,跳過
- CMD:在 Container 運行時的 command,通常就直接是你在實際 production 環境運行的時候的 command,這樣佔的資源也比較少(我使用 npm run dev 就沒辦法在 Azure B2ats_v2 的 2vCPU 1GB Ram 開起來…)
- EXPOSE:你的 App 會使用哪個 port,到時候要把 Container 的跟伺服器實際的 port 的連起來
我的資料階層:
My-app
—app
—-route
—node_modules
–Dockerfile
–compose.yaml
–package.json
–.dockerignore
FROM node:alpine
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
CMD ["npm", "start"]
EXPOSE 3000
(Optional) docker-compose 製作 image
如果只是一個應用程式加上從 repository 抓其他的,這個步驟可以跳過。
compose.yaml 是截至我寫這篇時最新的用法,之前有 docker-compose.yml 之類的也可以,不過 compose.yaml 會被優先選用;另外新的版本不需要指定 version 了,他會自動選適合的 version。
先有個概念,在整個 compose 裡面會存在多個 container,這些 container 如果需要互相對話的話,只需要通過 service_name,以我的為例就是 remix://blablabla、cql://blablabla。你可以試著使用 docker exec -it container_name 進到其中一個 container 裡面使用 ping remix、ping cql 來看結果(container 裡面運行的 OS 可能需要安裝 ping)。
# compose.yaml
# 這個檔案可以直接使用 docker-compose up 執行
services:
remix:
image: your_docker_user/my-app
build: . # where to find the Dockerfile
ports:
- 3000:3000
environment: # environment variables
# the url for scylla and database in composed network, not localhost. cql is the service name, you could try ping cql from remix container sh.
DB_URL: cql
cql:
image: scylladb/scylla
ports:
- 9042:9042
# https://docs.docker.com/storage/volumes/#use-a-volume-with-docker-compose
volumes:
- db:/var/lib/scylla # should be where scylla store files
volumes:
db:
# should always define a name for volume in order to use it in volumes:
docker-compose build --no-cache
不過像我這樣一個自己的一個從 Docker Hub 抓的 compose,其實不需要使用到 build 啦,只要把我的那個 push 上去,就可以在其他地方使用 docker-compose up 啟動!
使用 docker-compose up 整包啟動
在其他地方直接寫一個 compose.yaml 然後執行 docker-compose up -d。這邊就不用 build 那行了。
這些 container 如果需要互相對話的話,只需要通過 service_name,以我的為例就是 remix://blablabla、cql://blablabla,所以我在 remix 的 environment 設定 DB_URL,然後在我的 app 裡面就直接使用環境變數 DB_URL。
# compose.yaml
services:
remix:
image: gabrieljc/quipu
ports:
- 3000:3000
environment:
DB_URL: cql
cql:
image: scylladb/scylla
ports:
- 9042:9042
volumes:
- db:/var/lib/scylla
volumes:
db:
docker-compose up -d
Docker 會為 compose.yaml 裡面你編寫的 services 各建立一個 container,也可以在 docker desktop 看到 compose 的 container 圖案變成好幾層的橘色。
自動建立的 images 是由 “foldername_servicename_serialnumber” 組成,最後的 serialnumber 在當 scale up 使用同個 image 建立多個 composed container 時很有用。
使用 docker exec -it 進入 Container 玩玩
直接使用 docker exec 進入 compose container 的 cql container 的 cqlsh。可以在這邊操作各個 container 的資料跟系統,如果有安裝 docker desktop 也可以直接開啟 container 裡面的 exec。
# 這邊的 cqlsh 跟 bash 一樣是一個 shell,但特別給 cql 語言的
user@mycomputer % docker exec -it quipu-cql-1 cqlsh
Connected to at 172.19.0.2:9042
[cqlsh 6.2.0 | Scylla 5.4.3-0.20240211.cf42ca0c2a65 | CQL spec 3.3.1 | Native protocol v4]
Use HELP for help.
cqlsh>