仓库自包含化:Docker/CI/文档/规范入库,路由分组拆分
CI / test (push) Successful in 15s

This commit is contained in:
Wang Defa
2026-07-09 19:18:04 +08:00
parent b9a3e97e84
commit 3e0389c1e9
83 changed files with 20241 additions and 248 deletions
+104
View File
@@ -0,0 +1,104 @@
<div align="center">
<img src="docs/assets/logo.svg" width="104" alt="OCI Portal logo">
# OCI Portal
**Oracle Cloud Infrastructure 多租户管理面板**
![Go](https://img.shields.io/badge/Go-1.26-00ADD8?logo=go&logoColor=white)
![License](https://img.shields.io/badge/License-MIT-blue)
![Docker](https://img.shields.io/badge/Docker-amd64%20%7C%20arm64-2496ED?logo=docker&logoColor=white)
本仓库为后端;前端工程见 [oci-portal-dash](https://github.com/wangdefaa/oci-portal-dash)(构建产物嵌入本服务成单文件)
</div>
## 界面预览
| 总览 | 登录 |
| --- | --- |
| ![总览](docs/assets/screenshot-overview.png) | ![登录](docs/assets/screenshot-signin.png) |
| 租户 | 任务 |
| --- | --- |
| ![租户](docs/assets/screenshot-tenants.png) | ![任务](docs/assets/screenshot-tasks.png) |
| AI 网关 | 通知设置 |
| --- | --- |
| ![AI 网关](docs/assets/screenshot-ai-gateway.png) | ![通知设置](docs/assets/screenshot-settings-notify.png) |
## 特性
- **多租户管理**:多份 OCI API Key 配置集中管理,私钥/口令 AES-256-GCM 加密落库;分组、批量测活、账户类型与订阅信息识别
- **资源管理**:实例(含创建/电源操作/更换公网 IP/IPv6/VNIC/引导卷)、VCN/子网/安全列表、块存储、限额与成本查询,多区域/多区间支持
- **抢机任务**:cron 周期尝试创建实例直到成功,支持熔断与通知
- **网页控制台**:实例串行控制台(xterm)与 VNC(noVNC),两跳 SSH 隧道
- **AI 网关**OpenAI / Anthropic 兼容端点转发 OCI GenAI(对话/Responses/Embeddings),号池渠道加权负载均衡、熔断探测、密钥管理与用量日志
- **日志回传**OCI Audit 事件经 Connector Hub → Notifications HTTPS 订阅回传入库,一键创建链路
- **租户治理**IAM 用户/MFA/API Key 管理、密码策略、身份提供商(SAML)、通知收件人
- **安全**JWT + bcrypt、TOTP 两步验证、OIDC/GitHub 外部登录、登录锁定、IP 限速、真实 IP 头可配、系统操作审计
- **通知**Telegram 模板化推送(测活/抢机/成本/锁定等事件)
## 快速开始
### 二进制运行
从 Release 下载对应架构的二进制后:
```bash
DATA_KEY=$(openssl rand -hex 32) JWT_SECRET=$(openssl rand -hex 32) ADMIN_PASSWORD=<初始密码> ./oci-portal-server
```
访问 `http://localhost:8080`,用 `admin` 与初始密码登录。
### Docker Compose
```bash
DATA_KEY=$(openssl rand -hex 32) JWT_SECRET=$(openssl rand -hex 32) ADMIN_PASSWORD=<初始密码> docker compose up -d
```
### 源码构建(单文件,含前端)
```bash
# 1. 获取前端产物:从前端仓库 Release 下载 dist.zip(或本地 npm run build 后拷入)
curl -fL -o dist.zip https://github.com/wangdefaa/oci-portal-dash/releases/latest/download/dist.zip
rm -rf internal/webui/dist && mkdir -p internal/webui/dist && unzip -q dist.zip -d internal/webui/dist
# 2. 编译(免 CGO,可交叉编译)
CGO_ENABLED=0 go build -trimpath -ldflags "-s -w" -o bin/oci-portal-server ./cmd/server
```
> 注意:上述解压会覆盖仓库占位文件 `internal/webui/dist/index.html`,提交代码前勿把真实产物带入版本库。
## 环境变量
| 变量 | 必填 | 默认值 | 说明 |
| --- | --- | --- | --- |
| `DATA_KEY` | 是 | 无 | 敏感字段加密主密钥(更换后已入库密文无法解密) |
| `JWT_SECRET` | 是 | 无 | 登录令牌签名密钥 |
| `ADMIN_USERNAME` | 否 | `admin` | 初始管理员用户名 |
| `ADMIN_PASSWORD` | 首次启动是 | 无 | 仅在用户不存在时创建;已存在不重置 |
| `ADDR` | 否 | `:8080` | HTTP 监听地址 |
| `DB_DRIVER` | 否 | `sqlite` | `sqlite` / `mysql` / `postgres`(后两者 experimental |
| `DB_DSN` | 外部库时是 | 无 | MySQL 需 `parseTime=True`PostgreSQL 标准 DSN |
| `DB_PATH` | 否 | `oci-portal.db` | SQLite 文件路径 |
| `PUBLIC_URL` | 否 | 无 | 面板公网基址,日志回传一键创建链路用 |
| `HTTPS_PROXY` | 否 | 无 | 出站代理(如 Telegram 通知走代理) |
| `TZ` | 否 | 系统 | cron 表达式解释时区(容器内建议显式设置,二进制已嵌 tzdata) |
| `SWAGGER` | 否 | 关 | `1` 时开放 `/swagger/index.html` API 文档(生产建议按需临时开启) |
## 开发
```bash
go test ./... # 全量测试
go vet ./... && gofmt -l .
go tool swag init -g cmd/server/main.go -o docs --parseInternal --parseDependency # 接口注释变更后重新生成 OpenAPI
```
API 文档:全部接口带 swaggo 注释,`SWAGGER=1` 启动后访问 `/swagger/index.html`spec 文件在 `docs/swagger.json|yaml`
编码规范与项目约定见 [AGENTS.md](AGENTS.md) 与 [.trellis/spec/](.trellis/spec/)。
## License
[MIT](LICENSE)