Dev vs Production Mode
Keycloak มีสองโหมดการเริ่มต้น: start-dev สำหรับ development และ start สำหรับ production ทั้งสองใช้แทนกันไม่ได้ — start-dev มีการประนีประนอมหลายอย่างที่ไม่ปลอดภัยสำหรับสภาพแวดล้อมจริง การเข้าใจความแตกต่างนี้สำคัญก่อนที่คุณจะก้าวข้ามการเรียนรู้บน local
start-dev: development mode
หัวข้อที่มีชื่อว่า “start-dev: development mode”start-dev ถูกออกแบบมาเพื่อให้เริ่มต้นได้รวดเร็ว โดยใช้ embedded H2 in-memory database (ข้อมูลจะหายเมื่อ restart), เปิดใช้ HTTP (ไม่มี TLS), ปิดการตรวจสอบ hostname และผ่อนปรน security checks หลายอย่าง ใช้โหมดนี้เฉพาะบน localhost ตอนเรียนรู้ Keycloak เท่านั้น
docker run --name keycloak -p 8080:8080 \ -e KC_BOOTSTRAP_ADMIN_USERNAME=admin \ -e KC_BOOTSTRAP_ADMIN_PASSWORD=admin \ quay.io/keycloak/keycloak:latest start-devstart: production mode
หัวข้อที่มีชื่อว่า “start: production mode”start คือคำสั่งสำหรับ production ซึ่งต้องการ external database, hostname ที่แน่นอน และ HTTPS (หรือ reverse proxy ที่กำหนดค่าไว้) Keycloak จะปฏิเสธการ start ใน production mode หากไม่มีการกำหนดค่า hostname และ TLS ที่ถูกต้อง environment variable ที่สำคัญมีดังนี้:
| Environment variable | Purpose | Example |
|---|---|---|
KC_DB | vendor ของ database | postgres |
KC_DB_URL | JDBC connection URL | jdbc:postgresql://db:5432/keycloak |
KC_DB_USERNAME | ชื่อผู้ใช้ DB | keycloak |
KC_DB_PASSWORD | รหัสผ่าน DB | changeme |
KC_HOSTNAME | hostname สาธารณะของ Keycloak | auth.example.com |
KC_PROXY_HEADERS | ไว้วางใจ proxy headers (xforwarded หรือ forwarded) | xforwarded |
KC_HTTP_ENABLED | อนุญาต HTTP (จำเป็นเมื่อ proxy ทำ TLS termination) | true |
docker run --name keycloak -p 8080:8080 \
-e KC_DB=postgres \
-e KC_DB_URL=jdbc:postgresql://db:5432/keycloak \
-e KC_DB_USERNAME=keycloak \
-e KC_DB_PASSWORD=changeme \
-e KC_HOSTNAME=auth.example.com \
-e KC_PROXY_HEADERS=xforwarded \
-e KC_HTTP_ENABLED=true \
quay.io/keycloak/keycloak:latest startOptimized build
หัวข้อที่มีชื่อว่า “Optimized build”สำหรับ production Keycloak แนะนำให้รัน kc.sh build (หรือ kc.bat build) ภายใน image ก่อนที่จะ start ซึ่งจะ pre-process configuration และลดเวลา startup ลงอย่างมาก Dockerfile สำหรับ production โดยทั่วไปใช้ two-stage build: stage หนึ่งรัน kc.sh build และอีก stage คัดลอก distribution ที่ build แล้วมารัน kc.sh start
# Stage 1: buildFROM quay.io/keycloak/keycloak:latest AS builderRUN /opt/keycloak/bin/kc.sh build --db=postgres
# Stage 2: runFROM quay.io/keycloak/keycloak:latestCOPY --from=builder /opt/keycloak/ /opt/keycloak/ENTRYPOINT ["/opt/keycloak/bin/kc.sh", "start"]ข้อแลกเปลี่ยน
หัวข้อที่มีชื่อว่า “ข้อแลกเปลี่ยน”| ตัวเลือก | Benefit | Cost |
|---|---|---|
start-dev (development mode) | Setup เร็ว ไม่ต้องมี TLS certificate, hostname หรือ external database — เหมาะกับการเรียนรู้และ local development | ไม่มี TLS, ข้าม hostname check, ใช้ in-memory H2 database ที่ข้อมูลหายทุกครั้งที่ restart — ใช้ใน production ไม่ได้ |
start (production mode) | บังคับให้กำหนด TLS/hostname/database ให้ถูกต้องก่อน start ได้จริง ป้องกันการ deploy ที่ไม่ปลอดภัยโดยไม่ตั้งใจ | ต้องเตรียม external database, certificate และ reverse proxy configuration ล่วงหน้า — setup ใช้เวลานานกว่า |
ข้อผิดพลาดที่พบบ่อย
หัวข้อที่มีชื่อว่า “ข้อผิดพลาดที่พบบ่อย”- รัน
start-devใน production เพราะ setup ง่ายกว่า — ทีมที่รีบ deploy มักลืมสลับไปใช้startทำให้ระบบไม่มี TLS และข้อมูลอยู่ใน in-memory database ที่หายทุกครั้งที่ container restart - ลืมตั้งค่า
KC_HOSTNAMEให้ตรงกับ domain จริง — ถ้า hostname ไม่ตรง token ที่ issue ออกมาจะมี issuer URL ผิด ทำให้แอปที่ validate token อย่างเข้มงวด reject token ทั้งหมด - เปิด
KC_HTTP_ENABLED=trueโดยไม่มี reverse proxy ทำ TLS termination จริง — ค่านี้ควรใช้เฉพาะเมื่อมี proxy อย่าง Nginx หรือ load balancer จัดการ TLS ให้แล้วเท่านั้น ไม่ใช่เปิดทิ้งไว้เฉยๆ บน public endpoint
💡 ตัวอย่างจากของจริง
องค์กรที่ทำ SSO consolidation — บริษัทที่มีแอปภายในหลายสิบระบบมักย้ายทุกแอปมาใช้ Keycloak instance เดียวใน production mode พร้อม external PostgreSQL และ TLS ผ่าน load balancer เพื่อให้พนักงาน login ครั้งเดียวเข้าทุกระบบ
Red Hat build of Keycloak (RH-SSO) — เวอร์ชัน supported ของ Red Hat ใช้หลักการเดียวกันคือบังคับ production mode configuration (DB, hostname, TLS) ก่อน deploy จริง เพื่อป้องกันลูกค้าตั้งค่าระบบแบบไม่ปลอดภัยโดยไม่ตั้งใจ