Videos How web automation saved my friendship

Description

ใครเป็นสายเกม Minecraft และสนใจเรื่อง automation บ้าง? มาฟังอุดดี้เล่าประสบการณ์สุดป่วนจากการเล่น Minecraft กับเพื่อนๆ ที่นำไปสู่การสร้าง project สนุกๆ อย่าง Montainer (Minecraft in a container) เพื่อแก้ปัญหาการอัปเดต server และ backup ข้อมูลเกม อุดดี้จะพาไปดู workflow การใช้ Docker, web management API, GitHub Actions และ Selenium เพื่อ automate กระบวนการต่างๆ ตั้งแต่การ fetch version ใหม่สุดจากเว็บ Mojang การดาวน์โหลด server binary ไปจนถึงการ build image และ deploy server มาร่วมเรียนรู้วิธีจัดการ server Minecraft ให้มีประสิทธิภาพและไม่ต้องกังวลเรื่อง version mismatch อีกต่อไป พร้อมรับชม demo การใช้งานจริงของ Montainer ได้ในวิดีโอนี้

Chapters

  • เปิดตัวและเกริ่นนำ: ปัญหาจาก Minecraft 0:00
  • Backstory: ความพยายามสร้างสรรค์สูญสลาย 0:42
  • Workflow การเล่น Minecraft และปัญหาการอัปเดต 1:41
  • ปัญหาหลัก: การบังคับอัปเดตเวอร์ชันใหม่ 2:41
  • วิธีแก้เบื้องต้นแบบบ้านๆ: Ansible, systemd และ Web Interface 3:02
  • ปัญหาค่าไฟและการพัฒนา Web Interface 4:00
  • สาเหตุที่แท้จริงของปัญหา: Mojang ไม่ยอม Auto-Update 5:14
  • Montainer: โซลูชันใน Docker Container 5:47
  • Web Automation: GitHub Actions และ Selenium 6:19
  • Workflow การอัปเดตอัตโนมัติ 7:40
  • Demo: Montainer ทำงานอย่างไร 8:13
  • สาธิตการใช้งาน Montainer 9:03
  • วิธีการเล่น Minecraft ผ่าน Montainer 10:15
  • สรุปและขอบคุณ 11:03

Transcript

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

เปิดตัวและเกริ่นนำ: ปัญหาจาก Minecraft0:00

ขอเสียงปรบมือให้กับอุดดี้อีกครั้งครับ โอเคครับ ก็สวัสดีทุกคนด้วยนะครับ ก็อันนี้เรียกว่าเป็น session แรกที่ผมเคย talk นะครับ ก็ต้องขอบคุณ organizer พี่ไทด้วยนะครับ ที่ให้โอกาสผมมาพูดในวันนี้ เรื่องที่จะพูดต่อไปนี้ ก็มีส่วนที่เป็น web automation ด้วย แล้วก็มีส่วนที่เป็น automation อย่างอื่นด้วยนะครับ ก็จะมาเล่าให้ฟัง มันเกิดจากความ frustration ของผมกับเพื่อนในระหว่างที่เราเล่นเกม Minecraft กัน จนเราต้องเอา automation เข้ามาช่วย โอเค ขอถามก่อนมีใครในห้องนี้ ไม่เคยเล่น Minecraft บ้างครับ

เฮ้ย ถามจริง

อ่ะใครเคยเล่น Minecraft บ้างครับ อ๋อ โอเคทุกคนแล้วกัน งั้นเราจะ ignore คนที่ไม่เคยเล่นแล้วกันนะครับ

Backstory: ความพยายามสร้างสรรค์สูญสลาย0:42

