---
# System prepended metadata

title: 利用 Docker Compose 管理多個容器

---

# 利用 Docker Compose 管理多個容器

## docker-compose.yml 範例
研究 docker-compose 是因為我在目前的專案上有一些需求 (暫時稱呼我的專案叫作專案A好了)，包括:
1. 需要利用 docker 建立兩個 container，一個跑專案 A 的 server，一個跑 redis server
2. A_server 跑 Django 框架，且需在本地端 build image
3. A_server 需要掛載本地端的資料夾到容器內
4. A_server 需要看得到 redis_server
5. 兩個容器可以一起管理

依照我自己的需求我製作了以下的 docker-compose.yml 檔案
```
version: '3'
services:
  A_server:
     build: .
     depends_on:
       - redis_server
     ports:
       - "8000:8000"
     volumes:
       - ./AWebCode1:/home/smart/AWebCode1
       - ./AwebCode2:/home/smart/AWebCode2
     restart: always
     container_name: servicebox
  redis_server:
     image: redis:latest
     ports:
       - "6379:6379"
     restart: always
     container_name: redis_box
```
我們來看一下上面這份檔案
1. 第一行 version 一定要寫。
2. services 定義所有的容器內容及相關細項，這裡定義了兩個容器，包括 A_server 和 redis_server。
3. 對於 A_server 來說
    * 因為需要在本地端編譯成 docker image，所以使用 build。後面使用 . 代表直接在 docker-compose.yml 這份檔案的所在地直接找尋 dockerfile 然後開始做編譯
    * depends_on 後面接 redis_server，代表當容器啟動時，會先將 redis_server 的容器啟動後再啟動 A_server 的容器
    * ports 這邊指明 8000:8000 的對映關係，就跟 docker run -p 8000:8000 一樣意思
    * volumes 這邊指定需要掛載本地端到容器內的資料夾，就跟 docker run -v aaa:bbb 一樣意思，甚至這邊可以掛載多個還可以一次寫滿寫好
    * container_name 可以指定當容器啟動時的預設名稱
4. 對於 redis_server 來說
    * 因為直接使用 docker registry 上面的 image，所以可以直接利用 image 關鍵字指定需要 docker pull 的 image 名稱和 tag
5. 還記得在使用 docker run -v 的時候，後面的資料夾必須寫完整路徑嗎？但是在 docker-compose 檔案裡可以使用相對路徑，是不是很方便？
6. 如果 docker-compose 裡沒有特別指定網路的話，則會自動建立一個 default 網路，然後把兩個 service 都加入到此網路中，重點是他們**要怎麼認到彼此**呢？請記得在這個網路中，定義好的 service name 會自動代換成他們在這個網路中的 DNS name，因此對於 A_server 這個 container 來說，只要在網址列輸入 http://redis_server 就可以連到 redis_server 這個容器，相反的從 redis_server 要連到 A_server 也是一樣的道理。

## 這次的重點整理
1. 由於我這次的專案主要是使用 Django 框架，而在 Django 的 settings 裡面應該要設定 redis server 的 url，原本我是寫 127.0.0.1 然後永遠連不到，現在知道要直接寫 yml 檔裡的 redis server 的名稱。以這個範例來說，要在 settings 裡面寫的 url 是 *redis_server* 這個字串。
2. 使用 docker-compose 工具最明顯的優點
    * 設定檔可以使用相對路徑
    * 可以先寫好多個掛載點，不用每次 docker run 時再慢慢輸入
    * 可以建立容器之間的共同橋樑
3. docker-compose.yml
    * 用來定義 docker 環境及所有服務彼此之間的關係
4. command
    * docker-compose up -d
        會將 docker-compose.yml 裡所有定義的服務一起啟動，流程包括
        1. 先開創一個共同的網路，預設名稱為 {docker-compose.yml 所在的資料夾名稱}\_default
        2. 依序啟動各個服務，並將每個服務加入至此預設網路內
        3. 後面加上 -d 參數代表 detach，跟 docker run -d 一樣意思
    * docker-compose down
        依序關閉每個服務，最後將預設的網路停止
    * docker-compose ps
        查看 Docker Container 的執行狀態
5. 縮排規定要空白鍵，而不是 tab。

## Reference
[Day 24：使用 Docker-Compose 啟動多個 Docker Container](https://ithelp.ithome.com.tw/articles/10194183)
[Build a Multi-Container Docker Application with Docker Compose with a React, Node, and Postgres App](http://bit.ly/2I7oHqT)
[Docker Compose 初步閱讀與學習記錄](http://bit.ly/39iEEpW)
[透過 Docker Compose 設定 network](http://bit.ly/2Ic0e3G)
[官方快速教學範例](https://docs.docker.com/compose/wordpress/)
[Docker Compose 配置檔案 Docker-Compose.yml 檔案詳解](https://codertw.com/程式語言/617564/)









