Files
OllaHubBackend/README.md
T

9.0 KiB

O que é

Um servidor HTTP e WebSocket em Rust (Actix Web) que cuida do Ollama por você: verifica se ele está instalado e respondendo, instala quando falta, lista e baixa modelos de um catálogo e conversa com eles por WebSocket. Traz também criptografia AES-256-GCM e um CRUD de usuários, com JWT e Swagger UI. O .env.example indica que os tokens vêm de um frontend separado.

Por que usar

  • Setup do Ollama num lugar só. GET /v2/api/ollama/check diz se o Ollama está no PATH, qual a versão e se a API responde (reachable, unreachable ou degraded). POST /v2/api/ollama/install instala por sistema: no Windows baixa o OllamaSetup.exe e roda /silent, no Linux usa o script oficial e no macOS extrai o zip em /Applications.
  • Chat que prepara o modelo. Em /v2/ws/chat, se o modelo pedido não estiver instalado, o servidor o baixa antes de responder e avisa o progresso por mensagens de status.
  • Contrato documentado pelo código. O OpenAPI é gerado com utoipa e servido no Swagger UI em /docs.

Quando não usar: exposto na internet ou em produção. Rotas que baixam e executam instaladores são públicas, os usuários ficam só em memória e o chat não faz streaming incremental. Se você só precisa conversar com um Ollama já instalado, a API dele na porta 11434 basta.

Important

