| 工具 | 版本要求 | 安装方式 |
|---|---|---|
| Go | 1.22+ | golang.org/dl |
| Docker Desktop | 最新版 | docker.com |
| Node.js | 18+ | nodejs.org (推荐用 nvm) |
| Make | - | macOS 自带,Linux: apt install make |
验证安装:
go version # go1.22.x
docker --version # Docker version 2x.x
node --version # v18.x 或 v20.x
make --version # GNU Makegit clone https://github.com/anyfast/anyfast-cloud.git
cd anyfast-cloud
# 下载 Go 依赖
go mod tidy# 使用 docker compose 启动本地开发依赖
docker compose -f docker-compose.dev.yaml up -d
# 确认容器运行正常
docker ps正常输出应看到两个容器:
| 容器名 | 端口 | 说明 |
|---|---|---|
| anyfast-mysql | 3306 | MySQL 8.0,自动执行 init-db.sql |
| anyfast-redis | 6379 | Redis 7 Alpine |
# 连接 MySQL 验证
docker exec -it anyfast-mysql mysql -uroot -proot anyfast -e "
SELECT slug, name, type FROM tenants;
SELECT username, email FROM users;
SELECT role FROM user_roles;
SELECT count(*) AS menu_count FROM menus;
SELECT count(*) AS perm_count FROM permissions;
"期望输出:
- 1 个租户:
platform / AnyFast Platform / platform - 1 个用户:
admin / admin@anyfast.com - 1 个角色:
owner - 17 条菜单记录
- 多条权限记录
初始化脚本中的 bcrypt hash 对应密码 admin123。如果登录失败,可能是 hash 格式问题,手动生成:
# 使用 Go 生成正确的 bcrypt hash
go run -e 'package main
import (
"fmt"
"golang.org/x/crypto/bcrypt"
)
func main() {
hash, _ := bcrypt.GenerateFromPassword([]byte("admin123"), bcrypt.DefaultCost)
fmt.Println(string(hash))
}'或者更简单地直接更新:
# 先生成 hash
HASH=$(docker exec anyfast-mysql mysql -uroot -proot -N -e "
SELECT '\$2a\$10\$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy';
")
# 如果需要更新密码
docker exec anyfast-mysql mysql -uroot -proot anyfast -e "
UPDATE users SET password = '\$2a\$10\$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy' WHERE username = 'admin';
"默认管理员账号:
admin/admin123
# 终端 1: 启动 auth 服务 (端口 8080)
make dev-auth等价于:
ANYFAST_SERVER_HTTP_PORT=8080 ANYFAST_SERVER_GRPC_PORT=50051 go run ./cmd/auth/看到以下日志说明启动成功:
auth HTTP server listening on :8080 (version=dev)
快速验证:
# 健康检查
curl http://localhost:8080/health
# 期望: {"service":"auth","status":"ok"}
# 获取登录页品牌信息
curl http://localhost:8080/oauth/login?tenant=platform
# 期望: {"tenant_name":"AnyFast Platform","logo_url":"","theme_color":"#6c8cff"}
# 登录
curl -X POST http://localhost:8080/oauth/login \
-H "Content-Type: application/json" \
-d '{"tenant": "platform", "account": "admin", "password": "admin123"}'
# 期望: {"access_token":"eyJ...","expires_in":86400,"user":{...}}保存 access_token! 后续步骤会用到。
# 终端 2: 启动 core 服务 (端口 8081)
make dev-core等价于:
ANYFAST_SERVER_HTTP_PORT=8081 ANYFAST_SERVER_GRPC_PORT=50052 go run ./cmd/core/看到以下日志说明启动成功:
core HTTP server listening on :8081 (version=dev)
快速验证:
# 设置 token 变量 (替换为上一步获取的值)
TOKEN="eyJhbGciOiJIUzI1NiIs..."
# 健康检查
curl http://localhost:8081/health
# 期望: {"service":"core","status":"ok"}
# 获取菜单 (需要 JWT)
curl http://localhost:8081/api/menus \
-H "Authorization: Bearer $TOKEN"
# 期望: {"menus":[...],"permissions":[...]}
# 创建 API Key
curl -X POST http://localhost:8081/api/tokens \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "测试 Key"}'
# 期望: {"id":1,"name":"测试 Key","full_key":"sk-...","key_prefix":"sk-...","quota":-1,"rate_limit":60,"status":"active"}
# 查询 API Key 列表
curl http://localhost:8081/api/tokens \
-H "Authorization: Bearer $TOKEN"
# 期望: {"items":[...],"pagination":{...}}billing-svc、config-syncer、adapter-svc 在本地开发中通常不需要启动:
| 服务 | 是否必须 | 说明 |
|---|---|---|
| auth-svc | 是 | 登录/鉴权依赖 |
| core-svc | 是 | 前端所有 API 调用 |
| billing-svc | 否 | 需要 Kafka,本地可跳过 |
| config-syncer | 否 | 需要 Kafka + Higress,本地可跳过 |
| adapter-svc | 否 | 仅非标模型开发时需要 |
如果需要启动:
# 终端 3 (需先启动本地 Kafka)
make dev-billing
# 终端 4 (需先启动本地 Kafka)
make dev-syncer
# 终端 5
make dev-adapter # 端口 8082# 终端 3 (或新终端): 启动前端
cd web
npm install
npm run dev前端默认在 http://localhost:3000 启动。
环境变量 (已在代码中设置默认值,通常不需要额外配置):
| 变量 | 默认值 | 说明 |
|---|---|---|
NEXT_PUBLIC_API_URL |
http://localhost:8081 |
Core API 地址 |
NEXT_PUBLIC_AUTH_URL |
http://localhost:8080 |
Auth API 地址 |
如需自定义,创建 web/.env.local:
NEXT_PUBLIC_API_URL=http://localhost:8081
NEXT_PUBLIC_AUTH_URL=http://localhost:8080访问前端: 打开 http://localhost:3000,使用 admin / admin123 登录。
| 端口 | 服务 | 协议 | 说明 |
|---|---|---|---|
| 3000 | 前端 (Next.js) | HTTP | 开发服务器,热重载 |
| 3306 | MySQL | TCP | Docker 容器映射 |
| 6379 | Redis | TCP | Docker 容器映射 |
| 8080 | auth-svc | HTTP | 认证服务 |
| 8081 | core-svc | HTTP | 核心业务服务 |
| 8082 | adapter-svc | HTTP | 非标适配器 (可选) |
| 50051 | auth-svc | gRPC | gRPC 端口 |
| 50052 | core-svc | gRPC | gRPC 端口 |
所有配置都可以通过环境变量覆盖,前缀 ANYFAST_,层级用 _ 连接:
# 示例: 修改 MySQL 连接
ANYFAST_MYSQL_PRIMARY=192.168.1.100:3306 \
ANYFAST_MYSQL_USERNAME=dev \
ANYFAST_MYSQL_PASSWORD=dev123 \
make dev-auth
# 示例: 修改 JWT 过期时间
ANYFAST_JWT_EXPIRE_HOUR=1 make dev-auth常用覆盖项:
| 环境变量 | 默认值 | 说明 |
|---|---|---|
ANYFAST_SERVER_HTTP_PORT |
8080 | HTTP 端口 |
ANYFAST_MYSQL_PRIMARY |
127.0.0.1:3306 | MySQL 地址 |
ANYFAST_MYSQL_USERNAME |
root | MySQL 用户名 |
ANYFAST_MYSQL_PASSWORD |
root | MySQL 密码 |
ANYFAST_REDIS_ADDR |
127.0.0.1:6379 | Redis 地址 |
ANYFAST_JWT_SECRET |
dev-secret-... | JWT 密钥 |
ANYFAST_JWT_EXPIRE_HOUR |
24 | JWT 过期小时数 |
ANYFAST_KAFKA_BROKERS |
127.0.0.1:9092 | Kafka 地址 |
ANYFAST_OTEL_ENDPOINT |
(空) | OTel Collector 地址 |
Kafka 在本地开发中是可选的。
core-svc 创建 Producer 时,如果 Kafka brokers 为空或连接失败,会使用 Noop Producer 模式:
// NewProducer: brokers 为空时返回 noop producer
func NewProducer(brokers []string) *Producer {
if len(brokers) == 0 || brokers[0] == "" {
return &Producer{writers: nil} // noop
}
// ...
}
// Publish: noop 模式直接返回 nil
func (p *Producer) Publish(...) error {
if p.writers == nil {
return nil // noop mode
}
// ...
}这意味着:
- core-svc 正常工作,创建租户/Token 等操作不受影响
- 但不会发送 Kafka 事件,config-syncer 不会感知到变化
- billing-svc 不会处理用量数据
如果需要完整测试 Kafka 流程:
# 使用 docker 启动本地 Kafka
docker run -d --name kafka \
-p 9092:9092 \
-e KAFKA_CFG_NODE_ID=0 \
-e KAFKA_CFG_PROCESS_ROLES=controller,broker \
-e KAFKA_CFG_LISTENERS=PLAINTEXT://:9092,CONTROLLER://:9093 \
-e KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=0@localhost:9093 \
-e KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER \
bitnami/kafka:3.7原因: MySQL 容器未启动或未就绪。
解决:
# 检查容器状态
docker ps -a | grep anyfast-mysql
# 如果未运行,重新启动
docker compose -f docker-compose.dev.yaml up -d
# 等待 MySQL 就绪 (有 healthcheck,约 30 秒)
docker compose -f docker-compose.dev.yaml ps可能原因:
- 密码不对: 默认密码是
admin123 - bcrypt hash 异常: 某些环境下 init-db.sql 中的 hash 可能被转义
解决: 参考第四步重新生成 hash。
可能原因: 角色-菜单关联数据未初始化。
解决:
docker exec -it anyfast-mysql mysql -uroot -proot anyfast -e "
SELECT count(*) FROM role_menus WHERE role = 'owner';
"
# 如果是 0,重新执行初始化脚本
docker exec -i anyfast-mysql mysql -uroot -proot anyfast < scripts/init-db.sql原因: 本地开发使用单节点 Redis,不需要 Sentinel。
检查: 确保 configs/config.yaml 中 redis.master_name 为空:
redis:
addr: "127.0.0.1:6379"
master_name: "" # 留空 = 单节点模式原因: 后端 CORS 配置仅允许 localhost:3000。
解决:
- 确保前端在 3000 端口运行:
npm run dev(默认 3000) - 如果改了端口,需要修改
internal/pkg/middleware/cors.go中的AllowOrigins
# 查看端口占用
lsof -i :8080
lsof -i :3306
# 杀掉占用进程
kill -9 <PID>
# 或使用其他端口
ANYFAST_SERVER_HTTP_PORT=8090 make dev-auth# 设置 Go 代理 (国内)
go env -w GOPROXY=https://goproxy.cn,direct
go mod tidy| 层 | 热重载 | 说明 |
|---|---|---|
| Go 后端 | 否 | 修改代码后需要 Ctrl+C 重新 make dev-xxx |
| 前端 | 是 | Next.js 自动热重载,保存文件即生效 |
| MySQL | 否 | 修改 init-db.sql 后需重建容器或手动执行 SQL |
如果需要 Go 后端自动重载,可安装 air:
go install github.com/air-verse/air@latest
# 使用 air 启动 (自动监听文件变化)
ANYFAST_SERVER_HTTP_PORT=8080 air -c .air.toml -- ./cmd/auth/# 终端 1: 基础设施
docker compose -f docker-compose.dev.yaml up -d
# 等待 30 秒确保 MySQL 就绪
# 终端 2: auth 服务
make dev-auth
# 终端 3: core 服务
make dev-core
# 终端 4: 前端
cd web && npm install && npm run dev
# 浏览器打开 http://localhost:3000
# 用 admin / admin123 登录