内容
# 健身追踪器
> 后端、Telegram 小程序和 MCP,允许任何兼容的代理作为私人教练。
健身追踪器与 Hermes、Claude、Codex 或任何提供商无关。代理与运动员交谈,健身追踪器负责持久化配置文件、会话、锻炼、系列和测量。
## 包含内容
- **API**: FastAPI + SQLModel + PostgreSQL。
- **小程序**: Astro + Preact,由 API 提供服务。
- **MCP**: Streamable HTTP 的 FastMCP。
- **媒体**: 与 S3 兼容的 MinIO,用于图像和 GIF。
- **身份验证**: Telegram InitData 用于小程序和 MCP 共享密钥。
- **部署**: Docker Compose 或 Coolify。
```text
代理(Hermes、Claude、Codex、...)
│ MCP
▼
gym-tracker-mcp
│ API
▼
gym-tracker + Postgres + MinIO
│
▼
Telegram 小程序
```
## 使用 Docker Compose 快速启动
要求:Docker Engine 和 Docker Compose v2。
```bash
git clone https://github.com/jlfernandezfernandez/gym-tracker.git
cd gym-tracker
cp .env.example .env
# 本地开发:ENVIRONMENT=development 允许 auth 留空。
# 要测试 auth,请设置 TELEGRAM_BOT_TOKEN 和 COACH_API_KEY。
docker compose up -d
```
本地端点:
| 服务 | URL |
|---|---|
| 应用 + API + 小程序 | `http://localhost:8000` |
| MCP | `http://localhost:8001/mcp` |
| MinIO API | `http://localhost:9000` |
| MinIO 控制台 | `http://localhost:9001` |
检查启动:
```bash
curl http://localhost:8000/health
curl http://localhost:8001/health
docker compose ps
```
MCP 与代理独立。 在 Hermes、Claude、Codex 或其他 MCP 客户端中配置 URL:
```text
http://localhost:8001/mcp
```
## 在 Coolify 上部署
Coolify 的推荐安装使用独立资源,与项目的生产安装相同:
```text
持久化 PostgreSQL
持久化 MinIO
来自 Dockerfile 的应用程序
来自 Dockerfile.mcp 的 MCP
```
小程序可以使用 Coolify 提供的 URL 或自定义域名。域名是可选的。
完整指南:[`docs/deploy-coolify.md`](docs/deploy-coolify.md)。
在任何实际部署中,请配置 `ENVIRONMENT=production`。如果缺少 PostgreSQL、S3、Telegram、教练密钥或显式 CORS 源,应用程序将启动失败;生产环境不允许 `CORS_ORIGINS=*`。
## 配置
`.env.example` 包含完整参考:
| 变量 | 用途 |
|---|---|
| `ENVIRONMENT` | 本地 `development` 或实际部署 `production` |
| `DATABASE_URL` | 异步 PostgreSQL 连接 |
| `TELEGRAM_BOT_TOKEN` | 验证 Telegram InitData |
| `COACH_API_KEY` | 验证 MCP 调用 |
| `CORS_ORIGINS` | 允许的源,逗号分隔 |
| `S3_ENDPOINT` | MinIO/S3 端点 |
| `S3_ACCESS_KEY`、`S3_SECRET_KEY` | 对象存储凭证 |
| `S3_BUCKET`、`S3_REGION` | 存储桶和区域 |
| `EXERCISE_DATASET_REPOSITORY` | 存储库 `owner/repo`;使用其 `main` 分支 |
Docker Compose 默认仅在本地使用 `development` 作为默认值。
对于生产环境,请定义 `ENVIRONMENT=production` 并替换所有示例凭证。
## 域名和反向代理
如果您在反向代理后面公开小程序,请在 `.env` 或 Coolify 中配置:
```env
PUBLIC_APP_URL=https://gym.example.com
CORS_ORIGINS=https://gym.example.com
```
代理必须将域名发送到端口 `8000` 的 **app** 服务。
如果远程代理需要访问 MCP,请使用单独的域名发布它,例如:
```text
https://gym-mcp.example.com/mcp
```
使用 HTTPS 和 `COACH_API_KEY`。除非有特定原因,否则不要公开 PostgreSQL 或 MinIO。
## 持久化
用户数据不会存储在应用程序或 MCP 容器中:
| 数据 | 存储 |
|---|---|
| 配置文件、会话、系列和测量 | PostgreSQL |
| 图像和 GIF | MinIO |
在 Compose 中,持久化卷为:
```text
gym-tracker-postgres-data
gym-tracker-minio-data
```
正常重启或重新部署会保留数据。`docker compose down -v` 删除卷,仅应在从头开始时使用。持久化不能替代备份。
在 Coolify 中,为 PostgreSQL (`/var/lib/postgresql`) 和 MinIO (`/data`) 配置持久存储。请参阅 [`docs/deploy-coolify.md`](docs/deploy-coolify.md)。
## 代理和 MCP
MCP 公开产品操作:配置文件、测量、目录、会话(创建、更新日期/标题/备注、完成、删除)、系列和小程序链接。代理决定如何沟通以及何时使用每个工具。
指南:[`docs/agent-setup.md`](docs/agent-setup.md)。
可选的个性和操作模板位于 [`templates/`](templates/)。
## 开发
```bash
docker compose up -d --build
curl http://localhost:8000/health
```
`app-init` 在 API 启动前运行一次 `python -m scripts.bootstrap`。引导程序应用 Alembic,在内存中下载远程目录,更新 PostgreSQL,并仅将缺少的图像和 GIF 上传到 S3。不会在磁盘上保存目录或媒体,任何故障都会中止启动。
无 Docker:
```bash
cd backend
uv sync --locked
uv run python -m scripts.bootstrap
uv run uvicorn app.main:app --reload
```
后端检查:
```bash
uv run ruff format --check .
uv run ruff check .
uv run pyright
uv run pytest
```
## 结构
```text
backend/app/ API、模型、路由、服务和 S3 访问
backend/alembic/ PostgreSQL 迁移
backend/scripts/ 迁移引导 + 远程种子
backend/tests/ 后端测试
backend/pyproject.toml + uv.lock 锁定依赖和工具
frontend/ Astro + Preact 小程序
landing/ 静态登录页面(Astro + Tailwind)
mcp/ 代理无关的 MCP 工具
Dockerfile API + 小程序镜像
Dockerfile.mcp MCP 服务器镜像
Dockerfile.minio MinIO 镜像/配置
docker-compose.yml 完整本地栈
docs/ 部署、连接和设计系统指南(DESIGN.md)
templates/ 代理可选模板
```
## 多用户和安全
小程序通过 Telegram InitData 识别用户。MCP 必须在配置文件和会话操作中发送 `telegram_user_id`,以维护运动员之间的隔离。
- 不要分享 `TELEGRAM_BOT_TOKEN`、`COACH_API_KEY` 或 S3 凭证。
- 不要公开 PostgreSQL。
- 当小程序或 MCP 可以从 Internet 访问时,请使用 HTTPS。
- 使用带有共享令牌的链接;不要手动构建会话 URL。
## 贡献
请参阅 [`CONTRIBUTING.md`](CONTRIBUTING.md)。API 更改必须保持 MCP 和小程序的对齐。在打开 PR 之前,请确保 Docker Compose 启动并检查 `/health`。
## 许可证
MIT。请参阅 [`LICENSE`](LICENSE)。