คำถามที่พบบ่อยเกี่ยวกับการใช้งาน ServBay ร่วมกับ Docker (FAQ)
หากคุณกำลังพัฒนาเว็บด้วย ServBay บนเครื่องของคุณ อาจต้องการใช้งานร่วมกับ Docker เพื่อสร้างสภาพแวดล้อมแบบ container เอกสาร FAQ นี้จะตอบข้อสงสัยเกี่ยวกับการตั้งค่า ServBay และ Docker ให้ทำงานร่วมกันได้บน macOS และ Windows ทั้งวิธีการเข้าถึงเว็บไซต์จากใน Docker และการใช้ ServBay เป็น Reverse Proxy รับส่งข้อมูลกับแอปพลิเคชันใน Container
Q1: ทำไม ServBay ถึงแก้ไขไฟล์ hosts
ของระบบ? และสามารถยกเลิกได้หรือไม่?
ServBay จะเพิ่ม entry ในไฟล์ hosts
เช่น mysite.servbay.demo 127.0.0.1
เพื่อให้คุณเรียกดูเว็บบนเครื่องด้วยโดเมนเฉพาะ เช่น mysite.servbay.demo
โดยที่เว็บนั้นรันอยู่ที่ 127.0.0.1
บนเครื่องคุณ
แต่เนื่องจากกลไกของ Docker จะอ่านไฟล์ hosts จากระบบหลัก (macOS หรือ Windows) ทำให้ mysite.servbay.demo
ถูก resolve ไปที่ 127.0.0.1
ภายใน container ทำให้ Docker ไปหา service อีกตัว (ใน container) ไม่ใช่ของ ServBay ตามที่คาดหวัง
กลไกสำคัญ:
- เมื่อคุณสร้างเว็บไซต์ใหม่ผ่าน ServBay แล้วกำหนดชื่อโดเมน เช่น
example.servbay.demo
ระบบจะ map โดเมนนั้นไปหา127.0.0.1
- โดยหลักการนี้จะช่วยให้เปิดเว็บด้วยชื่อโดเมนที่เป็นมิตรกับนักพัฒนา หากไม่แก้ไขไฟล์ hosts คุณจะสามารถเข้าเว็บได้แค่แบบ
http://127.0.0.1:PORT
และจะไม่สามารถใช้โดเมนที่ตั้งเองได้
สามารถยกเลิกได้หรือไม่?
โดยทฤษฎีแล้ว คุณสามารถลบ entry ที่ ServBay เพิ่มเข้าไปด้วยตัวเอง แต่จะไม่สามารถเปิดเว็บผ่านโดเมนที่ตั้งไว้โดย ServBay ได้ ซึ่งขัดกับแนวคิดของ ServBay ที่ออกแบบมาเพื่อให้งานพัฒนาง่ายขึ้น ถ้าคุณไม่ต้องการให้ ServBay จัดการ entry hosts ของชื่อโดเมนใดๆ แนะนำว่าอย่าสร้างเว็บไซต์นั้นใน ServBay
สำหรับงานพัฒนาส่วนใหญ่ การให้ ServBay จัดการไฟล์ hosts
อัตโนมัติ จะช่วยลดความซับซ้อนในการใช้งาน
Q2: จะให้ Docker Container เข้าถึงเว็บไซต์ ServBay ด้วยโดเมนที่ตั้ง (เช่น mysite.servbay.demo
) ได้อย่างไร?
เป็นข้อสงสัยยอดนิยม และต้องตั้งค่าให้ถูกต้อง เมื่อเว็บของ ServBay (เช่น mysite.servbay.demo
ที่อยู่บน host) ถ้าใน Container เรียกหา 127.0.0.1
จะไปหา service ใน container แทน
วิธีที่ผิด: ใช้ host.docker.internal
ตรงๆ เป็น Host ใน URL
ถึงแม้ Docker Desktop บน Mac หรือ Windows มี DNS name พิเศษคือ host.docker.internal
เพื่อ resolve IP เครื่อง host จากใน container แต่ ไม่แนะนำอย่างมากให้ใช้ใน URL โดยตรงเวลาจะเข้าถึงเว็บไซต์ ServBay (เช่น เข้า http://host.docker.internal/
แล้วหวังว่า system จะไปหา mysite.servbay.demo
)
เหตุผลคือ เวลาส่ง request ไปที่ ServBay (เช่น Caddy หรือ Nginx) field Host
ใน HTTP header จะเป็น host.docker.internal
ซึ่ง web server จำเป็นต้องรู้ Host ว่าจะไปหาเว็บไซต์ไหน หาก Host เป็น host.docker.internal
แทนที่จะเป็น mysite.servbay.demo
จะ route ไม่ถูก หรือถ้าเป็น HTTPS จะ เกิดข้อผิดพลาด SNI (Server Name Indication) เพราะใบรับรอง SSL ถูกออกให้กับโดเมน mysite.servbay.demo
ไม่ใช่ host.docker.internal
วิธีที่ถูกต้อง: เพิ่ม entry ให้ container รู้จักโดเมนผ่าน extra_hosts
ควรเพิ่ม entry ที่ map ชื่อโดเมนของเว็บ ServBay (เช่น mysite.servbay.demo
) ไปยัง IP ของเครื่อง host ผ่าน /etc/hosts
ของ container ทำได้ทั้งใน docker-compose หรือ docker run
ใช้
docker run
:bashdocker run --add-host=mysite.servbay.demo:host-gateway ... your_image
1(
host-gateway
คือค่าพิเศษที่ Docker จะ resolve เป็น IP ภายในของ host ส่วนใหญ่จะแทนhost.docker.internal
)ใช้
docker-compose.yml
:yamlversion: '3.8' services: myapp: image: your_image extra_hosts: - "mysite.servbay.demo:host-gateway"
1
2
3
4
5
6
เมื่อ config แล้ว ภายใน container:
- แอปที่เรียก
http://mysite.servbay.demo
หรือhttps://mysite.servbay.demo
จะ resolve ไปที่ IP ของ host บน macOS - Request จะส่งไปที่ ServBay บนเครื่อง host
- HTTP header
Host
จะถูกต้องเป็นmysite.servbay.demo
ทำให้ ServBay route ได้ถูกและออกใบรับรอง SSL ได้ (ถ้าใช้ HTTPS)
Q3: Docker Container จะเชื่อมต่อฐานข้อมูลที่ ServBay จัดการอยู่ได้อย่างไร (เช่น MySQL, PostgreSQL หรือ TCP Service อื่น)?
สำหรับบริการประเภท Database หรือ TCP Service ซึ่งไม่ขึ้นกับ Host field หรือ SNI ใช้ host.docker.internal
เป็น hostname ได้เลย สะดวกและปลอดภัย
ขั้นตอน:
- ตรวจสอบว่า service ใน ServBay (เช่น MySQL/ PostgreSQL) เปิดให้เชื่อมจาก host แล้ว (ค่าตั้งต้นเหมาะกับงาน dev)
- ภายใน container: ตั้งค่าการเชื่อมต่อฐานข้อมูลเป็น
- Host/Server:
host.docker.internal
- Port: ใช้ port ที่ตั้งค่าใน ServBay (MySQL มาตรฐานคือ
3306
, PostgreSQL คือ5432
) - User/Password: ตามที่ตั้งไว้ใน ServBay
- Host/Server:
ตัวอย่าง (เชื่อมต่อ MySQL): หาก MySQL รันอยู่ที่ 3306
ในแอปใน container สามารถตั้งค่า
- Host:
host.docker.internal
- Port:
3306
- User:
your_db_user
- Password:
your_db_password
Q4: ถ้าต้องการให้ Docker Container เชื่อถือใบรับรอง ServBay User CA ทำอย่างไร?
กรณีคุณตั้งค่าตาม Q2 แล้วใช้โดเมน (เช่น secure.servbay.demo
) และโดเมนนั้นใช้ SSL จาก ServBay User CA container ของคุณจะยังไม่ trust CA นี้ ทำให้ handshake SSL ไม่สำเร็จ
ตำแหน่งไฟล์ ServBay CA:
- ไฟล์ราก CA (Root certificate):
- macOS:
/Applications/ServBay/ssl/private/ServBay-Private-CA-ECC-Root.crt
- Windows:
C:\ServBay\ssl\private\ServBay-Private-CA-ECC-Root.crt
- macOS:
- ไฟล์ PEM รวม CA หลักและ Mozilla Root:
- macOS (ARM):
/Applications/ServBay/package/common/openssl/3.2/cacert.pem
- macOS (Intel):
/Applications/ServBay/package/common/openssl/1.1.1u/cacert.pem
- Windows:
C:\ServBay\package\common\openssl\3.3\cacert.pem
- macOS (ARM):
แนวทางแก้ไข:
มี 3 วิธีหลักให้ Container เชื่อถือ ServBay User CA:
- วิธีที่ 1: update trust ตอน build Docker image (Dockerfile) - เหมาะสำหรับกรณีที่ build image เองและต้อง trust CA ในระดับ system
- วิธีที่ 2: trust ด้วยการ mount ไฟล์และตั้งค่า env ของ app - เหมาะกับกรณีต้องการ trust เฉพาะแอป ไม่อยากแตะ image
- วิธีที่ 3: mount ไฟล์แล้ว update CA ตอนรัน container ด้วย command - ไม่ต้อง build image แค่ mount ไฟล์และเปลี่ยน command ตอน start
วิธีที่ 1: update CA ให้ system trust ตอน build image (Dockerfile)
ใส่ไฟล์ ServBay User CA ไปใน build context แล้วคัดลอกเข้าไปใน image
- เตรียมไฟล์ CA: copy ServBay User CA ไป directory ที่มี Dockerfile
- macOS:
/Applications/ServBay/ssl/private/ServBay-Private-CA-ECC-Root.crt
- Windows:
C:\ServBay\ssl\private\ServBay-Private-CA-ECC-Root.crt
- macOS:
- Dockerfile สำหรับ Debian/Ubuntu:dockerfile
FROM ubuntu:latest COPY ServBay-Private-CA-ECC-Root.crt /usr/local/share/ca-certificates/ServBay-User-CA.crt RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates && \ update-ca-certificates && \ rm -rf /var/lib/apt/lists/*
1
2
3
4
5 - Dockerfile สำหรับ Alpine:dockerfile
FROM alpine:latest COPY ServBay-Private-CA-ECC-Root.crt /usr/local/share/ca-certificates/ServBay-User-CA.crt RUN apk add --no-cache ca-certificates && update-ca-certificates
1
2
3 - Build ด้วย Compose:yaml
version: '3.8' services: myapp: build: context: ./app_service # ต้องมี Dockerfile & ServBay-Private-CA-ECC-Root.crt extra_hosts: ["secure.servbay.demo:host-gateway"]
1
2
3
4
5
6
วิธีที่ 2: trust CA ตอนรันด้วยการ mount แล้ว set environment
mount CA เข้า container แล้วตั้ง env ให้ app รู้จัก path นี้
- ตัวอย่างใน
docker-compose.yml
:yamlดูคู่มือของแต่ละแอปว่าจะตั้ง env ไหนversion: '3.8' services: myapp: image: some-base-image volumes: # macOS - /Applications/ServBay/ssl/private/ServBay-Private-CA-ECC-Root.crt:/etc/ssl/certs/MyCustomCA.crt:ro # Windows # - C:\ServBay\ssl\private\ServBay-Private-CA-ECC-Root.crt:/etc/ssl/certs/MyCustomCA.crt:ro environment: # Node.js - NODE_EXTRA_CA_CERTS=/etc/ssl/certs/MyCustomCA.crt # Python requests # - REQUESTS_CA_BUNDLE=/etc/ssl/certs/MyCustomCA.crt # งานอื่น # - SSL_CERT_FILE=/etc/ssl/certs/MyCustomCA.crt extra_hosts: ["secure.servbay.demo:host-gateway"]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
วิธีที่ 3: trust CA ให้ทั้งระบบตอนรัน ด้วย command
mount CA เข้าไป แล้วสั่ง update CA ตอน startup container
- ตัวอย่าง
docker-compose.yml
(Debian/Ubuntu):yamlหมายเหตุ:version: '3.8' services: myapp: image: ubuntu:latest volumes: - /Applications/ServBay/ssl/private/ServBay-Private-CA-ECC-Root.crt:/usr/local/share/ca-certificates/ServBay-User-CA.crt:ro command: > sh -c " echo 'Attempting to update CA certificates...' && if command -v update-ca-certificates > /dev/null; then if [ ! -f /usr/bin/update-ca-certificates ]; then apt-get update && apt-get install -y --no-install-recommends ca-certificates; fi && update-ca-certificates && echo 'CA certificates updated.' else echo 'update-ca-certificates command not found, skipping CA update.' fi && echo 'Starting application...' && exec your_original_application_command_here # เปลี่ยนเป็นคำสั่ง start แอปคุณ " extra_hosts: ["secure.servbay.demo:host-gateway"] # user: root # ถ้า command นั้นต้องใช้ root
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21- อาจจะต้องปรับ command หรือ entrypoint ให้เหมาะกับ flow ของแอป
- สิทธิ์: update CA ต้องใช้ root
- มี package และ command ที่จำเป็นใน image (ca-certificates, update-ca-certificates)
- ใช้ Alpine ให้เปลี่ยนเป็น
apk add --no-cache ca-certificates && update-ca-certificates
เลือกใช้อันไหนดี?
- ถ้า build image ได้ และต้องการ trust CA ในทุก process ให้ใช้ วิธีที่ 1
- ถ้าต้อง trust CA ให้เฉพาะบางแอปใน container ใช้ วิธีที่ 2
- ถ้าไม่อยาก build image และอยากปรับ trust system ตอนรัน ใช้ วิธีที่ 3
กรณีใช้ใบรับรองสาธารณะ เช่น Let's Encrypt ถ้าเว็บใน ServBay ใช้ใบรับรองจาก CA สาธารณะ (เช่น Let's Encrypt) base image ส่วนใหญ่จะ trust CA เหล่านี้อยู่แล้ว ไม่จำเป็นต้องตั้งพิเศษเพิ่มเติม
Q5: จะตั้งชื่อโดเมน และ Reverse Proxy ด้วย ServBay ไปยังแอปใน Docker Container ได้อย่างไร?
ถ้าแอปของคุณรันใน Docker (เช่น Node.js ที่ listen port 3000 ใน container) และต้องการเปิดผ่านโดเมนแบบสวยๆ จาก browser ที่ host (เช่น myapp.servbay.demo
) และจัดการ SSL ด้วย ServBay สามารถทำดังนี้
ขั้นตอน:
รัน container แล้ว map port ออกมาเฉพาะที่ host ที่ IP
127.0.0.1
: ให้ mapping port แอปจาก container ออกมาที่ host (macOS หรือ Windows) และ bind เฉพาะที่127.0.0.1
เพื่อให้ปลอดภัยจาก external accessbash# เช่น container listen port 3000 แต่ host map ที่ 127.0.0.1:3001 docker run -d -p 127.0.0.1:3001:3000 your-docker-app-image
1
2ตอนนี้เปิดผ่าน browser ด้วย
http://127.0.0.1:3001
สร้างเว็บไซต์ใหม่ใน ServBay แบบ Reverse Proxy:
- เปิดหน้า admin ของ ServBay
- คลิก "เพิ่มเว็บไซต์"
- โดเมน: กำหนดชื่อโดเมน เช่น
myapp.servbay.demo
- ชนิดเว็บไซต์: เลือก "reverse proxy"
- IP: กำหนด
127.0.0.1
- port: ใส่ port ที่ container map ออกไป เช่น
3001
- คลิก "บันทึก" หรือ "เพิ่ม"
(ถ้าต้องการ) ตั้งค่า SSL: หลังเพิ่มเว็บแล้ว ไปหน้า settings เพื่อเปิด SSL ได้ ServBay รองรับใบรับรองจาก Let's Encrypt หรือจะใช้ ServBay User CA / Public CA ก็ได้ SSL termination อยู่ที่ ServBay แล้วจากนั้นจะ proxy ไปทาง HTTP ที่
127.0.0.1:3001
ทดสอบเข้าถึง: เสร็จแล้วเข้าผ่าน browser ได้เลยที่
http://myapp.servbay.demo
หรือhttps://myapp.servbay.demo
(ถ้าตั้ง SSL) ServBay จะ proxy request ไปหาแอปใน Docker
Workflow: Browser ของผู้ใช้ ->
https://myapp.servbay.demo
->
ServBay (จัดการ SSL, route ตาม reverse proxy) ->
http://127.0.0.1:3001
(port บน host) ->
แอปใน container
สรุป
ServBay ทำให้การพัฒนาเว็บบน macOS และ Windows สะดวกกว่าเดิม เมื่อใช้ร่วมกับ Docker:
- ถ้าต้องการเข้าถึงเว็บจาก Container ให้ใช้
extra_hosts
หรือ--add-host
map โดเมนไป IP ของ host ผ่านhost-gateway
เพื่อให้ Host header ถูกต้องและไม่เจอปัญหา SNI - ถ้าจะเชื่อมต่อฐานข้อมูลหรือ TCP service ใช้
host.docker.internal
เป็น hostname ได้ง่ายๆ - ถ้าต้องให้ Container trust ใบรับรองจาก ServBay User CA ให้นำ CA ไป update ใน container
- ถ้าต้องเปิดเว็บผ่าน ServBay แล้ว proxy เข้า container สร้างเว็บแบบ reverse proxy ใน ServBay โดย map port ไปที่ host
ควรตรวจสอบให้แน่ใจว่า Service ต่างๆ ใน ServBay และ Container ตั้งค่าถูกต้องและกำลังรันอยู่