ทำเว็บไซต์ด้วย Hugo แล้วโฮสบน GitLab Pages และ Cloudflare

สวัสดี​ครับ วันนี้ผมจะมาแนะนำเรื่องการทำเว็บไซต์​แล้วไปโฮสบน GitLab​ กันต่อ ซึ่งวันนี้จะมาแนะนำเครื่องมือ​ทำเว็บไซต์​ที่เป็น static websit generator ที่ผมเพิ่งได้ลองใช้แล้วติดใจมาก มันมีชื่อว่า Hugo โดยบทความนี้จะแนะนำให้รู้จักกับ Hugo ข้อดี ข้อด้อย เปรียบเทียบ​กับการใช้ CMS ทั่วไป การใช้งานเบื้องต้น ไปจนถึงการโฮสบน production server โดยใช้ GitLab​ และ Cloudflare​ ให้ไปรับงานกันอย่างมันมือ

สำหรับบทความนี้จะมีทั้งหมด 3 ตอน ดังนี้

  1. ใช้ GitLab Pages โฮส Static Website ฟรีๆ ไม่ต้องตั้ง Server
  2. การต่อ HTTPS กับ GitLab Pages ด้วย Cloudflare​ ให้ได้ SSL Lab เกรด A+
  3. ทำเว็บไซต์แบบเป็นเรื่องเป็นราวบน GitLab Pages ด้วย Hugu

ผมเชื่อว่าทุกท่านคงรู้​จัก WordPress อยู่แล้ว แล้วหลายๆ ท่านก็ทำมาหากินปั้มเว็บไซต์​ขายกันด้วย WordPress​ นี่แหละ แต่คำถามคือ เว็บที่ท่านๆ ทำกันเนี่ย หลายเว็บก็เป็นแค่ content website ทั่วไปที่นานๆ ทีจะมีการเข้ามาแก้ไขข้อมูล​สักครั้ง​ แล้วทำไมเราถึงจะต้องเอาเว็บที่มันไม่ dynamic ไปโฮสบน PHP server ให้เปลือง​ด้วย เสี่ยงปัญหา​เรื่องการ scale ไปจนถึงการเสี่ยงโดน​แฮค จะดีกว่าไหมถ้าเราไม่ต้องเสียเงินค่าโฮส แต่ส่งงานคุณภาพ​ให้ลูกค้าได้เหมือนเดิม สิ่งเหล่านั้นสามารถเกิดขึ้นได้ถ้าเราเปลี่ยนมาใช้ static website แทน แต่ทีนี้จะจัดการบริหาร content บน static website มันยาก จนกระทั้งเราหลบมาใช้สิ่งมี่เรียกว่า static website generator ที่จะแยกส่วนของ content ให้จัดการง่ายอย่าง CMS แล้วจัดการสร้างหน้าสวยๆ เป็น static files ให้ด้วยโปรแกรมที่รันครั้งเดียว​

ข้อดีที่ Static Web Generator

  • ใช้ Static File Hosting ธรรมดาได้เลย ซึ่งราคาแทบจะฟรี (S3, GCS) ไปจนถึงฟรี (GitLab Pages, Netlify)
  • ไม่ต้องห่วงเรื่องเว็บจะโดนแฮค เพราะหน้าเว็บแสดงผลเป็น static files ทั้งหมด ถ้าจะแฮคได้ก็ต้องเข้าถึง account ของ hosting เท่านั้น
  • ไม่ต้องห่วงเรื่อง backend performance เพราะมันไม่ต้องมีการประมวลผลใดๆ แย่โยนไฟล์​ออกมา และยังสามารถใช้ CDN ได้อย่างเต็มประสิทธิภาพ​อีกด้วย
  • เวลาทำ content มาทำฝั่ง local ได้ สามารถตรวจความเรียบร้อยทั้งหมดจนมั่นใจก่อน push ขี้นไป เหมือนแยก dev env กับ prod env ไปโดยอัตโนมัติ​
  • ใน dev env มันมีโหมดคอย watch file changes แก้ปุ๊บ เห็นผลลัพธ์​ใหม่ปั๊บ ทำงานสะดวกมาก

