部署开源版
本文档帮助你从零开始完成 Code Bird Cloud 平台的安装、部署和初始化配置。
概述
Code Bird Cloud 是一个基于 OIDC/OAuth 2.1 标准的身份认证与访问管理平台。完成以下步骤即可开始使用:
- 准备环境 -- 确认基础设施依赖(数据库、缓存等)
- 安装部署 -- 选择 Docker 部署或手动部署
- 首次初始化 -- 创建平台管理员账户和基础数据
初始化完成后,你将获得:
- 一个可运行的 Code Bird Cloud 实例
- 平台超级管理员账户,用于登录 Platform Admin Console
- ECDSA 签名密钥,用于 JWT/OIDC 令牌签名
- 默认的登录体验配置
环境要求
必需依赖
| 依赖项 | 最低版本 | 说明 |
|---|---|---|
| Go | 1.25.6+ | 后端编译运行(Makefile 会严格校验版本) |
| Node.js | >= 18.0.0 | 前端编译运行 |
| pnpm | >= 10.11.0 | 前端包管理器 |
| PostgreSQL | 14+ | 主数据库 |
| Redis | 6.0+ | 缓存与会话存储 |
可选工具
| 工具 | 用途 |
|---|---|
| air | Go 热重载开发工具 |
| swag | Swagger API 文档生成 |
| gofumpt | Go 代码格式化 |
| golangci-lint | Go 代码静态检查 |
| Docker | 容器化部署 |
安装可选工具:
# Go 开发工具
go install github.com/air-verse/air@latest
go install github.com/swaggo/swag/cmd/swag@v1.8.12
go install mvdan.cc/gofumpt@latest
go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.63.4
# pnpm 包管理器
npm install -g pnpm部署方式一:Docker 部署(推荐)
Docker 部署使用多阶段构建,将前后端打包到同一个镜像中运行。
1. 准备数据库
确保 PostgreSQL 和 Redis 服务已启动,并创建好数据库:
CREATE DATABASE codebird;2. 准备配置文件
在项目根目录创建后端配置文件 backend/conf/app.yaml,可参考示例文件 backend/conf/app.sample.yaml:
db:
postgres:
host: 127.0.0.1
port: 5432
user: postgres
password: postgres
database: codebird
sslmode: disable
redis:
database: 0
host: localhost
port: 6379
domain: localhost:18000
protocol: http
oidc:
issuer: http://localhost:18001
access_token_ttl: 3600 # 1 小时
refresh_token_ttl: 1209600 # 14 天
id_token_ttl: 3600 # 1 小时
auth_code_ttl: 600 # 10 分钟
admin:
jwt_secret: "请替换为随机字符串"
web:
port: 18001
# 三域名部署配置(生产环境必填,开发环境可省略)
# domains:
# console: "console.your-domain.com"
# platform: "platform.your-domain.com"
# auth: "auth.your-domain.com"注意:
admin.jwt_secret用于管理后台的 JWT 签名,请务必替换为一个高强度随机字符串。域名配置:生产环境部署时需配置
web.domains,Go 后端根据 HTTPHost头分发不同的 SPA 前端。开发环境下各前端有独立的 dev server 端口,无需配置域名。
3. 构建镜像
docker build -t code-bird-cloud:latest .4. 运行容器
docker run -d \
--name code-bird-cloud \
-p 18001:18001 \
-v $(pwd)/backend/conf:/app/conf \
code-bird-cloud:latest容器启动后,可通过以下地址访问:
开发环境(未配置域名):
| 服务 | 地址 |
|---|---|
| 后端 API | http://localhost:18001 |
| Login Page(默认 SPA) | http://localhost:18001/ |
| 健康检查 | http://localhost:18001/ping |
| Swagger 文档(非生产) | http://localhost:18001/swagger/index.html |
生产环境(三域名模式):
Go 后端通过 HTTP Host 头判断返回哪个 SPA,需在 app.yaml 中配置 web.domains:
| 服务 | 域名 | 说明 |
|---|---|---|
| Admin Console | https://console.your-domain.com/ | 管理后台 |
| Platform Admin | https://platform.your-domain.com/ | 平台管理 |
| Login / OIDC / API | https://auth.your-domain.com/ | 认证服务 |
5. 执行初始化
首次部署需要进入容器运行初始化命令:
docker exec -it code-bird-cloud ./main init初始化的详细流程请参阅下方「首次初始化」章节。
部署方式二:手动部署
1. 克隆项目
git clone <仓库地址>
cd code_bird_cloud2. 安装依赖
使用项目根目录的 Makefile 一键安装前后端依赖:
make init该命令会执行:
go mod download和go mod tidy(后端 Go 依赖)pnpm install(Admin、Platform Admin 和 Login 前端依赖)
3. 配置数据库与应用
复制配置文件模板并修改:
cp backend/conf/app.sample.yaml backend/conf/app.yaml根据实际环境修改 backend/conf/app.yaml 中的数据库连接、Redis 地址、OIDC 签发者等配置项。详细配置说明参阅下方「配置文件说明」章节。
4. 构建项目
# 构建整个项目(后端二进制 + 前端静态文件)
make build构建产物:
| 产物 | 路径 |
|---|---|
| 后端二进制文件 | backend/bin/main |
| Admin 前端 | frontend/admin/dist/ |
| Login 前端 | frontend/login/dist/ |
5. 执行初始化
cd backend
./bin/main init或者使用 go run 直接运行:
cd backend
go run main.go init初始化的详细流程请参阅下方「首次初始化」章节。
6. 启动服务
生产模式:
cd backend
./bin/main --env=prod开发模式(热重载):
# 在项目根目录
make dev # 启动后端(热重载)
make frontend-dev # 启动 Admin 前端开发服务
# 或同时启动前后端
make dev-all开发模式下的默认端口:
| 服务 | 端口 |
|---|---|
| 后端 API | 18001 |
| Admin 前端开发服务器 | 18000(自动代理 API 请求到后端) |
配置文件说明
backend/conf/app.yaml
这是后端服务的主配置文件,核心配置项如下:
| 配置项 | 说明 | 默认值 |
|---|---|---|
db.postgres.host | PostgreSQL 主机地址 | 127.0.0.1 |
db.postgres.port | PostgreSQL 端口 | 5432 |
db.postgres.user | PostgreSQL 用户名 | postgres |
db.postgres.password | PostgreSQL 密码 | postgres |
db.postgres.database | 数据库名称 | codebird |
db.postgres.sslmode | SSL 模式 | disable |
db.redis.host | Redis 主机地址 | localhost |
db.redis.port | Redis 端口 | 6379 |
db.redis.database | Redis 数据库编号 | 0 |
domain | 前端访问域名(含端口) | localhost:18000 |
protocol | 协议类型(http / https) | http |
oidc.issuer | OIDC 签发者地址 | http://localhost:18001 |
oidc.login_url | OIDC 授权跳转的登录页地址 | 默认 {issuer}/sign-in |
oidc.access_token_ttl | Access Token 有效期(秒) | 3600 |
oidc.refresh_token_ttl | Refresh Token 有效期(秒) | 1209600 |
oidc.id_token_ttl | ID Token 有效期(秒) | 3600 |
oidc.auth_code_ttl | Authorization Code 有效期(秒) | 600 |
admin.jwt_secret | 管理后台 JWT 签名密钥 | 必须手动设置 |
web.port | 后端服务监听端口 | 18001 |
web.domains.console | Admin 控制台域名 | 空(生产环境必填) |
web.domains.platform | 平台管理域名 | 空(生产环境必填) |
web.domains.auth | 认证服务域名 | 空(生产环境必填) |
web.domains.docs | 文档站域名 | 空(可选,如 docs.your-domain.com) |
数据库迁移
Code Bird Cloud 使用 GORM AutoMigrate 自动完成数据库表结构迁移。服务启动时会自动创建或更新所有必需的数据表,包括:
- 核心身份:
tenants、users、admin_users、platform_admins - 应用管理:
applications - RBAC:
resources、scopes、roles及关联表 - OIDC 存储:
signing_keys、oidc_auth_codes、oidc_access_tokens、oidc_refresh_tokens、oidc_pkces - 连接器:
connectors - 登录体验:
sign_in_experiences - 审计日志:
logs - 组织管理:
organizations、organization_roles、organization_permissions及关联表 - 验证码:
verification_codes
无需手动执行 SQL 迁移脚本。
首次初始化
前提条件
在执行初始化之前,请确保:
- PostgreSQL 数据库已启动并可连接
- Redis 服务已启动
- 配置文件
backend/conf/app.yaml已正确填写数据库连接信息 - 后端项目依赖已安装(已执行
make init或go mod download)
运行初始化命令
根据部署方式选择对应的初始化方式:
# 方式一:go run 直接运行
cd backend
go run main.go init
# 方式二:使用已编译的二进制文件
cd backend
./bin/main init
# 方式三:Docker 容器内运行
docker exec -it code-bird-cloud ./main init交互式初始化流程
运行 init 命令后,系统会依次执行以下步骤:
第一步:创建默认租户
系统自动创建 ID 为 default 的默认租户。如果已存在则跳过。
开始初始化...
正在创建默认租户...第二步:创建平台超级管理员
系统会提示交互式输入管理员信息:
正在创建管理员用户...
请输入邮箱: admin@example.com
请输入密码: ******
请输入用户名: admin
请输入显示名称(可选,回车跳过):输入验证规则:
| 字段 | 验证规则 |
|---|---|
| 邮箱 | 标准邮箱格式 |
| 密码 | 至少 8 个字符,不能包含空格 |
| 用户名 | 至少 3 个字符 |
| 显示名称 | 可选,可直接回车跳过 |
如果管理员用户已存在(例如重复执行 init),系统会自动跳过此步骤。
第三步:生成签名密钥
系统自动生成 ECDSA P-256 签名密钥,用于 JWT 令牌的签名与验证。密钥以 JWK(JSON Web Key)格式存储在数据库中。
正在生成 ECDSA 签名密钥...
签名密钥创建成功 (kid: xxxxxxxxxxxx)密钥特性:
| 属性 | 说明 |
|---|---|
| 算法 | ECDSA P-256(ES256) |
| 用途 | JWT 签名(use: "sig") |
| 存储 | 加密存储在数据库 signing_keys 表中 |
| 标识 | 每个密钥有唯一的 kid(Key ID),用于 JWKS 端点 |
第四步:创建默认登录体验配置
系统自动创建默认的登录体验配置:
- 登录方式:用户名 + 密码登录、邮箱 + 密码登录、邮箱 + 验证码登录
- 注册方式:邮箱注册,需要密码和邮箱验证
- 密码策略:最少 8 个字符,默认不强制要求大小写、数字或特殊字符
正在创建默认登录体验配置...
初始化完成!完整初始化输出示例
开始初始化...
正在创建默认租户...
正在创建管理员用户...
请输入邮箱: admin@example.com
请输入密码: ******
请输入用户名: admin
管理员用户创建成功: admin
正在生成 ECDSA 签名密钥...
签名密钥创建成功 (kid: abc123xyz)
正在创建默认登录体验配置...
初始化完成!
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
初始化成功
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Platform Super Admin: admin@example.com
用户名: admin
访问地址:
Platform Admin Console: http://localhost:18002/ (开发模式)
生产环境请配置 web.domains 后通过对应域名访问
下一步:
1. 启动后端服务: make dev
2. 登录 Platform Admin Console
3. 在后台创建租户和租户管理员
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━初始化完成后
系统自动创建的数据
| 数据项 | 说明 |
|---|---|
| 默认租户 | ID 为 default 的系统租户 |
| 平台超级管理员 | 拥有最高权限的管理员账户,用于登录 Platform Admin Console |
| ECDSA 签名密钥 | 用于 OIDC/JWT 令牌签名的 ES256 密钥对 |
| 默认登录体验 | 预配置的登录/注册方式和密码策略 |
接下来的操作
- 启动后端服务(
make dev或./bin/main --env=prod) - 访问 Platform Admin Console:
- 开发模式:
http://localhost:18002/(需启动 Platform Admin 前端 dev server) - 生产环境:
https://platform.your-domain.com/(需配置web.domains.platform)
- 开发模式:
- 在 Platform Admin Console 中创建租户和租户管理员
- 租户管理员使用 Admin Console 管理租户内的用户、应用和权限
- 创建 OAuth2 应用(Application),获取 Client ID 用于接入
- 配置连接器(邮件/短信),启用验证码登录和注册功能
- 阅读 API 参考文档 了解完整的 Management API 接口
安全提示
- 管理员密码 -- 请使用高强度密码,初始化后建议定期更换
- JWT 密钥 -- 请确保
app.yaml中的admin.jwt_secret已替换为随机字符串 - 签名密钥 -- ECDSA 私钥存储在数据库中,请确保数据库访问安全
- 重复执行 --
init命令支持幂等操作,已存在的数据会自动跳过,不会覆盖
常见问题
初始化失败:数据库连接错误
请检查 backend/conf/app.yaml 中的数据库配置是否正确,并确认 PostgreSQL 服务已启动。常见原因包括:
- 数据库主机地址或端口错误
- 数据库用户名或密码错误
- 数据库
codebird未创建 - 网络不通(Docker 环境中需注意容器网络配置)
初始化失败:提交事务失败
可能是数据库权限不足。请确保数据库用户拥有 CREATE TABLE 和 INSERT 权限。
如何重新创建管理员?
init 命令会检测管理员是否已存在。如需重新创建,可先在数据库中删除 platform_admins 表中的记录,然后重新运行 init 命令。
如何更换签名密钥?
删除 signing_keys 表中对应租户的记录后重新运行 init 命令,系统会自动生成新的密钥对。注意:更换密钥后,之前签发的 JWT 令牌将无法验证。
Redis 连接失败
请确认 Redis 服务已启动,并检查 app.yaml 中的 Redis 配置是否正确。如果 Redis 需要密码认证,请在配置文件中添加 password 字段。
Docker 容器无法访问数据库
如果 PostgreSQL 和 Redis 运行在宿主机上,Docker 容器中的 127.0.0.1 指向容器自身而非宿主机。解决方案:
- 使用
host.docker.internal(macOS / Windows)作为数据库主机地址 - 使用
--network=host模式运行容器(Linux) - 将数据库服务也运行在 Docker 网络中,使用容器名称访问
