Authentik SSO โฮสต์เองด้วย Docker Compose และ Traefik
คู่มือติดตั้ง Authentik 2026.5 ด้วย Docker Compose ตั้งค่า env และ akadmin bootstrap พร้อมใช้ forward auth ของ Traefik ปกป้องทุกแอปด้วยการเข้าสู่ระบบครั้งเดียว
การเข้าสู่ระบบครั้งเดียวสำหรับทุกแอปที่โฮสต์
Authentik เป็นเซิร์ฟเวอร์ SSO (single sign-on) ที่โฮสต์เอง ผู้ใช้ของคุณเข้าสู่ระบบเพียงครั้งเดียว แล้วทุกแอปที่อยู่ด้านหลังจะยอมรับเซสชันนั้นโดยไม่ขอรหัสผ่านของแอปเอง การติดตั้งใช้ไฟล์ Docker Compose อย่างเป็นทางการและ secrets ที่สร้างขึ้น 2 รายการ ส่วนที่ต้องวางแผนจริงอยู่หลังจากนั้น คือการกำหนด reverse proxy ให้ชี้ไปยังเซิร์ฟเวอร์นี้ และนำแอปที่มีอยู่แล้ว 1 แอปไปไว้ด้านหลัง forward auth
Authentik มาพร้อม 3 services ในไฟล์ Compose ดังกล่าว ได้แก่ ฐานข้อมูล PostgreSQL, กระบวนการ server และกระบวนการ worker คอนเทนเนอร์ของเซิร์ฟเวอร์ยังเรียกใช้ outpost ที่ฝังอยู่ภายในด้วย ซึ่งเป็นคอมโพเนนต์ที่ตอบคำถามว่า "คำขอนี้เข้าสู่ระบบแล้วหรือไม่" สำหรับทุกแอปที่ได้รับการปกป้อง Version 2026.5 เป็นรีลีสปัจจุบัน ณ เดือนกรกฎาคม 2026 และโครงการแนะนำให้ใช้โฮสต์ที่มีอย่างน้อย 2 CPU cores และ RAM 2 GB ให้ถือว่านี่เป็นค่าขั้นต่ำ PostgreSQL และ worker จะใช้หน่วยความจำเพิ่มขึ้นหลังจากเครื่องทำงานต่อเนื่องเป็นเวลา 1 วัน
สิ่งที่ต้องมีก่อนเริ่ม
คุณต้องมี Docker Engine พร้อมปลั๊กอิน Compose v2 ซึ่งตรวจสอบได้ด้วย docker compose version หากคำสั่งนี้แสดงข้อผิดพลาดแทนที่จะแสดงเวอร์ชัน ให้ติดตั้งปลั๊กอินก่อนดำเนินการต่อ โดยมีรายละเอียดพื้นฐานใน การเรียกใช้แอปด้วย Docker Compose บน VPS นอกจากนี้ คุณต้องมีระเบียน DNS A ที่ชี้ไปยังเซิร์ฟเวอร์ โดยในตัวอย่างด้านล่างคือ auth.example.com เนื่องจาก Authentik สร้าง URL สำหรับการเปลี่ยนเส้นทางจากชื่อโฮสต์ที่เบราว์เซอร์ใช้
ให้เรียกใช้ stack ในฐานะผู้ใช้ทั่วไปที่อยู่ในกลุ่ม docker แทนการใช้ root การเป็นสมาชิกของกลุ่มนี้มีสิทธิ์เทียบเท่า root บนโฮสต์ ดังนั้นควรเพิ่มเฉพาะบัญชี deploy หนึ่งบัญชีและไม่เพิ่มบัญชีอื่น ตามแนวทางใน บัญชีผู้ใช้ที่มีสิทธิ์เท่าที่จำเป็นบน VPS
ติดตั้งด้วยไฟล์ Compose อย่างเป็นทางการ
sudo install -d -o "$USER" -g "$USER" /opt/authentik
cd /opt/authentik
wget https://docs.goauthentik.io/compose.yml
echo "PG_PASS=$(openssl rand -base64 36 | tr -d '\n')" >> .env
echo "AUTHENTIK_SECRET_KEY=$(openssl rand -base64 60 | tr -d '\n')" >> .env
docker compose pull
docker compose up -ddocker compose ps ควรแสดง container 3 รายการ โดย postgresql รายงาน healthy และ server และ worker รายงาน running การเริ่มทำงานครั้งแรกจะเรียกใช้การย้ายข้อมูลของฐานข้อมูล จึงควรรอประมาณ 1 นาทีก่อนที่เว็บอินเทอร์เฟซจะตอบสนอง
ค่าที่สร้างขึ้นทั้ง 2 ค่ามีความสำคัญด้วยเหตุผลที่แตกต่างกัน PG_PASS คือรหัสผ่าน PostgreSQL และจำกัดความยาวสูงสุดไว้ที่ 99 อักขระ AUTHENTIK_SECRET_KEY ใช้ลงลายเซ็นให้เซสชันและโทเค็น ดังนั้นหากเปลี่ยนค่านี้ภายหลัง ผู้ใช้ทุกคนจะถูกออกจากระบบ และ API token ที่ออกไปทั้งหมดจะใช้ไม่ได้อีก เก็บ .env ด้วย mode 600 และเก็บสำเนาไว้ในสถานที่ปลอดภัย เพราะฐานข้อมูลที่กู้คืนโดยไม่มีคีย์ลับที่ตรงกัน จะเป็นฐานข้อมูลที่ไม่มีใครเข้าสู่ระบบได้
ไฟล์ Compose อ่านค่าทั้ง 2 ค่าด้วยรูปแบบ ${PG_PASS:?database password required} ซึ่งหมายความว่า Compose จะปฏิเสธการเริ่มทำงานเมื่อไม่มีไฟล์ดังกล่าว การเรียกใช้ docker compose up -d จากไดเรกทอรีที่ไม่ถูกต้องจะแสดง required variable AUTHENTIK_SECRET_KEY is missing a value: secret key required แล้วหยุดทำงาน ข้อความดังกล่าวเป็นปัญหาเกี่ยวกับ path ไม่ใช่ปัญหาเกี่ยวกับ config
ค่าของสภาพแวดล้อมที่สำคัญ
ค่าที่เหลือทั้งหมดอยู่ในไฟล์ .env เดียวกัน Authentik จะแปลงขีดล่างคู่เป็นคีย์การกำหนดค่าแบบซ้อน ดังนั้น AUTHENTIK_EMAIL__HOST จึงกำหนดค่า email.host ขีดล่างเดี่ยวจะถูกละเว้นโดยไม่มีคำเตือน ซึ่งเป็นสาเหตุที่พบบ่อยที่สุดที่ทำให้การตั้งค่าดูเหมือนไม่มีผล
AUTHENTIK_BOOTSTRAP_PASSWORDกำหนดรหัสผ่านของผู้ใช้akadminในตัวเมื่อเริ่มต้นครั้งแรก ดังนั้นคุณจึงไม่ต้องป้อนรหัสผ่านลงในแบบฟอร์มเว็บสาธารณะAUTHENTIK_BOOTSTRAP_EMAILและAUTHENTIK_BOOTSTRAP_TOKENกำหนดที่อยู่ของผู้ใช้รายนั้นและโทเค็น API ในลักษณะเดียวกันCOMPOSE_PORT_HTTPและCOMPOSE_PORT_HTTPSย้ายพอร์ตที่เผยแพร่จากค่าเริ่มต้น 9000 และ 9443AUTHENTIK_EMAIL__HOST,AUTHENTIK_EMAIL__PORT,AUTHENTIK_EMAIL__USERNAME,AUTHENTIK_EMAIL__PASSWORD,AUTHENTIK_EMAIL__USE_TLSและAUTHENTIK_EMAIL__FROMกำหนดค่าอีเมลขาออก หากไม่มีค่าเหล่านี้ Authentik จะพยายามใช้localhostผ่านพอร์ต 25 ดังนั้นอีเมลรีเซ็ตรหัสผ่านจะจบลงด้วยข้อผิดพลาดการเชื่อมต่อในบันทึกของ workerAUTHENTIK_LOG_LEVEL=debugเปิดใช้รายละเอียดที่คุณต้องการขณะที่ login flow ทำงานผิดปกติ หลังจากนั้นให้เปลี่ยนกลับเป็นinfoAUTHENTIK_ERROR_REPORTING__ENABLEDมีค่าเริ่มต้นเป็นfalseตั้งค่าเป็นtrueเฉพาะเมื่อคุณยอมรับการส่งรายงานข้อขัดข้องไปยังผู้พัฒนา
ค่าเหล่านี้เป็นข้อมูลลับในไฟล์แบบข้อความธรรมดา ดังนั้นให้ดูแลไดเรกทอรีนี้เช่นเดียวกับแหล่งจัดเก็บข้อมูลรับรองอื่นๆ password manager เช่น อินสแตนซ์ Vaultwarden ที่โฮสต์ด้วยตนเอง เหมาะสำหรับเก็บสำเนาสำหรับกู้คืนมากกว่าการจดไว้ในโน้ตบนแล็ปท็อป
การเข้าสู่ระบบครั้งแรกและบัญชีผู้ดูแลระบบ
เปิด http://SERVER_IP:9000 ในเบราว์เซอร์ Authentik จะแสดงขั้นตอนการตั้งค่าเริ่มต้น และขอให้คุณตั้งรหัสผ่านสำหรับผู้ใช้ akadmin เริ่มต้น หากคุณตั้งค่า AUTHENTIK_BOOTSTRAP_PASSWORD ไว้แล้ว ขั้นตอนนี้จะเสร็จสมบูรณ์ และระบบจะนำคุณไปยังหน้าลงชื่อเข้าใช้โดยตรง
สร้างผู้ใช้ผู้ดูแลระบบทั่วไปสำหรับตนเองใน Directory จากนั้นเลือก Users เพิ่มผู้ใช้ดังกล่าวไปยังกลุ่ม authentik Admins แล้วลงชื่อเข้าใช้ด้วยบัญชีนั้น ให้เก็บ akadmin ไว้เป็นบัญชีสำหรับการกู้คืนฉุกเฉิน โดยใช้รหัสผ่านแบบยาวและจัดเก็บไว้นอกระบบ การใช้งานประจำวันภายใต้บัญชีในตัวที่ใช้ร่วมกันจะทำให้บันทึกการตรวจสอบใช้การไม่ได้ เพราะทุกเหตุการณ์ระบุเพียง akadmin และไม่ระบุว่าใครเป็นผู้ดำเนินการ
นำ Authentik ไว้หลัง reverse proxy
การเปิดพอร์ต 9000 สู่อินเทอร์เน็ตใช้งานได้ แต่คุณต้องการ TLS (transport layer security) และ hostname จริง หากคุณใช้งานการตั้งค่าจาก Traefik เป็น reverse proxy สำหรับแอป Compose หลายรายการ อยู่แล้ว ให้เชื่อม Authentik เข้ากับเครือข่ายภายนอก proxy เดียวกันโดยใช้ไฟล์ override สร้าง docker-compose.override.yml ไว้ถัดจาก compose.yml:
services:
server:
networks:
- default
- proxy
labels:
traefik.enable: "true"
traefik.docker.network: proxy
traefik.http.routers.authentik.rule: Host(`auth.example.com`)
traefik.http.routers.authentik.entrypoints: websecure
traefik.http.routers.authentik.tls.certresolver: le
traefik.http.services.authentik.loadbalancer.server.port: "9000"
networks:
proxy:
external: trueใช้ docker compose up -d เพื่อปรับใช้ Compose จะผสานไฟล์ override โดยอัตโนมัติ ดังนั้นบริการ server จะคงการตั้งค่าทั้งหมดจากไฟล์ทางการไว้ และเพิ่ม labels เข้าไป ตรวจสอบด้วย curl -I https://auth.example.com/if/user/ ซึ่งควรตอบกลับด้วย HTTP/2 200 หาก Traefik แสดง 404 page not found แสดงว่า container ไม่ได้อยู่ในเครือข่าย proxy และ Traefik ไม่สามารถกำหนดเส้นทางไปยัง container ที่ไม่สามารถเข้าถึงได้
เมื่อ hostname ใช้งานได้แล้ว ให้ผูกพอร์ตที่เผยแพร่ไว้กับ 127.0.0.1 ในไฟล์ override เพื่อให้เข้าถึงได้ผ่าน proxy เท่านั้น
ปกป้องแอปหนึ่งรายการด้วย forward auth
Proxy provider ของ Authentik มี 3 โหมด การเลือกโหมดผิดอาจทำให้เสียเวลา 1 ชั่วโมง Proxy หมายถึง outpost เป็นผู้ส่งต่อทราฟฟิกไปยังแอป upstream เอง Forward auth (single application) หมายถึง reverse proxy ของคุณยังคงส่งต่อทราฟฟิก และสอบถาม Authentik เฉพาะว่าคำขอนั้นลงชื่อเข้าใช้แล้วหรือไม่ Forward auth (domain level) ใช้ปกป้องทุกแอปภายใต้ parent domain เดียวกันด้วย provider รายการเดียว แต่ต้องกำหนดกฎการอนุญาตแยกตามแอป เมื่อใช้ Traefik เป็น reverse proxy ด้านหน้า ให้เลือก forward auth (single application)
ในเว็บอินเทอร์เฟซ ให้เปิด Applications แล้วเปิด Providers จากนั้นสร้าง Proxy Provider เลือกโหมด forward auth single application และตั้งค่า external host เป็น https://app.example.com สร้าง Application ที่ชี้ไปยัง provider ดังกล่าว จากนั้นเปิด Outposts แก้ไข authentik Embedded Outpost และเพิ่มแอปใหม่ลงใน selected applications outpost จะตอบสนองเฉพาะแอปที่ถูกกำหนดไว้ ดังนั้นการข้ามขั้นตอนสุดท้ายจึงเป็นสาเหตุที่ provider ซึ่งกำหนดค่าถูกต้องยังคงไม่ส่งผลลัพธ์
กำหนด middleware เพียงครั้งเดียวบนคอนเทนเนอร์ Authentik แล้วอ้างอิง middleware นี้จากทุกแอปที่ต้องการปกป้อง:
traefik.http.middlewares.authentik.forwardauth.address: http://server:9000/outpost.goauthentik.io/auth/traefik
traefik.http.middlewares.authentik.forwardauth.trustForwardHeader: "true"
traefik.http.middlewares.authentik.forwardauth.authResponseHeaders: X-authentik-username,X-authentik-groups,X-authentik-email,X-authentik-name,X-authentik-uid,X-authentik-jwt,X-authentik-meta-jwks,X-authentik-meta-outpost,X-authentik-meta-provider,X-authentik-meta-app,X-authentik-meta-versionauthResponseHeaders คือรายการ header ที่ Traefik คัดลอกจากคำตอบของ Authentik ไปยังคำขอที่ส่งต่อไปยัง upstream หากไม่ระบุรายการนี้ แอปจะยังคงได้รับการปกป้อง แต่จะไม่ทราบว่าผู้ใช้เป็นใคร ดังนั้นสิ่งใดก็ตามที่อ่าน X-authentik-username เพื่อเข้าสู่ระบบโดยอัตโนมัติจะยังคงอยู่ในสถานะไม่ได้ลงชื่อเข้าใช้
แอปที่ต้องการปกป้องต้องมี router 2 รายการ ไม่ใช่ 1 รายการ:
labels:
traefik.enable: "true"
traefik.http.routers.myapp.rule: Host(`app.example.com`)
traefik.http.routers.myapp.entrypoints: websecure
traefik.http.routers.myapp.tls.certresolver: le
traefik.http.routers.myapp.middlewares: authentik@docker
traefik.http.routers.myapp-auth.rule: Host(`app.example.com`) && PathPrefix(`/outpost.goauthentik.io/`)
traefik.http.routers.myapp-auth.entrypoints: websecure
traefik.http.routers.myapp-auth.tls.certresolver: le
traefik.http.routers.myapp-auth.priority: "15"
traefik.http.routers.myapp-auth.service: authentikrouter รายการที่สองคือส่วนที่มักถูกละไว้ หลังจากลงชื่อเข้าใช้ Authentik จะส่งเบราว์เซอร์กลับไปยัง path ภายใต้ /outpost.goauthentik.io/ บน hostname ของ แอป ไม่ใช่บน auth.example.com หากไม่มี router ที่ส่งต่อ path prefix ดังกล่าวไปยังบริการ Authentik คำขอจะมาถึงแอปของคุณ แอปจะตอบกลับด้วย 404 และการเข้าสู่ระบบจะไม่เสร็จสมบูรณ์ ค่า priority ที่สูงกว่าคือสิ่งที่ทำให้กฎ path เฉพาะเจาะจงมีผลเหนือกว่ากฎ Host() ทั่วไปบนโดเมนเดียวกัน
ทดสอบในหน้าต่างเบราว์เซอร์ส่วนตัว ระบบควรส่งคุณไปยัง auth.example.com จากนั้นให้ลงชื่อเข้าใช้และกลับมายังแอป docker compose logs -f server ฝั่ง Authentik จะแสดง authorization event สำหรับแต่ละความพยายาม ซึ่งช่วยบอกได้ว่าคำขอนั้นไปถึง Authentik หรือไม่
ปัญหาที่จะพบจริง
การเปลี่ยนเส้นทางวนซ้ำไม่สิ้นสุดระหว่างแอปกับหน้าเข้าสู่ระบบ โฮสต์ภายนอกบนผู้ให้บริการไม่ตรงกับโฮสต์ที่เบราว์เซอร์ใช้ โดยทั่วไปคือ http:// ในผู้ให้บริการไม่ตรงกับ https:// ในแถบที่อยู่ จากนั้นคุกกี้เซสชันจะถูกกำหนดให้กับ origin อื่น ทำให้ทุกครั้งที่กลับเข้ามาถูกมองว่าเป็นคำขอแบบไม่ระบุชื่อรายการใหม่ แก้ไขโฮสต์ภายนอก แล้วล้างคุกกี้ของทั้งสองโดเมนก่อนทดสอบอีกครั้ง
พบ 404 ที่ /outpost.goauthentik.io/start ไม่มี outpost router หรือมี priority ต่ำกว่า catch-all router สำหรับโฮสต์นั้น
แอปโหลดได้โดยไม่เคยขอให้เข้าสู่ระบบ ป้ายกำกับ middlewares ระบุ middleware ที่ไม่มีอยู่ Traefik จะไม่แสดงคำเตือนกรณีนี้ ดังนั้นการพิมพ์ authentik@docker ผิดจึงทำให้ไม่มี middleware ทำงาน เปิด Traefik dashboard และตรวจสอบว่า router แสดง middleware ดังกล่าว
ได้รับ 403 จาก Authentik หลังเข้าสู่ระบบสำเร็จ ผู้ใช้ได้รับการตรวจสอบสิทธิ์แล้ว แต่ไม่ได้รับอนุญาตให้ใช้งาน แอปมี policy binding หรือข้อกำหนดกลุ่มที่ผู้ใช้นี้ไม่ผ่าน Events log ในอินเทอร์เฟซผู้ดูแลระบบจะแสดง policy ที่ปฏิเสธคำขอ
เมื่อ Keycloak เหมาะสมกว่า
Keycloak เป็นโครงการที่มีมานานกว่าและได้รับการสนับสนุนจาก Red Hat จึงเหมาะกับงานด้านการจัดการข้อมูลประจำตัวระดับองค์กรแบบดั้งเดิมมากกว่า โดยเฉพาะการทำ SAML federation ในระดับสูง การทำหน้าที่เป็นตัวกลางสำหรับการเข้าสู่ระบบจากผู้ให้บริการข้อมูลประจำตัวภายนอกหลายรายพร้อมกัน รวมถึงการ export และ import realm ซึ่งเป็นแนวทางการย้ายระบบที่มีเอกสารรองรับ การมีบริการสนับสนุนเชิงพาณิชย์อยู่เบื้องหลังอาจมีความสำคัญต่อบางองค์กรในเชิงเอกสาร อย่างไรก็ตาม Keycloak ไม่มี proxy ในตัว ดังนั้นการปกป้องแอปที่ไม่รองรับ OIDC (OpenID Connect) จึงต้องติดตั้งสิ่งอย่าง oauth2-proxy เพิ่มเติมและทำงานร่วมกัน Authentik มี built-in proxy provider ซึ่งทำหน้าที่นี้และผสานรวมไว้แล้ว จึงเป็นเหตุผลที่ผู้ดูแลระบบที่โฮสต์บริการเองและมีแอปหลายประเภทมักเลือกใช้ Authentik.
การสำรองข้อมูลและการอัปเกรด
มี 3 สิ่งที่ทำให้สามารถกู้คืนระบบได้ ได้แก่ ฐานข้อมูล PostgreSQL ไดเรกทอรี ./data และ .env
cd /opt/authentik
docker compose exec -T postgresql pg_dump -U authentik authentik | gzip > authentik-$(date +%F).sql.gzจัดเก็บ dump และ .env ไว้ด้วยกัน การมีเฉพาะ dump ไม่เพียงพอ เพราะคีย์ลับที่ใช้ปกป้องข้อมูลเซสชันและโทเค็นอยู่ใน .env
การอัปเกรดเป็นการเปลี่ยน tag กำหนด AUTHENTIK_TAG ใน .env ให้เป็น release ที่ต้องการ จากนั้นเรียกใช้ docker compose pull แล้วตามด้วย docker compose up -d อ่าน release notes ก่อน เนื่องจาก Authentik ใช้เวอร์ชันตามวันที่ และ release บางรายการมี migration ที่ต้องเริ่มต้นจาก release ก่อนหน้า ให้ทำ database dump ก่อน pull ไม่ใช่หลังจากนั้น
FAQ
Authentik สามารถโฮสต์เองได้ฟรีหรือไม่
รุ่นโอเพนซอร์สใช้งานได้ฟรี และครอบคลุมทุกอย่างที่กล่าวไว้ข้างต้น ได้แก่ proxy provider, forward auth, OIDC (OpenID Connect), SAML และ flows engine ระดับองค์กรแบบมีค่าใช้จ่ายจะเพิ่มบริการสนับสนุนและฟีเจอร์สำหรับองค์กรบางรายการ แต่เนื้อหานี้ไม่ต้องใช้ licence
จำเป็นต้องใช้ Traefik เพื่อใช้งาน Authentik หรือไม่
ไม่จำเป็น forward auth ทำงานร่วมกับ nginx ผ่าน auth_request และทำงานร่วมกับ Caddy ผ่าน forward_auth รูปแบบการทำงานเหมือนกันในทุกกรณี reverse proxy จะสอบถาม Authentik สำหรับแต่ละ request และ path prefix /outpost.goauthentik.io/ บน hostname ที่มีการป้องกันต้อง route ไปยัง Authentik แทนที่จะไปยังแอป
เหตุใดแอปที่มีการป้องกันจึงวนซ้ำระหว่างหน้าเข้าสู่ระบบและข้อผิดพลาดตลอดเวลา
external host ที่กำหนดค่าไว้ใน proxy provider ไม่ตรงกับ URL ที่เบราว์เซอร์ใช้งาน โดยมักเกิดจาก http ไม่ตรงกับ https ระบบจะออก session cookie สำหรับ origin หนึ่ง แต่ไปอ่านจากอีก origin หนึ่ง ดังนั้น Authentik จึงมองทุก request ว่าไม่ได้ยืนยันตัวตน แก้ไข external host แล้วล้าง cookie ของ hostname ทั้งสองรายการก่อนทดสอบอีกครั้ง
Authentik ต้องใช้ RAM เท่าใด
ณ July 2026 ขั้นต่ำตามเอกสารคือ CPU 2 cores และ RAM 2 GB ซึ่งครอบคลุม PostgreSQL, server และ worker รวมกัน บนเครื่องที่มี RAM 2 GB worker จะเป็น process แรกที่ kernel ยุติการทำงานเมื่อหน่วยความจำไม่เพียงพอ อาการคือ background tasks และอีเมลขาออกหยุดทำงาน ขณะที่หน้าเข้าสู่ระบบยังใช้งานได้ หาก server เดียวกันยังเรียกใช้แอปที่คุณกำลังป้องกันอยู่ด้วย ควรจัดสรร RAM 4 GB