Skip to content

moa-devops/bahiatur-ia

Repository files navigation

BahiaTUR IA 🌊

Guia de turismo inteligente da Bahia — IA local rodando em Kubernetes na AWS, sem depender de APIs pagas de LLM.

🔗 Produção: https://bahiatur.mateusassis.com


Stack

Componente Tecnologia
LLM Ollama + llama3.2:3b (local, sem custo de API)
Backend Python 3.11 + FastAPI + SSE Streaming
Autenticação Google OAuth 2.0 (GCP) + JWT + bcrypt
Banco de usuários SQLite async (SQLAlchemy + aiosqlite)
Frontend HTML/CSS/JS puro com streaming token a token
Distâncias OSRM (OpenStreetMap) — gratuito
Geolocalização Browser API + Nominatim (OpenStreetMap) — gratuito
Infraestrutura MicroK8s na AWS EC2
CI/CD GitLab CI/CD com pipeline automático
Deploy Helm Charts
Registry Registry privado (registry.mateusassis.com)
TLS cert-manager + Let's Encrypt
DNS AWS Route 53

Arquitetura

Internet
    │
    ▼
Route 53 (DNS: bahiatur.mateusassis.com)
    │
    ▼
┌─────────────────────────────────────────────────────────────┐
│                        AWS us-east-2                        │
│                                                             │
│  ┌─────────────────┐  ┌──────────────────┐  ┌───────────┐   │
│  │  gitlab-server  │  │   k8s-server     │  │ registry  │   │
│  │  t3a.large      │  │   t3a.xlarge     │  │ -runner   │   │
│  │                 │  │                  │  │ t3a.large │   │
│  │                 │  │                  │  │           │   │
│  │  GitLab CE      │  │  MicroK8s        │  │           │   │
│  │  Repositórios   │  │  ├─bahiatur-ai   │  │ Registry  │   │
│  │  CI/CD Pipelines│  │  │ ├─FastAPI     │  │ privado   │   │
│  │                 │  │  │ └─Ollama      │  │           │   │
│  │                 │  │  └─cert-manager  │  │ GitLab    │   │
│  │                 │  │    nginx ingress │  │ Runner    │   │
│  └─────────────────┘  └──────────────────┘  └───────────┘   │
└─────────────────────────────────────────────────────────────┘

Estrutura do Projeto

bahiatur-ia/
├── infrastructure/
│   ├── main.py          # FastAPI + SSE streaming + auth + OSRM
│   ├── auth.py          # JWT + Google OAuth + bcrypt
│   ├── database.py      # SQLite async (usuários)
│   ├── destinos.py      # Base de 60+ destinos baianos verificados
│   ├── settings.py      # Configurações (injetado via CI/CD)
│   └── requirements.txt
├── frontend/
│   ├── index.html       # Chat UI com streaming + geolocalização
│   ├── bg-login.jpg     # Elevador Lacerda
│   └── bg-chat.jpg      # Vista aérea Farol da Barra
├── deploy/
│   ├── chart/           # Helm chart da aplicação
│   │   ├── templates/
│   │   │   ├── deployment.yaml
│   │   │   ├── service.yaml
│   │   │   ├── ingress.yaml    # timeout 300s para LLM
│   │   │   ├── pvc.yaml
│   │   │   └── secret.yaml
│   │   ├── Chart-main.yaml
│   │   └── Chart-hml.yaml
│   ├── ollama/          # Manifests do Ollama no K8s
│   │   ├── ollama-deployment.yaml
│   │   ├── ollama-service.yaml
│   │   ├── ollama-pvc.yaml
│   │   └── ollama-job-pull.yaml
│   └── values/
│       ├── main.yml     # Produção
│       └── homolog.yaml # Homologação
├── .gitlab-ci.yml
├── .gitlab-production-ci.yml  # 4 stages: build → ollama → deploy → restart
├── Dockerfile
└── docker-compose.yml   # Para desenvolvimento local

Configuração da Infraestrutura AWS

EC2 — 3 instâncias

Instância Tipo IP Função
gitlab-server t3a.large GitLab CE — repositório e pipelines CI/CD
k8s-server t3a.xlarge MicroK8s — cluster K8s, aplicação e Ollama
registry-runner t3a.large Registry Docker privado + GitLab Runner

Todas as instâncias rodam Ubuntu 22.04 LTS na região us-east-2 (Ohio).

Nota: O k8s-server foi migrado de t3a.large para t3a.xlarge (4 vCPU, 16GB) para suportar LLMs maiores. Upgrade feito sem perda de dados via AWS Console (Stop → Change Instance Type → Start).

MicroK8s

# Instalação
sudo snap install microk8s --classic --channel=1.29/stable

# Addons necessários
microk8s enable dns storage ingress cert-manager registry metrics-server

# Kubeconfig
microk8s config > ~/.kube/config

StorageClass

# Verificar StorageClass disponível
kubectl get storageclass
# NAME                          PROVISIONER            
# microk8s-hostpath (default)   microk8s.io/hostpath

Configuração Google OAuth (GCP)

1. Criar projeto no GCP

  1. Acesse console.cloud.google.com
  2. Criar novo projeto ou usar existente

2. Configurar tela de consentimento OAuth

  1. APIs & Services → OAuth consent screen
  2. Tipo de usuário: Externo
  3. Preencher:
    • Nome do app: BahiaTUR IA
    • E-mail de suporte: seu e-mail
    • Domínio: bahiatur.mateusassis.com
  4. Salvar