ข้อจำกัดของ Static​ Web Generator

  • จะมีลูกเล่นซับซ้อนที่จะต้องใช้ server มาเก็บข้อมูล​ไม่ได้แล้ว ตัวอย่างเช่นจะเอามาทำ online shopping cart แบบนี้ไม่รอด
  • การอัพเดท content ไม่กดปุ๊บขึ้นปั๊บ จะต้องผ่านการ compile และ deploy ก่อน (สามารถทำให้มัน auto ได้ แต่ก็ต้องมี git commit,​ git push อยู่ดี)​
  • ควรจะต้องลง Hugo ในเครื่องที่ใช้ dev ไม่เหมือนการใช้ wordpress ที่จะอัพโหลดแล้วใช้งานผ่านทางเว็บได้เลย ความจริงจะอัพเดท content ผ่านทาง GitLab​ Web IDE ก็ได้ แต่จะทำให้ตรวจความถูกต้องก่อน deploy​ ไม่ได้

ลักษณะเว็บที่สามารถเปลี่ยนมาใช้ Hugo ได้

  • เป็นเว็บที่เน้นให้บริการ content เป็นหลัก เช่น เว็บแนะนำสินค้าหรือผลิตภัณฑ์​ขององค์กร​ ที่สนแค่เสนอเนื้อหาเท่านั้น และนานๆ จะอัพเดทสักที เหมาะอย่างยิ่งที่จะเอาไปใช้ทำเว็บโรงเรียน เว็บ อบต เพราะเว็บพวกนี้ไม่ค่อยมีคนมาดูแล มาอัพเดท CMS กัน ทำให้โดนเจาะกันอยู่บ่อยๆ เปลี่ยนมาใช้ Hugo แบบนี้ไม่ต้องกลัวจะโดนแฮค (ส่วนใหญ่เวลารับงานกันก็เว็บพวกนี้แหละ)​
  • เว็บ blog ส่วนตัว ทำอยู่คนเดียว​ ไม่สนใจใคร เปลี่ยนมาใช้ก็ช่วยให้ไม่ต้องไปห่วงเรื่อง Hosting​
  • ต้องการเก็บ stat ผ่านทาง frontend ก็พอ สามารถติด Google Analytics ได้ตามปรกติ (อาจดู Stat ฝั่ง Backend ได้นิดหน่อยผ่านทาง Cloudflare)
  • อาจจะมี embedded forms ต่างๆ ได้ เช่นส่งอีเมล์​เพื่อสอบถามข้อมูล​ หรือช่อง comment ต่างๆ แต่จะต้องใช้เป็นบริการจาก 3th party เช่น Facebook​ หรือ HubSpot เป็นต้น

สร้าง Hugo เว็บไซต์​ด้วย GitLab​ Pages

เนื่องจาก GitLab​ มี Project Hugo ให้ฝช้กันอยู่เเล้ว เราก็จะไปลอกมาเลย เข้าไปที่ https://gitlab.com/pages/hugo แล้วไป copy repo url แบบ https ออกมา


จากนั้นไปสร้าง project ใหม่ของเราเอง แล้วเลือกเป็น Import project แล้ววาง repo url ที่ copy เอาไว้วางลงไป


ตั้งชื่อ config อะไรให้เรียบร้อย แล้ว Create​ Project​ โลด


หลังจากได้ Project​ มาแล้ว ผมอยากให้เข้าไปศึกษา​ไฟล์​ .gitlab-ci.yml กันหน่อย มันคือ script ที่เอาไว้ compile และ deploy ขึ้น GitLab​ Pages

ข้างในนี้มันบอกว่า ถ้ามีการใช้ git submodule ซึ่งส่วนใหญ่​มักจะเป็นเรื่องธีม ให้ pull มาอัพเดทด้วย ทำให้เวลา theme ต้นทางที่เราใช้ ถ้ามีอัพเดท มันจะ auto update ให้เราทุกครั้ง

ต่อมาเป็นเรื่องของการเช็คความถูกต้อง​ว่า Source code ของเรานั้นรันได้ ถ้ามัน compile ไม่ผ่าน ก็ไม่ต้องทำต่อ

