1 คะแนน โดย GN⁺ 3 시간 전 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • VPS ของ DigitalOcean ที่ใช้ Ubuntu 16.04 LTS มีปัญหาเรื่องหมดระยะซัพพอร์ตและภาระด้านความปลอดภัย แต่ก็ยังคง uptime ได้ถึง 1491 วันก่อนปลดระวาง
  • เซิร์ฟเวอร์ใหม่ย้ายไปใช้ Hetzner VPS ในเยอรมนีพร้อม FreeBSD 14.3 และได้สเปกแรงกว่าเซิร์ฟเวอร์เดิมราคา $13/เดือน โดยจ่ายไม่ถึง 6 ยูโรต่อเดือน
  • ใช้ Jails และ Bastille เพื่อสร้างสภาพแวดล้อมแยกตามแต่ละเว็บไซต์ โดย Caddy Jail รับหน้าที่ SSL และ reverse proxy ก่อนส่งต่อไปยังแต่ละ nginx Jail
  • ในการทดสอบโหลด เซิร์ฟเวอร์ FreeBSD ใหม่มี throughput สูงกว่า 3 ถึง 11 เท่า หลังปรับ kern.ipc.somaxconn เพื่อรองรับการเชื่อมต่อพร้อมกัน 10,000 รายการ
  • การย้ายระบบต้องเรียนรู้เรื่อง เครือข่าย และการตั้งค่า FreeBSD แต่ด้วยการตั้งค่าแบบรวมศูนย์และเอกสารที่มีคุณภาพ ทำให้ตั้งระบบได้ง่ายกว่าที่คาด

ที่มาของการย้ายระบบ

  • บล็อกเดิมรันอยู่บน DigitalOcean VPS มานานกว่า 10 ปี และใช้ Ubuntu 16.04 LTS ในดาต้าเซ็นเตอร์นิวยอร์ก
    • Ubuntu 16.04 LTS หมดการซัพพอร์ตมาตั้งแต่อย่างน้อย 5 ปีก่อน และไม่สามารถรับอัปเดตจากคลังแพ็กเกจ apt ได้อีก
    • ระบบเก่ามีความเสียเปรียบด้านความปลอดภัย และก่อนหน้านี้บล็อก WordPress อีกตัวหนึ่งเคยถูกโจมตีแทรกลิงก์คาสิโนและการพนันบน VPS เก่า
  • นอกจากบล็อกแล้ว เซิร์ฟเวอร์เดิมยังให้บริการอีกหลายเว็บไซต์ แต่ส่วนใหญ่เป็น เว็บไซต์แบบ static
    • แม้แต่บล็อกที่ได้รับความนิยมมากที่สุดก็ปกติอยู่ที่ระดับไม่กี่พัน pageview ต่อเดือน และแทบไม่มีทราฟฟิกสูงมาก ยกเว้นบางบทความที่ไวรัลบน Hacker News
    • เซิร์ฟเวอร์ให้บริการไฟล์ static ด้วย nginx/1.10.3 และตั้งค่าแยกตามเว็บไซต์ไว้ใน /etc/nginx/sites-available
    • บล็อกสร้างด้วย Hugo และขั้นตอน deploy เดิมคือ เขียนบนเครื่อง local → commit และ push ไปยัง repository → SSH เข้าเซิร์ฟเวอร์ → pull repository → รัน hugo
  • เดิมที VPS เครื่องนี้ยังถูกใช้สำหรับการทดสอบและเขียนโปรแกรม จึงมีซอฟต์แวร์เก่าหลงเหลืออยู่มาก
    • ถึงอย่างนั้นมันก็ยังทำงานได้ปกติ และตอนปลดระวางมี uptime 1491 วัน หรือราว 4 ปีโดยไม่ต้องรีบูต
  • เซิร์ฟเวอร์ใหม่ย้ายไปใช้ Hetzner VPS ในเยอรมนี ซึ่งสเปกดีกว่าเดิมแต่ค่าใช้จ่ายต่อเดือนต่ำกว่าครึ่ง
    • เซิร์ฟเวอร์เดิมของ DigitalOcean มี RAM 2GB, vCPU 1 ตัว, ดิสก์ 50GB, ทราฟฟิกต่อเดือน 2TB และราคา $13/เดือน
    • เซิร์ฟเวอร์ที่ถูกที่สุดของ Hetzner ก็ยังมีหน่วยความจำและ CPU เป็นสองเท่าของเดิม พื้นที่เก็บข้อมูลน้อยลงเล็กน้อย แต่ทราฟฟิกมากกว่า 10 เท่า
    • สเปก Hetzner ที่เลือกใช้สุดท้ายแรงกว่าเดิมในราคาไม่ถึง 6 ยูโรต่อเดือน

เหตุผลที่เลือก FreeBSD

  • เลือก FreeBSD เพราะต้องการลองใช้ระบบใหม่ในสภาพแวดล้อม production จริง
    • ข้อดีที่ถูกยกมาคือการออกแบบแบบบูรณาการ ความเสถียร ความปลอดภัย และ Jails
  • Jails คือความสามารถด้าน virtualization/containerization ที่มีอยู่ใน FreeBSD มานานกว่า 25 ปี
    • สามารถรัน “มินิซิสเต็ม” ในลักษณะ sandbox ที่ไม่สามารถเข้าถึง host system ได้
    • ขณะที่โซลูชันคอนเทนเนอร์อย่าง Docker เหมาะกับการแพ็กโปรแกรมและมีลักษณะชั่วคราวหรือ immutable มากกว่า แต่ Jails ถูกใช้งานใกล้เคียงกับ subsystem หรือ mini VM ที่แชร์ kernel เดียวกัน
  • ZFS ก็เป็นตัวเลือกที่น่าสนใจสำหรับไฟล์ซิสเต็มฝั่งเซิร์ฟเวอร์
    • มีทั้งความสามารถด้าน data integrity และ snapshot และมีบางส่วนคล้าย Btrfs ฝั่ง Linux
    • ZFS ถูกมองว่าสุกงอมกว่า Btrfs มาก และหากทำ snapshot บ่อย ๆ ก็อาจพึ่งพาระบบ snapshot/backup แบบเสียเงินของผู้ให้บริการ VPS น้อยลงได้
  • โครงสร้างเป้าหมายคือให้แต่ละเว็บไซต์มี Jail ของตัวเอง และในแต่ละ Jail มีทั้งเครื่องมือ build ที่จำเป็นและ nginx
    • Jail สำหรับเมนเว็บเซิร์ฟเวอร์จะรับบทเป็น reverse proxy ที่เชื่อมต่อกับภายนอก
    • หาก Jail ใดถูกเจาะ ก็ออกแบบให้สามารถลบแล้วสร้างใหม่ได้