โอเค ก็ backstory ก่อนนะครับ ก็คือใน summer นึง ผมกับเพื่อนประมาณ 3-4 คนนะครับ พวกเราได้ลงทุนประมาณ 1,000 man-hour ในการสร้างอะไรก็ไม่รู้กันขึ้นมานะครับ ก็พวกเราสนุกมากเลย ตั้งแต่เช้ายันเย็น จนกระทั่งวันนึง ก็ผมเข้าไปใน server แล้วผมก็พิมพ์ command นี้เข้าไป อ่ะ มีใครไม่เข้าใจบ้างครับ ขอซาวก่อน โอเค ไม่เข้าใจ มันคือ teleport ทุกๆ entity ในเกมไปที่ตำแหน่งที่เราอยู่ตอนนี้ พูดง่ายๆ ก็คือผมทำพังทุกอย่าง แล้วต่อมาคือเพื่อนผมมันมี backup ไว้ ด้วยการ backup ตัว server เกม ซึ่งเป็น binary base พวก database พวกนั้นน่ะ ด้วย Git LFS ไว้ แต่ว่าก็มันก็คือ 1 อาทิตย์ก่อนนะครับที่ backup เพราะฉะนั้นก็คือ progress แบบหลายร้อยชั่วโมง ก็หายไปในไม่ถึง 30 วินาทีที่ผม abuse administrator command นี้

Workflow การเล่น Minecraft และปัญหาการอัปเดต1:41

โอเค เพราะฉะนั้นเมื่อเรารู้ถึงปัญหาที่มันเกิดขึ้น จากความอาจจะปัญญาอ่อนนิดหน่อยของผมแล้ว ผมอยากให้เห็น workflow นิดนึง คือเนื่องจากผมกับเพื่อนเนี่ยเราเล่น Minecraft ทุกคนอาจจะเล่นแบบ version Java กัน คือ Minecraft เนี่ยมันมี 2 version version นึงเขียนด้วย C++ อีก version เขียนด้วย Java ซึ่งพวกผมเล่น version ที่เขียนด้วย C++ กัน

ซึ่งวิธี host ตัว dedicated server ของมัน ให้เราเล่นเกมด้วยกันได้เนี่ย ก็ไม่มีอะไรก็คือเราโหลดตัว archive มันมา จากเว็บ Mojang แล้วก็– เว็บ Mojang คือคนที่พัฒนาเนาะ แล้วก็ไปแตกไฟล์มัน ก็จะ run ได้เลย มันก็มีอยู่ 3 อย่างเนี่ย ก็คือมีอันแรกก็แน่นอน server binary ที่เอาไว้ก็คือตัวโปรแกรมที่เอามา run server มันเนี่ย แล้วก็มีพวก ผมเรียกมันเนี่ย persistent file กับ non-persistent persistent ก็จะเป็นพวกที่แบบพวก progress ที่พวกเราเล่นไป ของที่พวกเราต้องการจะ backup เนี่ย ส่วน non-persistent เนี่ยมันเป็น version specific ก็คือเราไม่ต้องการ backup มัน เพราะเปลี่ยน version มันก็หาย เราก็เปลี่ยนไป นึกออกใช่มั้ยครับ

ปัญหาหลัก: การบังคับอัปเดตเวอร์ชันใหม่2:41

โอเค ทีนี้ปัญหาที่ผมเจอเลยเนี่ยคือ

ไอ้ version ที่พวกผมเล่นกันเนี่ย มันบังคับให้เราเล่น version ใหม่สุดตลอดครับ แล้วตัวผู้พัฒนาเกมมันก็นิสัยไม่ค่อยดี มันก็ไม่ให้ auto-update พวกเรา คือมันให้ใน client แต่มันไม่ให้ในตัว server เท่ากับว่าทุกครั้งที่มี version ใหม่อัพเดตขึ้นมา

วิธีแก้เบื้องต้นแบบบ้านๆ: Ansible, systemd และ Web Interface3:02