หลังจากรันได้แล้ว จึงทำการ Deploy โดยเวลารันคำสั่ง Hugo มันจะสร้าง Directory ชื่อ public แล้วเอา static content ที่ compile ได้ ไปใส่ไว้ในนั้น และนั่นคือสิ่งที่จะเก็บลง Artifact เพื่อใช้กับ GitLab ​Pages​


ต่อไปเรามา deploy ครั้งแรกกัน ไปที่ Pipeline แล้วกด Run Pipeline​


หน้านี้มันจะให้เราเลือกว่าจะรัน Pipeline​ ท่าไหน ซึ่งตอนนี้เรามีแต่ master และไม่ต้องเซทอะไรเพิ่ม ก็กด Create​ Pipeline​ ได้เลย


เข้าไปดูมันรันสักหน่อย ก็จะเห็นว่ามันทำอะไร ถ้าทุกอย่างปรกติดี มันก็จะขึ้นเขียวๆ ว่า Passed


ต่อมาไปที่ Settings > Pages เราก็จะเห็น URL​ ของ GitLab​ Pages​ ขึ้นมาแล้ว ลองเปิดเข้าไปเลย


นั่นแหละครับ ปัญหา​เดิม GitLab​ Pages​ การ Deploy​ ครั้งแรก​จะใช้เวลานาน เราช่างมันแล้วเราหลบไปทำอย่างอื่นก่อน


ทีนี้จะมาแก้ Content บน Hugo กัน กลับไปที่เครื่องของเรา แล้วทำการ Clone Project ลงมา


จากนั้นเข้าไปที่ Directory​ ที่ Clone​ ลงมา แล้วรัน hugo server -D มันจะเปิด server dev ขึ้นมาที่ port 1313 ก็ตามไปเปิดบน web browser ได้เลยที่ http://localhost:1313


เปิดแล้วก็จะได้หน้าตาประมาณ​นี้ สังเกตดูว่าจะต้องใส่ /hugo ด้วย เพราะว่ามันถูกเซท base url เอาไว้ เดี๋ยว​เราจะไปเอาออกกัน


เข้า​ไปที่ไฟล์​ config.toml ดูบรรทัด​บนสุด comment มันออกด้วย # แล้วปิด server (กด ctrl+c) แล้วรันใหม่อีกครั้ง

ทีนี้เข้าผ่านทาง / ได้แล้ว


ต่อมา ลองมาแก้ content หน้าแรกกัน เข้าไปที่ไฟล์​ content/_index.md ไฟล์นี้เป็น content ส่วนแรกของหน้าแรก ลองแก้เป็น Hello World! แล้วเซฟ


ไปเปิดดูก็จะเห็นว่า content เปลี่ยน​ไปแล้ว


จากนั้นเรา git commit แล้ว push ขึ้นไปข้างบนกัน


รอ Pipeline รันเสร็จ​


จากนั้นไปเปิด URL ที่ GitLab​ Pages ให้มา ก็จะเห็นว่าเว็บไซต์​ขึ้นไปออนไลน์​เรียบร้อย​แล้ว :)​


ทำ Custom Domain และ HTTPS ให้ GitLab​ Pages ด้วย Cloudflare​

ต่อมาถึงขั้นตอนสุดท้าย คือการสร้าง Custom Domain ให้ GitLab Pages ทำให้เว็บเราเข้าผ่าน Domain ที่เราต้องการได้ ซึ่งขั้นตอนนี้ก็จะเหมือนกับตอนก่อนหน้าเรื่อง การต่อ HTTPS กับ GitLab Pages ด้วย Cloudflare​ ให้ได้ SSL Lab เกรด A+ เลยครับ สามารถตามไปอ่านกันได้เลย ผมเขียนเอาไว้แล้วค่อนข้างละเอียด

หลังจากต่อกันเรียบร้อยแล้ว ก็ลองเข้าผ่านทาง custom domain ที่ใส่ลงไปดู ถ้าทำถูกต้อง ไม่นานทุกอย่างก็น่าจะเข้าได้ตามปรกติครับ

