Deploys.app is better than Cloud Run [Theory]

Chanon Yaklai
7 min readOct 28, 2019

--

#DISCLAIMER

  • Deploys.app เป็น Product ของบริษัท Acoshift.me ผมมาช่วยเขียนอธิบายเพื่อให้คนอื่นๆได้ทดลองใช้กันครับ ถ้า Official Document เค้าเขียนดีผมน่าจะลบบทความนี้ทิ้งครับแล้วให้ไปอ่าน Official Document กันดีกว่า
  • ไม่เหมาะกับคนที่มีความรู้ความเข้าใน DevOps เป็นอย่างดี

TLDR ; บทความยาวมากแต่ผมว่ามันเปลี่ยนวิธีการ Development และการ Deployment ของการพัฒนา Web Application และการนำขึ้น Production ของผมไปตลอดกาลและหวังว่ามันจะเปลี่ยนของผู้อ่านด้วยนะครับ เชื่อเถอะคุ้ม

!!! ความรู้ที่ต้องมีก่อนอ่านบทความนี้

  1. พอเขียน Dockerfile ได้บ้าง
  2. พอเขียน Frontend ได้บ้าง
  3. พอเขียน Backend ได้บ้าง
  4. พอเขียน SQL ได้บ้าง
  5. พอใช้ Git ได้บ้าง
  6. พอรู้จัก Google Cloud run บ้าง
  7. *พอรู้จัก Amazon AWS หรือ Azure หรือ Google Cloud Platform มาบ้าง
  8. **ต้องมีบัตรเครดิต หรือ เดบิต ที่เปิด Billing ของ Google Cloud Platform ได้

*ที่อยากให้พอรู้มาบ้างก็คือ GCP มันถูกกว่า AWS อย่างน้อยๆ 2 เท่าแทบจะทุก Product ที่ชนกันตรงๆ บาง Product นี้ 10 เท่าเลยครับ ส่วน Azure ไม่เคยเล่นครับ

**สมัครเฉยๆ ครับ แต่จริงๆแทบไม่เสียเงินเลย แต่ต้อง Activate Billing Account เพื่อเอาไว้ปลดล๊อค Service ต่างๆ เฉยๆ เพราะส่วนใหญ่ Service ที่ใช้ไม่น่าจะได้ใช้ถึง Tier ที่ต้องเสียเงินเลยครับ ไว้เก็บเงินไปเสียให้ Deploys.app แทนนะ 555+

ถ้ายังไม่มีความรู้ ข้อ 1–5 หรือขาดข้อใดข้อหนึ่งไปก็ข้ามบทความนี้ไปได้เลยครับผมว่าเสียเวลาอ่าน

ส่วนข้อ 7–8 เป็นเรื่องของการเสียเงินนิดๆ หน่อยๆ แล้วครับ แต่ถ้าอยากฟรี 100% หรือ ไม่มีเครดิตการ์ด ก็สามารถติดตามต่อในบทความได้เลย :)

ส่วนถ้าใครยังไม่รู้จัก ข้อ 6. Google Cloud Run ก็ไปอ่านบทความด่านล่างได้เลยนะครับ เจ้าของบทความหน้าตาดีมากเขียนไว้ ที่สำคัญโสดครับ ทักได้ :)

พออ่านจบจะพบว่า เจ๋งมากเลยนะครับ Cloud run แต่

ข้อเสียคือ

  1. มันมี Cold Start ….
  2. ต่อจากข้อ 1 เค้าคิดเงินตาม CPU ที่ใช้ 100ms … ถ้า ping ทุกๆ 5 วินาทีเพื่อให้เครื่องมัน อยู่ในสถานะ Warm อยู่ OMG ก็คือ มันคิดเงินตามเวลาที่ใช้เลยน่ะเอ้อ อาจจะแพง
  3. ทำ Cronjob กับ Worker ไม่ได้ (ตรงนี้งงไม่เป็นไรครับผมเองก็ยังไม่รู้เรื่อง พอดี Deploys.app บอกมาว่าเค้าทำได้ Cloud Run ทำไม่ได้)
  4. ถ้ามีข้อเสียอีกจะมาเขียนเพิ่มครับ

ปัญหาทุกอย่างจะหมดไปถ้าคุณใช้ Deploys.app

Deploys.app — Dashboard