แล้วผมล็อกอินเข้าไปเล่นไม่ได้ เพราะมันเตือน version mismatch กับตัว server ผมต้อง SSH เข้าไปใน VM ของผม แล้วก็นั่งมึนอยู่ประมาณ 5 นาทีว่าจะเอาไงดี แล้วก็ผมก็ copy folder ที่เป็น persistent file ออกมา แล้วก็ลบ folder เกมทิ้ง แล้วมาผมก็โหลด archive นี่มาใหม่ แล้วผมก็เปิด server 1 ครั้ง แล้วผมก็ copy ไอ้อันเดิม กลับไปใส่ในตัวที่ผมเพิ่งโหลดมา และแน่นอนครับ ผมเคยเผลอลบทุกอย่างทิ้งมันอีกแล้ว แล้วพวกเราก็ต้องเริ่มใหม่หมด เพราะฉะนั้นตอนแรกผมแก้ง่ายๆ ด้วยการที่ผมเขียน Ansible script ขึ้นมา เพื่อที่จะ automate เรื่องพวกนี้ ก็ช่วยระดับนึง อ่ะมีใครไม่รู้จัก Ansible มั้ยครับ มันเป็นเครื่องมือ devops tool ตัวนึง ที่เราใช้ในการ พูดง่ายๆ คือเหมือนเก็บ action ที่เรา จะ SSH เข้าไปทำเนี่ย อยู่ในแบบเป็น code แล้วเราก็จะได้ execute มันได้ ทีนี้ปัญหาที่ 2 ที่ผมเจอคือ

ปัญหาค่าไฟและการพัฒนา Web Interface4:00

เนื่องจากผม host มันโดย server ที่บ้านเนาะ แล้วถ้าเกิดผมเปิดมัน 24 ชั่วโมง พ่อผมจะเอามิเตอร์มาติดที่ rack ผม แล้วบอกว่าจะคิดค่าไฟผม เพราะฉะนั้นเราก็ต้องคิดอีกว่า เอ๊ะ แล้วทำไงให้ผมแค่กดเปิด server เนี่ย แล้วตอนที่ VM มันเปิดขึ้นมา เราสามารถเล่นได้เลย วิธีแรกที่ผมคิดง่ายๆ ก็นะ เราก็ใช้ systemd ใน Linux ในการเปิดง่ายๆ เลย แต่สิ่งที่เจออีกต่อมาคือ เนื่องจากตัว server Minecraft เองเนี่ย มันเป็น interactive application คือเราสามารถเข้าไป abuse admin command เหมือนที่ผมทำในตอนต้นเนี่ยครับได้

พอผมใช้ systemd ซึ่งมันไม่มี terminal attach อยู่ เออ มันก็ interact ไม่ได้

แล้วพอถามว่าเราจะแก้เรื่อง interact ไม่ได้ยังไง ก็ช่วงแรกๆ ผมก็ทำแบบนี้นะครับ พอจะ… ใช้ command หน่อยผมก็ปิด server แล้วก็เปิดอีก อีก session ใน terminal แล้วก็ใส่ command ปิด server แล้วก็ค่อย systemd เปิดขึ้นมาอีกรอบ จนกระทั่งมันทนไม่ไหวครับ เพื่อนผมก็เลยเขียน web interface แบบโง่ๆ ขึ้นมานึง เพื่อเอามาดัก stdin กับ stdout ของตัว binary เพื่อที่จะเอามาใช้ ซึ่งมันก็ดีครับ มันดีแต่สุดท้าย ผมก็ยัง auto update จริงๆ จังๆ โดยที่ผมไม่ทำพลาดไม่ได้อยู่ดี

สาเหตุที่แท้จริงของปัญหา: Mojang ไม่ยอม Auto-Update5:14

ก็เลยสรุปว่าปัญหาทั้งหมดเนี่ยมันเกิดจาก… มันไม่ได้เกิด– แบบว่าพวกเราพยายามแก้ไขปัญหาที่ปลายเหตุ แล้วที่ผมจะบอกว่าเป็น band-aid fixes เนี่ย ไม่ว่าจะเป็นการที่ผมใช้ Ansible เข้ามาช่วย ผมใช้ systemd เข้ามาช่วย ผมใช้ทำ web interface เข้ามาช่วย แต่สุดท้ายแล้วคือความผิดมันไม่ใช่ของผม มันคือของ Mojang ที่มันไม่ยอมทำให้ server update เองได้ เพราะฉะนั้นผมก็เลยจะแก้ไขปัญหา ที่ต้นเหตุจริงๆ ครับ ด้วยการซื้อ Minecraft Realm ครับ ไม่ๆ ไม่ใช่ๆๆๆ