3. Criar credencial OAuth 2.0

  1. APIs & Services → Credenciais → Criar credencial → ID do cliente OAuth 2.0
  2. Tipo: Aplicativo da Web
  3. Nome: BahiaTUR IA
  4. Origens JavaScript autorizadas:
    https://bahiatur.mateusassis.com
    
  5. Copiar o Client ID gerado

4. Configurar no projeto

No infrastructure/settings.py:

GOOGLE_CLIENT_ID     = "SEU_CLIENT_ID.apps.googleusercontent.com"
GOOGLE_CLIENT_SECRET = "SEU_CLIENT_SECRET"

No frontend/index.html:

const GOOGLE_CLIENT_ID = 'SEU_CLIENT_ID.apps.googleusercontent.com';

Variáveis CI/CD (GitLab)

Variável Tipo Descrição
APP_SETTINGS_64_PRD File Conteúdo completo do settings.py de produção
KUBECONFIG_PRD_K8S Variable (masked) kubeconfig em base64

Gerar KUBECONFIG_PRD_K8S

# Na EC2 do cluster
microk8s config | sed 's/127.0.0.1/IP_INTERNO_EC2/g' | base64 -w0
# Colar o resultado na variável KUBECONFIG_PRD_K8S no GitLab

Gerar APP_SETTINGS_64_PRD

  1. Edite o infrastructure/settings.py com os valores de produção
  2. Cole o conteúdo diretamente na variável CI/CD (tipo: File, Expand variable references: OFF)

Pipeline CI/CD

O pipeline tem 4 stages automáticos ao fazer push na branch main:

build-and-push-main
    → Injeta settings.py via variável CI
    → Build da imagem com tag única (main-N)
    → Push para registry privado

deploy-ollama
    → Aplica PVC, Deployment e Service do Ollama
    → Verifica se modelo já existe (evita re-download)

deploy-main
    → helm upgrade --install com tag da imagem nova
    → Cria namespace se não existir

restart-pod
    → kubectl rollout restart
    → Aguarda pod ficar Ready

Deploy do Ollama

# Aplica os manifests
kubectl apply -f deploy/ollama/ollama-pvc.yaml
kubectl apply -f deploy/ollama/ollama-deployment.yaml
kubectl apply -f deploy/ollama/ollama-service.yaml

# Baixa o modelo (primeira vez — ~2GB)
kubectl exec -n bahiatur-ai deployment/ollama -- ollama pull llama3.2:3b

# Verifica modelos disponíveis
kubectl exec -n bahiatur-ai deployment/ollama -- ollama list

Modelos disponíveis

Modelo Tamanho Velocidade CPU Qualidade PT
qwen2:0.5b 352MB Muito rápido Básica
gemma2:2b 1.6GB Rápido Boa
llama3.2:3b 2.0GB Rápido Muito boa
mistral:7b 4.4GB Lento Excelente

Desenvolvimento Local

# Clone
git clone git@gitlab.mateusassis.com:aws/bahiatur-ia.git
cd bahiatur-ia

# Sobe com Docker Compose
docker compose up -d --build

# Baixa o modelo
docker exec bahiatur-ollama ollama pull llama3.2:3b

# Acessa
http://localhost

Funcionalidades

  • ✅ Login com Google OAuth 2.0 (GCP)
  • ✅ Cadastro com e-mail e senha (bcrypt)
  • Streaming SSE — respostas token a token
  • Geolocalização — botão 📍 detecta cidade do usuário via browser
  • Distâncias reais via OSRM (OpenStreetMap) — sem custo
  • ✅ Base de 60+ destinos baianos com informações verificadas
  • ✅ Cobertura: Litoral Norte, Linha Verde, Chapada Diamantina, Costa do Cacau, Costa do Descobrimento, Costa das Baleias, Sertão, Recôncavo
  • ✅ HTTPS com Let's Encrypt automático
  • ✅ Pipeline CI/CD completo com 4 stages

Manutenção

Monitorar recursos

kubectl top nodes
kubectl top pods -n bahiatur-ai
kubectl get pods -n bahiatur-ai

Ver logs

# App
kubectl logs -n bahiatur-ai -l app.kubernetes.io/name=bahiatur-ai -f

# Ollama
kubectl logs -n bahiatur-ai -l app=ollama -f

Limpeza de imagens (evitar disk-pressure)

sudo microk8s ctr --namespace k8s.io images ls | grep bahiatur-ai | awk '{print $1}' | while read img; do
  sudo microk8s ctr --namespace k8s.io images rm "$img" 2>/dev/null
done
df -h /

Disco cheio (disk-pressure)

# Remove taint manualmente
kubectl taint nodes ip-10-0-1-16 node.kubernetes.io/disk-pressure:NoSchedule- 2>/dev/null

# Expande disco após aumentar EBS no AWS Console
sudo growpart /dev/nvme0n1 1
sudo resize2fs /dev/nvme0n1p1
df -h /

Custos AWS

Recurso Tipo Custo/mês
EC2 gitlab-server t3a.large ~$55
EC2 k8s-server t3a.xlarge ~$108
EC2 registry-runner t3a.large ~$55
EBS volumes (~60GB cada) gp3 ~$15
Route 53 Hosted Zone ~$0.50
Total estimado ~$233/mês

Dica de economia: As EC2s podem ser paradas quando não estiver em uso — você paga apenas pelo tempo ligado. Para portfólio/demos, ligue somente quando for demonstrar o projeto.


#DevOps #Kubernetes #Python #IA #AWS #Bahia #OpenSource #Ollama #FastAPI #GitLab

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors