The Cloud Camp Week#05 (docker compose)

ใน Week นี้มีเรียนวันเดียวครับ และเป็นการเรียนจาก Overview of the get started guide | Docker Docs และมี Recap ช่วงท้ายครับ ใน Blog จะจดบางส่วนที่ควรรู้เพิ่มครับ ขยายจาก The Cloud Camp Week#03 (Container 101)

docker network

อันนี้จะเสริมจาก Blog เดิมนะครับ

  • Create
docker network create [OPTIONS] NETWORK

--Default User-defined bridge networks - isolated network for multiple containers belonging to a common project or component. 
docker network create invworker

--Add More Option
docker network create \
  --driver=bridge \
  --subnet=172.28.0.0/16 \
  --ip-range=172.28.5.0/24 \
  --gateway=172.28.5.254 \
  invworkerfix
  • Delete
docker network rm <network name>
  • List
docker network ls
  • Example
    - สร้าง Bridge Network (isolated network) วง wordpress ให้ คุยกันภายในระหว่าง wordpress / mysql
    - ถ้าประกาศ Network wordpress ตอนสร้าง mysql สามารถระบุชื่อ network ได้เลย --network wordpress ไม่ต้องเปิด Port ออกมาข้างนอก
docker network create wordpress

docker run -d --name wordpress-db --network wordpress --network-alias db -e MYSQL_ROOT_PASSWORD=secret -e MYSQL_DATABASE=wordpress mysql

docker run -d -p 8080:80 --network wordpress -e WORDPRESS_DB_HOST=db -e WORDPRESS_DB_USER=root -e WORDPRESS_DB_PASSWORD=secret -e WORDPRESS_DB_NAME=wordpress wordpress:6-apache
docker ps --format 'table {{.ID}}\t{{.Image}}\t{{.Status}}\t{{.Names}}\t {{ json .Networks }}'

สำหรับเคสอื่นๆ ดูจาก Network drivers overview | Docker Docs

docker volume

Ref: Manage data in Docker | Docker Docs
  • Create หรือ Auto Create docker create / docker run จาก Flag -v เอาจริง ผมใช้แบบหลังมากกว่านะ
#docker จัดสรรที่เอง /var/lib/docker/volumes/
docker volume create database-files 

#หรือ Auto Create docker create / docker run
# -v host_path:container_path
docker run --name mysql-db -d -e MYSQL_ROOT_PASSWORD=secret -v database-files:/var/lib/mysql --label training.app=persistent-db mysql
  • docker inspect - ถ้าอยากรู้ มันเก็บที่ไหน ดูตรง Mount
docker inspect <volume name>

#sample
docker inspect database-files 
  • Delete
docker volume rm <volume name>
  • List
docker volume ls
  • ตัวอย่าง Bind Mount จาก host
#Base Path dockercon23-workshop-materials

docker run --name init-db -d -v $pwd/mysql_data:/var/lib/mysql -v $pwd/database-initialization:/docker-entrypoint-initdb.d -e MYSQL_ROOT_PASSWORD=secret -e MYSQL_DATABASE=db mysql

ถ้าต้องการดูเพิ่มเติม ลองดูได้จาก Manage data in Docker | Docker Docs ครับ

อ๋อ แล้วที่ลองโจทย์ dockercon จะเจอว่าเหมือนตัว MySQL จำ Volume เก่า แก้ตามนี้ครับ mysql - MYSQL_ROOT_PASSWORD is set but getting "Access denied for user 'root'@'localhost' (using password: YES)" in docker container - Stack Overflow

docker clear resource

docker network prune
docker volume prune
docker system prune

health check

มีหลายอัน ผมเข้าใจผิด อย่างตัว --health-cmd คิดว่ามันมีเฉพาะ podman docker ก็มีนะ

docker run --name cats -p 5050:5000 -l training.app=cats --health-cmd="curl -f http://localhost:5000/ || exit 1" --health-interval=5s mikesir87/cats:1.0

Ref: Docker Healthcheck Command Status for Unhealthy Containers (couchbase.com)

docker compose

- ทำไมต้องมีตัว Compose
  • OLD Way
    - ถ้ามี Container หลายอัน สิ่งที่เราต้องทำ คือ docker run ที่ละตัวไปจนครบ หรือ ทำ Shell Script มาช่วยจัดการ
  • New Way
    - ยุคถัดมา มี บ Orchard สร้าง Fig Tools ที่มาช่วยทำ Tools และ Configuration ในรูปแบบ YAML ตอนปี 2014 (มี How to ด้วยแฮะ)
    - ต่อมา docker ซื้อ Orchard แล้วปรับเจ้า Fig Tools > docker-compose
    - ล่าสุด docker ปรับ CLI ใหม่เป็น docker compose เขียนด้วย GO
- docker compose 101

เอาจริงๆ ปกติผมเอาของคนอื่นที่ทำไว้มารันซะมากกว่า ถ้าสร้างต้องมาเข้าใจ YAML ที่สำคัญ

  • version: ต้องระบุ จะได้ Lock Feature ที่เราจะใช้ใน Compose ได้ ถ้าไม่ใส่ ตัว Runtime มันจะเลือกใช้ อาจจะเจอ Breaking Change หรือ พฤติกรรมแปลกๆได้
    Ref: Compose file version 3 reference | Docker Docs
version: "your-version"
  • service: ส่วนที่แทน Container แต่ละตัว