การใช้งาน Cloudflare คือการใช้งาน CDN ซึ่งมันจะทำการ Cache ข้อมูลของเราไว้บน Edge Server ช่วยให้เวลา User Request เข้ามาไม่ต้องดึงข้อมูลออกไปจาก Origin Server แต่จะดึงออกไปทาง Edge Server แทน แบบนี้จะทำให้เครื่องของเราโหลดไม่หนัก นอกจากนั้นยังมีฟีเจอร์ Always On ด้วย ที่ถึงแม้ Origin Server จะล่มไป แต่ถ้า Edge Server มีข้อมูลอยู่ก็ยังให้บริการต่อไปได้ อันนี้ดีมากๆ เวลาใช้โฮสที่ไม่ Stable แต่! ผมอยากให้ระวังเรื่องนึงคือ เจ้า Caching บน Edge Server เนี่ย เวลาเราอัพเดท Content แล้วมันจะไม่อัพเดทตามนะครับ เราต้องไปกด Clear Cache เอง ยังไม่จบ แล้ว Caching บนฝั่ง Web Client ก็ด้วย อันนี้ต่อให้ลบทางฝั่ง Edge Server แล้ว ก็ต้องรอฝั่ง Client หมดเวลาด้วย ดังนั้นแล้วกำหนดเวลาจะแก้ไขรูปภาพเอย ไฟล์ JS/CSS เอย ถ้าเป็นไปได้ ให้ใช้ URL ที่แตกต่างกัน หรือใส่ Hash อะไรบางอย่างลงไปด้วยครับ เวลา User เปิดใหม่จะได้เห็น Content เป็นแบบเดียวกัน และแนวทางที่ดีที่สุดก็คือ ทำทุกอย่างให้เรียบร้อยก่อนอัพโหลดขึ้นไปครับ


แนะนำการพัฒนาเว็บด้วย Hugo แบบเร็วๆ

หลังจากที่เว็บ Hugo ของเราขึ้นไปแล้ว ทีนี้ก็ถึงเวลามาแก้ไข Content ต่างๆ ซึ่งก็จะเริ่มต้องมีความเข้าใจโครงสร้างพื้นฐานกันบ้าง สำหรับผมที่ผ่านการทำมาแล้วบ้างนิดหน่อย ก็พอจะจับประเด็นได้ว่ามีอะไรที่จำเป็นต้องรู้บ้าง ซึ่งจะมีประเด็นดังนี้

ไปเลือก Theme มาให้ได้ก่อน ก่อนจะทำอะไรทั้งปวง เนื่องจาก Hugo มันอิงโครงสร้างตาม Theme ที่เราเลือกใช้งาน แล้วแต่ละ Theme ก็มีโครงสร้างไฟล์ที่แตกต่างกัน ดังนั้นแล้วก่อนจะทำอะไรทั้งปวง ไปเลือก Theme มาก่อน ซึ่งมีให้เลือกมากมายที่นี่ https://themes.gohugo.io/

ติดตั้ง Theme แบบ Git Submodule หรือ Copy มาใส่ เลือกเอาสักอย่าง หากเราต้องการใช้งานให้ผ่านๆ ไป การ Copy Theme มาแปะเป็นสิ่งที่ง่ายที่สุด ทำครั้งเดียวจบ แต่ถ้าต้องการให้ Theme มีการอัพเดทตามต้นทาง เราจะต้องติดตั้งด้วย Git Submodule เวลามันโหลดบน GitLab มันจะดึงข้อมูลธีมใหม่มาจาก Repo ต้นทางทุกรอบ แต่ก็จะตามมาด้วยความซับซ้อนว่า หลายๆ คนงงเรื่อง Git Submodule ดังนั้นถ้าจะต้องใช้ ไปศึกษาเรื่อง Git Submodule ให้รู้เรื่องก่อน เพราะมันจะทำให้รันบน GitLab Pipeline ไม่ผ่านถ้าตั้งค่าไม่ถูกต้อง เลือกเสร็จเอามาใช้แล้ว ไปแก้ไฟล์ config.toml เพื่อใช้งาน theme ใหม่