#ขั้นตอนที่ 1.สมัครใช้งาน login ด้วย google account ได้เลย

#ขั้นตอนที่ 2.สร้าง Project

Deploys.app — Create Project

โดยสามารถเลือกได้ทั้งหมด 2 Locations ดังนี้

  • GKE (ใช้ Google Kubernetes Engine อยู่ที่ Singapore)
  • bangmod-cloud (ได้ข่าวว่า Deploys.app จะปิดละอาจจะเหลือ แค่ GKE อย่างเดียว)

คราวนี้มาดูตัวอย่างการใช้งานกันบ้าง

โดยผมได้นำเอา Project ที่มีอยู่แล้ว มาทำการ Deploy ให้ดู และ ทำการต่อกับ Database CockroachDB ซึ่งเป็น Distributed SQL Database

แต่ก่อนอื่นเพื่อให้เข้าใจได้ง่ายขึ้นเรามาดู Infra ของ Project กันก่อนดีกว่า ผมขอเล่าแบบ Walkthough ไปด้วยกันเลยนะครับเพื่อความเข้าใจโดยเรียง ตามหมายเลขภาพด้านล่างเลยครับ

# (0) PROJECT INFRASTRUCTURE

todo-deploys-demo : Project Infrastructure

# (1) FIRST WALKTHROUGH

Infrastructure ของ Deploys.app นั้น (ณ.เวลานี้ 13 Nov 2019) รันอยู่บน 2 Physical Location ด้วยกันคือ

  • GKE
  • Bangmod-cloud

โดยจากภาพด้านบนผมจะขออธิบายในส่วนของ GKE อย่างเดียวนะครับ

GKE หรืออีกชื่อ คือ Google Kubernetes Engine ส่วน ถ้า ใครยังไม่รู้จัก Kubernetes ก็ไม่ต้องสนใจก็ได้ครับ เพราะเราจะ Focus อยู่แค่ที่ Layer การทำ Web Application ข้อดีของการใช้ Deploys.app นั้นคือ เราไม่ต้องไปสนใจในส่วนของการจัดการ Docker Image เลย

Deploys.app นั้นจะช่วยเราในส่วนที่เราเรียกกันว่า Docker orchestration

หน้าที่เราแค่สามารถบิ้ว Docker Image แล้ว push ไปเก็บไว้ที่ Container Registry ของ Google หรือ จะ Push ขึ้น Docker Hub (Free 1 private reop) ได้เลยครับ และสามารถตั้งได้ด้วยว่า Docker Image นี้เป็น แบบ private หรือ public ถ้าตั้ง private เราก็ต้องไปสร้าง Service Account เพื่ออนุญาติให้ Deploys.app มีสิทธิ์ในการอ่าน Docker Image ของเรา ก็จะทำให้ Deploys.app สามารถเอา Docker Image ของเราไปรันได้ หรืือ ถ้าเขียน cloudbuild.yaml ตั้ง trigger บน GCP ได้นี้คือ git push ปุ๊ป ก็เสร็จปั๊ปเลยครับ มันจะทำการบิ้ว และ Deploy ให้เองโดยอัตโนมัติ

ปล.ถ้าอยากเก็บ Docker Image ไว้ที่อื่น นอกจาก GCR หรือ Docker hub ก็ทำได้ครับ Deploys.app มี Feature “Pull Secret” สามารถดึง Docker Image จากที่ไหนก็ได้มาเพื่อรันได้แล้ว

GCP — Container Registry

!!! ขั้นตอนนี้เสียเงินแล้วนะครับ โดย GCP คิดเงิน 0.0026 / เดือน / GB (คิดแบบ Multi-region) ซึ่งถ้ารวมกับค่า Bandwidth ในการ push ขึ้นไป หรือ pull ลงมาดู คิดให้ง่ายๆเล่นๆ ถ้า มี docker image ไม่เกิน 1 gb เสียเงินประมาณเดือนล่ะ 1 บาทครับ