services: 
  <<ServiceName such as db>>:
    image: <<your image>>
    ports:
    - 5432:5432
    environment:
    #Setting ตาม Guild Line ของแต่ละ Image ใน Docker Hub
    - POSTGRES_USER=dockeruser
    - POSTGRES_PASSWORD=dockerpass
    - POSTGRES_DB=pets
    volumes:
     #Setting ตาม Guild Line ของแต่ละ Image ใน Docker Hub
    - pg-data:/var/lib/postgresql/data
    - ./db:/docker-entrypoint-initdb.d
    networks:
      - frontend   # >> ชื่อ Network โดยจะกำหนดใน Network Section ในที่นี้จะชื่อ frontend   
  <<ServiceName n such as app>>:
    image: pingkunga/web1
     build:
      context: .   # >> Dockerfile
      target: dev  # >> Stage in Dockerfile
    ports:
    - 3000
    environment:
    - DB_HOST=db
    depends_on:    # >> บอกว่า Container นี้จะทำงานได้ให้รออีกตัวทำงานให้เรียบร้อยก่อน
    - <<service name such as db
  • volumes: ส่วนที่แทน volume แต่ละตัว
  • network ส่วนที่แทน network แต่ละตัว อันนี้เดี๋ยวดูตัวอย่างจาก dockercon23-workshop-materials/multi-deploy-compose
networks:
  frontend:   # >> ชื่อ Network โดยจะกำหนดใน Network Section ในที่นี้จะชื่อ frontend
    driver: custom-driver-1 #ถ้าใช้ Custom Drive มากำหนด เพิ่ม

ตัวอย่าง Full Docker Compose

version: "3.8" 
services: 
  db:
    image: postgres:alpine
    ports:
    - 5432:5432
    environment:
    - POSTGRES_USER=dockeruser
    - POSTGRES_PASSWORD=dockerpass
    - POSTGRES_DB=pets
    volumes:
    - pg-data:/var/lib/postgresql/data
    - ./db:/docker-entrypoint-initdb.d
  
  pgadmin:
    image: dpage/pgadmin4
    ports:
      - 5050:80
    environment:
      PGADMIN_DEFAULT_EMAIL: admin@acme.com
      PGADMIN_DEFAULT_PASSWORD: admin
    volumes:
      - pgadmin-data:/var/lib/pgadmin

  web:
    image: pingkunga/web1
    ports:
    - 3000
    environment:
    - DB_HOST=db
    depends_on:
    - db

volumes: 
  pg-data:
  pgadmin-data:
- docker compose command
# Use Compose to reconcile and launch what’s defined
docker compose up

# -f specific compose file 
# -d run in backgroud
docker-compose -f .\app-dogs\compose.yaml up -d

# Multiple Compose File Example Up
docker-compose -f .\proxy\compose.yaml -f .\app-cats\compose.yaml -f .\app-dogs\compose.yaml up -d

#===================================================
#List Docker Compose 
docker compose ls

#===================================================
# Tear everything down (leaves volumes by default)
docker compose down
# Multiple Compose File Example Down
docker-compose  -f .\app-cats\compose.yaml -f .\app-dogs\compose.yaml -f .\proxy\compose.yaml down

#===================================================
# Share logs from all of the application services
docker compose logs
#===================================================

#Sync Change and Update Container for Development Purpose
docker compose watch

แล้วตัว Compose เองมีหลายทางในการจัดการ Structure (Ref: Working with multiple Compose files

  • Include - เอารวมไฟล์ Common เข้าด้วยกัน และให้ไฟล์อื่นๆ อ้างอิงเอาไปใช้ต่อ
  • Extend - คล้ายๆ Include การ Override Config ได้
  • Merge เป็นการ Override Config ที่กำหนดไว้ในไฟล์ docker compose เช่น
    - dev
    - ci test
    - prod
#dev
docker compose -f .\docker-compose.base.yml -f .\docker-compose.dev.yml up
#ci test
docker compose -f .\docker-compose.base.yml -f .\docker-compose.ci.yml up
#prod
docker compose -f .\docker-compose.base.yml -f .\docker-compose.prod.yml up

แล้วถ้าเอา docker compose ไปเทียบกับ K8S มี Criteria อะไรที่เอามาพิจารณาในการเลือกใช้บ้าง

ปิดท้าย

ถ้าใครสนใจเรื่องอื่นๆ สามารถได้อ่าน Blog เกี่ยวกับ Docker ใน Tag Container ครับ และถ้าใครอยากดู docker แบบรวบรัด Slide ของ DockerCon23 น่าสนใจครับ

และก็อีกเรื่องลืมเขียนไป เวลาออกแบบระบบ วาง Architecture อย่างลืมทำเอกสาร Architectural Decision Records (ADRs) เผื่อคนรุ่นหลังมาศีกษาว่าทำไมถึงต้องทำแบบนี้

อย่างผมเพิ่งโดนสดๆ บ่ายวันนี้ 2023-10-17 เลย ทีมที่มาดูต่อถามว่าทำไมไม่แยกระบบ Parallel อีกชุด และทำ Tools ให้ครบ ผมเลย Forword Mail + Wiki ที่บันทึกการตัดสินใจนั้นไป ลูกค้าไม่บอกแต่แรกว่าต้องการ Parallel อีกชุด และทำ Tools แต่มีคนรับปากมาก่อนเลย เลยทำให้การ Design อยู่ที่ประหยัดสุด และไม่เสียเงินเพิ่ม

ปล. การบ้าน Week นี้ คุณโจโจ้จัดเต็มมาก ได้รู้อะไรหลายๆอย่างที่ไม่่เคยใช้กัน อย่างตัว Compose ที่แยกหลายไฟล์ แล้วให้มันOverride กัน เหมือนเขียน Code เพิ่งรู้ว่าทำได้ ปกติผมจะชอบไปหาที่คนอื่นทำไว้ใน GitHub แล้วมาแก้มากกว่าครับ

Reference


Discover more from naiwaen@DebuggingSoft

Subscribe to get the latest posts to your email.