สร้าง Reverse proxy แบบไม่ยากด้วย Caddy

หลายคนคงรู้จัก Webserver ชื่อดังอย่าง Ngix และ Apache แต่ตอนนี้ผมจะมาแนะนำน้องใหม่สุดนั่นก็คือเจ้า Caddy ซึ่งผมเพิ่งได้มีโอกาสได้ทดลองใช้งานจริงจัง

โดยความเฉียบของตัวนี้คือ

  • เป็น HTTP/2 มาโดยกำเนิดเลย
  • สามารถทำ HTTPS ได้แบบง่ายมาก ๆ โดยเราสามารถใช้งานตัว Let’s Encryptออก cert ให้ได้เลย เพราะ Caddy มัน built-in มาให้เรียบร้อยแล้ว
  • ง่าย… เพราะผมก็มือใหม่กับการเซ็ตพวก Webserver เจ้าตัว Caddy จะช่วยให้ชีวิตคุณง่ายขึ้นอย่างมาก ด้วย Document ที่อ่านง่ายมีการวางเนื้อหาที่ละเอียดกำลังพอเหมาะพอดี, Config ไฟล์เดียวสามารถจบงานยาก ๆ ได้ไม่กี่บรรทัด และ Syntax เจ้า config นี่มันเข้าใจได้ง่ายมาก มันส่งผลให้เราทำงานได้เร็วขึ้น เพราะเครื่องมือที่มีให้ใช้ค่อนข้างมาครบ และ เข้าใจง่าย

ตอนนี้หลายคนก็เริ่มรู้จัก Caddy กันบ้างแล้วน่ะครับ วันนี้เราจะมาลองทำ Reverse proxy กัน โดยใช้ Caddy ครับ
ซึ่งโจทย์ครั้งนี้ ผมได้หยิบเอามาจาก Blog นี้มาประยุกต์ครับ ซึ่งโจทย์เดิมผู้เขียนได้ใช้ nginx ในการทำเป็น Reverse proxy ดังรูปด้านล่าง ซึ่งวันนี้สิ่งที่เราจะได้ทำกันก็คือ

  • ใช้ Caddy มาแทน nginx เป็นตัวเชื่อมระหว่าง domain กับเว็บไซต์ของเราทั้ง 2 เว็บในเครื่อง Server เดียวกัน (สมมติว่ารันคนละ port)
  • ทำให้ domain ของเรารองรับ HTTPS ด้วย (แบบ self signed เพื่อทดลองการใช้งานคร่าว ๆ)

https://medium.com/@francoisromain/host-multiple-websites-with-https-inside-docker-containers-on-a-single-server-18467484ab95

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


เอาล่ะ ถ้าพร้อมแล้วก็เริ่มกันเลย!

  1. ทำการ clone project ตัวอย่างที่ผมได้สร้างไว้ไปที่เครื่องของตัวคุณเอง
git clone https://github.com/nitipatl/caddy-reverse-proxy

2. เข้าไปที่โฟลเดอร์นั้น เราก็จะเห็นไฟล์แบบนี้

.
├── Caddyfile
├── docker-compose.yml
├── welovecat.com
│   └── index.html
└── welovedog.com
    └── index.html
  • จะพบว่าผมจำลองว่าเรามีสองเว็บไซต์ในเครื่องเดียวกัน นั่นคือโฟลเดอร์ welovecat.com และ โฟลเดอร์welovedog.com โดยทั้ง 2 เว็บนี้ มีแค่ไฟล์ index.htmlอยู่ เพื่อที่ใช้แสดงให้เห็นว่าเราสามารถเชื่อมต่อไปยังเว็บไซต์นี้ได้แล้ว
  • ส่วน docker-compose.yml นี้ก็มีเนื้อหาดังนี้
version: '3'
 services:
  gateway:
   image: abiosoft/caddy
   command: ["-log", "stdout", "-agree", "-conf", "/etc/Caddyfile"]
   ports:
    - "443:443"
   volumes:
    - ./welovedog.com:/welovedog.com:ro
    - ./welovecat.com:/welovecat.com:ro
    - ./Caddyfile:/etc/Caddyfile:ro
    - ./data/caddy:/root/.caddy

ซึ่งผมได้เลือกใช้ image นี้ ในการทดลองครับ โดยมีการตั้งค่าให้แสดง log ต่าง ๆ ออกมาผ่าน terminal ของเราเลย, -agree คือการยอมรับการใช้งาน Let’s encryptและ สุดท้ายคือการระบุว่า Path ของ Caddy config อยู่ที่ไหน

ซึ่งจะมีการ map volume เข้าไปใน container ด้วยทั้งโฟลเดอร์เว็บไซต์ที่จำลองตอนแรก กับ ไฟล์ Config ของ Caddy เอง

ทีนี้ให้คุณลองสังเกตที่บรรทัดสุดท้ายน่ะครับ

./data/caddy:/root/.caddy

ตรงนี้ผมเจอปัญหาตอนเอาใช้งานจริง ผมได้พบว่าถ้าเราไม่ map volume ออกมาให้กับตัว Caddy มันก็จะยิงไปขอ cert ใหม่เรื่อย ๆ จาก Let’s encrypt ในทุกครั้งที่มีการ start container ใหม่ ซึ่งทำให้เราโดน limit exceed ได้ครับ