ข้อดีที่ได้จากการ Deploy แบบนี้คือ

  1. ไม่มี Cold start , ไม่มี Downtime แค่นี้ก็พอล่ะมั้งครับ จริงๆ Downtime ขึ้นอยู่กับ Infrastructure ของ google ซึ่งถ้ามัน down ก็จะบอกว่าไม่มีทางเค้ามีระบบการ maintanance แบบเหมือนยก Datacenter ไปไว้ที่อื่นแบบชั่วคราว ถ้าจะ down จริงๆ มันน่าจะอยู่ระดับกระพริบตาแล้วกับมาติดใหม่ โหดจัดปลัดบอก !!!
  2. แค่บิ้ว Docker เป็น ก็สามารถ Deploy ขึ้นได้เลย และ ยังส่งผลให้ Docker container ของเรา Scale ได้โดยอัตโนมัติ เพราะเราวางอยู่บน Infra ที่เป็น Kubernetes
  3. Deploys.app มีการทำ Load Balancing และอื่นๆ ไว้อีกมากมายเดี๋ยวมาเขียนเพิ่มจำไม่ได้ละต้องถามทีมงานก่อน
  4. ไม่ต้องเสียเงินค่าตั้ง Master, Worker ของ Kubernetes คือพูดง่ายๆ คือไม่ต้องไปยุ่งอะไรกับ Kubernetes เลย ไม่ต้องรู้ ไม่ต้องเข้าใจอะไรเลยก็ได้ รู้แค่ว่าได้ใช้แต่ของที่ดีที่สุดในโลกของการวาง Infrastructure ที่โลกนี้จะมีได้แค่นั้นพอ Deploys.app จัดการให้หมดแล้ว แค่ไปใช้กับเค้าพอ
  5. ถูก !!!! มากๆๆๆ เอาเป็นว่า ถูกกว่า Cloud run แน่ๆ แถมทำงานแบบไม่มี Downtime แต่คิดเงินเป็น ตามเวลาที่ใช้จริง คือเปิดให้ตลอด แต่ถ้าไม่มี การใช้งาน CPU ก็จะไม่คิดเงิน คือ เบื้องหลัง Deploys.app มีการเก็บ Stat และ Monitor CPU , RAM ตลอดเวลา เพราะฉะนั้นจึงคิดเงินได้อย่างแม่นยำตามวินาทีที่ใช้จริง
นี้คือเปิดไป 1 วัน น่าจะเสียเงินประมาณ 0.3 บาท

<<<< ข้อความด่วนจากผู้บริหาร acoshift ณ.เวลา 16:10 28/oct/2019>>>>

นี้คือแปลว่า ถ้าเปิด 1 เดือน จะเสียเงินประมาณ 5 บาท !!! WTF###

!!! หมายเหตุ 1 ราคาอาจจะมีการเปลี่ยนแปลงขึ้นกับการใช้งาน

!!! หมายเหตุ 2 อันนี้ เป็น WebApp ที่กดเล่นเอง ทดสอบเอง ไม่ได้มีอะไรมากครับ แต่ถ้ามากแล้วมันแพงเดี๋ยวมาบ่นอีกที แต่มั่นใจว่าถูกว่า VM ตั้งเองแน่นอน ผู้บริหาร acoshift พูดเองนะเอ้อ

!!! หมายเหตุ 3 เดี๋ยวตัวอย่างภาคปฎิบัติ จะพาทำแบบฟรีครับ คือ ไม่ต้องเสียเงินเลย แม้แต่บาทเดียว แต่ใช้เพื่อทดสอบเฉยๆ นะครับ ดับเมื่อไหร่ไม่รู้ Infra แบบบ้านๆ

# (2) SECOND WALKTHROUGH

ต่อๆในความเป็นจริงแล้ว Concept การใช้งานจะเหมือนกับ Cloud run มากๆ เรียกว่าลอกมานั้นแหละครับ เพราะฉะนั้น การออกแบบ application ภายใน Docker image ควรเป็น Stateless ทั้งหมด ไม่อย่างนั้นเวลามัน Scale ขึ้น หรือ ลง (ดับๆ ติดๆ) ตามที่ Kubernetes จัดการให้ ข้อมูลมันจะหายไปได้ครับ และด้วยการออกแบบที่เป็น Stateless จึงส่งผลทำให้การ Scale ของ Application เป็นไปได้ด้วยความสมบูรณ์แบบที่สุด

แต่มันก็จะเพิ่มความยากลำบากให้กับ เราเช่นกันพอสมควร ยกตัวอย่างว่าเราจะทำ Todo app ขึ้นมา (ตัวอย่างด้านล่าง)