โอเค ไม่ใช่ๆ โอเค

Montainer: โซลูชันใน Docker Container5:47

วิธีแก้ไขปัญหาผมก็เป็น project สนุกๆ ที่ผมทำขึ้นมานะครับ ที่ผมชื่อว่า Montainer คือมาจาก Minecraft in a container เผื่อใครมีชื่อดีกว่านี้ก็บอกผมได้นะ ก็คือผมเอา server Minecraft ทั้ง binary แบบเนี่ยเลย ไปใส่ใน Docker container แล้วต่อมาผมก็ใส่ตัว web management API ทำให้ผม interact กับมันได้ เนี่ยก็เลยมี web interface แล้วก็มี player แล้วต่อมาผมก็ map volume ให้ตัวพวก file world file config เนี่ย ไอ้ออกมา แล้วเราก็ backup ง่ายๆ บน S3 กันได้

Web Automation: GitHub Actions และ Selenium6:19

แต่ทีนี้ก็จะกลับเข้าสู่ topic ของวันนี้แล้ว เรื่อง web automation ผมจะทำยังไงให้ทั้ง project ของผมเนี่ย มันได้ version ใหม่สุดตลอด เพราะอย่างที่ผมบอก เค้าบังคับให้เราเล่น version ใหม่สุด แต่เค้าไม่ auto-update ผมต้องไปโหลด version ใหม่สุดทุกครั้ง ง่ายๆ ครับ ผมใช้ GitHub Actions เข้ามาช่วยในการ run cron job ทุกๆ วัน ส่วนใหญ่เวลาที่ run ก็จะเป็นแบบช่วงเที่ยงคืน ที่ผมไม่น่าเล่นเกมอยู่แล้วเพราะผมเป็นเด็กดี

ลีโอๆ เราเล่นกันถึงกี่โมงนะช่วงนั้นอะ ตีสองตีสาม โอเค ก็คือมันจะเป็น cron job ทุกวัน ที่จะเอา Selenium เนี่ยครับ ไป fetch ในเว็บ Mojang เพื่อเอาเลข version ใหม่สุดของมันออกมา ทีนี้ถ้ามันไม่มี version ใหม่สุดเราก็ช่างมันถูกมั้ย แต่พอมันมี version ใหม่สุดเนี่ย มันก็จะไป trigger GitHub Actions อีกตัวเหมือนกัน ที่จะเอา Selenium เข้าไปกดติ๊กถูกตรงนี้ครับ ตรงที่บอกว่าเรายอมรับ agree license เนี่ย แล้วมันก็จะมีลิงก์โผล่มา เพื่อให้เราได้ลิงก์ดาวน์โหลด server ทีนี้ก็จะเป็น GitHub Actions ตัวอื่นๆ แล้ว ที่จะคอยไปโหลดตัว binary ตัวใหม่สุด ตัว resource ทุกอย่างใหม่สุดจากเว็บมา แล้วมา build image version ใหม่ ของตัว server Minecraft ที่ผมเขียนเองครับ ประมาณนี้

Workflow การอัปเดตอัตโนมัติ7:40

โอเคนี่ก็เป็น workflow คร่าวๆ นะ ก็อย่างที่ผมบอก ก็คือขั้นแรกคือทุกวันเราไป fetch version ใหม่สุดมา ถ้าไม่มี version ใหม่สุดก็คือไม่ทำอะไร ส่วนถ้ามีเราก็สร้าง version ใหม่ เราก็สร้าง image version ใหม่ แล้วต่อมาผมก็ deploy ตัว server ผมเนี่ยคู่กับ ตัวอีก image นึงที่ชื่อว่า Watchtower ที่จะคอยดูว่ามี version ใหม่ออกมาหรือเปล่า เวลาที่ผม push ตัวอันใหม่ขึ้น registry ทีนี้ผมก็สามารถทุกครั้งที่เปิด server หรือทุกครั้งที่มันออก version ใหม่ ผมก็สามารถมีเกมเล่นได้แล้ว โดยที่ผมไม่ต้องไป update เอง หรือว่าทำให้มันพลาดนะครับ

