🃏Docker Exercise 01

ลองใช้งานเจ้าวาฬน้ำเงินครั้งแรกกันแบบละเอียดยิบ 🐳

🤠 จาก บทความที่ 2 เราน่าคันมืออย่าลองของจริงละ ดังนั้นบทความนี้เราจะลองใช้เจ้าวาฬน้ำเงิน 🐳 ว่ามันดีสมกับที่ 2 บทความโม้มาจิงป่ะ ?

แนะนำให้อ่าน บทความนี้เป็นส่วนหนึ่งของคอร์ส 🐳 Docker ที่จะสอนตั้งแต่เรื่องพื้นฐานยันระดับ master กันไปเลย ซึ่งเนื้อหาทั้งหมดจะทำให้เพื่อนๆเข้าใจและใช้งาน Docker โดยใช้ Kubernetes เป็น และสามารถสร้าง Cluster เพื่อนำไปใช้งานบน Cloud Providers ต่างๆได้ และทั้งหมดที่พูดมานั้นอ่านได้ฟรีเลย ดังนั้นหากสนใจก็สามารถกดเจ้าวาฬสีน้ำเงินเพื่อไปอ่านตั้งแต่เริ่มต้นได้ครัช 🤠

🚨 Installation

ก่อนที่เราจะเล่น Docker ได้นั้นเราก็ต้องติดตั้งโปรแกรมเขาก่อน โดยดาวโหลดได้จากลิงค์นี้ Docker.com โดยเครื่องเราใช้ Windows อะไรก็เลือกติดตั้งให้ถูกตัว ส่วนขั้นตอนติดตั้งไม่มีไรมาก Next เรื่อยๆได้เบย

ถ้าติดตั้งทุกอย่าง + รีสตาร์ทเครื่อง เสร็จหมดละ ที่มุมหน้าจอเราก็จะเห็น Icon ปลาวาฬโผล่ขึ้นมา ซึ่งเราต้องให้เวลาเขาเตรียมตัวซักครู่ จนกว่า Icon จะหยุดนิ่งๆเหมือนในรูปด้านล่าง ก็จะเป็นอันพร้อมใช้งาน

คราวนี้เราลองมาเช็คให้มั่นใจรอบสุดท้ายว่าเครื่องเราพร้อมใช้งานหรือเปล่า โดยการเปิด Command Prompt / PowerShell หรือ Terminalขึ้นมา (เลือกเปิดซักตัวนะไม่ต้องเปิดหมด 🤣) แล้วในหน้าจอดำๆให้เราลองใช้คำสั่งเช็คเวอร์ชั่นของ Docker ที่เราพึ่งลงไป ด้วยคำสั่งด้านล่าง

Command Prompt คนที่ใช้ Microsoft Windows สามารถกดปุ่ม Windows ด้านล่างซ้าย แล้วพิมพ์คำว่า cmd แล้วกดปุ่ม Enter ได้เลย แล้วหน้าจอ Command Prompt ก็จะโผล่ขึ้นมาครัช

docker --version

ผลลัพท์ Docker version 19.03.13, build 4484c46d9d

ถ้ามันขึ้นมาประมาณนี้ก็ถือว่าพร้อมใช้งานละ (เลขเวอร์ชั่นอาจไม่เหมือนของผมก็ไม่เป็นไรนะ) แต่ถ้าใครไม่ขึ้นแบบนี้ก็แสดงว่าการติดตั้งอาจจะมีปัญหาอะไรซักอย่างลองกลับไปตรวจดู

Emulators หากใครที่ติดตั้งโปรแกรม Emulators ที่มันใช้พวก Hyper-V อาจจะมีปัญหากับ Docker ได้ เช่นโปรแกรมจำลอง Android อย่าง BlueStacks ไรงี้ อาจจะต้องลบของพวกนั้นทิ้งก่อน

🐳 Docker Pull

จากการติดตั้งด้านบนจะทำให้เครื่องคอมของเรามีปลาวาฬทำงานเป็นเบื้องหลังเรียบร้อยตามรูปด้านล่างละ