จากตัวอย่างจะเห็นได้ว่าเค้าเก็บข้อมูลไว้ใน State ของ React แปลว่าถ้า Refresh หรือ Clear Cache ของ Web Browser ข้อมูลมันก็จะหายไปเลย

วิธีแก้โดยปกติก็คือเราก็ทำให้ Frontend เป็น Stateless กล่าวคือไม่มีการเก็บข้อมูลภายใน Docker Image ที่เราทำขึ้นมาเลย

แล้วเอาข้อมูลไปเก็บไว้บน Database แทน

แต่ Database มันเป็น Stateful

แปลว่าจริงๆ การออกแบบ Web Application ของเราก็อาจจะมีปัญหาเรื่องการ Scale อยู่ดี เพียงแต่ปัญหาจะไปเกิดที่ Layer ของ Database แทน

แต่ ก็ยังดีกว่าไม่ทำอะไรเลย อย่างน้อย Frontend เป็น Stateless แล้ว จึงและ Scale ได้

ส่วน Database เดี๋ยวค่อยมาว่ากันต่อใน (3)THIRD WALKTHROUGH

Stateless ให้นึกว่าอะไรก็ตามที่รันใน Container แต่ห้าม Save ลง disk แม้แต่ Disk ใน container เองก็ตาม

Stateful ให้นึกว่า ถ้ามีการเก็บข้อมูล เก็บ State ของ Application หรือมีการ Rely ของข้อมูลนับเป็น Stateful หมด

# (3) THIRD WALKTHROUGH

ยอมรับว่าจริงๆ ผมได้มีโอกาสได้ยิน เรื่องของ Deploys.app มาสักพักแล้ว แต่ไม่อินครับ เหตุผลคือ ถ้ามันไม่มี Solution ที่จัดการ การติดต่อ กับ Database ได้ คือ acoshift บอกให้ผมไปตั้ง Database เองซึ่งผมมองว่าไร้สาระมาก คือ มันจะมี Usecase ไหนในการทำ Software Product ออกมาที่เราไม่เก็บข้อมูลบ้าง ?? ผมว่ามันไม่มี ….. แล้วถ้าผมต้องมาจัดการ DATABASE เองผมเปิด VM ใช้เองเลยไม่ดีกว่าเหรอ ?? (อันนี้หมายถึง Project เล็กๆ นะครับ) ซึ่งถ้า Deploys.app ไม่มีทางออกในเรื่องการใช้ SQL Database ที่ดีให้ผม Deploy Frontend ที่เป็น Stateless ก็ยังมีปัญหาอยู่ดีเพราะ SQL Database โดยพื้นฐานมัน Scale ยาก

เหมือนฟ้าฝนเป็นใจอยู่ดีๆ acoshift ก็บอกว่ามีแนวทางการจัดการเรื่อง Database ให้ผมเล่นแล้ว

ขอแนะนำ cockroachDB

cockroachDB

อ่านไม่ผิดครับ cockroachDB ซึ่ง cockroach ที่แปลว่า แมลงสาบ เนี้ยแหละครับเข้าใจว่าที่มามันคือ มันจะไม่ยอมตายง่ายๆ ชื่อดูแย่เนอะครับ ชื่อน่ากลัว แต่ความหมายตรงไปตรงมา คือ เป็น Database ที่จะไม่ยอมตาาย แม้โดนกระหน่ำ 555+

โหแค่ฟังก็ต้องใช้แล้วแหละ …

คำถามต่อมาคงจะมีคนคิดดังๆ ในใจ เชี้ยยย แล้วกรูใช้ SQL อยู่จะ migrate มายังไงละเนี้ย ….

cockroachDB is PostgresDB but scalable.

คือผมแค่จะบอกว่า ใครใช้ PostgresDB dump database มาได้ดื้อๆ เลยครับ แล้วยัดเข้า PostgresDB ได้เลย ยิ่งถ้าใครเขียน TEST มาลองรันดู ถ้าไม่พังคือใช้ได้ คิดซ่ะว่า แมลงสาบมันคือ PostgresDB ได้เลยครับ

ส่วน ใครใช้ MariaDB , MySQL ผมไม่แน่ใจเลยครับว่ามัน Compatible มากพอให้เราไม่ต้องแก้เยอะหรือเปล่า

  • สรุปคือ acoshift ช่วยผมแก้ปัญหาที่ผมเจอได้ล่ะ แถม Cluster ของ cockroachDB วางอยู่บน GKE ครับ แปลว่า นอกจาก cockroachDB มันไม่ตายแล้ว มันยังแพร่พันธุ์แตกลูกแตกหลานให้โดยอัตโนมัติ ผมไม่ต้องไปยุ่งอะไรเลย OMG !!!!

