Add isolated Gemini image proxy

This commit is contained in:
“Naeel”
2026-08-28 19:20:51 +03:00
parent ec57cf5d57
commit df5afcec8f
11 changed files with 849 additions and 0 deletions
+76
View File
@@ -0,0 +1,76 @@
# Gemini Proxy
Минимальный изолированный HTTP-прокси для вызова Gemini с изображением.
## Назначение
Прокси принимает один crop изображения от основного российского сервера,
передаёт его в Gemini Developer API и возвращает текст модели вместе с
метаданными использования токенов.
В прокси нет бизнес-логики распознавания рецептов, словаря лекарств,
нормализации, scoring или хранения результатов. Эти функции находятся на
основном сервере.
## API
### `GET /health`
Возвращает:
```json
{"status":"ok"}
```
### `POST /gemini`
Формат: `multipart/form-data`.
Поле `image` должно содержать JPEG, PNG или WEBP размером не более 10 MB.
Необязательное поле `api_key_override` позволяет передать ключ только для
текущего запроса. Если оно не задано, используется `GEMINI_API_KEY` из
серверной конфигурации. Передача ключа в запросе менее безопасна и допустима
только по защищённому каналу между доверенными серверами; ключ не записывается
прокси в логи или на диск.
Ответ:
```json
{
"text": "{\"date\":null,\"medicines\":[]}",
"usage": {}
}
```
## Секреты
API-ключ не хранится в коде и не коммитится. Сервис читает:
- `GEMINI_API_KEY` — обязательный ключ;
- `GEMINI_MODEL` — модель, по умолчанию `gemini-3.6-flash`.
На сервере секрет хранится отдельно в `/etc/gemini-proxy/gemini-proxy.env`
с правами `600`, владельцем `root:gemini-proxy` и не доступен через HTTP.
## Изоляция
- отдельный пользователь `gemini-proxy`;
- отдельный каталог `/opt/gemini-proxy`;
- отдельный virtualenv;
- отдельный systemd-юнит;
- bind только на `127.0.0.1:8768`;
- изображения обрабатываются в памяти и не сохраняются приложением;
- существующие сервисы и их virtualenv не используются и не перезапускаются.
## Запуск
```text
systemctl status gemini-proxy
systemctl restart gemini-proxy
curl http://127.0.0.1:8768/health
```
Для внешнего доступа потребуется отдельный reverse-proxy маршрут nginx и
аутентификация между российским сервером и этим сервисом. До этого endpoint
доступен только локально на немецкой ВМ.