คราวนี้เราก็จะลองเอา 🖼️ Container Image ตัวฝึกหัดมาลองเล่นดู โดยให้เราเปิด Command Prompt หรือ Terminal ขึ้นมา (ต่อไปจะบอกว่า Command Prompt อย่างเดียวนะ) แล้วเรียกใช้คำสั่งด้านล่าง

docker pull docker/getting-started

เราจะเห็นว่า Docker จะไปดาวโหลดไฟล์บางอย่างมานั่นเพราะ คำสั่งด้านบนเป็นการสั่งให้ Docker ไปเอา Container Image มาเตรียมไว้ในเครื่อง ซึ่งหากมันหา Container Image นั้นๆไม่เจอ มันก็จะไปดาวโหลดมาจากส่วนกลางที่ชื่อว่า 🗃️ Docker Registry นั่นเอง โดยกระบวนการทั้งหมดนั่นก็จะออกมาเป็นตามรูปด้านล่าง

docker pull - เป็นการสั่งให้ docker ไปเตรียมเอา Container Image มาเตรียมไว้ในเครื่อง ซึ่งถ้ามันไม่เคยมีอยู่ในเครื่องล่ะก็ เจ้าวาฬก็จะไปดาวโหลดมาให้เรา แต่ถ้าเคยมีอยู่แล้วมันก็จะไม่โหลดใหม่ ไม่เชื่อลองใช้คำสั่งด้านบนซ้ำอีกรอบจิ

รายละเอียดของ 🗃️ Docker Registry เดี๋ยวเราค่อยกลับมาทำความเข้าใจมันอีกทีนะจ๊ะ 😋

🐳 Docker Images

หลังจากที่เราได้ Container Image ที่ชื่อว่า docker/getting-started มาอยู่ในเครื่องละ คราวนี้เราลองใช้คำสั่งเรียกดู Container Images ทั้งหมดที่มีอยู่ในเครื่องดูหน่อยดิ๊ ด้วยคำสั่งด้านล่าง

docker images

รายการ Container Images ทั้งหมดก็จะโชว์ออกมาพร้อมกับรายละเอียดต่างๆ ตามรูปด้านล่าง (หากใครเคยแอบเล่น docker มาก่อนแล้วรายการที่โชว์มันเยอะกว่าในรูปก็ไม่ต้องตกใจไปเด้อ)

เดี๋ยวค่อยกลับมาลงรายละเอียดของมันต่ออีกที ตอนนี้แค่จำง่ายๆว่า Container Image ที่เราดาวโหลดมาจากคำสั่ง docker pull นั้นมันมีหน้าตาราวๆนี้ละกัน

🐳 Docker Run

ภายใน Docker Image ตัวนั้นจะมี เว็บไซต์ ที่เขียนด้วยภาษา python และทำงานอยู่บน nginx อยู่ข้างใน ซึ่งเราจะลองเอามันมาทำงานในเครื่องเราดูดิ๊ ด้วยคำสั่งด้านล่าง

docker run -d -p 80:80 docker/getting-started

เมื่อใช้คำสั่งด้านบนไปเราจะได้ข้อความมั่วๆมา 1 บรรทัดและก็ไม่เกิดอะไรขึ้นชิมิ? คราวนี้เราลองเปิด Web Browser แล้วเข้าไปที่ http://localhost เราก็จะเจอกับเว็บหน้าตาประมาณนี้เบย

หน้าตาเว็บอาจจะไม่เหมือนกันก็ไม่เป็นไร เพราะตอนที่เพื่อนๆลองทำ เขาอาจจะอัพเดทหน้าตาไปแล้วก็ได้

🤠 ตัวเว็บที่เราเห็นมันคือเว็บที่อยู่ใน Container Image ที่ถูกเขียนด้วยภาษา python และทำงานอยู่บน nginx ตามที่บอกไป ซึ่งเราจะเห็นว่าเว็บทำงานได้ปรกติ แม้คอมเราจะไม่ได้ลง nginx ก็ตาม (ใครลง nginx ลองลบออกดูดิ) เพราะเจ้า 🐳 Docker มันไปสร้าง Environment ให้เราเรียบร้อยแล้วยังไงล่ะ . . . เพื่อให้เห็นภาพเราแมวน้ำจะขอฉายภาพแบบช้าๆให้ดูว่ามันเกิดอะไรขึ้นบ้างนะ