การติดตั้ง FreeBSD และการนำ Bastille มาใช้

  • หน้าสร้าง VM ของ Hetzner มีอิมเมจระบบปฏิบัติการพื้นฐานให้เลือกค่อนข้างจำกัด จึงไม่เห็น BSD โดยตรง
  • เลือกใช้ Bastille เพื่อให้การจัดการ Jails ทำได้ง่ายขึ้น
    • หลายขั้นตอนที่ต้องทำเองในการสร้าง Jail สามารถจัดการผ่านคำสั่ง bastille ได้
    • ตัวอย่างคำสั่งคือ bastille list, bastille create, bastille console
    • การติดตั้งและเปิดใช้งานทำตาม เอกสารเริ่มต้นของ Bastille
pkg install bastille
sysrc bastille_enable="YES"

เครือข่ายและโครงสร้าง reverse proxy

  • สแตกทั้งหมดใช้ Caddy Jail ตัวเดียวจัดการทุกโดเมนและใบรับรอง SSL แล้ว reverse proxy ทราฟฟิกไปยัง Jail ของแต่ละเว็บไซต์
    • Jail ของแต่ละเว็บไซต์มีเฉพาะเครื่องมือที่จำเป็นต่อการ build และให้บริการไซต์นั้น
    • โครงสร้างนี้มองได้คล้ายกับการมีหลาย virtual machine อยู่ในเครือข่ายเดียวกัน
  • สร้าง virtual network interface ภายในชื่อ bastille0
sudo sysrc cloned_interfaces+="lo1"
sudo sysrc ifconfig_lo1_name="bastille0"
sudo service netif cloneup
sudo sysrc ifconfig_bastille0="inet 10.0.0.1 netmask 255.255.255.0"
  • เป็นการ clone loopback interface ตั้งชื่อเป็น bastille0 และกำหนดเครือข่าย 10.0.0.1/24
  • Jail ต่าง ๆ จะทำงานอยู่บน network interface นี้
  • คำขอ HTTP/HTTPS จากภายนอกจะถูกส่งต่อไปยัง Caddy Jail ผ่านกฎของ PF(Packet Filter)
    • ใน /etc/pf.conf มีการตั้งค่า external interface vtnet0, internal interface bastille0 และ tailscale1
    • ทราฟฟิกพอร์ต 80, 443 จะถูก redirect ไปยัง 10.0.0.5 ซึ่งเป็น Caddy server
ext_if = "vtnet0"
int_if = "bastille0"
vpn_if = "tailscale1"
set skip on $int_if
set skip on $vpn_if
nat on $ext_if from 10.0.0.0/24 to any -> ($ext_if)
rdr pass on $ext_if proto tcp from any to any port {80, 443} -> 10.0.0.5
block all
pass out quick on $ext_if keep state
  • เปิดใช้งาน PF และ gateway ด้วยคำสั่งต่อไปนี้
sysrc pf_enable="YES"
service pf start
sysrc gateway_enable="YES"

การตั้งค่า Caddy และ Jail รายเว็บไซต์

  • เดิมทีเซิร์ฟเวอร์เก่าใช้ nginx มานาน แต่ในโครงสร้างใหม่เลือก Caddy เพื่อให้การจัดการใบรับรอง SSL เป็นอัตโนมัติ
    • ในสภาพแวดล้อม nginx เดิมต้องต่ออายุใบรับรองด้วย certbot เป็นระยะ และเคยลืมต่ออายุหลายครั้ง
  • ก่อนสร้าง Caddy Jail ต้อง bootstrap FreeBSD release ให้ Bastille ก่อน
bastille bootstrap 14.3-RELEASE
  • สร้าง Caddy Jail ด้วย IP 10.0.0.5
bastille create caddy 14.3-RELEASE 10.0.0.5 bastille0
bastille start caddy
  • ชื่อ Jail คือ caddy, release คือ 14.3-RELEASE, interface คือ bastille0
  • สามารถใช้ bastille list เพื่อตรวจสอบสถานะ และใช้ bastille console caddy เพื่อเข้าเชลล์ภายใน Jail
  • ติดตั้ง Caddy และเปิดใช้บริการจากภายใน Jail
pkg install caddy
sysrc caddy_enable="YES"
service caddy start
  • ไฟล์ตั้งค่า Caddy อยู่ที่ /usr/local/etc/caddy/Caddyfile ภายใน Jail
    • หากต้องการจัดการไฟล์ตั้งค่าจากฝั่ง host สามารถ mount ไดเรกทอรีของ host เข้าไปใน Jail ได้
    • ในตัวอย่างใช้ nullfs พร้อมตัวเลือกอ่านอย่างเดียว ro เพื่อไม่ให้ Caddy แก้ไขไฟล์ตั้งค่า
bastille mount caddy /usr/local/etc/my-caddy-config /usr/local/etc/caddy nullfs ro 0 0

การ deploy เว็บไซต์และบล็อก

  • เว็บไซต์แรกที่ deploy คือ es.cro.to และจัดการ repository ของเว็บไซต์ผ่าน GitHub repository
    • เก็บ repository ไว้ที่ /usr/local/www/escroto บน host และ mount ไดเรกทอรีนี้เข้าไปใน site Jail แบบอ่านอย่างเดียว
    • ทุกเว็บไซต์ถูกจัดระเบียบให้อยู่ใต้ /usr/local/www บน host
  • สร้าง Jail ชื่อ escroto ด้วย nginx Bastille template
bastille bootstrap https://github.com/bastillebsd/templates
bastille create escroto 14.3-RELEASE 10.0.0.11 bastille0
bastille template escroto www/nginx
  • กำหนด IP เป็น 10.0.0.11
  • หน้าเริ่มต้นของ nginx อยู่ที่ /usr/local/www/nginx ตามธรรมเนียมของ FreeBSD
  • mount ไดเรกทอรีเว็บไซต์จาก host เข้าไปใน Jail แบบอ่านอย่างเดียว
bastille mount escroto /usr/local/www/escroto /usr/local/www/escroto nullfs ro 0 0
  • ใช้สคริปต์ deploy เพื่อป้องกันไม่ให้ไดเรกทอรี .git ของ repository ถูกเสิร์ฟผ่านเว็บ
