เริ่มต้นใช้งาน Docker กัน Part 2

มาทำความรู้จักกับการสร้าง Container กับอีก 2 วิธีที่เหลือกันคือแบบ Docker Compose กับ Dockerfile
Feature Image

สวัสดีครับ มาต่อจาก Part ที่แล้วกันเลย โดย Part ที่แล้วเราพูดถึง Docker และเขียนวิธีการสร้าง Docker แบบธรรมดาไป วันนี้เราจะมาต่อกับการสร้าง Container อีก 2 แบบที่เหลือกัน

แบบ Docker Compose

Docker Compose เป็นส่วนเสริมของ Docker อีกทีหนึ่ง มีประโยชน์มากสำหรับคนต้องการเอาหลาย ๆ ซอฟต์แวร์หรือหลาย ๆ โปรแกรมรวมไว้ใน Container เดียว ถ้าต้องการใช้งานต้องติดตั้งก่อนนะ ถ้าใครติดตั้งแล้วลองพิมพ์คำสั่งใน Command Line ดู

docker-compose

หรือ

docker compose

ถ้ามี มันจะมีรายละเอียดเกี่ยวกับคำสั่งต่าง ๆ ให้ใช้งาน สำหรับใครที่ยังไม่ได้ติดตั้งสามารถดูได้ที่นี่ เอาล่ะ รู้จักกันพอประมาณแล้วเรามาเริ่มใช้งานกันเลย

