ใน 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
- 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 อะไรที่เอามาพิจารณาในการเลือกใช้บ้าง
- จำนวนคนที่ใช้งาน
- การ Operate จัดการ
- การ Scale ช่วง Peak-Time
- Ref: How to Scale Services in Docker Compose (linuxhint.com) - App Life-Cycle Management
ปิดท้าย
ถ้าใครสนใจเรื่องอื่นๆ สามารถได้อ่าน 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
- Docker Compose overview | Docker Docs
- Docker networks explained - part 2: docker-compose, microservices, chaos monkey | Accesto Blog
- Creating a Docker image with a preloaded database | Coding with Coffee (cadu.dev)
- Docker MySQL Container: 3 Easy Steps for Setup and Configuration | Hevo (hevodata.com) //น่าจะของ dockercon
- Docker Compose: Ports vs Expose Explained (ioflood.com)
- Docker: Port Mapping. Port mapping enables the connection… | by Claire Lee | Medium
- dockerfile - Run docker image without port forwarding - Stack Overflow
- Everything You Need to Know about Docker Compose (kubesimplify.com)
- How To Execute A Docker-Compose Build Efficiently (marketsplash.com)
Discover more from naiwaen@DebuggingSoft
Subscribe to get the latest posts sent to your email.