ปล.จริงๆแนวทางการ Scale SQL Database โดยปกติ PostgreSQL ก็มีการทำ PostgreSQL Replication อยู่แล้วนะครับ และวิธีอื่นๆ อีกมากมาย แต่ส่วนตัวผมเองยังไม่เคยลอง ไม่ได้มีโอกาสที่จะไป Optimize Database ใหญ่ๆ ขนาดนั้น ส่วน NoSQL ขอไม่พูดถึงแล้วกันนะครับคุณ Tino Thamjarat ผู้อ่านใจดี Comment มาและผมเห็นด้วยคือ NoSQL ออกแบบมาแก้ปัญหาคนละ Usecase กับ SQL ครับ ซึ่งสามารถอ่านต่อใน Comment ได้ครับ คุณ Tino อธิบายไว้ดีแล้ว :)

# (4) FOURTH WALKTHROUGH

ถ้าคิดตามผม ตั้งแต่แรก ก็น่าจะพอเข้าใจไอเดีย และน่าจะสามารถทำ TODO App ที่มี Database เก็บข้อมูล และยังสามารถ Scale ได้ระดับ Enterprise (ถ้ามีเงินจ่าย 555+) ที่เหลือก็น่าจะมีเรื่อง Domain name ที่จะทำไงดีที่จะกด F5 แล้ว Website ไม่ล่มเหมือน รัฐบาลบางประเทศที่กล่าวว่าเป็นการ Hack !!!!

มารู้จัก Cloudflare กันดีกว่าใครรู้แล้วก็ข้ามไป ได้เลยจร้า

หลักๆ ที่ต้องไปวุ่นวาย Config กับ Cloudflare เลยก็จะเป็น CNAME และต้อง SET ตามนี้ครับเพื่อให้ Cloudflare สามารถ Route ไปที่ address ที่ทาง deploys.app กำหนดไว้ออกมาให้ (เดี๋ยวพอไปทำ Workshop [ภาคปฎิบัติ] จะอธิบายละเอียดอีกทีนะครับ รอบทความหน้าครับ)

จริงๆ มันมีเรื่องการ Set https อีกนิดนึงด้วยครับ ซึ่งเดี๋ยวผมไปอธิบายละเอียดอีกทีภาคปฎิบัตินะครับ :) คือ ทาง Deploys.app เค้าใช้ letencrypt gen cer https ให้ในครั้งแรกที่ deploy นะครับ เพราะฉะนั้นตอน set cname ครั้งแรกอาจจะต้องปิด https ของ cloudflare ก่อน

# (5) FIFTH WALKTHROUGH

ขั้นตอนนี้ ถ้าใครเขียน WebApp แบบ MPA(Multi page application) หรือ php , index.html + css +jQuery ก็น่าจะข้ามขั้นตอนนี้ไปได้เลยครับ แต่ตัวอย่างนี้ผมยกตัวอย่างด้วย SPA(Single page application) จึงต้องทำขั้นตอนนี้ครับ

  • build จาก SPA เป็น static file (ให้เหลือแคื html , css , javascript) ถ้า clone project ผมมาแค่พิมพ์ yarn build ก็เสร็จแล้วครับ แต่อาจจะต้องแก้ค่า PATH ที่ต้องใช้ในการเรียก api โดยการสร้าง .env มาก่อน …. หรือถ้าทำเองก็แก้ค่าตรงๆ เลยก็ได้ครับ เอาที่สบายใจ
  • Project TODO App ผมเอาของคนอื่นมา แล้วเอาไปรวมกับ boiler plate ของ create-react-app เพื่อให้สามารถพิมพ์ yarn build ได้เลยง่ายๆ

