diff --git a/README.md b/README.md index de3b28d..61f984b 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,7 @@ These services require building custom Docker images from source. | [Gitea](./src/gitea) | 1.25.4-rootless | | [GitLab Runner](./src/gitlab-runner) | 17.10.1 | | [GitLab](./src/gitlab) | 18.8.3-ce.0 | +| [GoModel](./src/gomodel) | v0.1.25 | | [GPUStack](./src/gpustack) | v0.5.3 | | [Grafana](./src/grafana) | 12.3.2 | | [Grafana Loki](./src/loki) | 3.3.2 | diff --git a/README.zh.md b/README.zh.md index 4a221b1..9dd1b10 100644 --- a/README.zh.md +++ b/README.zh.md @@ -88,6 +88,7 @@ docker compose exec redis redis-cli ping | [Gitea](./src/gitea) | 1.25.4-rootless | | [GitLab Runner](./src/gitlab-runner) | 17.10.1 | | [GitLab](./src/gitlab) | 18.8.3-ce.0 | +| [GoModel](./src/gomodel) | v0.1.25 | | [GPUStack](./src/gpustack) | v0.5.3 | | [Grafana](./src/grafana) | 12.3.2 | | [Grafana Loki](./src/loki) | 3.3.2 | diff --git a/src/gomodel/.env.example b/src/gomodel/.env.example new file mode 100644 index 0000000..e18d503 --- /dev/null +++ b/src/gomodel/.env.example @@ -0,0 +1,87 @@ +# GoModel Configuration +# ===================== +# Copy this file to .env and fill in the values you need. +# All entries are optional — GoModel starts without any provider key +# configured, but will serve no models until at least one is set. + +# ---- Image version ---- +GOMODEL_VERSION=0.1.25 + +# ---- Network ---- +# Host port that maps to the container's port 8080 +GOMODEL_PORT_OVERRIDE=8080 + +# ---- Timezone ---- +TZ=UTC + +# ---- Security ---- +# Set a strong secret to protect all API endpoints. +# Without this key the gateway runs in UNSAFE (open) mode. +# Clients must send: Authorization: Bearer +# GOMODEL_MASTER_KEY=change-me-before-exposing-to-network + +# ---- Storage ---- +# Backend for audit logs and usage data. +# Options: sqlite (default), postgresql, mongodb +GOMODEL_STORAGE_TYPE=sqlite +# SQLite database file path inside the container (persisted via named volume) +# SQLITE_PATH=/app/data/gomodel.db + +# ---- Audit logging ---- +# Log all requests and responses to the configured storage backend. +# WARNING: May capture PII and API key values present in prompts. +GOMODEL_LOGGING_ENABLED=false + +# ---- Resource limits ---- +GOMODEL_CPU_LIMIT=1.00 +GOMODEL_MEMORY_LIMIT=512M +GOMODEL_CPU_RESERVATION=0.25 +GOMODEL_MEMORY_RESERVATION=128M + +# =========================================================================== +# Provider API Keys +# Set the credentials for every provider you want to route traffic through. +# Providers without a key (or base URL) are simply not registered. +# =========================================================================== + +# OpenAI +# OPENAI_API_KEY=sk-... +# OPENAI_BASE_URL=https://api.openai.com/v1 + +# Anthropic +# ANTHROPIC_API_KEY=sk-ant-... + +# Google Gemini +# GEMINI_API_KEY=... + +# Groq +# GROQ_API_KEY=gsk_... + +# xAI (Grok) +# XAI_API_KEY=... + +# DeepSeek +# DEEPSEEK_API_KEY=... + +# OpenRouter +# OPENROUTER_API_KEY=sk-or-... + +# Z.ai +# ZAI_API_KEY=... + +# Azure OpenAI +# AZURE_API_KEY=... +# AZURE_BASE_URL=https://your-resource.openai.azure.com/openai/deployments/your-deployment +# AZURE_API_VERSION=2024-10-21 + +# Oracle +# ORACLE_API_KEY=... +# ORACLE_BASE_URL=https://inference.generativeai.us-chicago-1.oci.oraclecloud.com/20231130/actions/v1 +# ORACLE_MODELS=openai.gpt-oss-120b,xai.grok-3 + +# Ollama (local inference server — no API key needed for default setup) +# OLLAMA_BASE_URL=http://host.docker.internal:11434/v1 + +# vLLM (OpenAI-compatible server — API key optional) +# VLLM_BASE_URL=http://host.docker.internal:8000/v1 +# VLLM_API_KEY=token-abc123 diff --git a/src/gomodel/README.md b/src/gomodel/README.md new file mode 100644 index 0000000..9f75569 --- /dev/null +++ b/src/gomodel/README.md @@ -0,0 +1,110 @@ +# GoModel + +[GoModel](https://github.com/ENTERPILOT/GoModel) is a fast, lightweight AI gateway written in Go. It exposes a single unified OpenAI-compatible API that transparently routes requests to OpenAI, Anthropic, Gemini, Groq, xAI, DeepSeek, OpenRouter, Azure OpenAI, Oracle, Ollama, vLLM, and more. It ships a built-in admin dashboard with token usage tracking, cost estimation, audit logging, and response caching. + +## Services + +| Service | Port | Description | +| ------- | ---- | ---------------------------------------------------- | +| GoModel | 8080 | OpenAI-compatible AI gateway API and admin dashboard | + +## Quick Start + +```bash +docker compose up -d +``` + +The gateway is available at `http://localhost:8080`. By default it starts in open (unauthenticated) mode with SQLite storage and no provider keys configured. + +To route real traffic, create a `.env` file from the example and add at least one provider credential: + +```bash +cp .env.example .env +# Edit .env — set GOMODEL_MASTER_KEY and at least one provider API key +docker compose up -d +``` + +Make your first API call: + +```bash +curl http://localhost:8080/v1/chat/completions \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer " \ + -d '{ + "model": "gpt-4o", + "messages": [{"role": "user", "content": "Hello!"}] + }' +``` + +Admin dashboard: `http://localhost:8080/admin/dashboard` + +List available models: `http://localhost:8080/v1/models` + +## Key Environment Variables + +### Gateway + +| Variable | Default | Description | +| ------------------------- | --------- | ------------------------------------------------------------------ | +| `GOMODEL_VERSION` | `0.1.25` | Docker image version | +| `GOMODEL_PORT_OVERRIDE` | `8080` | Host port for the API | +| `GOMODEL_MASTER_KEY` | _(empty)_ | API authentication key — **set this for any non-local deployment** | +| `GOMODEL_STORAGE_TYPE` | `sqlite` | Storage backend: `sqlite`, `postgresql`, or `mongodb` | +| `GOMODEL_LOGGING_ENABLED` | `false` | Enable full audit logging of requests and responses | +| `TZ` | `UTC` | Container timezone | + +### Provider Credentials + +Set the keys for whichever providers you want to use. Unset entries are silently ignored. + +| Variable | Provider | +| ------------------------------------ | ----------------------------- | +| `OPENAI_API_KEY` | OpenAI | +| `ANTHROPIC_API_KEY` | Anthropic | +| `GEMINI_API_KEY` | Google Gemini | +| `GROQ_API_KEY` | Groq | +| `XAI_API_KEY` | xAI (Grok) | +| `DEEPSEEK_API_KEY` | DeepSeek | +| `OPENROUTER_API_KEY` | OpenRouter | +| `ZAI_API_KEY` | Z.ai | +| `AZURE_API_KEY` + `AZURE_BASE_URL` | Azure OpenAI | +| `ORACLE_API_KEY` + `ORACLE_BASE_URL` | Oracle | +| `OLLAMA_BASE_URL` | Ollama (local, no key needed) | +| `VLLM_BASE_URL` | vLLM (local, key optional) | + +See `.env.example` for the full list including Azure, Oracle, and per-provider model lists. + +## Storage + +| Volume | Mount | Description | +| --------------- | ------------- | ------------------------------------------ | +| `gomodel_data` | `/app/data` | SQLite database, usage, and audit log data | +| `gomodel_cache` | `/app/.cache` | Model metadata registry cache | + +The default storage backend is SQLite (`/app/data/gomodel.db`). Switch to PostgreSQL or MongoDB by setting `GOMODEL_STORAGE_TYPE` and the corresponding `POSTGRES_URL` or `MONGODB_URL` environment variable. + +## API Endpoints + +| Endpoint | Description | +| --------------------------- | --------------------------------------------------- | +| `GET /v1/models` | List available models from all configured providers | +| `POST /v1/chat/completions` | Chat completions (streaming supported) | +| `POST /v1/embeddings` | Text embeddings | +| `POST /v1/responses` | OpenAI Responses API | +| `GET /health` | Health probe | +| `GET /admin/dashboard` | Admin UI — usage, costs, audit log | +| `GET /metrics` | Prometheus metrics (when `METRICS_ENABLED=true`) | + +## Security Notes + +- **`GOMODEL_MASTER_KEY` is unset by default.** Without it, all API endpoints are publicly accessible. Set a strong secret before exposing the service on any network beyond localhost. +- The container runs as a non-root user (UID 65532) on a read-only root filesystem. +- `cap_drop: [ALL]` — no Linux capabilities required. +- Never pass API keys via the command line; use the `.env` file or environment variables. +- Audit log bodies (`LOGGING_LOG_BODIES`) may capture PII and API keys embedded in prompts — keep it disabled unless you control the data retention pipeline. + +## Links + +- [GitHub Repository](https://github.com/ENTERPILOT/GoModel) +- [Documentation](https://gomodel.enterpilot.io/docs) +- [Docker Hub](https://hub.docker.com/r/enterpilot/gomodel) diff --git a/src/gomodel/README.zh.md b/src/gomodel/README.zh.md new file mode 100644 index 0000000..931d3e1 --- /dev/null +++ b/src/gomodel/README.zh.md @@ -0,0 +1,110 @@ +# GoModel + +[GoModel](https://github.com/ENTERPILOT/GoModel) 是一个用 Go 编写的快速、轻量级 AI 网关。它通过单一统一的 OpenAI 兼容 API,透明地将请求路由到 OpenAI、Anthropic、Gemini、Groq、xAI、DeepSeek、OpenRouter、Azure OpenAI、Oracle、Ollama、vLLM 等众多提供商。内置管理仪表盘,支持 Token 用量追踪、成本估算、审计日志和响应缓存。 + +## 服务组件 + +| 服务 | 端口 | 说明 | +| ------- | ---- | -------------------------------------- | +| GoModel | 8080 | OpenAI 兼容的 AI 网关 API 及管理仪表盘 | + +## 快速开始 + +```bash +docker compose up -d +``` + +服务启动后可通过 `http://localhost:8080` 访问。默认以开放(无鉴权)模式运行,使用 SQLite 存储,且未配置任何提供商密钥。 + +接入真实流量,请先从示例文件创建 `.env` 并填入至少一个提供商凭据: + +```bash +cp .env.example .env +# 编辑 .env,设置 GOMODEL_MASTER_KEY 以及至少一个提供商 API Key +docker compose up -d +``` + +发起第一次 API 调用: + +```bash +curl http://localhost:8080/v1/chat/completions \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer " \ + -d '{ + "model": "gpt-4o", + "messages": [{"role": "user", "content": "你好!"}] + }' +``` + +管理仪表盘:`http://localhost:8080/admin/dashboard` + +查看可用模型列表:`http://localhost:8080/v1/models` + +## 关键环境变量 + +### 网关配置 + +| 变量 | 默认值 | 说明 | +| ------------------------- | -------- | ------------------------------------------------ | +| `GOMODEL_VERSION` | `0.1.25` | Docker 镜像版本 | +| `GOMODEL_PORT_OVERRIDE` | `8080` | API 宿主机端口 | +| `GOMODEL_MASTER_KEY` | _(空)_ | API 鉴权密钥——**向本机以外的网络暴露时必须设置** | +| `GOMODEL_STORAGE_TYPE` | `sqlite` | 存储后端:`sqlite`、`postgresql` 或 `mongodb` | +| `GOMODEL_LOGGING_ENABLED` | `false` | 是否启用完整的请求/响应审计日志 | +| `TZ` | `UTC` | 容器时区 | + +### 提供商凭据 + +仅需设置你要使用的提供商密钥,未设置的条目会被静默忽略。 + +| 变量 | 提供商 | +| ------------------------------------ | ------------------------ | +| `OPENAI_API_KEY` | OpenAI | +| `ANTHROPIC_API_KEY` | Anthropic | +| `GEMINI_API_KEY` | Google Gemini | +| `GROQ_API_KEY` | Groq | +| `XAI_API_KEY` | xAI(Grok) | +| `DEEPSEEK_API_KEY` | DeepSeek | +| `OPENROUTER_API_KEY` | OpenRouter | +| `ZAI_API_KEY` | Z.ai | +| `AZURE_API_KEY` + `AZURE_BASE_URL` | Azure OpenAI | +| `ORACLE_API_KEY` + `ORACLE_BASE_URL` | Oracle | +| `OLLAMA_BASE_URL` | Ollama(本地,无需密钥) | +| `VLLM_BASE_URL` | vLLM(本地,密钥可选) | + +完整变量列表(含 Azure、Oracle 及各提供商模型列表配置)请参见 `.env.example`。 + +## 存储 + +| 数据卷 | 挂载路径 | 说明 | +| --------------- | ------------- | --------------------------------- | +| `gomodel_data` | `/app/data` | SQLite 数据库、用量数据及审计日志 | +| `gomodel_cache` | `/app/.cache` | 模型元数据注册表缓存 | + +默认使用 SQLite 存储(`/app/data/gomodel.db`)。如需切换至 PostgreSQL 或 MongoDB,请设置 `GOMODEL_STORAGE_TYPE` 及对应的 `POSTGRES_URL` 或 `MONGODB_URL` 环境变量。 + +## API 端点 + +| 端点 | 说明 | +| --------------------------- | ------------------------------------------------ | +| `GET /v1/models` | 列出所有已配置提供商的可用模型 | +| `POST /v1/chat/completions` | 聊天补全(支持流式输出) | +| `POST /v1/embeddings` | 文本向量嵌入 | +| `POST /v1/responses` | OpenAI Responses API | +| `GET /health` | 健康探针 | +| `GET /admin/dashboard` | 管理界面——用量、成本、审计日志 | +| `GET /metrics` | Prometheus 指标(需设置 `METRICS_ENABLED=true`) | + +## 安全说明 + +- **`GOMODEL_MASTER_KEY` 默认为空。** 未设置时,所有 API 端点均可公开访问。在将服务暴露到 localhost 以外的网络前,请务必设置强密钥。 +- 容器以非 root 用户(UID 65532)运行,根文件系统为只读。 +- `cap_drop: [ALL]`——无需任何 Linux 特权能力。 +- 请勿通过命令行传递 API 密钥;应使用 `.env` 文件或环境变量。 +- 审计日志体(`LOGGING_LOG_BODIES`)可能记录提示词中的敏感信息和 API 密钥,请在具备完整数据保留管控的情况下再启用。 + +## 相关链接 + +- [GitHub 仓库](https://github.com/ENTERPILOT/GoModel) +- [官方文档](https://gomodel.enterpilot.io/docs) +- [Docker Hub](https://hub.docker.com/r/enterpilot/gomodel) diff --git a/src/gomodel/docker-compose.yaml b/src/gomodel/docker-compose.yaml new file mode 100644 index 0000000..08f4aa3 --- /dev/null +++ b/src/gomodel/docker-compose.yaml @@ -0,0 +1,63 @@ +x-defaults: &defaults + restart: unless-stopped + logging: + driver: json-file + options: + max-size: 100m + max-file: '3' + +services: + gomodel: + <<: *defaults + image: ${GLOBAL_REGISTRY:-}enterpilot/gomodel:${GOMODEL_VERSION:-0.1.25} + ports: + - '${GOMODEL_PORT_OVERRIDE:-8080}:8080' + volumes: + - gomodel_data:/app/data + - gomodel_cache:/app/.cache + read_only: true + cap_drop: + - ALL + environment: + - TZ=${TZ:-UTC} + # Storage backend: sqlite (default), postgresql, or mongodb + - STORAGE_TYPE=${GOMODEL_STORAGE_TYPE:-sqlite} + - SQLITE_PATH=/app/data/gomodel.db + # Master key for API authentication — strongly recommended for production; + # leave empty to run in unsafe/open mode (local evaluation only) + - GOMODEL_MASTER_KEY=${GOMODEL_MASTER_KEY:-} + # Enable full audit logging of requests and responses to storage + - LOGGING_ENABLED=${GOMODEL_LOGGING_ENABLED:-false} + # Provider API keys — set at least one; unused entries are safely ignored + - OPENAI_API_KEY=${OPENAI_API_KEY:-} + - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:-} + - GEMINI_API_KEY=${GEMINI_API_KEY:-} + - GROQ_API_KEY=${GROQ_API_KEY:-} + - XAI_API_KEY=${XAI_API_KEY:-} + - DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY:-} + - OPENROUTER_API_KEY=${OPENROUTER_API_KEY:-} + - ZAI_API_KEY=${ZAI_API_KEY:-} + # Ollama / vLLM base URLs (no key required for default local setups) + - OLLAMA_BASE_URL=${OLLAMA_BASE_URL:-} + - VLLM_BASE_URL=${VLLM_BASE_URL:-} + # The image is built on distroless/static-debian12:nonroot which ships no + # shell, wget, or curl. /gomodel --version exits 0 while the binary is + # alive and serves as a process-level liveness probe. + healthcheck: + test: [CMD, /gomodel, --version] + interval: 30s + timeout: 5s + retries: 3 + start_period: 15s + deploy: + resources: + limits: + cpus: ${GOMODEL_CPU_LIMIT:-1.00} + memory: ${GOMODEL_MEMORY_LIMIT:-512M} + reservations: + cpus: ${GOMODEL_CPU_RESERVATION:-0.25} + memory: ${GOMODEL_MEMORY_RESERVATION:-128M} + +volumes: + gomodel_data: + gomodel_cache: