# Настройка Ollama Proxy --- ## Архитектура ``` Codex (клиентский ноутбук) ↓ HTTP-запрос с API-ключом в URL http://:8080/auth/<ключ>/v1 ↓ Go Proxy (сервер, порт 8080) ← единственная точка входа снаружи │ ├── извлечение API-ключа из URL │ ├── аутентификация пользователя │ ├── проверка доступа к модели │ ├── rate limiting │ └── приоритетная очередь (VIP первый) ↓ Ollama (сервер, localhost:11434) ← недоступна снаружи напрямую ``` --- ## Часть 1: Настройка сервера ### 1. Установить Ollama **Windows:** Скачать установщик с [ollama.com](https://ollama.com) и установить. **Linux:** ```bash curl -fsSL https://ollama.com/install.sh | sh ``` После установки скачать нужные модели (полный список смотрите на сайте ollama): ```bash ollama pull qwen2.5:1.5b ollama pull qwen3:8b ``` Проверить что модели скачались: ```bash ollama list ``` --- ### 2. Настроить переменные Ollama По умолчанию Ollama слушает `0.0.0.0` — это значит, что к ней можно подключиться напрямую из сети, минуя прокси. После настройки прокси Ollama должна слушать только `localhost`. **Windows** (PowerShell от имени администратора): ```powershell # Ollama слушает только localhost. Внешние подключения идут через прокси setx OLLAMA_HOST "127.0.0.1" /M # Модель остаётся в памяти 30 минут после последнего запроса. # Без этого каждый запрос ждёт повторной загрузки модели (15-30 сек) setx OLLAMA_KEEP_ALIVE "30m" /M # Количество параллельных запросов. # ВАЖНО: должно совпадать с MAX_PARALLEL в .env прокси setx OLLAMA_NUM_PARALLEL "2" /M # Ускорение инференса на GPU (если поддерживается) setx OLLAMA_FLASH_ATTENTION "1" /M ``` После `setx /M` закрой и открой PowerShell заново — иначе переменные не подхватятся. Запустить Ollama в новом PowerShell: ```powershell ollama serve ``` **Linux:** ```bash sudo systemctl edit ollama ``` Необходимо **между** строками `Anything between here and the comment below...` и `Edits below this comment will be discarded` вставить: ```ini [Service] Environment="OLLAMA_HOST=127.0.0.1" Environment="OLLAMA_KEEP_ALIVE=30m" Environment="OLLAMA_NUM_PARALLEL=2" Environment="OLLAMA_FLASH_ATTENTION=1" ``` Сохранить: `Ctrl+O` → `Enter` → `Ctrl+X`. Применить: ```bash sudo systemctl daemon-reload sudo systemctl restart ollama ``` Проверить что Ollama запущена: ```bash curl http://localhost:11434/api/tags ``` Должен вернуть JSON со списком установленных моделей. --- ### 3. Установить Go (только для сборки) Go нужен один раз — чтобы собрать бинарник прокси. **Windows:** Скачать установщик `goX.XX.X.windows-amd64.msi` с [go.dev/dl](https://go.dev/dl/) и установить. Проверить в новом PowerShell: ```powershell go version ``` **Linux:** ```bash wget https://go.dev/dl/go1.24.4.linux-amd64.tar.gz sudo tar -C /usr/local -xzf go1.24.4.linux-amd64.tar.gz echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc source ~/.bashrc go version ``` --- ### 4. Скопировать проект и собрать прокси ```bash git clone cd Proxy_for_codex # Скачать зависимости go mod download # Собрать бинарник # Windows: go build -o proxy.exe ./src # Linux: go build -o service ./src ``` --- ### 5. Создать конфиг пользователей Скопировать шаблон: ```bash # Windows: copy users.example.json users.json # Linux: cp users.example.json users.json ``` Открыть `users.json` для редактирования: **Windows** — открыть файл в любом текстовом редакторе (Блокнот, VS Code и т.д.). **Linux** (выполнять из папки проекта `Proxy_for_codex`): ```bash nano users.json ``` Как сохранить после изменений: `Ctrl+O` → `Enter` → `Ctrl+X`. Заполнить: ```json { "roles": { "vip": { "priority": 100, "allowed_models": ["qwen3:8b", "qwen2.5:1.5b"], "max_context_length": 32768, "rate_limit": { "requests": 60, "window": "1m" } }, "regular": { "priority": 10, "allowed_models": ["qwen2.5:1.5b"], "max_context_length": 8192, "rate_limit": { "requests": 20, "window": "1m" } } }, "users": { "ivanov-key-abc123": { "name": "Иванов", "role": "vip", "enabled": true }, "petrov-key-xyz789": { "name": "Петров", "role": "regular", "enabled": true } } } ``` **Поля конфигурации:** | Поле | Описание | |---|---| | `priority` | Приоритет в очереди. Когда все слоты заняты — VIP (100) обслуживается раньше regular (10) | | `allowed_models` | Белый список моделей. Пустой массив `[]` — доступны все модели | | `max_context_length` | Максимальный размер контекста (`num_ctx`). Прокси урежет запрос если превышен | | `rate_limit.requests` | Максимум запросов за окно | | `rate_limit.window` | Длительность окна: `"1m"`, `"30s"`, `"5m"` и т.д. | | `enabled` | `false` — пользователь заблокирован, все его запросы отклоняются с кодом 401 | **API-ключи** — любые строки, которые придумывает администратор. Каждый сотрудник получает свой уникальный ключ. Например: `ivanov-2024-abc`, `petrov-key-001`. --- ### 6. Создать файл .env **Windows** — создать файл `.env` в папке проекта в любом текстовом редакторе. **Linux** (выполнять из папки проекта `Proxy_for_codex`): ```bash nano .env ``` Как сохранить после изменений: `Ctrl+O` → `Enter` → `Ctrl+X`. Содержимое файла: ``` # Адрес и порт, на котором прокси принимает входящие подключения. # :8080 = все сетевые интерфейсы, порт 8080 LISTEN_ADDR=:8080 # URL бэкенда Ollama. Должен быть доступен только локально OLLAMA_BACKEND=http://localhost:11434 # Количество параллельных запросов к Ollama. # ОБЯЗАТЕЛЬНО должно совпадать с OLLAMA_NUM_PARALLEL MAX_PARALLEL=2 # Максимальный размер очереди ожидания. При переполнении — 503 MAX_QUEUE_SIZE=100 # Путь к файлу пользователей. # Можно указать абсолютный путь, если запускаете прокси из другой папки USERS_CONFIG_PATH=users.json # Ключ для admin API (чтобы менять users.json без перезапуска прокси). # Придумайте длинную случайную строку ADMIN_API_KEY=my-secret-admin-key # Уровень логирования: debug, info, warn, error LOG_LEVEL=info ``` --- ### 7. Запустить прокси **Windows:** ```powershell cd d:\путь\к\Proxy_for_codex .\proxy.exe ``` **Linux:** ```bash cd ~/Proxy_for_codex ./service ``` При успешном запуске: ``` level=INFO msg="Starting Ollama Proxy version 2.0.0" level=INFO msg="Конфигурация пользователей загружена" path=users.json active_users=2 total_users=2 level=INFO msg="Прокси запущен" addr=:8080 backend=http://localhost:11434 max_parallel=2 max_queue=100 auth_enabled=true ``` > Если `auth_enabled=false` — значит `users.json` не найден или содержит ошибку. Прокси работает, но без аутентификации. --- ### 8. Открыть порт в файрволе **Windows** (PowerShell от имени администратора): ```powershell New-NetFirewallRule -DisplayName "Ollama Proxy" -Direction Inbound -Port 8080 -Protocol TCP -Action Allow ``` **Linux:** ```bash # Проверить статус файрвола sudo ufw status # Если Status: active — открыть порт sudo ufw allow 8080/tcp ``` Если `Status: inactive` — файрвол выключен, ничего делать не нужно. --- ## Часть 2: Настройка клиента ### 1. Установить Codex **Windows:** Установить [Node.js](https://nodejs.org), затем в PowerShell: ```powershell npm install -g @openai/codex ``` **Linux:** ```bash curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash - sudo apt-get install -y nodejs npm install -g @openai/codex ``` --- ### 2. Настроить конфиг Codex Codex по умолчанию обращается к серверам OpenAI. Чтобы перенаправить его на наш прокси — нужно создать файл конфигурации и указать адрес прокси и API-ключ. #### Где находится файл конфига **Linux:** ```bash mkdir -p ~/.codex nano ~/.codex/config.toml ``` **Windows** — найти файл по пути: ``` C:\Users\<ваш_логин>\.codex\config.toml ``` #### Содержимое конфига Вставить следующее, **заменив два значения** (объяснение ниже): ```toml # Модель по умолчанию, ставьте какую хотите и какая скачана model = "qwen2.5:1.5b" model_provider = "ollama_proxy" [model_providers.ollama_proxy] name = "Ollama (прокси)" base_url = "http://:8080/auth/<ключ>/v1" wire_api = "responses" ``` **Что нужно заменить:** **``** — IP-адрес машины, где запущен прокси. Узнать IP сервера: - На сервере Windows: `ipconfig` → строка `IPv4-адрес` - На сервере Linux: `hostname -I` → первое число **`<ключ>`** — персональный API-ключ сотрудника из `users.json` на сервере. Администратор выдаёт каждому сотруднику свой ключ. **Пример готового конфига для Иванова** с ключом `ivanov-key-abc123` и сервером `10.111.111.40`: ```toml model = "qwen2.5:1.5b" model_provider = "ollama_proxy" [model_providers.ollama_proxy] name = "Ollama (прокси)" base_url = "http://10.111.111.40:8080/auth/ivanov-key-abc123/v1" wire_api = "responses" ``` > Поле `model` — модель по умолчанию, которая используется при обычном запуске `codex`. Прокси проверит, разрешена ли эта модель для роли пользователя. Если нет — вернёт ошибку 403. --- ### 3. Запуск Запустить Codex с моделью по умолчанию (из конфига): ```bash codex ``` Запустить с другой моделью (если роль позволяет): ```bash codex -m qwen3:8b #или любая другая модель ``` Codex отправит запрос на прокси → прокси проверит ключ → проверит, разрешена ли модель → поставит в очередь если все слоты заняты → Ollama сгенерирует ответ. **Если что-то не работает** — попросить администратора сервера посмотреть логи прокси: там будет видно, отклонён ли запрос и по какой причине (неверный ключ, запрещённая модель, превышен rate limit). --- ## Часть 3: Администрирование ### Изменение users.json без перезапуска прокси Можно менть положение клиентов и их роли во время работы прокси без его перезапуска. Достаточно в `users.json` изменить что хотите и тогда после любых изменений в `users.json` — добавления пользователя, смены роли, блокировки — отправить команду reload: ```bash # Linux / Windows (в Git Bash или WSL): curl -X POST -H "Authorization: Bearer my-secret-admin-key" http://localhost:8080/admin/reload # Windows PowerShell: curl -Method POST -Headers @{"Authorization"="Bearer my-secret-admin-key"} http://localhost:8080/admin/reload ``` Ответ: `{"status":"reloaded"}` > `my-secret-admin-key` — заменить на значение `ADMIN_API_KEY` из файла `.env` на сервере. --- ### Заблокировать пользователя В `users.json` поставить `"enabled": false` и выполнить reload: ```json "petrov-key-xyz789": { "name": "Петров", "role": "regular", "enabled": false } ``` --- ### Сменить роль пользователя В `users.json` поменять `"role"` и выполнить reload: ```json "petrov-key-xyz789": { "name": "Петров", "role": "vip", "enabled": true } ``` --- ### Мониторинг логов **Windows** — логи выводятся в терминал, где запущен `proxy.exe`. **Linux (systemd):** ```bash # Следить за логами в реальном времени sudo journalctl -u ollama-proxy -f # Последние 50 строк sudo journalctl -u ollama-proxy -n 50 ``` Примеры записей: ``` level=INFO msg="запрос" method=POST path=/v1/responses status=200 duration=3.456s level=INFO msg="запрос вышел из очереди" priority=100 in_flight=1 queued=0 level=WARN msg="Запрос к запрещённой модели" user=Петров role=regular model=qwen3:8b allowed=[qwen2.5:1.5b] level=WARN msg="Превышен rate limit" user=Петров role=regular limit=20 window=1m0s level=WARN msg="Невалидный API-ключ" key_prefix=unknown-*** ``` --- ## HTTP-коды ошибок | Код | Причина | Решение | |---|---|---| | 401 | Нет ключа или невалидный | Проверить `base_url` в config.toml — ключ должен быть между `/auth/` и `/v1` | | 403 | Модель запрещена для роли | Добавить модель в `allowed_models` роли в `users.json` | | 429 | Превышен rate limit | Подождать или увеличить лимит в роли | | 502 | Ollama не отвечает | Проверить что Ollama запущена на сервере | | 503 | Очередь переполнена | Увеличить `MAX_QUEUE_SIZE` или `MAX_PARALLEL` в `.env` | --- ## Важно: MAX_PARALLEL и OLLAMA_NUM_PARALLEL Эти два значения **обязаны совпадать**: - `MAX_PARALLEL` в `.env` прокси — сколько запросов прокси одновременно пропускает к Ollama - `OLLAMA_NUM_PARALLEL` в переменных среды сервера — сколько запросов Ollama обрабатывает параллельно Если значения расходятся (например, прокси=3, Ollama=2) — третий запрос попадёт во внутреннюю очередь Ollama, минуя приоритетную очередь прокси. VIP не получит преимущества.