OAuth2 Proxy คือ reverse proxy ที่ทำ authentication ให้กับ backend services โดยรองรับหลาย OAuth providers (Google, GitHub, etc.) และ htpasswd authentication สำหรับ quick setup แบบไม่ต้องมี OAuth provider
image: quay.io/oauth2-proxy/oauth2-proxy:latest
container_name: oauth2-proxy
OAUTH2_PROXY_CLIENT_ID: dummy
OAUTH2_PROXY_CLIENT_SECRET: dummy
OAUTH2_PROXY_REDIRECT_URL: https://your-domain.com/oauth2/callback
OAUTH2_PROXY_HTPASSWD_FILE: /etc/oauth2-proxy/htpasswd
OAUTH2_PROXY_COOKIE_SECRET: 12345678901234567890123456789012
OAUTH2_PROXY_COOKIE_SECURE: "true"
OAUTH2_PROXY_UPSTREAMS: http://backend-service:8080
OAUTH2_PROXY_HTTP_ADDRESS: "0.0.0.0:4180"
OAUTH2_PROXY_SKIP_AUTH_ROUTES: "^/api(/.*)?$"
OAUTH2_PROXY_DISPLAY_HTPASSWD_FORM: "true"
OAUTH2_PROXY_EMAIL_DOMAINS: "*"
- ./proxy/htpasswd:/etc/oauth2-proxy/htpasswd:ro
- ./proxy/logs:/var/log/oauth2-proxy
image: your-backend-image
container_name: backend-service
ใช้ dummy สำหรับ CLIENT_ID และ CLIENT_SECRET เมื่อใช้ htpasswd auth เท่านั้น
# ติดตั้ง apache2-utils ก่อน
apt install apache2-utils
# สร้าง file ใหม่ (สร้าง user)
htpasswd -c ./proxy/htpasswd admin
# พิมพ์ password ที่ต้องการ 2 ครั้ง
# เพิ่ม user เพิ่มเติม (ไม่ใช้ -c)
htpasswd ./proxy/htpasswd another-user
admin:$apr1$L5/8HJ..$k8kTfxCj4E8K5T5X5xXyX/
bob:$apr1$Hz/8HJ..$m8kTfxCj4E8K5T5X5xXyX/
| Variable | Description | Required |
|---|
OAUTH2_PROXY_UPSTREAMS | Backend service URL | ✅ |
OAUTH2_PROXY_HTTP_ADDRESS | Listen address | ✅ |
OAUTH2_PROXY_HTPASSWD_FILE | Path to htpasswd file | ✅ |
OAUTH2_PROXY_COOKIE_SECRET | Secret for cookie encryption (32 chars) | ✅ |
| Variable | Description | Default |
|---|
OAUTH2_PROXY_CLIENT_ID | OAuth client ID (ใช้ dummy กับ htpasswd) | - |
OAUTH2_PROXY_CLIENT_SECRET | OAuth client secret (ใช้ dummy กับ htpasswd) | - |
OAUTH2_PROXY_REDIRECT_URL | OAuth callback URL | - |
OAUTH2_PROXY_EMAIL_DOMAINS | Allowed email domains (* for all) | * |
OAUTH2_PROXY_DISPLAY_HTPASSWD_FORM | แสดง htpasswd login form | false |
OAUTH2_PROXY_COOKIE_SECURE | Set Secure flag on cookies | true if HTTPS |
| Variable | Description | Example |
|---|
OAUTH2_PROXY_SKIP_AUTH_ROUTES | Routes to skip auth (regex) | ^/api(/.*)?$ |
OAUTH2_PROXY_SKIP_PROVIDER_CHECK | Skip OAuth provider check | true |
| Variable | Description | Values |
|---|
OAUTH2_PROXY_LOG_LEVEL | Log verbosity | debug, info, warn, error |
OAUTH2_PROXY_LOG_JSON | JSON format logging | true or false |
OAUTH2_PROXY_SKIP_AUTH_ROUTES ใช้ regex สำหรับ public API routes ที่ต้องการเข้าถึงได้เลย
image: quay.io/oauth2-proxy/oauth2-proxy:latest
container_name: oauth2-proxy
OAUTH2_PROXY_UPSTREAMS: http://backend-service:8080
OAUTH2_PROXY_HTPASSWD_FILE: /etc/oauth2-proxy/htpasswd
OAUTH2_PROXY_COOKIE_SECRET: 12345678901234567890123456789012
OAUTH2_PROXY_HTTP_ADDRESS: "0.0.0.0:4180"
OAUTH2_PROXY_DISPLAY_HTPASSWD_FORM: "true"
- ./proxy/htpasswd:/etc/oauth2-proxy/htpasswd:ro
- "traefik.http.routers.oauth2-proxy.rule=Host(`grist.example.com`)"
- "traefik.http.routers.oauth2-proxy.entrypoints=websecure"
- "traefik.http.routers.oauth2-proxy.tls=true"
- "traefik.http.services.oauth2-proxy.loadbalancer.server.port=4180"
- "traefik.http.routers.oauth2-proxy.middlewares=oauth2-proxy-auth"
- "traefik.http.middlewares.oauth2-proxy-auth.forwardauth.address=http://oauth2-proxy:4180"
- "traefik.http.middlewares.oauth2-proxy-auth.forwardauth.trustForwardHeader=true"
image: your-backend-image
container_name: backend-service
- "traefik.http.routers.backend.rule=Host(`grist.example.com`)"
- "traefik.http.routers.backend.entrypoints=websecure"
- "traefik.http.routers.backend.tls=true"
- "traefik.http.routers.backend.middlewares=oauth2-proxy-auth"
docker logs -f oauth2-proxy
# ตรวจสอบว่า container ทำงานอยู่
docker ps | grep oauth2-proxy
- ตรวจสอบว่า backend service ทำงานอยู่และ port ถูกต้อง
- ดูว่า network ถูกตั้งค่าถูกต้อง
- ตรวจสอบ htpasswd file ว่าถูก mount ถูกต้อง
- ตรวจสอบ path ใน
OAUTH2_PROXY_HTPASSWD_FILE ว่าตรงกับ volume mount
- ลองลบ cookies ของเว็บ
- ตรวจสอบว่า
OAUTH2_PROXY_COOKIE_SECRET มีความยาว 32 ตัวอักษร
openssl rand -base64 32 | tr -d '=' | head -c 32
python3 -c "import secrets; print(secrets.token_hex(16))"