ข้ามไปที่เนื้อหา

Docker Compose

Docker compose คือไฟล์ script สำหรับการ deploy container โดยจะเป็นไฟล์ .yml หรือ .yaml

ประโยชน์ของการใช้ Docker compose

  1. เนื่องจากการใช้ CLI deploy container ที่เต็มไปด้วย parameter เช่น -p:port, --name:ชื่อ, -e key:value และอื่นๆอีกมากมาย คำสั่ง docker run ... จึงมีความยาวและมีโอกาศผิดพลาดได้ง่าย Docker compose จึงเข้ามีมีบทบาทโดยการบันทึก parameter ทั้งหมดออกมาเป็นไฟล์ และเราสามารถ reuse file นี้ในทุก ๆ การ deploy ได้

  2. สามารถ deploy กลุ่มของ container ได้พร้อมๆกัน นั่นหมายความว่าใน 1 compose จะสามารถกำหนดได้หลาย image พร้อมๆกัน ลดโอกาศผิดพลาดได้

  3. สามารถทำระบบ override variable ได้และ reuse environment variable ได้ในหลาย container พร้อมๆกัน

ที่กล่าวมาเป็นเพียงเบื้องต้น เราสามารถประยุกต์การใช้งานได้ในหลาย ๆ รูปแบบเช่น

  • การ Deploy application ที่ต้องการ database เป็นของ service เอง

  • การ Deploy microservice ที่จะต้องมีการ depend on service อื่นๆ


เริ่มต้นใช้งาน Docker compose

Generate docker-compose ด้วย Visual Studio

การเพิ่ม docker-compose.yml สามารถทำได้เหมือนขั้นตอนการ Add docker support โดยการคลิกขวาที่ Project > Add > เลือกเมนูที่ชื่อว่า Container Orchestrator Support... เลือกเป็น docker-compose และระบบปฏิบัติการ Linux

Add docker-compose

การ Generate Docker compose โดยการ Add Container Orchestrator Support to project

หลังจากการ Add Container Orchestrator Support แล้วจะได้ Project เพิ่มขึ้นมาใน solution ชื่อ docker-compose ซึ่งจะประกอบไปด้วย

ไฟล์ หน้าที่
.dockerignore สำหรับการใส่รายการไฟล์ หรือ extension องไฟล์ที่ต้องการจะให้ docker ละเว้นไม่นำไปใช้ในการสร้าง container เช่น .env
docker-compose.yml ไฟล์ compose
docker-compose.override.yml ไฟล์ compose แบบ override
launchSettings.json เก็บค่า profile การรันด้วย docker-compose

About docker-compose.yml

ไฟล์ .yml จะใช้ indent หรือย่อหน้าเป็นตัวแยกลำดับขั้น หมวดหมู่ของ service ดังนั้นการแก้ไขไฟล์จะต้อง Tab ในการเว้นย่อหน้า

แต่ละ version ของ docker compose จะมีการเขียนตัวแปรที่ไม่เหมือนกัน ให้ใช้พื้นฐานที่ version 3.4

Docker compose จะถูกตั้งชื่อด้วย docker-compose.yml เสมอ ไม่สามารถเปลี่ยนชื่อได้

ไฟล์ docker-compose.yml จะเก็บข้อมูลการ Deploy หลักๆที่สามารถใช้ร่วมกันในทุก ๆ environment ได้เช่น image address

ในกรณีที่มี service มากกว่า 1 project ภายใน solution เดียวกันหรือ service ที่จะต้องดึง image จากภายนอกมาให้เพิ่ม service ต่อท้ายได้เลย โดย service จะต้องเรียงจาก service ที่ใหญ่ที่สุดและเป็น service ภายในก่อนและตามด้วย service อื่นๆจากภายนอกเช่น database

docker-compose.yml
version '3.4'

services:
    [service-name1]:
        image: [{docker-image-registry-address}/{image-name}:{tag}]
        build:
            context: .
            dockerFile: DockerFile

    # Container อื่น (ถ้ามี)
    [service-name2]:
        image: [{docker-image-registry-address}/{image-name}:{tag}]
        build:
            context: .
            dockerFile: DockerFile

    ...

Meaning of docker-compose.yml

บรรทัด ความหมาย
1 version ของ docker-compose มีผลกับ ชื่อ parameter และ syntax
3 หมวดหมู่ services สำหรับการใส่รายการ service ทั้งหมด นอกจาก services ในตัวอย่างแล้วก็จะมี networks, volumes เป็นต้น
4 ชื่อ service
5 image address คือที่อยู่ของ image หรือ gitlab image registry ตามด้วย /{service-name}:{tag} ใช้สำหรับการ push image หลัง publish และใช้ pull image ถ้าเป็น service จากภายนอกในขั้นตอนการ run
6 หมวดการ build image
7 context: . คือ การกำหนด directory ของโปรเจค
8 dockerFile: DockerFile คือ directory ของ Dockerfile ภายในโปรเจค จะมีความแตกต่างไปตามลักษณะโครงสร้างของ Solution

ไฟล์ .override.yml จะใช้สำหรับการตั้งค่าการทำงานของ container ในต่าง environment ซึ่งการ Deploy ไปยัง site ทดสอบหรือ UAT จะต้องใช้ .staging.yml และ Deploy ไปยัง Production site จะต้องใช้ .production.yml