แต่สำหรับการลองใช้งาน self signed ในเครื่องเราเองนั้นก็ไม่จำเป็นต้องทำครับ เพราะ ไม่ได้มีการขอ cert ไปที่ Let’s encrypt แต่อย่างใด
ส่วนที่ผมใส่มาไว้ก็เผื่อ คุณอยากเอาไปลองทำต่อกันบนเครื่อง และ โดเมนจริง

  • เราจะมาสำรวจไฟล์ต่อมา นั่นก็คือ Caddyfile
:8081 {
    root /welovecat.com
}
:8082 {
    root /welovedog.com
}

จะเห็นว่าผมทำการจำลองว่า พอร์ต 8081 และ 8082 คือ Container ของเว็บไซต์ของเรา ซึ่งเอาจริงก็ยังไม่มีอะไรครับ แค่ให้ host files ไปที่โฟลเดอร์ตามที่ระบุด้วยคำสั่ง root ตามที่เราได้ทำการ map volume เข้าไปครับ

welovecat.com:443 {
    proxy / localhost:8081 {
        transparent
    }
    tls self_signed
}
welovedog.com:443 {
    proxy / localhost:8082 {
        transparent
    }
    tls self_signed
}

ซึ่งความเฉียบของมันก็อย่างที่เห็นครับ คุณน่าจะพอเดาได้ว่าผมทำอะไรต่อ ในส่วนถัดมานี้ก็คือการกำหนด Domain แต่ละอันว่าจะให้ proxy ชี้ไปที่ตัว port ไหนจากด้านบน จะเห็นว่าคำสั่งในการ config นั้นง่ายจริง เราสามารถทำอะไรหลายอย่างได้ด้วยไม่กี่คำสั่ง และ อ่านง่ายมากครับ
ซึ่งส่วนสุดท้ายของแต่ละอันก็คือการกำหนด tls ให้เป็นแบบ self sigend นั่นเอง สำหรับการใช้งาน HTTPS จริงให้ลองดูคำสั่งได้จากลิงค์นี้ครับ (ถ้าอยากใช้ Let’s encrypt ในการออก cert คุณก็แค่เปลี่ยนเป็น tls [email protected] ก็จบเลยครับ)


เอาล่ะ ลงมือได้แล้ว!

  1. เราเริ่มด้วยคำสั่งที่คุ้นตานั่นก็คือ docker-compose up เพื่อทำการรัน container ขึ้นมาจาก docker-compose.yml ที่เราเขียนไว้

2. ให้คุณแก้ไข Host file ของเครื่องก่อน เพื่อทำการชี้โดเมนมาที่ 127.0.0.1นั่นก็คือเครื่องเรานั่นเองครับ

ไฟล์ /etc/hosts

3. เมื่อเสร็จแล้ว ให้คุณทดลองเข้าผ่าน browser ด้วย domain ด้านบน คุณจะพบหน้าตาประมาณนี้…

อ้าว… เข้

ทำไมเข้าไม่ได้…

ไม่ต้องตกใจไป เพราะ เราออก cert แบบไม่มีใครรับรองให้นั่นแหละครับ ดังนั้นสิ่งที่เราต้องทำ… คือกด Advanced แล้วกดเลือกว่ายังไงก็จะเข้าครับ

จะเห็นว่าเราสามารถทำให้ 2 เว็บไซต์ที่อยู่ในเครื่อง Server เดียวกันแต่รันต่าง port กัน สามารถเข้าใช้งานได้ผ่าน Domain ของตัวเองด้วย Caddy กันแล้วครับ ส่วนถ้าใครอยากจะลองดูวิธีที่แสนจะซับซ้อนของ nginx ก็ให้เลื่อนไปด้านบนหาลิงค์ของ blog ที่ผมอ้างอิงโจทย์นี้มาตอนต้นน่ะครับ อิอิ


สรุป

สำหรับ Caddy ในแง่ของ Performace เท่าที่ผมหาดูก็ยังไม่สามารถเทียบได้กับ nginx แน่นอนครับ ส่วนตัวผมมองในแง่ของการ config ที่ไม่ยาก, การที่เราสามารถดูแลได้เพราะเข้าใจได้ง่าย มาประกอบด้วย ผมก็มองว่าในส่วนนี้ถือว่าคุ้มน่ะครับที่ได้ใช้งาน ผมคิดว่าถ้าระบบของคุณไม่ต้องการอะไรที่เว่อร์วังอลังการ ถ้าอยากลองอะไรที่ไม่ยากเหมือนแค่ฉีกซองมาม่าต้มน้ำร้อนแล้วนั่งรอกินได้เลย อีกทั้งยังไม่ต้องใช้ความรู้อะไรมากในเรื่องการปรับจูนอีกด้วย ทำให้เราลดเวลาในการทำงานส่วนนี้ไป มีเวลามากขึ้นในการโฟกัสงานส่วนอื่นที่สำคัญได้อีกด้วย

อ้างอิง

ไม่จำเป็นต้องหาสิ่งที่ดีที่สุด แค่หาความดีพอ ที่ พอดีกับเรามันก็เพียงพอแล้ว

ไว้เจอกันใหม่ครั้งหน้า ผมจะมาแชร์เกี่ยวกับการทำ Caddy + Codeigniter ครับ
หากมีข้อสงสัยหรือข้อเสนอแนะก็ comment มาได้ครับ จะได้แลกเปลี่ยนประสบการณ์กันครับ

 

Please follow and like us:

Comments