ก่อนอื่นเลยเราสร้างไฟล์ขึ้นมาก่อน ตั้งชื่อว่า docker-compose.yml เอาไว้ในโฟลเดอร์หรือ Directory ที่เรากำหนด (แนะนำว่าควรเอาไว้ที่โปรเจคเรา เพราะเวลาเราจะ Mount Volume และไฟล์จะได้ทำได้ง่าย ในทีนี้สร้าง Directory ที่มีชื่อว่า nginx เอา docker-compose.yml ไว้ในนี้ ผู้เขียนใช้ Visutal Studio Code ดังรูป (จริง ๆ ใช้ Editor ไหนก็ได้นะ ในการแก้ไข docker-compose.yml)

Visual Studio Code

ขออธิบายไฟล์ docker-compose.yml ก่อนที่จะทำการเขียน เราจะเห็นว่าไฟล์ที่เราจะเขียนนั้นเป็นนามสกุล .yml ซึ่งย่อมาจาก YAML (YAML Ain’t Markup Language) เป็นภาษาที่ไม่ใช่ Markup ก็แอบงง ๆ อะไรคือไม่ใช่ภาษา Markup มันก็คือภาษาหนึ่งที่ไม่มีแท็กกำกับ เช่น ถ้าเป็น html มันก็จะมี <html> หรือ <body> อะไรอย่างงี้ แต่ YAML นั้นไม่ใช่ เป็นภาษาที่ถูกออกแบบมาไว้สำหรับให้คนอ่านเข้าใจได้ง่าย เราจะเห็นได้ทั่วไปจาก Config หรือทำ Document ต่าง ๆ เช่น Docker Compose, Swagger, Kubernestes อะไรแบบนี้ ตัวภาษาค่อนข้างเขียนง่าย แต่ต้องดู Tab ดูวรรคให้ดีนะ รายละเอียดของ YAML สามารถดูได้ที่นี่

เอาล่ะ เรามาเริ่มกัน ทำการเพิ่ม code ตามที่อยู่ด้านล่างนี้เลย (ต้อง Space อะไรให้ตรงด้วยนะ)

version: "3.8"

services:
  web:
    container_name: some-nginx
    image: nginx:latest
    ports:
      - '8085:80'
    restart: always

อธิบายเพิ่มเติม

  • version เป็น version ของ Docker Compose ที่ใช้รัน ในทีนี้ขอใช้เป็น 3.8 รายละเอียด version สามารถดูได้ที่นี่
  • services เป็นการเรียกใช้งาน Services โดยเริ่มต้นเวลาจะสร้าง Service เราก็ต้องประกาศแบบนี้แหละ
  • web เป็นชื่อ Service ตั้งเป็นอะไรก็ได้ แต่แนะนำว่าให้สื่อความหมาย เผื่อไว้มาอ่านทีหลังจะได้เข้าใจ ห้ามใช้สัญลักษณ์พิเศษและห้ามเว้นวรรคนะ
  • container_name เป็นชื่อ container ในที่นี้ตั้งเป็น some-nginx
  • image เป็นชื่อ image ที่เราเลือกใช้งาน ในที่นี้เลือกเป็น nginx:latest
  • ports เป็นพอร์ตหรือการเชื่อมต่อระหว่างภายนอกและภายใน container ตั้งได้หลาย port นะ ในทีนี้ตั้งเป็น 8085:80
  • restart เป็นสถานะของ Container ในที่นี้ตั้งเป็น always คือ ถ้า Container เกิดหยุดทำงานขึ้นมาให้ Restart ตัวมันเอง สามารถไปดูรายละเอียดของ restart ได้ที่นี่

เสร็จแล้ว เปิด Command Line ไปที่ Folder ที่เราสร้างและพิมพ์คำสั่งเลย

docker compose -f docker-compose.yml up -d

เมื่อรันแล้ว ลองไปดูที่ Docker

Docker Desktop Containers/Apps

อธิบายคำสั่งเพิ่มเติม

  • docker compose เป็นการเรียกใช้งาน Docker Compose
  • -f เป็นการเรียกอ่านไฟล์ ในที่นี้ให้อ่านไฟล์ docker-compose.yml
  • up คือสถานะเปิดใช้งาน
  • -d เหมือนกับ Docker ธรรมดา เป็นโหมดการทำงานแบบ Background

จากคำสั่งด้านบนจะเห็นว่าสามารถสั่งทำงานได้เหมือนกับ Docker แบบธรรมดาเลย ทีนี้ถ้าเราต้องการรวมหลาย ๆ Container เป็น Container เดียวล่ะ เรามาดูกัน

ในที่นี้ขอเพิ่มตัวอย่างเป็น phpmyadmin ละกัน ที่เลือกตัวนี้เพราะมันมีหน้า UI จะได้เห็นง่าย ๆ

Nginx คิดว่าคงรู้จักกันไปแล้ว สำหรับ phpmyadmin ล่ะ คืออะไร ง่าย ๆ phpmyadmin เป็น Web UI สำหรับจัดการฐานข้อมูล MySQL ไม่มี MySQL ก็สามารถใช้งาน phpmyadmin ได้ รายละเอียดเพิ่มเติมของ phpmyadmin ของ docker สามารถดูได้ที่นี่ เอาล่ะ เราไปต่อกันเลย

ก่อนอื่นก็ลบ Container เก่าออกก่อนนะ จากนั้นไปที่ไฟล์เดิม เราจะเพิ่มในส่วนของ MySQL ก็จะได้แบบนี้

version: "3.8"

services:
  web:
    container_name: some-nginx
    image: nginx:latest
    ports:
      - '8085:80'
    restart: always

  phpmyadmin:
    image: phpmyadmin
    ports:
      - 8086:80
    environment:
      - PMA_ARBITRARY=1
    restart: always

จากนั้นรันคำสั่งเดิมเลย

docker compose -f docker-compose.yml up -d

เสร็จแล้วไปดูที่ Docker Desktop กัน

Docker Desktop Containers/Apps

ไปดูที่ http://localhost:8085/ จะได้ดังรูป

Open Browser Chrome

ไปดูที่ http://localhost:8086/ จะได้ดังรูป

phpmyadmin

เป็นไงกันบ้างครับ สำหรับการสร้าง Container ด้วย Docker Compose ไม่ยากเลยใช่มั้ย อันนี้เป็นแค่พื้นฐานสำหรับการสร้าง Container แบบ Docker Compose เท่านั้น ผู้เขียนอยากให้รู้วิธีการใช้งานคำสั่ง Docker Compose จะได้เข้าใจมากขึ้น ต่อไปเราไปดูแบบสุดท้ายกัน

แบบ Dockerfile

เอาล่ะ เรามาถึงแบบสุดท้ายกันแล้ว ส่วนตัวคิดว่าแบบนี้ยากสุด เพราะเราต้องเข้าใจคำสั่ง Linux พอสมควรเลย การสร้างแบบนี้จะใช้งานก็ต่อเมื่อ Image ที่มีอยู่นั้นไม่เพียงพอต่อการใช้งาน เช่น สมมติว่าเราอยากได้ Image ที่ติดตั้ง Package ต่าง ๆ นอกเหนือจากที่มีอยู่ หรือใช้หลายซอฟต์แวร์ ไม่ก็ Image ที่เราอยากได้มันไม่มี ประสบการณ์ส่วนตัวที่เคยเจอมา เคยใช้แบบนี้ตอนใช้งาน Laravel ขอนอกเรื่องนิดหนึ่ง Laravel เป็น Framework สำหรับ PHP ทำไว้สำหรับสร้างเว็บไซต์ แล้วใน Docker มันไม่มี ณ ตอนนั้นนะ อยากได้ Laravel ไม่พออยากได้ MySQL, Nginx, Redis อะไรแบบนี้รวมด้วย เลยต้องใช้วิธีทำ Dockerfile นี้ การใช้ Dockerfile จะต้องมี Image ตั้งต้นหรือต้นแบบก่อน ก็เลยไปหา Image มาได้ 2 ตัวคือ ใช้ Ubuntu กับใช้ Alpine (สำหรับคนไม่รู้จัก Alpine ตัว Alpine นั้นเป็นระบบปฎิบัติการ Linux ที่มีขนาดเล็กมาก ๆ อยู่ที่ 5MB เท่านั้น แต่ด้วยความที่มันเล็ก เราต้องมานั่งติดตั้งทุกอย่างตามที่เราใช้ และเคยมีการถกเถียงถึงความปลอดภัยของมัน เพราะด้วยความที่มันเล็ก แปลว่ามันไม่มีอะไรป้องกันเลย กับบางคนก็บอกว่ามันเล็ก มันไม่มีช่องโหว่เลยปลอดภัย ลองหาอ่านตาม Google ได้ หลายประเด็นอยู่ ส่วนรายละเอียดของ Alpine สามารถดูได้ที่นี่)

ต้องบอกว่าเคสที่ว่ามา เราลง Container แยกก็ได้นะ ตอนนั้นอยากได้แบบจัดการที่เดียว แล้วเวลาย้ายคือย้ายไปทั้งก้อนเลย ไรงี้

เอาล่ะกลับมาเข้าเรื่อง ที่จะบอกก็คือ Dockerfile มันไว้สำหรับคนอยากลอง อยากมี Image เป็นของตัวเอง ไม่ก็มันหาไม่เจอแล้วจริง ๆ ไรแบบนี้ ก็ลองดูนะว่าชอบแบบไหน แต่วันนี้เราจะมาสอนวิธีการสร้างแบบง่าย ๆ เข้าใจได้ไม่ยาก เรามาดูกัน

เราจะใช้ Nginx เหมือนเดิมเลย และใช้ Config เหมือนที่เค้าทำมาให้เลย ไปดูกัน

ก่อนอื่นเลย เราต้องสร้าง Dockerfile ไว้ก่อน จากนั้นเพิ่ม Code นี้ลงไปเลย

FROM nginx

ไปที่โฟลเดอร์ที่เราสร้าง Dockerfile จากนั้นรันโดยใช้คำสั่ง

docker build -t some-content-nginx .

จากนั้นไปดูที่ Docker Desktop ใน Tab Images กัน

Docker Desktop Images

เราจะเห็น Image ที่เราสร้างมาใหม่ โดยใช้ชื่อว่า some-content-nginx

อธิบายเพิ่มเติม

  • docker build เป็นการแปลงไฟล์ที่เราเขียนออกมาเป็น Image
  • -t เป็นการสร้าง tag ใหม่ที่ชื่อว่า some-content-nginx
  • . เป็นการอ้างอิง Path ที่เก็บ Dockerfile

สามารถอ่านรายละเอียดเพิ่มเติมได้ที่นี่

ส่วนตัวแล้วเข้าใจว่า เวลาเขียน Dockerfile เราจะต้องอ้างอิง Image ต้นแบบ จากนั้นเราจะใช้ Tag ในการอ้างอิงและสร้างเป็น Image ของตัวเอง

ต่อมาเราจะเอา Image ที่สร้างเมื่อกี้ไปรันเป็น Container เราจะรันด้วยวิธีธรรมดาเลย (จะใช้ Docker Compose ก็ได้นะ ก็ต้องสร้างไฟล์ docker-compose.yml ขึ้นมาและไปเขียนตามแบบ Docker Compose)

docker run --name some-nginx -d -p 8087:80 some-content-nginx

ผลที่ได้ก็ตามนี้เลย

Command Line docker run

เปิด Browser ก็จะได้

Open Browser Chrome

พอเห็นแบบนี้อาจจะคิดว่าง่ายนิดเดียวเอง ใส่แค่บรรทัดเดียวก็ได้แล้ว แต่เดี๋ยวก่อน อันนี้เป็นการเอา image nginx มาใช้แบบไม่ได้แก้อะไรเลย เรามาดูตัวอย่างที่ยากขึ้นกัน ในที่นี้จะขอใช้เป็น Ubuntu แล้วติดตั้ง Nginx จะเป็นอย่างไรนั้นไปดูกัน

แก้ไขไฟล์เดิมเปลี่ยนเป็นตามนี้

FROM ubuntu:latest

RUN apt-get update
RUN apt-get install nginx -y

EXPOSE 80/tcp

CMD ["/usr/sbin/nginx", "-g", "daemon off;"]

จากนั้นใช้คำสั่งเดิมเลย

docker build -t nginx-ubuntu .

รอสักครู่จะได้ Image ชื่อ nginx-ubuntu มา ตามรูปเลย

Docker Desktop Images

จากนั้นรันคำสั่งเพื่อสร้าง Container จาก Image นี้เลย

docker run --name some-nginx -d -p 8088:80 nginx-ubuntu

ไปดูที่ Docker Desktop เลย

Docker Desktop Containers/Apps

เปิด Browser กันเลย

Open Browser Chrome

จะเห็นว่าได้เหมือนกัน (แอบงงว่าทำไมทำใน Nginx ที่เป็น Image ของมันดันเป็น Dark Theme ตาม Default ของ Chrome เลย แต่พอเป็น Ubuntu ดันเป็นสีขาว ได้เว็บเหมือนกันต่างกันที่สี น่าจะต้องตั้งค่าเพิ่ม)

อธิบายเพิ่มเติม

  • FROM ubuntu:latest เป็นการโหลด Image ชื่อ ubuntu:latest มา
  • RUN apt-get update เป็นคำสั่ง Linux ตระกูล Debian จะเป็นการอัพเดท OS เพิ่มเติม มันจะไปโหลดไฟล์และส่วนเสริมอื่น ๆ มาเพิ่ม ส่วนใหญ่ต้องทำทุกครั้งเพราะบางที OS ที่เราโหลดมันเก่าเกิน
  • RUN apt-get install nginx -y เป็นคำสั่งติดตั้ง Nginx โดยที่ปกติถ้าเราไม่เติม -y มันจะคอนเฟิร์มเราก่อนว่าคุณยืนยันที่จะติดตั้งใช่มั้ย พิมพ์ y เพื่อยืนยัน พิมพ์ n เพื่อยกเลิก แต่พอใช้ -y จะเป็นการยืนยันว่าเราติดตั้งนะ
  • EXPOSE 80/tcp เป็นการเปิด Port 80 ของ Container
  • CMD [“/usr/sbin/nginx”, “-g”, “daemon off;”] เป็นคำสั่งรัน nginx บน Container

จากข้างบนจะเห็นว่าพอเป็น Ubuntu คำสั่งเยอะขึ้นเลย นี่ยังไม่นับว่าลง PHP, MySQL, Redis นะ คำสั่งยาวแน่ ๆ ต้องเป็นคนที่รู้คำสั่งพอสมควรไม่ก็ค้นหาเก่ง ๆ ส่วนตัวแล้วไม่ได้เขียนเองทั้งหมดนะ อ้างอิงจากที่นี่ เพราะมันจะไม่เหมือนตอนติดตั้ง Ubuntu หรือเซิฟเวอร์ ถ้าเป็นเซิฟเวอร์ตอนรันคำสั่ง apt-get จะเหมือนกันหมด แต่พอตอนเปิด Port จะไปใช้ ufw หรือไม่ก็ iptables หรือ firewall ของเว็บนั้น ๆ แทน แล้วก็ตอน Start Nginx ก็คนละคำสั่งกัน ยังไงก็ลองศึกษาเพิ่มเติมดู

จบไปแล้วกับการสร้าง Container ทั้ง 3 แบบ เป็นยังไงกันบ้าง เรามาทบทวนกันว่ามีอะไรบ้าง

  • แบบ Docker ธรรมดา คือใช้คำสั่ง docker run เลย
  • แบบ Docker Compose สำหรับคนมีรวมหลาย ๆ Container เป็น Container เดียว
  • แบบ Dockerfile จะนับว่าแบบนี้เป็นการสร้าง Container ก็ไม่เชิง เพราะมันเป็นการสร้าง Image แต่พอไปรันก็ต้องใช้แบบ Docker ธรรมดาไม่ก็ใช้ Docker Compose อยู่ดี แต่ที่เขียนรวมไว้เพราะอยากให้เข้าใจว่าการสร้าง Container นั้นไม่จำเป็นจะต้องเอาสิ่งที่เค้ามีให้มาใช้อย่างเดียว เราสามารถสร้างเอง และไปรันเองก็ได้

สำหรับพื้นฐานการสร้าง Container ก็มีประมาณนี้แหละ ไม่น่าจะเกินจากนี้นะ ไม่งั้นอาจจะต้องสร้างด้วยโปรแกรมหรือตัวช่วยอื่นไปเลย จริง ๆ เรื่องของ Docker ยังมีอีกเยอะมากเลยนะ เดี๋ยวไว้จะเขียนในบทความต่อ ๆ ไป

สำหรับบทความนี้ก็พอแค่นี้ก่อนละกันครับ หากมีคำถามหรือข้อสงสัยสามารถสอบถามได้ทาง Email หรือทาง Social ที่ทางเว็บมีให้ครับ สำหรับวันนี้ สวัสดีครับ

ช่องทางการติดต่อ

Email: [email protected]

Website: https://blog.tichaky.com/

Facebook: https://www.facebook.com/tichaky

Youtube: https://www.youtube.com/@tichaky_diary

Post navigation

ติดตั้ง Laravel ด้วย Docker กัน

รีวิว Low Code Appsmith กัน

เชื่อมต่อ Binance เข้ากับ Freqtrade พร้อมการใช้งานเบื้องต้น

ใช้ Portainer จัดการ Container กัน