ติดตั้ง Theme แล้ว ล้าง Content เปลี่ยนมาเริ่มจากี่ Theme ให้มา ปัญหาเรื่องโครงสร้างมันอิงตาม Theme ยังไม่จบ เพราะถ้าเรามี Content พื้นฐานจาก Theme เก่าอยู่ แล้วพอเปลี่ยน Theme มันอาจจะมี Content บางประเภทที่ Theme ใหม่ที่เราเลือกมานั้นไม่ Support ดังนั้นให้ไปดูว่า Theme ที่เราโหลดมาใหม่หน้าตาเป็นยังไง แล้วลบของเก่า เอา Content ของเขามาทับได้เลย รันให้ได้อย่างที่ Demo ของเขาโชว์ให้ได้ก่อน หลังจากนั้นชีวิตจะง่ายแล้ว

อยากจะแก้อะไร ให้ Find หาดูจาก Theme แล้วสร้าง Directory ให้ตรงกัน อย่าไปแก้ไฟล์ใน Theme Hugo ออกแบบมาให้ Directory ข้างนอก Overide ข้อมูลข้างใน Theme ดังนั้นเราสามารถแก้ทุกอย่างได้อิสระสุดๆ โดยการสร้าง Directory ที่ตรงกับโครงสร้างของ Theme (จินตนาการว่า root directory ของ theme ที่เราโหลดมา คือ root directory ของ project hugo ของเรา) เวลาต้องการแก้ไฟล์อะไร ก็ให้ Copy สิ่งนั้นออกมาจาก Theme วางไว้ในโครงสร้างเดียวกัน เช่น ไฟล์ logo.png อยู่ใน /theme/{THEME_NAME}/static/images/logo.png ก็ให้เอาไฟล์ไปวางเอาไว้ที่ /static/images/logo.png แล้วก็จะเห็นว่ามันเอาไฟล์ของเราไปทับของ theme แล้วเรียบร้อย ดังนั้นเราสามารถ customize อะไรเลยก็ได้ตามใจชอบ

ไฟล์เนื้อหาแบบ Dynamic มักจะอยู่ที่ content เข้าไปศึกษาให้ดี ถ้าเราจะใช้สร้าง Blog 1 entry ก็คือ 1 ไฟล์ แล้วมันจะมีรูปแบบการวางไฟล์ของแต่ละ Theme อยู่ ให้ลองไปศึกษาดูว่าเขาวางยังไง ต้องใส่ attribute อะไร บลาๆ มันขึ้นอยู่กับ Theme เลยครับ ทางที่ง่ายที่สุดก็คือไป copy ไฟล์ต้นฉบับมาแก้ซะเลย

ถ้าจะแก้แบบ Advance อาจต้องศึกษา Golang นิดหน่อย การที่ Hugo มันทำตัวเองให้ Dynamic ได้ มันเกิดจากการที่มี Golang คอยควบคุมอยู่ ถ้าไปเปิดไฟล์ต้นทางของ Theme ก็จะเห็นว่ามันมีการโหลด resources รัน for ต่างๆ สามารถ sort, filter ได้ แต่ละ element มีการดึงข้อมูลออกมาจาก attribute ที่ต้องการได้ ถ้าอยากแก้ได้ดั่งใจถึงขนาดนี้ อาจต้องเรียน Golang กันนิดๆ หน่อยๆ ซึ่งก็ไม่ได้ใช้ความรู้เยอะอะไรครับ ศึกษากันได้ JS ยังเขียนกันได้เลย ใช่มะ


จบแล้วสำห​รับ​ตอนนี้ หวังว่าท่านผู้อ่านน่าจะพอเห็นภาพและเลือกเอา Hugo ไปใช้งานกันเมื่อเจองานที่เหมาะสมเข้ามานะครับ สำห​รับ​ท่านใดมีข้อสงสัย​หรือต้องการพูดคุย​ ก็สามารถ​ comment กันไว้ที่ข้างล่างได้เลยครับ แล้วพบกันใหม่โอกาส​หน้า สวัสดี​ครับ​