เริ่มต้นใช้งาน Docker กัน Part 1
สวัสดีครับ วันนี้เราจะมาเริ่มต้นใช้งาน Docker กัน ยังไงก็ไปดูกันเลย
ก่อนเริ่มต้นขอบอกก่อนว่า Docker นั้นมีมานานแล้ว และปัจจุบันมีคนใช้งานเยอะแยกมากมาย สามารถหาอ่านเพิ่มเติมได้จาก Google แต่วันนี้จะมาเขียนคร่าว ๆ ตามความเข้าใจของตัวเอง และการนำไปใช้จริง แล้วทำไมเขียนเรื่องนี้ขึ้นมา เพราะอยากให้เข้าใจพื้นฐานก่อน เวลาเราไปสอนวิธีติดตั้งแบบ Docker คิดว่าอยากให้หลาย ๆ คนเข้าใจว่าคืออะไร และสามารถหาอ่านได้จากที่นี่ และเป็นประโยชน์สำหรับผู้อ่าน ถ้ายังไงก็ไปเริ่มกันเลย
Docker นั้นก็คือ โปรแกรมหรือแพลตฟอร์มสำหรับสร้าง ทดสอบ และติดตั้งแอพได้อย่างรวดเร็ว โดยตัว Docker จะมีซอฟต์แวร์บรรจุลงไปเค้าเรียกว่า Container และมีซอฟต์แวร์ที่เราสามารถเรียกใช้งานได้และมีคนอื่นทำไว้แล้วเราจะเรียกว่า Image รายละเอียดเพิ่มเติมของ Docker สามารถอ่านเพิ่มเติมได้ที่นี่
เรามาดูข้อดีข้อเสียกันว่าเป็นอย่างไร
ข้อดี
- สามารถติดตั้งแอพได้อย่างรวดเร็ว คือเราไม่ต้องไปหาวิธีติดตั้งให้เสียเวลา เพียงแค่ใช้งาน Image ที่มีไว้ให้หรือสร้างขึ้นเอง แล้วติดตั้งก็สามารถใช้งานได้เลย แต่ต้องเข้าใจก่อนนะว่าทำยังไง
- เปลี่ยน Version หรือ Maintenance ได้ง่าย เพราะเราสามารถเปลี่ยน Version ได้ทาง Image ได้เลย ส่วนถ้าจะ Maintenance ก็เอา Image นั้นขึ้นไปเก็บไว้บน Registry ของแต่ละที่ แล้วค่อยแก้ไขก็ได้
- ย้ายเครื่องได้ง่าย เพราะถ้ามี Config เก็บไว้ที่ Image ก็สามารถเอาไปติดตั้งอีกที่ได้
- ประหยัดพื้นที่ เนื่องจากว่าตัว Docker มันสามารถลงโปรแกรมแบบย่อยได้ คือในอดีตเวลาเราจะเทสโปรแกรมหรือจำลองเครื่อง เราต้องใช้งาน VM (Virtual Machine) แล้วมันมีขนาดใหญ่มาก ๆ เพราะภายใน VM ต้องมี OS หรือระบบปฎิบัติการ เช่น Windows, Mac, Linux เป็นต้น แล้วสมมติว่าเรามีหลายโปรเจค คนละที่ เราก็ต้องสร้าง VM มาทดสอบแยก จะกินเนื้อที่เยอะมาก แต่ถ้าใช้ Docker เราไม่ต้องลง OS เราแค่ติดตั้งโปรแกรมที่ใช้งาน เราก็สามารถใช้งานได้แล้ว
- Community เยอะมาก อันนี้เป็นเรื่องดี เพราะเวลาเราติดปัญหา เราสามารถค้นหาข้อมูลจากคนที่ลองผิดลองถูกมาแล้ว และ Docker ก็มีมานานแล้ว คิดว่า Community น่าจะใหญ่มาก ๆ
- เป็นตัวต่อยอด เพราะอนาคตถ้าเรามีระบบที่ใหญ่ขึ้นและต้องสเกลคนหรือเครื่องมากขึ้น ก็จำเป็นจะต้องไปใช้ Tools หรือซอร์ฟแวร์ตัวอื่นช่วยอย่างพวก Kubernetes ไม่ก็ Docker Swarm แต่การจะไปใช้งานสิ่งนั้นได้ เราต้องเข้าใจและทำ Docker ให้เป็นซะก่อน
ข้อเสีย
- ต้องเข้าใจในสิ่งที่เราติดตั้งมาพอสมควร เพราะเราจะต้องมาทำใน Docker เพราะฉะนั้นเราต้องเข้าใจว่ามันคืออะไร ใช้ทำอะไร ตั้งค่าแบบไหนได้ ไฟล์คอนฟิคอยู่ที่ไหน
- ต้องเรียนรู้พอสมควร เพราะมันมีทับศัพท์ค่อนข้างเยอะ และเหมาะสำหรับคนที่มีความรู้เรื่อง Server พอสมควร
- ไฟล์หาย อันนี้เคยเจอมากับตัวเอง คือ พอลง MySQL ไว้แล้วไม่ได้ Mount Volume ไว้ ปรากฎว่าเวลาเราลบและสร้าง MySQL ใหม่ ข้อมูลหายเกลี้ยง ทำใหม่เลยทีนี้
จากข้างต้นคิดว่าลองชั่งน้ำหนักดูว่าเป็นยังไง ส่วนตัวแล้วรู้จักกับสิ่งนี้มานานมาก ๆ ลองใช้แบบคร่าว ๆ ไป ลองผิดลองถูกก็เยอะ แต่ก็ไม่เคยใช้งานจริง แต่ด้วยปัญหาที่เจอคือ เวลาเราจะย้าย VPS หรือ Cloud ไปเจ้าอื่น เป็นเรื่องยากมาก ถ้าเราใช้วิธีแบบเดิม คือเราก็ต้องไปนั่ง Config ใหม่ ลงใหม่ บางทีก็จำได้บ้างไม่ได้บ้าง ไม่เหมือนเดิมอีก ครั้งนี้แหละยาว กับอีกอันหนึ่งคือ เวลาเราทดสอบแอพบน Local ได้ แต่พอเอาขึ้นเซิฟเวอร์ไม่ได้ ครั้งนี้แหละ วุ่นวายเลย หาวิธีกันยาว เลยคิดว่ามันถึงเวลาแล้วแหละที่เราจะมาทำสักที
การติดตั้งนั้นทำได้หลายวิธีมาก ขึ้นอยู่กับ OS หรือระบบปฎิบัติการ สามารถเข้าไปดูได้ที่นี่ แนะนำว่าให้ติดตั้ง App หรือ exe มาเลย จะได้ง่าย และปัจจุบันมันมีเวอร์ชั่น Desktop หรือ UI มาให้ใช้งานกัน สามารถเข้าไปโหลดได้ที่นี่ (เข้าใจว่าเราติดตั้ง Docker Desktop ก็มี Docker มาให้)
เมื่อเปิดเข้ามาแล้วจะได้หน้าตาดังรูปเลย อาจจะมี Tutorial ให้เริ่มต้นนิดหน่อย แต่ก็หน้าตาประมาณนี้
รายละเอียดเพิ่มเติมที่คนเริ่มต้น Docker เข้าใจคือ
- Containers/App เป็นซอฟต์แวร์ที่เราเอามาจาก Image โดยสามารถดู Log, Config, Stat และยังสามารถสั่งงานผ่าน Command Line เข้าไปใน Containers เพื่อตั้งค่าได้ เปิด Browser ตาม Port ที่เราตั้งค่าไว้ (ต้องเป็น Containers หรือ App ที่มี UI เท่านั้นนะ) เปิด/ปิด/ลบ Containers ก็ทำจากหน้านี้แหละ
- Images เป็นชุดคำสั่งหรือซอฟต์แวร์ที่เราติดตั้งใช้งานหรือเอามาจากข้างนอก โดย Image 1 อัน มีหลายโปรแกรมก็ได้ขึ้นอยู่กับคนสร้าง Image โดยเราสามารถสร้าง Image เองได้โดยใช้ Dockerfile แต่สำหรับใครที่ไม่ต้องการสร้างเอง แต่ต้องการเอามาใช้งานเลย สามารถเข้าไปดูได้ที่นี่ ซึ่งเป็นแหล่งรวมของ Images ต่าง ๆ ของนักพัฒนาทำไว้
- Volumes เป็นพื้นที่ภายนอกที่ใช้ยึดติด (Mount) ระหว่างภายใน Container และภายนอก Container โดยภายนอก Container ในที่นี้ก็คือเครื่องเซิฟเวอร์ที่ลง Docker หรือเครื่องเราที่ลง Docker นั่นเอง ส่วนภายใน Container ก็คือตัว Container เองนั่นแหละ ส่วนตัวแล้วที่เคยทำมาจะมี 2 อย่างที่เราเจอบ่อย ๆ คือ การเอา Config หรือไฟล์ไปใส่ไว้ใน Container เช่น เอา Package ไปใส่ไว้ใน Container, การทำ Cert SSL ไปใส่ใน Container ส่วนอีกแบบหนึ่งก็คือการ Backup ข้อมูล หรือการเก็บ Log เช่น เราใช้ Database MySQL เราจะเอาข้อมูลออกมาไว้ข้างนอกเผื่อเวลาเราลบ Container ไป ข้อมูลจะได้ไม่หาย เก็บ Log ไว้ก็จะเหมือนกัน
- Dev Environments ถ้าใน Docker Desktop ส่วนนี้ไม่เคยใช้
เอาล่ะครับเป็นไงกันบ้าง จากข้างต้นทำให้เรารู้จักกับ Containers, Image, Volumes มากขึ้น และพอมี UI คิดว่าน่าจะเข้าใจได้ง่าย
ต่อไปจะมาเริ่มสร้าง Container ง่าย ๆ กัน โดยที่เจอมาจะมีด้วยกัน 3 แบบ คือ
- แบบทำผ่าน Docker ธรรมดาเลย คือใช้คำสั่ง docker run ได้เลยตามที่มีให้ ไม่ต้องลงส่วนเสริมหรืออะไรเพิ่ม แต่ต้องมี Docker ก่อนนะ
- แบบ Docker Compose คือตัวช่วยที่เวลาเรามีหลาย Container ปกติถ้าเราจะรัน Docker แบบธรรมดา ต้องรันทีละคำสั่ง ๆ แต่ถ้าใช้ Docker Compose เราสร้างไฟล์มา ใส่ข้อมูลให้ถูกต้อง รันคำสั่ง docker compose ก็จะได้ Container ที่เชื่อมต่อกันมาแล้ว
- แบบ Dockerfile คือการสร้าง Image ไว้ใช้งานเอง
เรามาดูแต่ละวิธีกัน โดยตัวอย่างที่นำมาจะเป็นตัวอย่างการติดตั้ง Nginx ซึ่งเป็นตัวอย่างง่าย ๆ สำหรับคนจะเปิดเว็บไซต์ รายละเอียด Docker ของ Nginx นั้นสามารถไปดูได้ที่นี่ แต่ก่อนอื่นเลยเราไปดูกันก่อนว่า Nginx นั้นคืออะไร
Nginx คือ Web Server ตัวหนึ่งที่เวลาเราจะแสดงผลเว็บไซต์เราก็ต้องมี Web Server ซึ่งเจ้าตัว Nginx นี่แหละ เวลาเขียนเว็บเป็นภาษาอะไรก็ตามแต่ เวลาแสดงผลให้ผู้ใช้งานได้เห็นก็ต้องใช้สิ่งนี้แหละ แต่ Web Server ไม่ได้มีแค่อันเดียวนะ ปัจจุบันมีมากมาย ไม่ว่าจะเป็น Apache, Traefix, Caddy
ทำไมถึงเลือก Nginx ล่ะ ก็คือมันง่าย เห็นภาพ เหมาะสำหรับคนเริ่มต้น ไม่นับวิธีการตั้งค่านะ น่าจะยากพอสมควร แต่ถ้าเอาแบบให้เห็นเป็นหน้าเว็บล่ะก็ง่าย เพราะถ้าจะเอา Ubuntu หรือ Database ก็จะยาวและเห็นภาพยาก ต้องอธิบายเพิ่มเติมพอสมควร
แบบ docker ธรรมดา
เริ่มต้นก็ใช้คำสั่ง
docker pull nginx
คำสั่งนี้ Docker จะไปโหลด Image ที่อยู่บน Docker Hub มาไว้ที่เครื่องเราเอง โดยเราสามารถเข้าไปที่เว็บแล้วดูคำสั่งได้ตามรูปเลย
เราสามารถใช้คำสั่งเพื่อดู Image ที่เราโหลดมาได้ด้วยใช้คำสั่ง
docker images
ถ้าเป็น Docker Desktop จะได้ผลตามรูป
อธิบายเพิ่มเติม
- REPOSITORY เป็นชื่อ Image ที่เรา pull มา
- TAG เป็นป้ายหรือเวอร์ชั่นต่าง ๆ ของ image ส่วนนี้สำคัญมากเพราะถ้าเราไม่เลือกมันจะเป็น latest
- IMAGE ID เป็น ID ของ Image ที่เราสร้าง มีไว้สำหรับการแก้ไข/ลบ และการอัพขึ้น Registry
- CREATED เป็นเวลาที่ Image นี้สร้างขึ้นมา
- SIZE เป็นขนาดของ Image
เราสามารถระบุ tag ได้โดยเวลา pull ก็ระบุ tag ไปด้วย
docker pull nginx:latest
ต่อมาจะเป็นการสร้าง Container โดยตัวอย่างคำสั่งที่เจอกันบ่อย ๆ (อย่าพึ่ง Copy นะ แต่ถ้าอยากลองก็ได้)
docker run --name some-nginx -v /some/content:/usr/share/nginx/html:ro -d -p 8080:80 nginx
อธิบายคำสั่ง
- docker run เป็นการสั่งทำงาน
- –name เป็นการตั้งชื่อ Container ในที่นี้ตั้งชื่อเป็น some-nginx
- -v เป็นการ Mount Volume หรือ Path ที่เรากำหนด
- /some/content เป็นพื้นที่ local path หรือ path บนเครื่องเรานั่นเอง เป็นภายนอก Container
- : เป็นตัวคั่นระหว่างภายนอก Container และภายใน Container
- /usr/share/nginx/html เป็นพื้นที่ภายใน Container
- : เป็นการคั่นระหว่างภายใน Container กับการกำหนด Permission
- ro เป็นการสั่งให้พื้นที่ภายใน Container นั้นอ่านได้อย่างเดียว (Read Only) ส่วนตัวไม่เคยใช้ รายละเอียดอ่านได้ตาม Link นี้เลย
- -d เป็นการตั้ง Mode การทำงานของ Container ว่าจะใช้ Mode ไหน จะมี 2 Mode ด้วยกันคือ Foreground และ Background โดยค่าเริ่มต้นจะเป็น Foreground คือจะทำงานตอนที่เราพิมพ์คำสั่งเลย พอเรากดยกเลิกหรือ Ctrl + d ก็คือจบการทำงานเลย ส่วน Background เป็นการรันเบื้องหลังทิ้งไว้ สามารถไปทำอย่างอื่นได้ รายละเอียดเพิ่มเติมของ 2 Mode สามารถดูได้ที่นี่
- -p เป็นการ Mount หรือเพิ่ม Port การใช้งาน
- 8080 เป็น Port ที่เครื่องหรือภายนอก Container ที่เราเรียกใช้งาน อย่าเลือก Port ภายนอกเหมือนกัน เพราะมันจะไม่ทำงาน แต่ Port ภายใน Container เหมือนกันได้ ไม่มีปัญหา
- : เป็นตัวคั่นระหว่าง Port ภายนอก Container กับ Port ภายใน Container
- 80 เป็น Port ภายใน Container ขึ้นอยู่กับโปรแกรมหรือแอพที่เราติดตั้งด้วย เช่น nginx จะใช้ Port 80, Redis จะใช้ Port 6379, MySQL จะใช้ 3306 ถ้าจะเปลี่ยนต้องเปลี่ยนที่โปรแกรมหรือแอพก่อน แล้วค่อยมาตรงนี้
- nginx เป็นชื่อ Image ที่เรา pull หรือสร้างมา
เรามาเริ่มต้นสร้าง Container กันเลย พิมพ์คำสั่ง
docker run --name some-nginx -d -p 8080:80 nginx
จากนั้นไปดูใน Docker Desktop ใน Tab Containers/Apps จะได้ดังรูป
ถ้าดูใน Command Line จะใช้คำสั่ง
docker ps
จะแสดงผลตามรูป
จากนั้นเปิด Browser แล้วไปที่ http://localhost:8080 จะแสดงหน้าเว็บดังรูป
สาเหตุที่ไม่ทำแบบเพิ่ม Volume เข้าไปเพราะว่าถึงเพิ่มไปก็ไม่มีผล เพราะการตั้งค่า Nginx จะต้องมีการตั้งค่าในส่วนของ .conf ด้วย คิดว่าตอนนี้เอาแค่รู้ว่าสร้าง Container แล้วแสดงผลตามที่เราต้องการก็โอเคแล้ว
เรามาลองทดสอบเรื่องของ Port ดีกว่า (จะดูอย่างเดียวก็ได้นะ) โดยที่เราจะตั้งชื่อใหม่เป็น some-nginx2 ทีเหลือเหมือนเดิมหมด แล้วรันดู
docker run --name some-nginx2 -d -p 8080:80 nginx
เมื่อรันแล้วจะได้ผลตามรูป
ไปดูที่ Docker Desktop จะได้ผลดังรูป
ที่เป็นแบบนี้เพราะว่า Port ซ้ำกัน เลยทำงานไม่ได้
จากนั้นลอง docker ps จะได้ผลดังรูป
สาเหตุที่ได้ผลดังรูปเพราะ docker ps นั้นจะแสดงผลเฉพาะ container ที่ run อยู่ แต่เนื่องจากว่ามันเกิด error เลยอยู่ในสถานะ stop ถ้าอยากเห็น Container ในสถานะอื่น ๆ ด้วย ต้องใช้คำสั่ง
docker ps -a
จะได้ผลตามรูป สามารถดูรายละเอียดเพิ่มเติมของคำสั่งได้ที่นี่
ทีนี้เรามาลบ Container กัน โดยใช้คำสั่ง
docker rm ff8cd2edf14c
จะได้ผลดังรูป
อธิบายเพิ่มเติม
- rm เป็นการ Remove Container ตาม Container ID ที่เลือก
- ff8cd2edf14c เป็น Container ID ที่เราสร้างไว้ สามารถดู Container ID ได้จาก docker ps -a
ตอนนี้เราจะเหลือแค่ Container เดียวแล้ว (ให้เข้าใจกันก่อนว่าทำใน Docker Desktop กับ Command Line ให้ผลเหมือนกัน สามารถลบ Container ผ่าน Docker Desktop ก็ได้) เราจะมาใช้ชื่อเดิมกัน เป็นชื่อ some-nginx
docker run --name some-nginx -d -p 8080:80 nginx
เมื่อใช้แล้วจะไม่มีอะไรเกิดขึ้นเลย จะแจ้งชื่อซ้ำ และใน Container จะไม่ขึ้นด้วย
มาลองเปลี่ยน port กัน โดยรอบนี้จะใช้ชื่อ new-some-nginx และใช้ port 8081 แทน
docker run --name new-some-nginx -d -p 8081:80 nginx
จะได้ผลดังรูป
ไปดูบน Browser กัน
จะเห็นว่า Port ภายนอก Container เป็น Port อะไรก็ได้ ขอแค่ไม่ซ้ำกัน
ทีนี้มาลองตัวอย่างสุดท้ายกัน โดยจะตั้งชื่อเป็น new-port-some-nginx และใช้ port เป็น 8082:81
docker run --name new-port-some-nginx -d -p 8082:81 nginx
จะได้ผลดังรูป
ลองไปเปิด Browser จะได้
ที่ได้แบบนี้เพราะว่า Nginx ใช้ Port เริ่มต้นหรือตั้งค่าเป็น 80 อยู่แล้ว เพราะฉะนั้นถ้าเราไปเปลี่ยน Port ใน Container เป็น 81 มันก็จะเชื่อมต่อไม่ได้ แต่ที่มันยังแสดงผลได้แบบใน Command Line อยู่ก็เพราะตัว Container มันไม่มีปัญหาเรื่อง Port ชนหรือตั้งชื่อซ้ำอะไร เป็นปัญหาที่เราไปตั้งค่า Port ใน Container ผิดเอง แต่จริง ๆ เราสามารถเปลี่ยน Port ของ nginx เป็น 81 ได้นะ แต่เป็นการแก้ไขที่ Image อีกทีหนึ่ง
จากตัวอย่างด้านบน เราจะได้รู้จักกับการรันคำสั่งเบื้องต้นของ Docker ไปแล้ว แล้วก็อีกอย่างหนึ่งที่อยากบอกก็คือ Image ที่ pull มานั้นสามารถสร้าง Container กี่อันก็ได้นะ คือ pull มาครั้งเดียว ใช้ได้ยาว ๆ
เนื่องจากบทความนี้ยาวมาก ขอไปต่อเป็น Part 2 ละกันเพราะกลัวว่าบทความจะยาวเกินไป และมีรูปภาพเยอะ ทำให้โหลดรูปนาน
สำหรับบทความนี้ก็พอแค่นี้ก่อนละกันครับ หากมีคำถามหรือข้อสงสัยสามารถสอบถามได้ทาง Email หรือทาง Social ที่ทางเว็บมีให้ครับ สำหรับวันนี้ สวัสดีครับ
ช่องทางการติดต่อ
Email: [email protected]
Website: https://blog.tichaky.com/
Facebook: https://www.facebook.com/tichaky