Skip to content

🐳 Ollama no Google Cloud: Guia Completo

❓ Pergunta: "Como rodar Ollama no Google Cloud? Cloud Run serve?"

Resposta Rápida: - Cloud Run: ❌ Não é ideal (ephemeral, stateless) - Compute Engine: ✅ Perfeito (persistente, barato) - Ollama Cloud: ⭐ Melhor (managed, 0 ops)


📊 Comparação: Onde Rodar Ollama no GCP

Plataforma Cold Start Price/mês Setup State GPU Recomendação
Cloud Run 30-60s $5-20 Trivial ❌ Ephemeral ❌ Não
Compute E. <1s $20-30 30min ✅ Persistent ⚠️ SIM
GKE <1s $50-150 2h ✅ Persistent Overkill
Ollama Cloud <100ms $5-15 2min N/A BEST
Local (dev) N/A $0 5min Sim Dev only

❌ Por Que Cloud Run É Ruim para Ollama

Problema 1: Stateless Architecture

Cloud Run design:
└─ Starts container on request
└─ Runs handler
└─ Stops container after ~15 minutes idle

Mas Ollama precisa:
├─ Modelo carregado em memória
├─ Cache persistente entre requests
└─ Estado ininterrupto

Resultado:
├─ Request 1: Carrega modelo (~30s) + query (~1s) = 31s ⏱️ LENTO
├─ Request 2 (após 15min): Recarga modelo (~30s) + query (~1s) = 31s
└─ Request 3 (se <15min): Query (~1s) = 1s ✅

SLA: Imprevisível, usuários esperam 30s aleatoriamente

Problema 2: Ephemeral Storage

Cloud Run filesystem:
├─ /tmp é um tmpfs de 512MB
├─ Tudo é perdido ao container morrer
└─ Modelos Ollama = 270MB-7GB

Solução: Usar Cloud Storage + mounting
├─ Complexidade: Alta
├─ Latência: 100-500ms para carregar modelo
├─ Custo: $0.020/GB/mês storage + egress
└─ Overhead: Toda request começa com I/O

Realidade:
└─ Mais lento que simplesmente usar Compute Engine

Problema 3: Compute Engine

Cloud Run max: 4 vCPU, 16GB RAM
Ollama eficiente: 2 vCPU, 4GB RAM

Porém, problema = reuso:
├─ Cloud Run: Mata depois de 15min → reload
├─ Compute E.: Roda 24/7 → sempre pronto

Trade-off:
├─ Cloud Run: Economizar $10/mês custa +30s latência
└─ Compute E.: +$20/mês custa -30s latência (WIN)

✅ Solução Recomendada: Compute Engine

Arquitetura

┌──────────────────────────────────┐
│ Slack in Google Cloud Run        │
│ (ifriend-agents)                 │
└──────────────────┬───────────────┘
                   │
        ┌──────────┴──────────┐
        ▼                     ▼
    ┌────────────┐    ┌─────────────┐
    │ Supabase   │    │  Compute    │
    │ PostgreSQL │    │  Engine VM  │
    │ + pgvector │    │  + Ollama   │
    │  $25/mth   │    │  $25/mth    │
    └────────────┘    └─────────────┘

Total: $50/mth (vs $150+ Vertex AI)
Performance: Sub-200ms (vs Cloud Run 500ms+)

Setup Compute Engine

Passo 1: Criar VM

# Via Console GCP ou CLI:
gcloud compute instances create ollama-server \
  --image-family=debian-12 \
  --image-project=debian-cloud \
  --machine-type=e2-medium \           # 2 vCPU, 4GB RAM = $25/mth
  --zone=us-central1-a \
  --boot-disk-size=50GB \              # 50GB SSD para modelos
  --tags=ollama,http,https \
  --scopes=https://www.googleapis.com/auth/cloud-platform

# Output:
# NAME           ZONE           MACHINE_TYPE  PREEMPTIBLE  INTERNAL_IP    EXTERNAL_IP
# ollama-server  us-central1-a  e2-medium                  10.128.0.2     35.192.xxx.xxx

Passo 2: Configurar Firewall

# Allow HTTP from Cloud Run
gcloud compute firewall-rules create ollama-internal \
  --allow=tcp:11434 \
  --source-ranges=10.128.0.0/9 \       # GCP internal
  --target-tags=ollama