🐌 Step By Step

1️⃣ เราใช้คำสั่ง docker run docker/getting-started เป็นการสั่งให้เจ้าปลาวาฬนำ Image ชื่อ docker/getting-started ไปสร้างเป็น Container

2️⃣ อย่างที่เคยบอกไปใน บทความที่ 2 ว่า Container มันคือ Environments ที่ถูกสร้างตามที่ Image กำหนดไว้ ดังนั้นถ้าเราซูมเข้าไปในตู้คอนเทนเนอร์ เราก็จะเห็นว่ามันมีเว็บ python ที่ทำงานอยู่ใน nginx นั่นเอง

3️⃣ โดยปรกติ เราจะเข้าถึงของที่อยู่ภายใน Container ไม่ได้ แม้ว่าเราจะรู้ว่า nginx มันเปิด port 80 ไว้อยู่ก็ตาม

4️⃣ แต่ถ้าดูคำสั่งของเราดีๆจะเห็นว่ามันมี -p อยู่ด้วย ซึ่งมันคือการ map port ของที่อยู่ในโลก Container ให้ออกมาสู่โลกภายนอก โดยตัวคำสั่งเราเขียนว่า -p 80:80 หมายถึง เรากำหนดให้ port 80 ของโลกภายนอก (ซ้าย) เชื่อมกับ port 80 ที่อยู่ในโลก Container (ขวา) ซึ่งเมื่อเราทำแบบนี้ก็จะทำให้เราสามารถเข้าสู่โลกของ Container ได้จาก port 80 นั่นเอง ตามรูปเบย

5️⃣ สุดท้ายในคำสั่งของเราจะมี -d อยู่ด้วย ซึ่งมันคือการ detach หรือแปลให้เข้าใจง่ายๆคือ สั่งให้ docker ทำงานเป็น background ไป โดยถ้าทำงานเสร็จก็รบกวนบอกรหัสของ Container ตัวที่พึ่งสร้างให้ด้วยนะ ซึ่งพอพี่วาฬสร้าง Container นั้นๆเสร็จเราก็จะเห็น Container ID เป็นเหมือนข้อความมั่วๆนั่นเอง

Detach mode คำสั่ง detach จะทำให้ตัว Command Prompt ของเรา ไม่สนใจรายละเอียดของ process ที่เราสั่ง run ไป แต่ถ้าเราอยากดูรายละเอียดว่าตัว Container นั้นมัน run ขึ้นมาแล้วเป็นยังไง มี event อะไรเกิดขึ้นบ้าง เราก็แค่ไม่ต้องใส่ -d ลงไปเท่านั้นเองครับ (ลองสั่ง docker run ใหม่โดยไม่ใส่ -d เข้าไปดูนะ)

🤠 จากตรงนี้จะทำให้เราเห็นว่าตัว Container มันคือ Environments ที่แยกตัวออกไม่ยุ่งกับใครเลย ซึ่งข้างในของมันจะมีแอพคอยทำงานตามที่เรากำหนดไว้อยู่ ดังนั้นต่อให้เราลงโปรแกรมอะไรในเครื่องเราไปมันก็ไม่มีผลกับของที่อยู่ใน Container นั่นเอง

🐳 Docker PS

พอถึงตรงนี้พี่วาฬของเราก็จะมี Container อย่างน้อย 1 ตัวทำงานอยู่บนหัวมันละ ซึ่งเราสามารถดูว่าตอนนี้บนหัวพี่วาฬมี Container อยู่กี่ตัวได้จากคำสั่งด้านล่างนี้

docker ps

ซึ่งเราก็จะเห็นรายการ process ทั้งหมดที่กำลังทำงานอยู่ ตามรูปด้านล่าง (บางอย่างจะเห็นไม่เหมือนของผมนะ)