Nem toda rota exige JWT. O middleware só protege /api/v1/*, /v2/api/crypto* e /v2/api/models*. Ficam públicas /health, /v2/health, /v2/api/ollama/* (inclusive POST /v2/api/ollama/install, que baixa e executa o instalador do Ollama), /docs e os WebSockets /v2/ws*. Por padrão o servidor escuta só em 127.0.0.1; só mude HOST sabendo disso. O .env.example vem com um JWT_SECRET preenchido (sem ele, o padrão é changeme-dev-secret): troque pelo seu.

Como funciona

  • src/main.rs, src/config.rs e src/state.rs: sobem o servidor, leem a configuração das variáveis de ambiente e montam o AppContext (eventos, criptografia, URL do Ollama, catálogo, segredo JWT).
  • src/api/: rotas v2 de saúde, modelos, Ollama e criptografia.
  • src/core/models.rs: lê o modelList.json (93 modelos; a API expõe name e description), consulta /api/tags e baixa com /api/pull do Ollama.
  • src/services/install/: instalação do Ollama por sistema operacional.
  • src/ws/: WebSockets de eventos (/v2/ws) e de chat (/v2/ws/chat).
  • src/crypto/: AES-256-GCM com nonce aleatório de 12 bytes antes do ciphertext; a chave fica em hex em <config do usuário>/OllaHubBackend/crypto_v2.key.
  • src/middlewares/: JWT, CORS com uma única origem, log de requisições e erros no formato {"error": "..."}.
  • src/routes/, src/controllers/ e src/repositories/: CRUD de usuários em /api/v1, com repositório em memória.

Início rápido

Requisitos: Rust (edição 2021) e um Ollama acessível, ou use POST /v2/api/ollama/install depois de subir o servidor.

Warning

No Windows, o servidor mexe na configuração da máquina ao iniciar. Se estiver elevado (administrador), cria regras de entrada no Firewall para as portas 8080 e 11434 (perfis Domain, Private e Public) e adiciona uma exclusão do Windows Defender para o próprio executável (Add-MpPreference). Sem privilégios de administrador, só registra avisos e segue.

git clone https://git.evandro.dev.br/evandro/OllaHubBackend.git
cd OllaHubBackend
cp .env.example .env      # troque JWT_SECRET e ajuste ALLOWED_ORIGINS
cargo run                 # sobe em http://127.0.0.1:8080

curl http://127.0.0.1:8080/health
curl http://127.0.0.1:8080/v2/api/ollama/check
curl -H "Authorization: Bearer <jwt>" http://127.0.0.1:8080/v2/api/models

cargo build --release gera o binário em target/release; cargo test roda o único teste do repositório (ida e volta da criptografia).

Uso

Swagger UI em /docs, OpenAPI em /api-doc/openapi.json. Referência completa em docs/API.md.

Método Rota JWT O que faz
GET /health não Resposta simples "ok"
GET /v2/health não {"status":"ok"}
GET /v2/api/ollama/check não Estado do Ollama: PATH, versão, API alcançável e problemas encontrados
POST /v2/api/ollama/install não 202 com operation_id; instala em background e espera a API responder (até 60 s). Falhas não voltam na resposta
GET /v2/api/models sim Modelos do modelList.json
POST /v2/api/models/install sim 202; baixa o modelo ({"name": "..."}) em background via /api/pull
POST /v2/api/crypto/set-key sim Define a chave AES-256 ({"hex_key": "<64 hex>"}) e a grava em disco
POST /v2/api/crypto/rotate-key sim Gera uma chave nova e a devolve em hex
POST /v2/api/crypto/encrypt sim {"data": "texto"} → {"ciphertext": "<base64>"}
POST /v2/api/crypto/decrypt sim {"data": "<base64>"} → {"plaintext": "texto"}
GET/POST /api/v1/users sim Lista ou cria usuário (nome com 2+ caracteres, e-mail válido)
GET/PUT/DELETE /api/v1/users/{id} sim Lê, atualiza ou remove usuário
WS /v2/ws não Eco de mensagens e pong
WS /v2/ws/chat não Chat com um modelo do Ollama

Autenticação: Authorization: Bearer <jwt>, assinado em HS256 com JWT_SECRET, com as claims sub e exp (e role opcional). A API não emite tokens: o segredo precisa ser o mesmo do serviço que os emite.

No /v2/ws/chat, envie um JSON por mensagem de texto:

{ "model": "llama3.2", "messages": [{ "role": "user", "content": "Olá" }], "options": { "temperature": 0.7 } }

O servidor responde com status (checking, ready, installing com progress, installed) e depois com as linhas JSON do /api/chat do Ollama. Falhas chegam como {"error": "...", "done": true}. Há ping a cada 5 s, e a conexão fecha após 30 s sem atividade do cliente.

Configuração

O .env é carregado com dotenv na inicialização; as variáveis são lidas em src/config.rs e src/middlewares/.

Variável Padrão Uso
HOST 127.0.0.1 Endereço de escuta
PORT 8080 Porta de escuta
OLLAMA_BASE_URL http://localhost:11434 API do Ollama
MODEL_LIST_PATH modelList.json Catálogo exposto em /v2/api/models
JWT_SECRET changeme-dev-secret Segredo HS256; deve ser o mesmo de quem emite os tokens
ALLOWED_ORIGINS http://localhost:3000 Única origem aceita pelo CORS (com credenciais)

SKIP_ANTIVIRUS_WARNINGS aparece no .env.example, mas nenhum código lê essa variável.

Estado do projeto

Versão 0.1.0, com três commits entre 2025-11-05 e 2025-11-18: estrutura inicial com API v2, WebSocket e instalação do Ollama. Limites conhecidos:

  • Usuários só em memória: o CRUD de /api/v1/users perde os dados ao reiniciar.
  • /v2/ws não envia eventos: só ecoa mensagens e responde a pings. O envio de eventos (PushEvent) existe no código, mas nunca é acionado.
  • Chat sem streaming incremental: a resposta do Ollama é lida por inteiro (timeout de 300 s) antes de as linhas serem repassadas. O pull_model faz o mesmo, então downloads também não mostram progresso em tempo real.
  • Erros silenciosos: falhas de instalação do Ollama e de download de modelos em background são descartadas.
  • Firewall fixo: a regra criada no Windows usa a porta 8080 literal, mesmo com outro PORT.
  • Documentação defasada: docs/OLLAMA.md e docs/API_EXAMPLES.md citam rotas antigas como /ollama/install-check; as atuais são /v2/api/ollama/check e /v2/api/ollama/install.

Licença

GPL-3.0: você pode usar, estudar, modificar e redistribuir o código, desde que versões distribuídas mantenham o código-fonte aberto sob a mesma licença. Construído com Actix Web, utoipa, jsonwebtoken, aes-gcm e sysinfo.