rm -fr /usr/local/www/nginx/*
cp -R /usr/local/www/escroto/* /usr/local/www/nginx/
rm -fr /usr/local/www/nginx/.git
  • การ deploy เวอร์ชันใหม่ทำโดยอัปเดต repository บน host แล้วรันสคริปต์ deploy ภายใน Jail
cd /usr/local/www/escroto
git pull
bastille cmd escroto /root/deploy.sh
  • การตั้งค่า Caddy จะ redirect cro.to ไปยัง es.cro.to แบบถาวร และ proxy es.cro.to ไปยัง 10.0.0.11
cro.to {
    redir https://es.cro.to{uri} permanent
}
es.cro.to {
    reverse_proxy 10.0.0.11
}
  • บล็อกใช้ Hugo และจัดการผ่าน GitHub repository
    • clone repository ไว้ที่ /usr/local/www/blog บน host
    • สร้าง blog Jail ในลักษณะคล้าย escroto และกำหนด IP เป็น 10.0.0.12
bastille create blog 14.3-RELEASE 10.0.0.12 bastille0
bastille template blog www/nginx
bastille mount blog /usr/local/www/blog /usr/local/www/blog nullfs ro 0 0
  • ติดตั้ง Hugo ภายใน blog Jail
bastille pkg blog update
bastille pkg blog install gohugo
  • สคริปต์ deploy ของบล็อกจะล้าง nginx web root แล้วสร้างผลลัพธ์ของ Hugo ไปที่ /usr/local/www/nginx
rm -fr /usr/local/www/nginx/*
cd /usr/local/www/blog
hugo -d /usr/local/www/nginx
  • ก่อนย้าย DNS ใช้ crocidb.cro.to ชี้ไปยังเซิร์ฟเวอร์บล็อกใหม่เพื่อทดสอบแทนโดเมนเดิม
crocidb.cro.to {
    reverse_proxy 10.0.0.12
}

เบนช์มาร์กและการทดสอบโหลด

  • ก่อนเปลี่ยน DNS record ได้เปรียบเทียบความสามารถในการรับโหลดระหว่างเซิร์ฟเวอร์เดิม crocidb.com กับเซิร์ฟเวอร์ใหม่ crocidb.cro.to
    • ผู้เข้าชมบล็อกส่วนใหญ่มาจากอเมริกาเหนือ รองลงมาคือยุโรปและอเมริกาใต้ ดังนั้น latency ไปยังเซิร์ฟเวอร์ใหม่ในเยอรมนีอาจเพิ่มขึ้นเล็กน้อยสำหรับผู้ใช้บางส่วน
    • ประเด็นหลักที่สนใจคือความเร็วในการให้บริการเว็บไซต์ static และความสามารถในการทนโหลดสูง
  • มีการใช้เครื่องมือออนไลน์ฟรีอย่าง GTMetrix, Pingdom, WebPageTest ด้วย แต่ความต่างของสองเซิร์ฟเวอร์ส่วนใหญ่เห็นชัดแค่ในเรื่อง latency
  • ใช้ wrk และ hey เป็นเครื่องมือเบนช์มาร์กโหลด HTTP
    • ทั้งสองตัวสามารถสร้างคำขอพร้อมกันจำนวนมาก และเก็บข้อมูลอย่าง latency, error response และ throughput ต่อวินาที
  • เมื่อรัน wrk จาก VPS อีกเครื่องใน Hetzner เดียวกัน เซิร์ฟเวอร์ใหม่ทำผลงานเหนือกว่าอย่างชัดเจน
wrk -t4 -c100 -d30s --latency https://crocidb.com/
  • ตัวเลือกคือ 4 threads, การเชื่อมต่อพร้อมกัน 100 รายการ และรัน 30 วินาที
  • เซิร์ฟเวอร์เดิมมี average latency 89.63ms, requests per second 833.41, throughput 8.29MB/s
  • เซิร์ฟเวอร์ใหม่มี average latency 6.75ms, requests per second 12260.10, throughput 130.80MB/s
  • เครื่องที่ใช้ทดสอบอยู่ในดาต้าเซ็นเตอร์เดียวกับเซิร์ฟเวอร์ใหม่ จึงไม่ใช่การเปรียบเทียบที่ยุติธรรมนัก
  • ยังลองรัน wrk ผ่าน Proton VPN จากหลายภูมิภาค แต่ผลลัพธ์ต่ำกว่าที่คาด
    • ค่าเฉลี่ยของเซิร์ฟเวอร์เดิมอยู่ที่ประมาณ 300 requests/s ส่วนเซิร์ฟเวอร์ใหม่อยู่ที่ประมาณ 800 requests/s
    • สุดท้ายจึงเปลี่ยนจากการใช้ VPN สำหรับผู้ใช้ทั่วไป ไปเป็นการสร้าง VPS จริงในหลายภูมิภาคแทน

การทดสอบตามภูมิภาคด้วย Vultr VPS

  • เลือก Vultr เพื่อให้ใช้อินฟราสตรักเจอร์ต่างจาก DigitalOcean และ Hetzner ที่เป็นที่ตั้งของเซิร์ฟเวอร์
    • เนื่องจากภาระในการทำงานแบบ manual จึงจำกัดภูมิภาคไว้ 4 แห่งคือ London, São Paulo, Silicon Valley, Tokyo
    • สร้าง Fedora VM รุ่นที่ถูกที่สุดในแต่ละภูมิภาคแล้วใช้รันทดสอบ
  • สุดท้ายตัดสินใจว่า hey เหมาะกับการทดสอบมากกว่า
./hey_linux_amd64 -n 1000000 -c 10000 -t 10 -z 5m -h2 https://crocidb.com/ > crocidb.com.log
./hey_linux_amd64 -n 1000000 -c 10000 -t 10 -z 5m -h2 https://crocidb.cro.to/ > crocidb.cro.to.log
  • การตั้งค่าคือคำขอรวม 1,000,000 ครั้ง, concurrency 10,000, timeout 10 วินาที, เวลารวม 5 นาที และใช้ HTTP/2
  • เป็นโหลดที่สูงกว่าทราฟฟิกบล็อกจริงมาก
  • ในการรันครั้งแรก เซิร์ฟเวอร์ FreeBSD ใหม่รับ การเชื่อมต่อพร้อมกัน 10,000 รายการ ไม่ไหวและล้มเหลวตั้งแต่ช่วงต้น
    • เมื่อตรวจสอบขนาด socket queue ด้วย netstat -Lan พบว่าทั้งหมดเป็น 128
    • ค่าเริ่มต้น kern.ipc.somaxconn คือ 128 จึงเพิ่มเป็นดังนี้
sysctl kern.ipc.somaxconn=16384
  • ในการทดสอบจาก São Paulo ทั้งสองเซิร์ฟเวอร์ตอบกลับด้วย error จำนวนมาก แต่เซิร์ฟเวอร์ FreeBSD รับมือกับ 1,000,000 requests ตามที่ตั้งใจไว้ได้ ขณะที่เซิร์ฟเวอร์ Ubuntu เดิมยังตอบกลับไม่ถึง 20,000 requests
    • เซิร์ฟเวอร์ Ubuntu เดิมทำสำเร็จเพียงประมาณ 7% ของคำขอทั้งหมด
    • เซิร์ฟเวอร์ FreeBSD ใหม่ทำสำเร็จประมาณ 94%
    • ที่ Tokyo อัตราความสำเร็จของเซิร์ฟเวอร์ใหม่ลดลงเล็กน้อย แต่ยังไม่ถึงขั้นน่ากังวลมาก
  • เมื่อวัดด้วย requests per second เซิร์ฟเวอร์ใหม่ดีกว่าเดิมอย่างน้อย 3 เท่า และมากสุด 11 เท่า
    • ในส่วน latency percentile เซิร์ฟเวอร์ใหม่เพิ่มขึ้นค่อนข้างเป็นเส้นตรงจนถึงราวจุด 90% ทำให้คาดการณ์พฤติกรรมได้มากกว่า
    • แม้อยู่ภายใต้โหลดสูง ผู้ใช้ส่วนใหญ่ทั่วโลกก็ยังสามารถรับเนื้อหาหน้าแรกของบล็อกได้ในเวลา ต่ำกว่า 3.5 วินาที
  • ผลลัพธ์จาก Tokyo ไม่ได้ถูกวิเคราะห์เชิงลึก
    • การวิเคราะห์ตามช่วงของคำขอใน hey ชี้ว่าทราฟฟิกไปญี่ปุ่นอาจช้ากว่า
    • ค่า DNS dial-up/lookup ของโดเมนที่สองดูต่ำผิดปกติ และอาจมีผลจาก CNAME record
    • ค่า resp wait และ resp read ก็สูงผิดปกติเช่นกัน แต่เนื่องจากนับเฉพาะคำขอที่สำเร็จ จึงอาจเป็นไปได้ว่าเซิร์ฟเวอร์เดิมตอบสนองเร็วในช่วงแรก แล้วแทบจะกันคำขอใหม่ออกไปในช่วงหลัง

การสลับใช้งานจริงและบทเรียนสำคัญ

  • แม้เบนช์มาร์กจะยังตอบได้ไม่ครบทุกประเด็น แต่ผลลัพธ์ก็เป็นที่น่าพอใจพอที่จะสลับ DNS record ไปยังเซิร์ฟเวอร์ใหม่
    • จากนั้นบล็อกนี้จึงให้บริการอย่างเป็นทางการบนเซิร์ฟเวอร์ Hetzner ที่ใช้ FreeBSD
  • การตั้งเครื่องโฮสต์เว็บไซต์บน FreeBSD ต้องผ่านการทดลอง แก้ไข build และล้มเหลวอยู่หลายชั่วโมง แต่ไม่ได้ซับซ้อนอย่างที่คิด
    • หากต้องการก็สามารถเลือกใช้บริการเว็บโฮสติ้งที่ตรงตามเงื่อนไขได้ เช่น OpenBSD Amsterdam
    • หรือจะใช้ Proxmox เพื่อจัดการคอนเทนเนอร์และแดชบอร์ดบริหารก็ได้
    • ฝั่งทางเลือกของ FreeBSD ยังมี Sylve ถูกกล่าวถึงด้วย
    • อย่างไรก็ดี การประกอบระบบเองให้ประสบการณ์เรียนรู้มาก จึงถือว่าเป็นทางเลือกที่น่าพอใจ
  • เซิร์ฟเวอร์ Ubuntu เดิม ก็แข็งแกร่งมากเช่นกัน
    • ตลอด 10 ปีมันรับภาระโหลดของเว็บไซต์ได้ดี และใน 4 ปีสุดท้ายก็ทำงานต่อเนื่องโดยไม่ต้องรีบูต
    • ทำงานได้เสถียรโดยแทบไม่ต้องลงแรงกับการตั้งค่ามากนัก
  • การตั้งค่า FreeBSD ง่ายกว่าที่คาด โดยเฉพาะแนวทางรวมศูนย์การตั้งค่าระบบไว้ในที่เดียวและคุณภาพของเอกสารออนไลน์
  • หากต้องการประกอบเครื่องโฮสต์บล็อกด้วยตัวเอง จำเป็นต้องมี ความรู้ด้านเครือข่าย ที่ไกลเกินกว่าขอบเขตที่นักพัฒนาเกมมักคุ้นเคย
    • กระบวนการเรียนรู้ระบบอื่นเป็นเรื่องสนุก และครั้งหน้าอาจลอง OpenBSD หรือ NetBSD ก็ได้
    • อย่างไรก็ดี ผู้เขียนสรุปว่าประโยชน์ใช้สอยของงานทั้งหมดนี้มีขีดจำกัด เพราะทราฟฟิกของบล็อกส่วนใหญ่มาจากการ crawl ของระบบ AI

1 ความคิดเห็น

 
GN⁺ 3 시간 전
ความคิดเห็นจาก Hacker News
  • ความผิดพลาดที่ใหญ่ที่สุดที่ฉันเคยทำคือ uptime ที่สูง
    เพราะ arjie.com รันอยู่บน Hetzner VPS มานานกว่า 10 ปี ตอนที่ Hetzner จะปิดเครื่องโฮสต์พื้นฐานนั้น ฉันก็ไม่รู้เลยว่าตัวเองตอนเป็นวัยรุ่นตั้งค่าอะไรเอาไว้บ้าง
    มีแบ็กอัปอยู่ แต่เว็บดับมา 10 ปีแล้ว
    ทุกวันนี้เลยทำทุกอย่างให้ย้ายได้ และย้ายจริงหลายครั้งเพื่อเช็กว่ามันใช้ได้

    • คำว่า “ความผิดพลาดที่ใหญ่ที่สุดคือ uptime สูง” นี่จริงมาก
      ยังจำยุคที่คนมอง uptime ของเครื่องเหมือนเหรียญเกียรติยศได้อยู่เลย
      ฉันแก่ขึ้นแต่ไม่ได้ฉลาดขึ้นเท่าไร แค่เดี๋ยวนี้ดู uptime ของบริการ แทน
      เมื่อก่อน DNS record อย่าง MX ก็มีจุดประสงค์ใกล้เคียงกัน และคลัสเตอร์ยุคเก่า ๆ ก็ซับซ้อนพอตัว แต่ก็ทิ้งบทเรียนอย่าง split brain ไว้ จนถึงทุกวันนี้ยังต้องอธิบายอยู่เรื่อย ๆ ว่าทำไมคลัสเตอร์ Proxmox แบบ 2 โหนดถึงพัง และทำไมถึงแนะนำให้เพิ่ม witness
      ที่ VMware เคยเอาปัญหาของคลัสเตอร์ HA 2 โหนดไปกลบด้วยวิธีเฉพาะหน้าก้อนใหญ่ก็ผิดตั้งแต่แรก และถ้าวิธีนั้นยังอยู่ก็น่าจะยังผิดอยู่
      uptime สูงแปลว่าไม่ได้แพตช์ และการแพตช์ก็เป็นสิ่งที่ทุกคนชอบทำกันอยู่แล้ว
    • ทำให้นึกถึง ศาลเจ้าอิเสะ ของญี่ปุ่น
      มันจะถูกรื้อแล้วสร้างใหม่ทั้งหมดทุก 20 ปี และใน Breakneck ของ Dan Wang ที่เพิ่งอ่านมาก็อธิบายว่าแนวปฏิบัติการสร้างใหม่แบบนี้ช่วยรักษาความรู้ที่ไม่อย่างนั้นอาจสูญหายไปตามกาลเวลา
      Wang เปรียบเทียบศาลเจ้าอิเสะกับ Notre Dame โดยมองว่าหนึ่งในเหตุผลที่การสร้างหลังคา Notre Dame ใหม่ยากมาก อาจเป็นเพราะความรู้สูญหายไปแล้ว
      ฉันไม่ได้คุ้นกับอาคารทั้งสองมากพอจะบอกว่านี่เป็นการเทียบที่ยุติธรรมหรือเปล่า แต่ชอบหลักการนี้
      ในหนังสือมันเป็นแค่อุปมาเล็ก ๆ แต่โดยรวมแล้วแนะนำมาก
    • uptime สูง บน VM แทบไม่มีความหมายอะไรนัก
      รีบูตไม่กี่วินาทีก็กลับมาได้ และการอัปเกรดก็ทำแบบไม่สะดุดได้ด้วยการชี้ DNS ไปยังอินสแตนซ์ใหม่
      แต่ถ้าเป็นเครื่องจริงที่โคลนได้ไม่ง่าย เรื่องจะต่างออกไป
    • ฉันเริ่มเอาคอนฟิกไปเก็บไว้ใน Ansible playbook repository ขนาดใหญ่
      ไม่จำเป็นต้องให้ทุกอย่างถูกจัดการด้วย Ansible แบบเต็มรูปแบบ ส่วนใหญ่ฉันใส่แค่คอนฟิกเริ่มต้นไว้ตรงนั้น และยังมีอะไรที่จัดการด้วยมืออีกเยอะ
    • บางครั้งก็เขียน Architectural Decision Records ให้โปรเจกต์ส่วนตัวด้วย
      ฟังดูตลกนิดหน่อย แต่ช่วยได้บ่อยกว่าที่คิด
  • งานส่วนตัว/งานอดิเรกโดยมากฉันรันด้วยชุด Caddy หน้าเว็บ + Docker Compose
    ถ้าเป็นเว็บง่าย ๆ Caddy ก็เสิร์ฟคอนเทนต์เอง ส่วนถ้าเป็น “เว็บแอป” ก็แทบทั้งหมดจะถูกทำเป็นคอนเทนเนอร์ แล้วให้ Caddy ทำ TLS termination และ reverse proxy ไปยังแอปที่อยู่ใต้ Docker
    ปกติจะใช้โครงสร้าง ~/apps/appname และในแต่ละไดเรกทอรีของแอปจะมีไฟล์ Docker Compose กับไดเรกทอรีข้อมูลที่เมานต์ไว้
    หลัง compose down ก็สามารถดึงข้อมูลออกด้วย (s)ftp เพื่อเก็บระยะยาวหรือย้ายไซต์/บริการได้
    เมื่อก่อนเคยรันหลาย VM บน dedicated server แต่ย้ายไปเป็น VPS แยกของ OVH แล้ว และถ้าจะรันเมลบน OVH ต้องหลีกเลี่ยง local zone VM ที่ไม่อนุญาตเมลโฮสติ้ง
    ทั้งนี้ก็ขึ้นกับสภาพแวดล้อม

    • ฉันเริ่มใช้ Traefik กับโปรเจกต์หนึ่ง และมันเป็นการอัปเกรดที่ดีกว่า nginx proxy manager
      NPM ก็ดีมากและเว็บ GUI ก็โอเค แต่ Traefik แค่เขียนสิ่งที่ต้องการลงในไฟล์ Docker Compose ก็จบ
    • เซ็ตอัปที่บ้านฉันก็คล้ายกัน
      แค่ใช้ Unraid รันคอนเทนเนอร์ และมีตัวหนึ่งเป็นเครื่องมือสาย nginx ที่ออกแบบมาให้ทำ reverse proxy ให้บริการอื่น ๆ
    • ฉันก็ทำเกือบเหมือนกัน
      เพียงแต่กำลังคิดว่าจะย้ายจาก Debian ไปทางระบบ/OS แบบ immutable และเน้นคอนเทนเนอร์ก่อน อย่าง Flatcar ดีไหม
      FreeBSD มีข้อได้เปรียบทางเทคนิคที่น่าสนใจ แต่จะชอบหรือไม่ก็ตาม ค่าเริ่มต้นของซอฟต์แวร์โอเพนซอร์สจำนวนมากคือ Docker และฉันก็ไม่มีทั้งเวลาและแรงจูงใจจะย้ายทุกอย่างไปเป็น FreeBSD jail
  • เมื่อไม่กี่สัปดาห์ก่อนฉันก็ทำแบบเดียวกัน
    เซิร์ฟเวอร์ไม่ได้อัปเดตมาตั้งแต่ราวปี 2015 และยังมี Ghost blog กับ node 0.10 จากยุคนั้นติดตั้งอยู่
    ของฉันใช้วิธีดิบกว่านั้น คือทำแบ็กอัปไว้แล้วปล่อย Hermes agent (Gemini 3.1 Pro) ลุยเลย
    มันจัดการอัปเกรดและแพตช์ที่จำเป็นทั้งหมด แล้วก็ย้ายไปยังสิ่งที่รองรับล่าสุดด้วย
    หลังจากนั้นยังมีการ harden เซิร์ฟเวอร์และลบบริการที่ไม่ใช้ไปอีกพอสมควร และถ้าไม่มี AI ช่วย ก็คงจะผัดวันประกันพรุ่งต่อไป

    • ต่อให้ไม่มี AI การอัปเดตก็ทำได้ง่ายมากอยู่แล้ว
      ปัญหาจริงคือความเสี่ยงที่อะไรบางอย่างจะพัง และสิ่งที่ช่วยลดความเสี่ยงนั้นก็คือ แบ็กอัป
  • การใช้ FreeBSD บนเซิร์ฟเวอร์ส่วนตัวเคยเป็นประสบการณ์ที่สนุกมาก
    มันมีความเท่ สะอาด เรียบง่าย และให้อารมณ์แบบ “พังก์ร็อก”
    แต่สุดท้ายก็เลิกใช้เพราะจุดเจ็บหลัก ๆ: PM2 มีบั๊กบน FreeBSD และมันเป็นเครื่องมือที่ใช้จัดการโปรเซส, เลยพยายามใช้ rc.d รัน daemon แทนแต่การตั้งค่า log ยากเกินไป, ส่วนไฟร์วอลล์ก็มีอะไรให้ตั้งเองเยอะมากถ้าจะให้ตรงกับแนวปฏิบัติด้านความปลอดภัย เช่นจะจัดการ ICMP ยังไง และก็คิดถึงเทมเพลตสำเร็จรูปแบบค่าปริยายของ UFW

    • FreeBSD ก็มีเทมเพลตค่าเริ่มต้นแบบนั้นรวมมาให้เหมือนกัน
      แค่ทำด้วย IPFW แทน PF
      ดูคีย์ firewall_type ใน rc.conf ได้ที่: https://cgit.freebsd.org/src/tree/libexec/rc/rc.conf?id=8e08...
      ถ้าจะตั้งไฟร์วอลล์แบบเครื่องเดียวให้ง่าย ๆ ใช้ firewall_type=client ได้ หรือถ้าจะโฮสต์อะไรสักอย่างก็ใช้ firewall_type=workstation
      แบบหลังจะมี firewall_myservices และ firewall_allowservices ควบคุมว่าจะเปิดพอร์ตไหน และเครือข่าย/IP ไหนเข้าถึงได้
      ถ้าเป็น NAT gateway ง่าย ๆ ก็ใช้ firewall_type=simple กับ firewall_simple_(iif|inet|oif|onet)(_ipv6)? เพื่อกำหนดชื่ออินเทอร์เฟซฝั่ง ISP/ฝั่งภายใน และช่วงเครือข่าย IPv4/IPv6 ได้
      รายละเอียดว่าแต่ละตัวเลือกทำอะไรเป๊ะ ๆ ดูได้จากการอิมพลีเมนต์ใน /etc/rc.firewall: https://cgit.freebsd.org/src/tree/libexec/rc/rc.firewall?id=...
    • สงสัยว่าใช้ PM2 เพื่อทำ supervision หรือเปล่า
      สำหรับ log ของ daemon ใน rc.d ถ้าเป็นข้อความธรรมดาตามวิถียูนิกซ์ก็ใช้ logger(1) ได้ หรือจะ redirect ลงไฟล์แล้วใช้ newsyslog(8) จัดการขนาดไฟล์ก็ได้
      เรื่องไฟร์วอลล์ขอแนะนำ The Book of PF[0]
      PF บน FreeBSD มีความต่างด้านไวยากรณ์จาก pf ของ OpenBSD แต่ก็ยังดีพอสำหรับทำความเข้าใจว่าไฟร์วอลล์ทำงานอย่างไร และควรเขียนกฎแบบไหน
      [0]: https://nostarch.com/book-of-pf-4e
    • PM2 มีบั๊กไม่ว่าคุณจะใช้มันบน OS ไหน
      ตอนแรกมันดูสะดวกมาก แต่ขณะเดียวกันก็เป็นซอฟต์แวร์ที่น่าใช้งานแบบหงุดหงิด และตอน deploy เรื่อง การอัปเดต environment variable ก็ไม่เคยทำงานอย่างที่ตั้งใจเลยสักครั้ง
    • ปัญหาใหญ่ของฉันคือมันทนไฟดับไม่ได้
      ถ้าไฟดับ พอบูตกลับมาจะบังคับให้ไปรัน fsck กับไฟล์ซิสเต็มด้วยมือ
  • ออกนอกเรื่องนิดหน่อย แต่ตอนนี้ Linux distro ฟรีตัวไหนมี รอบการซัพพอร์ต ยาวที่สุดกันแน่
    ช่วงหนึ่งฉันใช้ CentOS 7 กับ VM เล็ก ๆ เพราะมีอัปเดตความปลอดภัยให้นานมาก และความเสี่ยงที่อะไรจะพังจากการอัปเดตก็น้อยที่สุด
    พอลองหาดูก็เหมือนว่าตอนนี้ Alma/Rocky Linux น่าจะเป็นตัวเลือกที่ดีที่สุด และมีซัพพอร์ต 10 ปี
    แต่ก็ยังสงสัยว่าได้รับการดูแลดีแค่ไหน

    • ฉันเองก็เคยรัน CentOS บนเซิร์ฟเวอร์มานานกว่า 10 ปี โดยหวังความนิ่งระยะยาวและความสบายใจ
      แต่พอเวลาผ่านไปนานขนาดนั้น ecosystem ก็ drift ไปมาก และการคงให้แอปพลิเคชันบน OS นั้นทันสมัยและยังรันได้ก็ยิ่งยากขึ้นเรื่อย ๆ
      แพ็กเกจโครงสร้างพื้นฐานอย่าง glibc, ชุด Python/Apache, GCC ค่อย ๆ เข้ากันไม่ได้กับแอปสแต็กล่าสุด
      การอัปเกรดเวอร์ชันครั้งหลังก็ทรมานเช่นกัน ไม่ใช่แค่เพราะฉันต้อนตัวเองจนมุมด้วยการผสมแพ็กเกจแปลก ๆ แต่เพราะเส้นทางอัปเกรดเองก็เป็นแบบพยายามให้ดีที่สุดมาโดยตลอด
      เหมือนฉันจะยอมแพ้ตอนข้ามจาก 6 ไป 7 และสุดท้ายก็ตระหนักว่าสิ่งที่ฉันต้องการจริง ๆ คือ Fedora
      ถ้าอัปเดตทุกปีหรือทุกครึ่งปี ก็ไม่ต้องสู้กับแพ็กเกจของ distro, คอนฟิกก็ทันสมัยและใช้งานได้, การอัปเกรด distro หลักก็ราบรื่น และ downtime ก็น้อยมาก
      ฉันไม่คิดจะกลับไปใช้ “server distro” อีกแล้ว
    • ตอนนี้ Alma ไม่ได้เข้ากันกับซอร์สของ RHEL แบบเป๊ะแล้ว เลยมีพื้นที่ให้ขยับนิดหน่อย
      เช่นอาจออกอัปเดตเคอร์เนลเพื่อแก้ ช่องโหว่ยกระดับสิทธิ์ ได้เร็วกว่า
      ส่วน Rocky ก็รับมือด้วยการมีคลังความปลอดภัยเสริมแบบเลือกใช้ซึ่งให้การบรรเทา exploit ระหว่างรอของจาก RHEL ลงมา
      ถ้ามองจากเหตุการณ์ล่าสุด ทั้งคู่ก็ดูเหมือนได้รับการดูแลค่อนข้างดี
    • ฉันไม่ค่อยเห็นเหตุผลที่จะไม่ใช้ rolling-release distro บนเซิร์ฟเวอร์ส่วนตัว
      ให้ทุกบริการรันในคอนเทนเนอร์ แล้วปล่อยให้ OS ฐานอัปเดตอัตโนมัติบ่อยเท่าที่จำเป็นก็พอ
      ฉันเลือก openSUSE MicroOS และเพราะมันอัปเดตกับรีบูตแทบทุกวัน เลยค่อนข้างมั่นใจว่าเซิร์ฟเวอร์ยังแข็งแรงดี
      เป็น atomic update ด้วย ดังนั้นถ้ามีอะไรพังก็แค่กดปุ่ม rollback ใน Cockpit แล้วค่อยกลับมาดูตอนมีเวลาได้
    • มันเหมือนพนันว่าสิ่งที่คุณโฮสต์จะอยู่ไม่ยาวเกินรอบอัปเกรด
      เพราะสุดท้ายพอถึงเวลาต้องอัปเกรดจริง ก็มักจะเจ็บหนักพอตัว
      ฉันคิดว่าการกระโดดเวอร์ชันเล็ก ๆ บ่อย ๆ ดีกว่าการปล่อยไว้นานจนทุกอย่างเปลี่ยนหมดแล้วค่อยกระโดดครั้งใหญ่
    • ถ้าต้องการฟรีแบบสุด ๆ หรือมีเครื่องจำนวนมาก Alma กับ Rocky ก็ตอบโจทย์
      แต่ถ้าลงทะเบียนกับ Red Hat ได้ก็มี RHEL ซึ่งให้เข้าถึงอัปเดตฟรีได้ถึง 10 เครื่องต่อบัญชีที่ลงทะเบียน
      RHEL น่าจะเสถียรที่สุดในบรรดา distro หลัก และ Alma กับ Rocky ก็เป็น downstream clone ของ RHEL โดยแก่นแท้
  • ฉันก็กำลังอยู่ในสถานการณ์เดียวกัน
    มีเซิร์ฟเวอร์เก่า 2 ตัวที่ปล่อยทิ้งไว้นาน “เกินไป” จนตอนนี้กลัวจะแตะเพื่ออัปเดต
    แต่พอเห็นดราม่าที่ Linux distro ต่าง ๆ เล่นกับเรื่องการยืนยัน/พิสูจน์อายุ ก็เริ่มคิดว่าจะย้ายหนีเหมือนกัน
    ฉันลอง Artix ด้วย แต่หลังรีสตาร์ตเมื่อสัปดาห์ก่อนมันพังไปเลย และดูเหมือนว่า kernel update ก่อนหน้านั้นจะมีอะไรผิด จนต้องหยิบ rescue ISO ออกมาใช้
    เลยเปลี่ยนเครื่องนั้นไปเป็น Devuan แต่ยังขอรอดูไปก่อน
    ยังไม่มีเรื่องให้บ่นมากนัก แต่ก็ยังอยู่ในช่วง burn-in
    บนแล็ปท็อปฉันใช้ Arch อยู่ แต่ชุมชนดูเป็นปฏิปักษ์เรื่องการเซ็นเซอร์พอสมควร เลยรอให้มีเวลาช่วงสุดสัปดาห์แล้วจะล้างลงอย่างอื่น
    ฉันไม่ต้องการ ดราม่าทางการเมือง ในซอฟต์แวร์
    ที่น่าสนใจคือครั้งนี้เป็นครั้งแรกที่ฉันซื้อแล็ปท็อปใหม่แล้วไม่เคยบูตเข้า Windows เลย แต่ลง Linux ทันที และทุกอย่างก็ “ใช้งานได้เลย”
    ยิ่งเศร้าที่พอถึงจุดที่เริ่มสนุกกับ Linux จริง ๆ ผู้เล่นรายใหญ่กลับยอมรับแนวทางที่กัดกร่อนความเป็นส่วนตัวอย่าง AI everywhere, การยืนยัน/พิสูจน์อายุ, telemetry เปิดเป็นค่าเริ่มต้น
    ฉันตั้งใจจะตอบทุกปฏิสัมพันธ์กับสิ่งพวกนั้นแบบ “ไม่เอา”

    • ฉันเคยปล่อย Ubuntu server ทิ้งไว้ 10 ปี แล้วอัปเดตมันแบบไม่เจ็บปวดภายใน 20 นาที
      ตอนนี้เซิร์ฟเวอร์นั้นก็ยังรัน LTS ล่าสุดอยู่
      ไม่รู้ว่าเริ่มจาก Ubuntu 4 หรือ 6 แต่ก็ผ่านมาได้เรื่อย ๆ แบบไม่มีปัญหา
      บางทีการอัปเกรดช้าอาจช่วยให้หลีกเลี่ยงความเจ็บปวดของคนใช้รุ่นแรก ๆ ได้
      เดี๋ยวนี้ฉันใช้ Debian มากกว่ามาก
      ในยุคที่ supply-chain attack เยอะขนาดนี้ Debian Stable เหมือนอัญมณีจริง ๆ และถึงจะมีบางแพ็กเกจที่ต้องจัดการเพิ่มเองเพราะอยากได้เวอร์ชันใหม่กว่า ฉันก็ชอบจิตวิญญาณวิศวกรรมแบบเรียบง่ายแต่หนักแน่นของมัน
    • เรื่องการยืนยัน/พิสูจน์อายุ คุณน่าจะถูกชี้นำผิดไป
    • ที่รีสตาร์ตแล้วพังเพราะ kernel update ก่อนหน้า ส่วนใหญ่เป็นปัญหาของ Arch/Artix
      ทั้งคู่เป็นฝั่งที่ตามกระแสใหม่ล่าสุดเร็วที่สุด และไม่ได้ดีที่สุดด้านเสถียรภาพเสมอไป
      แต่ก็ไม่ได้แปลว่า rolling distro จะต้องให้ทุกอย่างเป็นเวอร์ชันล่าสุดที่สุดตลอดเวลา
      ช่วงหลายเดือนมานี้ฉันใช้ Void Linux อยู่ มันเป็น rolling distro แต่ใช้ LTS kernel และก็เลือก mainline ได้ด้วย ขณะที่ผู้ดูแลให้ความสำคัญกับเวอร์ชันแอปที่เสถียรมากกว่าการอัปเดตให้เร็วสุด
    • เซิร์ฟเวอร์/VM ของฉันมักรัน FreeBSD หรือ Alpine
      และก็มี Debian บ้างในที่ที่จำเป็น เช่น Proxmox, VPS ที่ไม่รองรับ Alpine, อุปกรณ์เกี่ยวกับงานบริษัท เป็นต้น
      ยังมีเครื่องทดสอบบางตัวที่รัน Chimera แต่คงยังไม่พึ่งพามันมากจนกว่าจะมี stable release
      ช่วงนี้ก็ลองเล่น AerynOS อยู่บ้าง
    • อยากให้รอบซัพพอร์ตของ FreeBSD ยาวกว่านี้
      อายุซัพพอร์ตของแต่ละรีลีสสั้นกว่า 1 ปี ทำให้ถ้าพลาดช่วงอัปเกรดไปแล้ว การอัปเกรดภายหลังจะยากกว่า distro อื่นอย่าง Debian Stable มาก
  • ตอนนี้ย้ายงานเซิร์ฟเวอร์ไปใช้ Debian กับ Ubuntu แล้ว แต่ตอนหนุ่ม ๆ ช่วงกลางทศวรรษ 2000 ฉันเคยคลั่ง FreeBSD มาก
    สุดท้ายใช้เวลาตั้งค่าและเล่นกับมันมากกว่าทำอะไรที่เป็นประโยชน์จริง ๆ
    ตอนนั้นหาผู้ให้บริการ dedicated server หรือ VPS ที่มีสาย BSD ยากมาก และเหมือนฉันจะไปลงเอยกับ Panix.com
    ก่อนหน้านั้นก็จำได้ลาง ๆ ว่ามีบริษัทชื่อ 15MinuteServers ที่น่าจะอยู่แถว NAC ในนิวเจอร์ซีย์และมี BSD ให้ใช้
    ตอนนี้ก็แค่เล่าความหลังเฉย ๆ

    • เดี๋ยวนี้ติดตั้งกับผู้ให้บริการของฉันง่ายพอสมควร
      ฉันใช้ FreeBSD บน Hetzner กับ OVH และเมื่อก่อนก็เคยใช้ Vultr ด้วย
    • OVH มี FreeBSD template
      และผู้ให้บริการ KVM VM/VPS ส่วนใหญ่ก็ให้เข้าถึงคอนโซลและเมานต์ ISO ของผู้ใช้ได้ ดังนั้นจะติดตั้งอะไรก็ได้ตามต้องการ
  • ที่ fastfetch รายงานว่าใช้หน่วยความจำมากกว่าความจริง น่าจะเป็นเพราะ ZFS ARC
    คล้าย page cache ของ Linux คือเรียกคืนได้ทุกเมื่อ และแต่ละเครื่องมือก็เรียกมันไม่เหมือนกัน: https://www.linuxatemyram.com/

  • จำได้ว่าตอนมีคนอธิบาย Docker ให้ฟังครั้งแรก ฉันตอบไปว่า “อ๋อ หมายถึง jail ใช่ไหม?”
    อย่างที่บทความอธิบาย มันไม่ได้เหมือนกันทั้งหมด
    kqueue ก็เป็นชัยชนะครั้งใหญ่เหมือนกัน
    ต้องขอบคุณนักพัฒนา FreeBSD มากจริง ๆ
    ฉันสร้างบริษัทแรกและรันมันบน FreeBSD อยู่ 15 ปี และ uptime กับความทนทานของมันน่าทึ่งมาก

  • ฉันก็มีเซิร์ฟเวอร์ Ubuntu 16.04 ที่กลัวจะอัปเดตเหมือนกัน
    ตอนนี้ uptime อยู่ที่ 1281 วัน และพอมาถึงจุดนี้ก็รู้สึกผิดที่จะรีบูตมัน

    • ลอง dd ระบบไฟล์ไปไว้อีกเครื่อง แล้วบูตมันใน emulator อย่าง qemu เพื่อ ซ้อมใหญ่ ดูก็ได้
      แค่ต้องระวังถ้ามีอะไรที่สตาร์ตอัตโนมัติแล้วออกไปเชื่อมต่อภายนอก
    • ไม่เข้าใจว่ากลัวอะไร
      มีแบ็กอัปไม่ใช่เหรอ?
      ระบบ Debian/Ubuntu ตั้งให้อัปเดตอัตโนมัติและรีบูตเป็นประจำได้ง่ายอยู่แล้ว ดังนั้นงานดูแลด้วยมือก็จะเหลือแค่ตอนอัปเกรดเวอร์ชันใหญ่
    • เซิร์ฟเวอร์ที่เก่าที่สุดของฉันยังอยู่ที่ 8.04