จากตรงนี้จะทำให้เรารู้ว่าเจ้าตัว Container มันจะมีรายละเอียดของมันอยู่ หน้าตาราวๆนี้

🤠 คราวนี้เราลองปิดเจ้า ❌ Command Prompt ของเราทิ้งไป แล้วลองเข้าเว็บตัวเดิมดู http://localhost ก็จะพบว่าเว็บของเรายังใช้งานได้ปรกติสุขอยู่ เพราะเราสั่งให้มัน run เป็น background นั่นเอง (สำหรับคนที่ไม่ได้ run ด้วย detach mode เมื่อปิด Command Prompt ลงจะพบว่าเว็บเข้าบ่ได้ แต่ก็ไม่ต้องตกใจอ่านต่อโลด)

🐳 Docker Stop

คราวนี้ถ้าเราอยากจะ สั่งให้ Container ที่กำลังทำงานอยู่มันหยุดการทำงาน เราก็จะใช้คำสั่ง docker stop แล้วตามด้วย Container ID ที่อยากจะให้มันหยุดนั่นเอง (หากจำรหัสไม่ได้ก็ใช้คำสั่ง docker ps ด้านบนเรียกขึ้นมาดู)

ในการระบุ Container ID ไม่จำเป็นต้องพิมพ์จนครบทุกตัวก็ได้นะ เช่น จากรูปด้านผมก็จะพิมพ์แค่ตามโค้ดด้านล่าง (จะพิมพ์กี่ตัวก็ได้ขอแค่มัน unique พอที่จะระบุ container ที่อยากลบได้ก็พอ)

docker stop 3d4

อาวล่ะ คราวนี้เราลองเข้าไปดูตัวเว็บของเราอีกครั้งดิ๊ http://localhost .... กลายเป็นโกโก้ครั้นช์เรียบร้อย

หาก stop มันแล้วแต่ยังเข้าได้อยู่ อาจเป็นเพราะมันเป็น cache ของตัว browser ก็ได้ แนะนำให้เปิด Incognito mode หรือ private mode ของตัว browser ดูนะ

เพราะเราสั่งให้ Container ตัวนั้นมันหยุดยังไง เลยทำให้เราเข้าเว็บไม่ได้ และเมื่อเราใช้คำสั่ง docker ps อีกครั้ง เราก็จะไม่เห็น process ไหนเลยที่ทำงานอยู่ ตามรูปด้านล่าง

แต่จริงๆ Container นั้นก็ยังอยู่นะ เพียงแค่มันไม่โชว์ให้เราเห็นเฉยๆ ซึ่งถ้าเราอยากเห็นว่าตอนนี้ในเครื่องเรามี Containers อะไรอยู่บ้าง เราก็แค่เติม -a เพื่อให้โชว์ทั้งหมดนั่นเอง (All)

docker ps -a

เราก็จะได้ผลลัพท์ตามรูปด้านล่าง ซึ่งจะเห็นว่า Status มันเปลี่ยนเป็น Exited แล้วนั่นเอง

🐳 Docker Start

แน่นอนในเมื่อเราสั่งหยุดมันได้ เราก็ย่อมสั่งให้มันทำงานต่อได้เช่นกันด้วยคำสั่ง docker start แล้วตามด้วย Container ID ที่อยากจะให้มันทำงานต่อนั่นเอง ซึ่งก็ไม่จำเป็นต้องใส่รหัสเต็มๆเช่นเคย ตามตัวอย่างนี้ แล้วก็ลองเข้าเว็บตัวเดิมอีกครั้ง http://localhost ก็จะพบว่ามันกลับมาทำงานได้แบ๊ว 😙

docker start 3d

แล้วเมื่อเราใช้คำสั่ง docker ps ธรรมดาๆ ก็จะเห็น Container ตัวนั้นกลับมาเป็นสถานะ Up ละ

🐳 Docker RM