# Allow SSH (para admin)
gcloud compute firewall-rules create ollama-ssh \
  --allow=tcp:22 \
  --source-ranges=YOUR_IP/32 \         # Seu IP ou bastion
  --target-tags=ollama

Passo 3: SSH e Instalar Docker

gcloud compute ssh ollama-server --zone=us-central1-a

# Inside VM:
sudo apt update
sudo apt install -y docker.io docker-compose git

# Permitir user executar docker
sudo usermod -aG docker $USER
exit
gcloud compute ssh ollama-server --zone=us-central1-a

Passo 4: Setup Docker Compose

# Criar docker-compose.yml
cat > docker-compose.yml << 'EOF'
version: '3'
services:
  ollama:
    image: ollama/ollama:latest
    container_name: ollama
    ports:
      - "11434:11434"
    volumes:
      - /mnt/data/ollama:/root/.ollama
    environment:
      - OLLAMA_HOST=0.0.0.0:11434
      - OLLAMA_NUM_GPU=0              # CPU-only (mais barato)
    restart: always
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:11434/api/tags"]
      interval: 10s
      timeout: 5s
      retries: 3
    networks:
      - ollama_network

networks:
  ollama_network:
    driver: bridge
EOF

Passo 5: Criar Diretório de Dados

sudo mkdir -p /mnt/data/ollama
sudo chown $USER:$USER /mnt/data/ollama

Passo 6: Iniciar Ollama

docker-compose up -d

# Verificar
docker ps
curl http://localhost:11434/api/tags

# Output: {"models":[]}  ← Nenhum modelo ainda

Passo 7: Puxar Modelos

# Pull embedding model (274MB)
docker exec ollama ollama pull nomic-embed-text

# Pull reasoning model (opcional, para fallback)
docker exec ollama ollama pull mistral

# Verificar
curl http://localhost:11434/api/tags
# Output: {"models":[{"name":"nomic-embed-text:latest",...}]}

Passo 8: Testar API

# Teste embedding
curl http://localhost:11434/api/embeddings \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{
    "model": "nomic-embed-text",
    "input": "Hello world"
  }'

# Output: {"embedding":[0.123, -0.456, ...]}

🔗 Conectar do Cloud Run

1. Dentro da VPC do GCP

# Cloud Run precisa rodar na mesma VPC
gcloud run deploy ifriend-agents \
  --vpc-connector=projects/PROJECT_ID/locations/us-central1/connectors/default \
  --set-env-vars="OLLAMA_URL=http://ollama-server.default.svc.cluster.local:11434"

2. Via IP Externo (Menos seguro)

# Adicionar autenticação ao Ollama
# docker-compose.yml:
services:
  ollama:
    environment:
      - OLLAMA_AUTH=token:SECRET_TOKEN  # ⚠️ Não é padrão

# Cloud Run:
export OLLAMA_URL="http://EXTERNAL_IP:11434"

3. Recomendado: Via Secret Manager + VPC

# 1. Criar secret
echo "http://ollama-server:11434" | \
  gcloud secrets create ollama-url --data-file=-

# 2. Deploy Cloud Run com acesso a secret
gcloud run deploy ifriend-agents \
  --set-env-vars="OLLAMA_URL=http://ollama-server:11434" \
  --vpc-connector=default \
  --service-account=ifriend-sa \
  --update-secrets="OLLAMA_URL=ollama-url:latest"

💻 Código Python: Usar Ollama

Integração com CustomMemoryService

import aiohttp
import asyncio
from typing import List

class OllamaEmbedder:
    def __init__(self, ollama_url: str = "http://ollama-server:11434"):
        self.ollama_url = ollama_url

    async def embed(self, text: str, model: str = "nomic-embed-text") -> List[float]:
        """Generate embedding using Ollama"""
        try:
            async with aiohttp.ClientSession() as session:
                async with session.post(
                    f"{self.ollama_url}/api/embeddings",
                    json={"model": model, "input": text},
                    timeout=aiohttp.ClientTimeout(total=30)
                ) as resp:
                    if resp.status != 200:
                        raise Exception(f"Ollama error {resp.status}")

                    data = await resp.json()
                    return data["embedding"]

        except asyncio.TimeoutError:
            raise Exception("Ollama timeout - model may be overloaded")
        except aiohttp.ClientConnectorError as e:
            raise Exception(f"Cannot connect to Ollama: {e}")