Demo: Montainer ทำงานอย่างไร8:13

ทีนี้ผมก็อยากจะ demo ให้ดูนิดนึง ถึง project ที่ผมทำขึ้นมา

อันนี้คือตัว example ที่ผมทำไว้นะครับ

ก็ตัวอันนี้คือตัว Docker Compose ตรงนี้มีใครไม่เคยใช้ Docker มั้ยครับ โอเคทุกคนคุ้นเคยกับ Docker กันดีละ ก็อันแรกไม่มีอะไรก็คือ ผม pull image ไอ้ตัวที่เป็น server Minecraft ผมเข้ามา ซึ่งผมใส่ tag latest ไว้เนาะ เราได้ใช้กับพวก Watchtower พวกนั้นได้ เราได้เล่นใหม่ latest ตลอด แล้วต่อมาผมมีอีกอันนึงด้วยก็คือตัว MinIO ที่เป็น S3 compatible storage เพราะอย่างที่ผมบอกผมทำมันพังบ่อยมาก เพราะฉะนั้นเราต้องคอย backup เป็นช่วงๆ กันไว้

นี้พอผม run ตัว server ของผม

สาธิตการใช้งาน Montainer9:03

เดี๋ยวรบกวนซูมกด control บวกนะครับ จะได้เห็นกันชัดๆ

คอนโทรล บวก ครับ

มันมี VS Code ตรงไหนที่ทำให้กดได้ไหม

มันคือ… มันชื่ออะไร size

อ๋อ zoom

zoom in ครับ

หรือว่าถ้าใครมีแว่นขยายตอนนี้ ก็หยิบขึ้นมาส่องจอได้นะครับ

ทีนี้เรามารันอันนี้กันนะครับ เดี๋ยวผม cd examples\docker

ทีนี้มันก็จะเปิด 2 image ขึ้นมานะครับ image แรกก็อย่างที่ผมบอก คือตัว server ที่ผมทำขึ้นมา ซึ่ง map port 8000 ก็คือตัว web API ของผม แล้วก็ port ที่เราไว้เล่นกันนะครับ 19132 ซึ่ง map กับ MinIO ตามนี้เลย

วิธีการเล่น Minecraft ผ่าน Montainer10:15

ทีนี้ ต่อไปนี้ พอเวลาเราอยากเล่น Minecraft กับเพื่อน เราก็สามารถเล่นได้เลย ด้วยการเข้าไปที่นี่ครับ

เราก็จะมี web UI สวยๆ ที่เราสามารถใช้ในการเล่นได้เลย แล้วก็พอสมมุติผมอยากจะ abuse admin command เหมือนเดิม ผมจะ 𝚝𝚙 @𝚎 @𝚙 ผมก็สามารถเขียนในนี้ได้เลยเหมือนกัน นี่แหละครับ แล้วเมื่อสมมุติว่าก่อนที่ผมจะลองทำอะไรแปลกๆ ซึ่งอาจทำให้เพื่อนทุกคนจะรุมผมได้ ผมก็สามารถกด save 1 ครั้ง เพื่อมันจะหยุด server zip ทุกอย่าง แล้วก็อัปโหลดขึ้น S3 ที่เราเขียนไว้ได้เลย ทีนี้เราก็สามารถเล่นได้ ทำเรื่องแปลกๆ ได้ เล่นเวอร์ชันใหม่สุดได้ โดยที่ไม่ต้องแบบ frustration อีกต่อไปแล้ว

สรุปและขอบคุณ11:03

อันนี้ก็เป็นโปรเจคสนุกๆ ที่ผมเอา automation ไม่ว่าจะเป็นในส่วนที่ใช้ GitHub Action ในส่วนที่ใช้ Selenium ต่างๆ เข้ามาช่วยครับ

ก็ขอบคุณทุกคนมากครับที่ร่วมกันฟัง talk วันนี้ของผม

ก็ขอเสียงปรบมือให้กับอุดดี้ด้วยครับ

สรุปก็คือเราใช้ automation ในการเข้ามารัน

server Minecraft แบบ 24/7 เลยนะครับ