คราวนี้ถ้าเราไม่อยากจะใช้ Container แล้วล่ะ? เราจะให้พี่วาฬแบกหนักหัวเขาต่อมุ๊ย? (เช่น Container ในตัวอย่างนี้เราก็คงจะไม่ใช้ต่อละจิงป่าว) ซึ่งเมื่อเกิดเหตการณ์แบบนี้ขึ้น เราก็สามารถลบ Container ด้วยคำสั่ง docker rm แล้วตามด้วย Container ID ที่อยากจะลบมันทิ้งนั่นเอง 😢 ตามตัวอย่างด้านล่างเบย

docker rm 3d

Error response from daemon: You cannot remove a running container 3d4f30d3631032798f929cd21940041687b60787ad8329795ec92b1f065d46be. Stop the container before attempting removal or force remove

ลบไม่ด๊ายยยย!! 🤪 ไม่ต้องตกใจไป เพราะ Docker บอกว่า Container ตัวนั้นมันกำลังทำงานอยู่ ซึ่งเราจะเจอบ่อยมาก ซึ่งเราก็สามารถขืนใจมันได้โดยใช้คำสั่ง -f ย่อจาก force เพื่อเป็นการบังคับให้มันทำคำสั่งนั้นๆ ตามโค้ดด้านล่าง

docker rm -f 3d

จบข่าว ไม่หนักกบาลพี่วาฬล่ะ และใช้คำสั่ง docker ps -a ก็ไม่อยู่ให้กวนใจอีกต่อไป

🐳 Docker RMI

จะลบทั้งทีก็ต้องถอนรากถอนโคนทิ้ง 😈 !! เพราะรากเหง้าของ Container มันก็คือ Image ยังไงล่าาา ไหนๆก็จะจบบทความแล้วจะเก็บ Image มันไว้ทำไม!! ดังนั้นเราก็แค่ใช้คำสั่ง docker rmi แล้วตามด้วย Image ID ที่อยากจะลบมันทิ้งนั่นเอง 😈 ซึ่งหากใครลืมไปแล้วว่ารหัสของ Image คืออะไรก็ใช้คำสั่ง docker images เปิดดู แล้วลบทิ้งซ๊าาา

docker rmi 1f3

หากใครทำไม่ได้อีกก็ขืนใจมันด้วย -f เช่นเคย 😈

ก็เป็นอันปิดฉาก Container Image ที่ใช้ในการลองวิชาตัวแรกกั๊ฟป๋ม 😇

🎯 Summary

จนถึงตอนนี้เราน่าจะเข้าใจละว่า 🖼️ Container Image มันเป็นต้นแบบในการเอาไปสร้าง Environment นั่นเอง ส่วนเจ้า 📦 Container มันก็คือ Environment ที่เอาไว้ทำงานจริงๆ โดยมันจะถูกตั้งค่าทุกอย่างตามที่ตัว image กำหนดไว้เป๊ะๆเลย ส่วนเมื่อเราจะสั่งงาน 🐳 Docker เราก็จะใช้คำสั่งผ่าน CLI ที่ย่อมาจาก Command Line Interface อีกที โดยคำสั่งก็จะมีการแยกเป็นเรื่องๆของมันโดยเฉพาะ และสุดท้ายโลกของ Container มันถูกตัดขาดจากโลกภายนอก ดังนั้นเราต้องมีการเชื่อม PORT ระหว่าง 2 โลกก่อน ถึงจะทำให้โลกข้างนอกใช้งานโลก Container ได้

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

ในบทความถัดไปเราจะได้ลองใช้ 🐳 Docker แบบไม่ต้องมานั่งพิมพ์คำสั่งดูบ้าง และเริ่มลงรายละเอียดในส่วนของ 🖼️ Container Image กับ 🗃️ Docker Registry กันต่อกั๊ฟป๋ม

อ่านแล้วชอบป๋มก็ขอฝากแชร์ หรือกดติดตามเพื่อจะได้ไม่พลาดบทความอื่นๆจาก ดช.แมวน้ำ ได้จากลิงค์นี้เบยครัช Saladpuk Fanclub 😍

Last updated