พอจบขั้นตอนด้านบนมันก็จะได้ folder build มา โดยปกติเราจะเอาไปให้ Web Server ใช้เพื่อ Serve Static files ต่อไปครับ

  • เข้าใจว่าคนอื่นๆเค้าอาจจะไปใช้ NGINX เพื่อ Serve Static Files กัน ซึ่งก็ดีแล้วครับ สำหรับคนใช้งานเป็น config คล่องๆ แต่เนื่องจากผมขี้เกียจ config Nginx ผมเลยใช้ Golang ทำหน้าที่ Serve Static files และเพื่อเป็น Backend เพื่อใช้คุยกับ Database และไปในตัว … แนวมั้ยละ แนวไร้สาระ … 555+
    ปล. จริงๆ ถ้า config Nginx ไม่ค่อยเป็นเนี้ย ใช้ Go เพื่อ Server Static Files เร็วกว่านะครับ acoshift บอกมา :)

# (X) LOCAL DEVELOPMENT WALKTHROUGH

สุดท้ายละครับเพื่อเตรียมตัวสำหรับบทความหน้า คือเราควรมีการทดสอบบนเครื่อง local ได้ก่อนที่จะ Deploy ขึ้นไปบน Deploys.app ถ้าจะทดสอบแบบเหมือนผมเลยต้อง ลงโปรแกรมตามนี้ครับ

  1. Install Docker ในเครื่อง
  2. Install Golang และทำการ Set env path ด้วย
  3. ทำยังไงก็ได้ให้สามารถพิมพ์ npx create-react-app my-app ได้

แค่เนี้ย คิดว่าพอแล้วครับ ไว้ถ้าลืมอะไรจะมาแก้ให้ใน บทความหน้านะคร๊าบบบ

โดยสามารถ ลองเล่นตัวอย่างที่เสร็จเรียบร้อยแล้วได้ที่ Link ด้านล่างเลยครับ

ข้อเสียล่ะ ??

  • Infrastructure ของ *Digital Ocean และ **GKE ใกล้ไทยสุด อยู่ที่ Singapore นี้คือใกล้ไทยที่สุดแล้ว แต่ยังไงก็จะช้ากว่า Infra ที่อยู่ในไทยแน่นอน แต่คาดว่าช้ากว่าระดับ Millisecond เพราะมันมีเรื่องของ Premium Network ของ Google ด้วยที่มันจะเหมือนเตรียมทางด่วนมาให้ เรื่องนี้ก็ไปหาอ่านเพิ่มเติมเอานะครับ แต่ถ้าใครใช้ *Digital Ocean อาจจะอด อาจจะช้ากว่าการรัน **GKE
  • มีความรู้ที่ต้องพอเข้าใจเยอะพอสมควรเช่นพวก Service Account ของ Google และอื่นๆ อีกมากมาย
  • ถ้าใช้ฟรี (local.acoshift) นื้คือ Infra บ้านๆ เลยครับ Physical คือ เครื่อง Server ที่บ้าน Net 3BB แบบ Fixed IP โคตรจะไม่เสถียร แต่ก็ฟรีอ่าครับ เอาไว้ใช้ทดสอบ :)

และยังมีปัญหาอื่นๆอีกมากมาย ที่ไม่ได้อยู่ในบทความ เช่น

  • DATABASE อยู่คนละที่กับ Front-end
  • น่าจะต้องไป SET CORS ก่อนมั้ง
  • เดี๋ยวค่อยมาคิดเรื่อง Authen ด้วย Sessions หรือ JWT ทีหลังละกันตอนนี้พอก่อน
  • มันจะช้ามั้ยเนี้ย cockroachDB เห็นเค้าพูดๆ กันว่า Latency สูง

มีคู่แข่งด้วยนะเอ้อ

ถ้าเปรียบ Deploys.app เป็น Android , render.com เป็น IOS ครับ

https://www.render.com

เว้นแต่เค้ามี funding แล้ว ประมาณ 69 ล้านบาท …. Deploys.app ติดลบจร้า

https://www.crunchbase.com/organization/render#section-overview

หากอยากลองทำแล้ว ก็ไปต่อตอนที่ 2 กันได้เลยครับ

โดยผมแบ่งเป็น

  • Version [Free Workshop] เอาไว้ใช้ทดลองอะไรเล่นๆ ที่ไม่ซีเรียส
  • Version [Production Workshop] เอาไว้ใช้กับการทำงานจริงๆ ซึ่งเสียเงินแต่คุ้มค่ามาก

REF

--

--

Chanon Yaklai

I'm founder of GamingIdea.com | Part-time lecturer KU@Dept.Computer Engineering, KMUTT@Dept.Media Technology and KMUTT@Dept.Industrial Education and Technology