ตัวอย่างดังกล่าวเป็นค่าเริ่มต้นจาก Visual Studio ที่ generate docker-compose file ขึ้นมาให้ ส่วนไหนที่ไม่ใช้งาน สามารถลบออกได้เช่น การใช้ User secret ในส่วนของ Volumes

docker-compose.override.yml
version '3.4'

services:
    [service-name1]:
        environment:
          - ASPNETCORE_ENVIRONMENT=Development
          - ASPNETCORE_URLS=https://+:443;http://+:80
        ports:
          - "80"
          - "443"
        volumes:
          - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro
          - ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro

    ...

Meaning of docker-compose.yml

บรรทัด ความหมาย
1 version ของ docker-compose มีผลกับ ชื่อ parameter และ syntax
3 หมวดหมู่ services สำหรับการใส่รายการ service ทั้งหมด นอกจาก services ในตัวอย่างแล้วก็จะมี networks, volumes เป็นต้น
4 ชื่อ service
5 หมวดการตั้งค่าตัวแปร environment
6 ASPNETCORE_ENVIRONMENT=Development เป็นการกำหนดค่า Environment ของ .NET Application ว่าขณะนี้กำลังทำงานบน environment Development ค่าอื่น ๆ เช่น Staging, Production
7 ASPNETCORE_URLS=https://+:443;http://+:80 เป็นการกำหนดว่า container นี้จะมีการใช้งานผ่าน https และ http โดย default
8 ชื่อหมวดการตั้งค่า ports ที่ใช้
9 อนุญาตให้มีการติดต่อผ่าน port 80 หรือ http
10 อนุญาตให้มีการติดต่อผ่าน port 443 หรือ https
11 ชื่อหมวดการตั้งค่า volumes หรือ persistent storage
12 (optional) volume สำหรับไฟล์ user secret ของ .NET สำหรับการเก็บค่า Credential เช่น Connection string อ่านเพิ่มเติมที่ Safe storage of app secrets in development in ASP.NET Core
13 (optional) volume สำหรับการใช้งาน https

Volumes directory

เนื่องจาก Directory เบื้องต้นมีการเรียกใช้งานไปที่ Appdata ของ Windows ทำให้ขั้นตอนการสร้าง container บน Linux จะเกิด Error ได้ จะต้องเปลี่ยนเป็น

docker compose volumes
volumes:
  - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro
  - ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro
docker compose volumes
volumes:
  - ~/.microsoft/usersecrets/<user_secrets_id>/secrets.json
  - ~/.aspnet/https:/https:ro

ASPNETCORE_ENVIRONMENT

การกำหนดค่า ASPNETCORE_ENVIRONMENT จะส่งผลกับการอ่าน appsettings.json ของ .NET Application โดยจะมีการอ่าน override จากไฟล์ appsettings.production.json

การใช้งาน Docker Compose เบื้องต้น

ไฟล์ docker-compose.yml และ docker-compose.override.yml ใน solution นอกจากการ run ด้วย Visual Studio แล้ว สามารถใช้ผ่าน Terminal ได้โกยใช้คำสั่งดังนี้

Pull images

คำสั่งสำหรับการ pull images ของทุก container ที่ยังไม่มีในเครื่องลงมาเก็บไว้

pull every image in compose command
docker-compose pull

Run containers

คำสั่งสำหรับการ run เพื่อสร้างชุด container เทียบเท่ากับการใช้คำสั่ง docker run ... กับทุก image ใน compose และอ่านค่าจากตัวแปรต่าง ๆ เช่น ports, volumes, name เป็นต้น

create every containers from defined services command
docker-compose up -d

Stop containers

คำสั่งหยุดการทำงานของ container ทั้งหมดที่อยู่ใน compose เทียบเท่ากับการใช้คำสั่ง docker stop ... กับทุก image ใน compose

stop every containers from defined services command
docker-compose down

Deploy with Docker compose

การ Deploy ด้วย docker-compose จะต้องสร้างไฟล์หรือคัดลอกไฟล์ docker-compose.yml และ docker-compose.production.yml ไปยัง server ปลายทางที่ต้องการจะ deploy โดยจะต้องถูกจัดเก็บที่ folder [{ชื่อโปรเจค}-compose] และใช้คำสั่ง docker-compose up -d เพื่อ deploy application มีขั้นตอนดังนี้

Step1: Prepare docker-compose files in server

  1. remote เข้าไปที่ server
  2. สร้าง folder ชื่อ [{ชื่อโปรเจค}-compose] โดยการใช้คำสั่ง mkdir /[{ชื่อโปรเจค}-compose]
  3. เข้าไปยัง folder ที่สร้างด้วยคำสั่ง cd /[{ชื่อโปรเจค}-compose]
  4. สร้างไฟล์ docker-compose.yml ด้วยคำสั่ง nano docker-compose.yml
  5. copy เนื้อหาภายใน docker-compose.yml ใน Solution และคลิกขวาเพื่อวาง
  6. save and exit โดย Ctrl+X และ Enter
  7. สร้างไฟล์ docker-compose.production.yml ด้วยคำสั่ง nano docker-compose.production.yml
  8. copy เนื้อหาภายใน docker-compose.production.yml ใน Solution และคลิกขวาเพื่อวาง
  9. save and exit โดย Ctrl+X และ Enter

ตรวจสอบ Environment

ใน Production site จะต้องกำหนดให้ตัวแปร ASPNETCORE_ENVIRONMENT มีค่าเท่ากับ Production

Step2: Release services

ใช้คำสั่ง docker-compose up -d เพื่อสั่งให้ docker อ่าน compose และสร้าง container