# Usage
embedder = OllamaEmbedder(os.getenv("OLLAMA_URL"))

embedding = asyncio.run(
    embedder.embed("Customer feedback about product X")
)
print(f"Generated embedding: {len(embedding)} dimensions")

⭐ Alternativa: Ollama Cloud (RECOMENDADO)

Por Que é Melhor

Cloud Run + Compute Engine:
├─ Setup: 1-2 horas
├─ Maintenance: ~1h/semana
├─ Cost: $25-50/mth
└─ Performance: Sub-200ms

Ollama Cloud:
├─ Setup: 2 minutos
├─ Maintenance: $0
├─ Cost: $5-15/mth
└─ Performance: Sub-100ms

Setup Ollama Cloud

1. Sign Up

# Ir para https://ollama.ai/cloud
# Sign in com GitHub
# Create account

2. Gerar API Key

# Dashboard → API Keys → Create
# Copy key: ollama_xxxxxxxxxxxxx

3. Usar API

import os
import aiohttp

class OllamaCloudEmbedder:
    def __init__(self):
        self.api_key = os.getenv("OLLAMA_API_KEY")
        self.base_url = "https://api.ollama.cloud/v1"

    async def embed(self, text: str):
        """Generate embedding using Ollama Cloud API"""
        headers = {
            "Authorization": f"Bearer {self.api_key}",
            "Content-Type": "application/json"
        }

        async with aiohttp.ClientSession() as session:
            async with session.post(
                f"{self.base_url}/embeddings",
                headers=headers,
                json={
                    "model": "nomic-embed-text",
                    "input": text
                }
            ) as resp:
                data = await resp.json()
                return data["embedding"]

# Usage
embedder = OllamaCloudEmbedder()
embedding = await embedder.embed("Your text here")

Pricing

Free tier: 1000 requests/day

Pro: $5-15/mth
├─ 1M+ requests/day
├─ Priority support
└─ Custom models

📊 Comparação Final: Onde Rodar Ollama

Option A: Ollama Cloud ⭐ RECOMENDADO

Vantagens:
├─ ✅ Setup: 2 minutos
├─ ✅ No maintenance
├─ ✅ Performance: <100ms
├─ ✅ Auto-scaling
├─ ✅ SLA: 99.9%
└─ ✅ Custo: $5-15/mth

Desvantagens:
├─ ❌ API cost per token (small)
└─ ❌ Vendor dependency

Option B: Compute Engine e2-medium

Vantagens:
├─ ✅ Setup: 1-2 horas
├─ ✅ Performance: 1-5ms (local)
├─ ✅ Full control
├─ ✅ No per-token cost
└─ ✅ Custo fixo: $25/mth

Desvantagens:
├─ ❌ Maintenance: ~1h/semana
├─ ⚠️ Cold restart latency
└─ ⚠️ Manual scaling

Option C: Local + CLI (Development)

Vantagens:
├─ ✅ Custo: $0
├─ ✅ Performance: Best
└─ ✅ Easy debugging

Desvantagens:
├─ ❌ Não escalável
└─ ❌ Só para dev

🎯 Recomendação Final

Fase MVP (Agora):

Ollama Cloud + Supabase
├─ Custo: $30-40/mth
├─ Setup: 2-3 horas
├─ Manutenção: 0
└─ Time to market: Rápido

Fase Escala (Quando tiver tráfego):

Compute Engine + Supabase
├─ Custo: $50-60/mth
├─ Setup: 1-2 horas
├─ Manutenção: ~5h/semana
└─ Economia: 50-70% vs cloud APIs

✅ Checklist: Deploy Ollama no GCP

Ollamah Cloud Route

  • [ ] Criar conta em ollama.ai/cloud
  • [ ] Gerar API key
  • [ ] Testar API endpoint
  • [ ] Adicionar ao .env
  • [ ] Update CustomMemoryService com OllamaCloudEmbedder

Compute Engine Route

  • [ ] Criar VM e2-medium
  • [ ] Configurar firewall
  • [ ] Instalar Docker
  • [ ] Deploy docker-compose
  • [ ] Puxar nomic-embed-text
  • [ ] Testar http://IP:11434/api/embeddings
  • [ ] Conectar do Cloud Run
  • [ ] Monitorar disk space

Recomendação: Comece com Ollama Cloud (rápido), migre para Compute Engine depois