Keycloak 是企业级开源身份认证和访问控制解决方案,功能强大、支持多协议,并适合自建部署。本文将手把手教你如何基于 Docker 快速部署 Keycloak,涵盖 HTTP 模式、HTTPS 模式(自签证书)、以及结合 Nginx 的反向代理部署方案。每种模式都适用于不同的内网或生产环境场景,助你构建安全、稳定的身份认证系统。
🔍 1. Keycloak 简介
Keycloak 是一款开源的身份与访问管理(IAM)解决方案,支持 OAuth 2.0、OpenID Connect、SAML 等标准协议。它具备如下核心能力:
- 用户与角色管理
- 单点登录(SSO)与登出
- 多因素认证(MFA)
- 社交账号登录集成(Google、GitHub 等)
- 客户端权限控制与资源保护
⚙️ 2. Docker 快速部署 Keycloak
🚀 2.1 无代理 HTTP 快速部署(开发环境推荐)
适用于测试和开发,直接启用 HTTP 服务。
✅ 建议部署后尽快创建正式管理员账号,并删除初始的 KEYCLOAK_ADMIN 用户。
配置说明:
- 使用 PostgreSQL 作为持久数据库
- 通过 KC_HTTP_ENABLED=true 开启 HTTP 支持
- 监听容器的 8080 端口
services:
postgres:
image: postgres:15-alpine
container_name: keycloak_postgres
environment:
POSTGRES_DB: keycloak
POSTGRES_USER: keycloak
POSTGRES_PASSWORD: supersecret
volumes:
- keycloak-db:/var/lib/postgresql/data
keycloak:
image: quay.io/keycloak/keycloak:latest
container_name: keycloak
command: start
environment:
KC_DB: postgres
KC_DB_URL: jdbc:postgresql://postgres:5432/keycloak
KC_DB_USERNAME: keycloak
KC_DB_PASSWORD: supersecret
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: admin
KC_HOSTNAME_STRICT: false
KC_HTTP_ENABLED: true
ports:
- "8080:8080"
depends_on:
- postgres
volumes:
keycloak-db:
访问地址:http://:8080
🔐 2.2 启用原生 HTTPS:Keycloak 自持证书(适用于小规模生产)
此方式下 Keycloak 自行监听 8443,并启用 TLS。
关键点:
- 本地挂载证书并确保所有者为 UID 1000(非 root)
- 去除 KC_HTTP_ENABLED
- 设置 KC_PROXY=edge 告诉 Keycloak 它是直接暴露的边缘服务
keycloak:
image: quay.io/keycloak/keycloak:latest
container_name: keycloak
command: start
environment:
KC_DB: postgres
KC_DB_URL: jdbc:postgresql://postgres:5432/keycloak
KC_DB_USERNAME: keycloak
KC_DB_PASSWORD: supersecret
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: admin
KC_HTTPS_CERTIFICATE_FILE: /etc/certs/IP.cert.pem
KC_HTTPS_CERTIFICATE_KEY_FILE: /etc/certs/IP.key.pem
KC_HOSTNAME_STRICT: false
KC_PROXY: edge
volumes:
- /etc/certs:/etc/certs:ro
- /etc/localtime:/etc/localtime
depends_on:
- postgres
ports:
- "8443:8443"
🌐 2.3 结合 Nginx 做 HTTPS 卸载(推荐:中大型部署)
Nginx 负责 TLS,Keycloak 后端使用 HTTP 通信,部署灵活、适合域名区分服务的场景。内网环境可以使用端口来却分服务。
关键配置:
- KC_HOSTNAME 设置为对外访问地址(IP 或域名)
- 设置 KC_HTTP_ENABLED: true 以接受 HTTP 流量
- 设置 KC_PROXY: edge 告知 Keycloak 它处于边缘(有代理)
- 注意 KC_HOSTNAME_PORT 配置端口以防重定向丢失端口
services:
postgres:
image: postgres:15-alpine
container_name: keycloak_postgres
environment:
POSTGRES_DB: keycloak
POSTGRES_USER: keycloak
POSTGRES_PASSWORD: supersecret
volumes:
- keycloak-db:/var/lib/postgresql/data
networks:
- keycloak-net
keycloak:
image: quay.io/keycloak/keycloak:latest
container_name: keycloak
command: start
environment:
KC_DB: postgres
KC_DB_URL: jdbc:postgresql://postgres:5432/keycloak
KC_DB_USERNAME: keycloak
KC_DB_PASSWORD: supersecret
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: admin
KC_HOSTNAME: Intranet_IP
KC_HOSTNAME_PORT: Custom_Port
KC_HOSTNAME_STRICT: true
KC_HOSTNAME_STRICT_HTTPS: true
KC_HTTP_ENABLED: true
KC_PROXY: edge
volumes:
- /etc/localtime:/etc/localtime
expose:
- 8080
networks:
- nginx-proxy-network
- keycloak-net
volumes:
keycloak-db:
networks:
nginx-proxy-network:
external: true
keycloak-net:
external: true
Nginx 配置示例:
server {
listen Custom_Port ssl;
server_name Intranet_IP;
ssl_certificate /etc/nginx/certs/IP.cert.pem;
ssl_certificate_key /etc/nginx/certs/IP.key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers HIGH:!aNULL:!MD5;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
location / {
proxy_pass http://keycloak:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Upgrade $http_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Host $host:$server_port;
}
}
✅ 3. 最佳实践建议
🚫 删除默认管理用户(bootstrap admin)
✅ 使用 realm-management → realm-admin 角色创建正式管理员
🧠 优先使用 Nginx 模式,在多个服务和网段之间更灵活
🔐 为生产部署配置正式证书与强密码策略
📚 延伸阅读
更多内容持续更新于我的博客:https://www.zenseek.site