chore: initial commit

This commit is contained in:
Tiago Yamamoto 2026-01-10 10:21:12 -06:00
commit 4998b01e07
15 changed files with 1211 additions and 0 deletions

19
README.md Normal file
View file

@ -0,0 +1,19 @@
# Infracloud - Infraestrutura Rede5
Este repositório contém a documentação e os manifestos de Infraestrutura como Código (IaC) da Rede5.
## 📂 Estrutura do Projeto
### ☸️ Kubernetes (K3s)
Clusters Kubernetes gerenciados via K3s (Lightweight Kubernetes).
- [**Documentação Geral K3s**](./k3s/README.md)
- [Arquitetura](./k3s/architecture.md)
- [Inventário de Serviços](./k3s/services_inventory.md)
### 🖥️ VPS (Virtual Private Servers)
Servidores standalone gerenciados individualmente.
- [**Apolo**](./vps/apolo/README.md): Servidor de Produção/Staging (Podman + Systemd).

25
k3s/README.md Normal file
View file

@ -0,0 +1,25 @@
# Infraestrutura Kubernetes (K3s)
Documentação dos clusters Kubernetes baseados em **K3s** (Lightweight Kubernetes).
## 🖥️ Servidores / Nós
| Hostname | Função | IP | Status Cluster |
|----------|--------|----|----------------|
| **Zeus** | Control Plane (Master) | `45.39.210.92` | ✅ Ativo (Single Node) |
| **Posseidon** | Control Plane (Master)* | `45.39.210.21` | 🔄 Em verificação |
> (*) Posseidon rodando serviço `k3s` (server), indicando ser um master node. A confirmar se está em cluster com Zeus ou independente.
## 🛠️ Stack Tecnológico
- **Distro**: K3s (Rancher).
- **Ingress Controller**: Traefik (Built-in).
- **Storage**: Local Path Provisioner.
- **OS**: AlmaLinux 9.x.
## 📂 Estrutura da Documentação
- [Arquitetura e Topologia](./architecture.md)
- [Inventário de Workloads e Services](./services_inventory.md)
- [Guia de Operação e Deploy](./deployment_guide.md)

55
k3s/architecture.md Normal file
View file

@ -0,0 +1,55 @@
# Arquitetura K3s (Zeus & Posseidon)
Atualmente a infraestrutura conta com **dois clusters K3s independentes** (Single-Node), cada um atuando como Control Plane e Worker simultaneamente.
## Diagrama da Topologia
```mermaid
flowchart TB
subgraph ClusterZeus ["Cluster 1: Zeus"]
direction TB
Z_CP(Control Plane)
Z_WK(Worker)
Z_STORE[Local Path Storage]
Z_ING[Traefik Ingress]
Z_CP --- Z_WK
Z_WK --> Z_ING
Z_WK --> Z_STORE
end
subgraph ClusterPos ["Cluster 2: Posseidon"]
direction TB
P_CP(Control Plane)
P_WK(Worker)
P_STORE[Local Path Storage]
P_ING[Traefik Ingress]
P_CP --- P_WK
P_WK --> P_ING
P_WK --> P_STORE
end
%% Detalhes de Rede
Internet((Internet)) -->|TCP/80/443| Z_ING
Internet -->|TCP/80/443| P_ING
```
## Detalhes dos Clusters
### ⚡ Zeus (45.39.210.92)
- **Versão**: v1.34.3+k3s1
- **Role**: All-in-one (Master + Agent).
- **Workloads**: Sistema base (Traefik, Metrics, CoreDNS). *Nenhum app de negócio identificado no namespace default.*
### 🌊 Posseidon (45.39.210.21)
- **Versão**: v1.34.3+k3s1
- **Role**: All-in-one.
- **Workloads**: *A verificar inventário de pods.*
## Componentes Nativos
Ambos os clusters utilizam a stack padrão do K3s:
- **Container Runtime**: containerd (Embutido).
- **Ingress**: Traefik (v2/v3).
- **DNS**: CoreDNS.
- **Storage**: Local Path Provisioner (HostPath).

88
k3s/deployment_guide.md Normal file
View file

@ -0,0 +1,88 @@
# Guia de Operação K3s
Este guia aborda operações básicas nos clusters **Zeus** e **Posseidon**. Como são instalações K3s, o comando principal é `k3s kubectl`.
## 📡 Acesso aos Clusters
Acesso via SSH diretamente no nó master.
```bash
# Cluster Zeus
ssh zeus
sudo k3s kubectl get nodes
# Cluster Posseidon
ssh posseidon
sudo k3s kubectl get nodes
```
## 📦 Implantando Aplicações (Deploy)
### 1. Criar um Manifesto YAML
Crie um arquivo `meu-app.yaml`:
```yaml
apiVersion: v1
kind: Pod
metadata:
name: meu-nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: meu-nginx-svc
spec:
selector:
app: nginx
ports:
- port: 80
```
### 2. Aplicar no Cluster
```bash
sudo k3s kubectl apply -f meu-app.yaml
```
## 🌐 Expondo via Ingress (Traefik)
O K3s vem com Traefik habilitado. Para expor um serviço na porta 80/443 do host:
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: meu-nginx-ingress
annotations:
# Não precisa de annotations específicas para Traefik default no K3s
spec:
rules:
- host: meu-app.rede5.com.br
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: meu-nginx-svc
port:
number: 80
```
## 🛠️ Comandos Úteis
| Ação | Comando |
|------|---------|
| Ver Nós | `sudo k3s kubectl get nodes` |
| Ver Pods (Todos) | `sudo k3s kubectl get pods -A` |
| Ver Logs | `sudo k3s kubectl logs -f -n [namespace] [pod-name]` |
| Descrever Pod | `sudo k3s kubectl describe pod [pod-name]` |
| Reiniciar K3s | `sudo systemctl restart k3s` |
| Desinstalar | `/usr/local/bin/k3s-uninstall.sh` |

87
k3s/roadmap_learning.md Normal file
View file

@ -0,0 +1,87 @@
# Roadmap: Dominando Kubernetes (K3s)
Como você já tem dois clusters K3s ativos (**Zeus** e **Posseidon**), este roadmap é focado em prática (Hands-on). O objetivo é sair do "zero" até o deploy profissional.
## 🏁 Fase 1: Preparando sua Máquina (Local)
Não gerencie o cluster apenas acessando via SSH (`ssh zeus`). Instale as ferramentas no seu Windows/Computador para pilotar de "fora".
### O que instalar agora?
1. **Kubectl**: O "controle remoto" oficial.
* *Windows*: `winget install -e --id Kubernetes.kubectl`
2. **K9s**: Interface terminal "visual" (Indispensável para admins). Te economiza horas de digitação.
* *Windows*: `winget install -e --id Derailed.k9s`
3. **Helm**: Gerenciador de pacotes (o "apt/yum" do Kubernetes).
* *Windows*: `winget install -e --id Helm.Helm`
> **Desafio 1**: Baixe o arquivo `/etc/rancher/k3s/k3s.yaml` do Zeus para sua máquina (em `~/.kube/config`), troque `127.0.0.1` pelo IP do Zeus e tente rodar `k9s` localmente.
---
## 🚀 Fase 2: O Básico deworkloads (Pod & Service)
Entenda os blocos fundamentais. Esqueça "serviços systemd", aqui tudo é objeto.
### Conceitos para testar:
1. **Pod**: O menor item. Crie um Nginx simples.
2. **Deployment**: O gerenciador de pods (Replicas, Updates). Delete um pod e veja ele renascer "magicamente".
3. **Service (ClusterIP)**: O IP fixo interno para seus pods conversarem.
> **Desafio 2**: Crie um arquivo `nginx.yaml` com Deployment + Service e aplique no cluster (`kubectl apply -f nginx.yaml`).
---
## 🌐 Fase 3: Expondo para o Mundo (Ingress & Traefik)
Seus clusters K3s já vêm com **Traefik**. Você não precisa instalar outro Ingress Controller.
### O que estudar:
1. **Ingress Route**: Como mapear `meu-site.com` -> `Service do Nginx`.
2. **Certificados**: Como o Traefik lida com HTTPS (no K3s é um pouco diferente via CRDs ou Ingress padrão).
> **Desafio 3**: Faça seu Nginx do desafio anterior responder em `http://teste.rede5.com.br` (apontando o DNS para o IP do Zeus).
---
## 📦 Fase 4: Persistência (Storage)
Containers são efêmeros (morrem e perdem dados). Bancos de dados precisam de disco.
### Conceitos:
1. **PVC (Persistent Volume Claim)**: O "pedido" de disco.
2. **Storage Class**: O K3s usa o `local-path` (salva em `/var/lib/rancher/k3s/storage` no node).
> **Desafio 4**: Suba um PostgreSQL que, mesmo se você deletar o pod, os dados continuem lá quando ele voltar.
---
## 🛠️ Fase 5: Packagign com Helm
Parar de escrever YAML na mão para tudo.
### O que fazer:
1. Adicionar repositórios (Bitnami, etc).
2. Instalar softwares complexos com 1 comando: `helm install meu-redis bitnami/redis`.
---
## 🤖 Fase 6: GitOps (Nível Avançado/Final)
Aqui é onde brilha. Em vez de rodar `kubectl apply`, você commita no Git e o cluster se atualiza sozinho.
### Ferramenta recomendada: **ArgoCD**.
É o padrão da indústria. Ele fica monitorando seu GitHub e sincroniza o cluster.
> **Meta Final**: Ter um repositório git com toda a infra do Zeus/Posseidon definida lá.
---
## Resumo do Kit de Iniciante
| Ferramenta | Para que serve? | Instalar onde? |
|------------|-----------------|----------------|
| **kubectl** | Comandos básicos | Seu PC |
| **k3s** | O Cluster em si | Servidor (Já tem!) |
| **k9s** | Dashboard Turbo | Seu PC |
| **Traefik** | Porta de entrada (Reverse Proxy) | Servidor (Já vem no K3s) |
| **ArgoCD** | Automação de Deploy | Servidor (Futuro) |

29
k3s/services_inventory.md Normal file
View file

@ -0,0 +1,29 @@
# Inventário de Workloads K3s
Como ambos os clusters estão em estado "Pristine" (recém-instalados), apenas os workoads de sistema estão ativos.
## ⚡ Cluster 1: Zeus
**Node**: `zeus.rede5.com.br` (Master)
| Namespace | Pod Name | Status | Componente |
|-----------|----------|--------|------------|
| `kube-system` | `coredns` | Running | DNS Cluster Interno |
| `kube-system` | `traefik` | Running | Ingress Controller (Porta 80/443) |
| `kube-system` | `metrics-server` | Running | Coletor de métricas (CPU/RAM) |
| `kube-system` | `local-path-provisioner` | Running | Storage Class Default |
## 🌊 Cluster 2: Posseidon
**Node**: `posseidon.rede5.com.br` (Master)
| Namespace | Pod Name | Status | Componente |
|-----------|----------|--------|------------|
| `kube-system` | `coredns` | Running | DNS Cluster Interno |
| `kube-system` | `traefik` | Running | Ingress Controller (Porta 80/443) |
| `kube-system` | `metrics-server` | Running | Coletor de métricas (CPU/RAM) |
| `kube-system` | `local-path-provisioner` | Running | Storage Class Default |
## Ingress Classes
Ambos utilizam `traefik` como Ingress Class padrão.
## Storage Classes
Ambos possuem `local-path` configurado como default (`/var/lib/rancher/k3s/storage`).

33
vps/apolo/README.md Normal file
View file

@ -0,0 +1,33 @@
# Infraestrutura Apolo VPS
Documentação oficial do servidor **Apolo**, responsável por hospedar o ecossistema de produção/staging de diversas aplicações (SaveInMed, ObraMarket, Farmácia, etc.).
## 🖥️ Acesso Rápido
- [Arquitetura Detalhada](./architecture.md) - Diagrama de conexões e subsistemas.
- [Inventário de Serviços](./services_inventory.md) - Tabela de containers, portas mapeadas e domínios.
- [Guia de Deploy](./deployment_guide.md) - Padrões para publicação de serviços.
## 📊 Especificações do Sistema
| Propriedade | Valor |
|-------------|-------|
| **Hostname** | `apolo.rede5.com.br` |
| **IP Público** | `45.143.7.55` |
| **OS** | AlmaLinux 9.7 (Moss Jungle Cat) |
| **Kernel** | Linux 5.14.0 |
| **CPU** | AMD EPYC (Virtual) |
| **RAM** | 7.5 GB |
| **Disco** | 60 GB (33 GB usado) |
## 🛠️ Stack Tecnológico
- **Container Engine**: Podman (Rootless/Root).
- **Service Manager**: Systemd via **Quadlet**.
- **Reverse Proxy**: Traefik v3.0 (Gerencia HTTP/HTTPS e TCP).
- **Databases**:
- PostgreSQL 17 (Main)
- PostgreSQL 16 (Forgejo)
- Redis 7 (GoHorseJobs & Cache)
- **Registry**: Zot (Container Register Privado).
- **CI/CD**: Forgejo Runner.

137
vps/apolo/architecture.md Normal file
View file

@ -0,0 +1,137 @@
# Arquitetura do Sistema Apolo
Diagrama detalhado dos serviços hospedados no servidor Apolo.
```mermaid
flowchart LR
%% Nós Externos
Internet((Internet)) -->|HTTPS/443| T[Traefik Proxy]
Internet -->|SSH/2323| FG[Forgejo Git]
%% Core Infra
subgraph Core ["Infraestrutura Core"]
direction TB
FG[Forgejo]
PGADM[pgAdmin]
ZOT[Zot Registry]
GL[Glances Mon]
runner[Forgejo Runner]
end
%% Databases
subgraph Data ["Camada de Dados"]
PG[(PostgreSQL Main)]
PG_FG[(PostgreSQL Forgejo)]
RD[(Redis GoHorse)]
end
%% SaveInMed Ecosystem
subgraph SaveInMed ["SaveInMed"]
SIM_BE[Backend API]
SIM_BO[Backoffice]
SIM_MK[Marketplace]
SIM_SD[Seeder]
SIM_WEB[Website]
end
%% RodiziosDaqui Ecosystem
subgraph Rodizio ["Rodízios Daqui"]
RD_BE[Backend]
RD_BO[Backoffice]
RD_FE[Frontend]
RD_SD[Seeder]
end
%% ObraMarket Ecosystem
subgraph Obra ["ObraMarket"]
OM_BE[Backend]
OM_BO[Backoffice]
OM_FE[Frontend]
OM_SD[Seeder]
end
%% Outros Apps
subgraph Apps ["Outras Aplicações"]
FARM_BE[Farmácia Backend]
FARM_FE[Farmácia Frontend]
VEST_BE[Vestuário Backend]
VEST_FE[Vestuário Frontend]
Q1_BE[Q1 Agenda BE]
Q1_FE[Q1 Agenda FE]
end
%% Roteamento Traefik
T --> FG
T --> PGADM
T --> ZOT
T --> GL
T --> SIM_BE
T --> SIM_BO
T --> SIM_MK
T --> SIM_SD
T --> SIM_WEB
T --> RD_BE
T --> RD_BO
T --> RD_FE
T --> RD_SD
T --> OM_BE
T --> OM_BO
T --> OM_FE
T --> OM_SD
T --> FARM_BE
T --> FARM_FE
T --> VEST_BE
T --> VEST_FE
T --> Q1_BE
T --> Q1_FE
%% TCP Routing (Bancos expostos)
T -.->|TCP/27537| PG
T -.->|TCP/26380| RD
%% Conexões de Dados
FG --> PG_FG
runner --> FG
SIM_BE --> PG
SIM_BO --> PG
SIM_SD --> PG
RD_BE --> PG
RD_BO --> PG
RD_SD --> PG
OM_BE --> PG
OM_BO --> PG
OM_SD --> PG
FARM_BE --> PG
VEST_BE --> PG
Q1_BE --> PG
%% Legenda de Estilo
linkStyle default stroke-width:1px,fill:none,stroke:gray;
```
## Descrição dos Subsistemas
### 🌐 Traefik Proxy
O Traefik atua como gateway principal. Além de rotear tráfego HTTP/HTTPS (portas 80/443), ele também expõe serviços TCP como banco de dados (27537) e Redis (26380) para acesso externo controlado.
### 🏭 Infraestrutura & CI/CD
- **Forgejo**: Servidor Git self-hosted (codeberg fork). Possui banco de dados próprio (`forgejo-db`).
- **Zot**: Registry de containers para imagens privadas.
- **Glances**: Monitoramento de recursos do servidor.
### 🏥 SaveInMed
Ecossistema completo de saúde, incluindo Backend, Backoffice administrativo, Marketplace e Site institucional.
### 🏗️ ObraMarket e 🍕 RodíziosDaqui
Plataformas que seguem arquitetura similar: Backend API, Backoffice Admin, Frontend Web e Seeder (para popular dados).
### 🛒 Farmácia e Vestuário
Lojas/Apps específicos, compostos por pares de Backend/Frontend.

View file

@ -0,0 +1,132 @@
# Guia de Deploy e Manutenção - Apolo
Este guia descreve o processo completo para implantar, atualizar e manter serviços na VPS Apolo utilizando Podman e Quadlet, seguindo o padrão da infraestrutura.
## 🚀 Adicionando um Novo Serviço
O **Quadlet** permite declarar containers como serviços `systemd`. Siga estes passos para criar um novo.
### 1. Preparação
Escolha onde o arquivo ficará:
- **Global (Root)**: `/etc/containers/systemd/` (Padrão para serviços core/produção).
- **Usuário**: `~/.config/containers/systemd/` (Recomendado para experimentos ou serviços pessoais).
> **Nota:** A maioria dos serviços no Apolo roda como **root** em `/etc/containers/systemd/` para acesso facilitado a portas baixas e volumes globais, mas o modo rootless é suportado.
### 2. Criar o Arquivo `.container`
Crie um arquivo com sufixo `.container`, por exemplo, `meu-app.container`.
```ini
[Unit]
Description=Meu App Exemplo
After=network-online.target
[Container]
# 1. Imagem Docker
Image=docker.io/minha-empresa/meu-app:latest
AutoUpdate=registry
# 2. Variáveis de Ambiente
Environment=PORT=3000
Environment=DB_HOST=postgres-main
# 3. Persistência (opcional)
Volume=/mnt/data/meu-app:/app:Z
# Explicação:
# - /mnt/data/meu-app : Pasta no Host (Servidor)
# - /app : Pasta dentro do Container
# - :Z : Configura permissão SELinux (Essencial no AlmaLinux)
# 4. Rede e Exposição (Traefik)
Network=web_proxy
Label=traefik.enable=true
# Roteamento de Host (URL)
Label=traefik.http.routers.meu-app.rule=Host(`app.rede5.com.br`)
Label=traefik.http.routers.meu-app.entrypoints=websecure
Label=traefik.http.routers.meu-app.tls.certresolver=myresolver
# Porta Interna do Container (Load Balancer)
Label=traefik.http.services.meu-app.loadbalancer.server.port=3000
# Middleware (Ex: Redirect HTTP->HTTPS) - Opcional se entrypoints já for websecure
# Label=traefik.http.middlewares.https-redirect.redirectscheme.scheme=https
[Install]
WantedBy=multi-user.target
```
### 3. Aplicar as Alterações
O systemd precisa ler o novo arquivo e gerar o serviço correspondente.
```bash
# Se criado como Root (Padrão Apolo)
sudo systemctl daemon-reload
sudo systemctl start meu-app
# Se criado como Usuário
systemctl --user daemon-reload
systemctl --user start meu-app
```
---
## 🔄 Atualizando um Serviço
Se a imagem estiver configurada com `AutoUpdate=registry`, o Podman pode atualizar automaticamente. Para fazer manual:
1. **Baixar nova imagem**: `podman pull docker.io/minha-empresa/meu-app:latest`
2. **Reiniciar serviço**: `systemctl restart meu-app`
---
## 🛠️ Troubleshooting
### Verificar Status do Serviço
```bash
systemctl status meu-app
```
### Ver Logs da Aplicação
```bash
# Follow logs em tempo real
journalctl -f -u meu-app
# Ver logs anteriores
journalctl -u meu-app -n 100
```
### O Container não sobe?
1. Verifique erros de sintaxe no arquivo `.container`:
```bash
/usr/libexec/podman/quadlet -dryrun
```
2. Verifique se a porta está em uso.
3. Verifique se a imagem existe e foi baixada.
### O domínio não responde (Erro 404/502)?
1. Verifique se o container está na rede `web_proxy`.
2. Confira se a `port` no Label do Traefik bate com a porta que a aplicação escuta internamente.
3. Veja os logs do Traefik: `journalctl -f -u traefik`
---
## 📂 Estrutura de Diretórios Recomendada
Mantenha os volumes organizados em `/mnt/data/`:
```text
/mnt/data/
├── postgres-general/ # Banco de Dados Principal
├── redis-gohorsejobs/ # Redis Dedicado
├── saveinmed/
│ ├── backend/
│ │ └── .env
│ ├── marketplace/
│ └── ...
├── farmacia/
├── obramarket/
└── [nome-do-projeto]/
```

View file

@ -0,0 +1,56 @@
# Inventário de Serviços Apolo
## Tabela Geral de Serviços
| Serviço | Container | Domínio / URL | Porta Interna | Banco de Dados |
|---------|-----------|---------------|:-------------:|----------------|
| **Traefik** | `traefik` | n/a | 80/443 | - |
| **Forgejo Git** | `forgejo` | `forgejo-gru.rede5.com.br` | 3000 | `forgejo-db` |
| **Forgejo SSH** | `forgejo` | `forgejo-gru.rede5.com.br` | 22 (Ext: 2323) | - |
| **Zot Registry** | `zot` | `zot-gru.rede5.com.br` | 5000 | - |
| **pgAdmin** | `pgadmin` | `pgadmin.rede5.com.br` | 80 | - |
| **Glances** | `glances` | `gms1.rede5.com.br` | 61208 | - |
| **Farmácia BE** | `farmacia-backend` | `api.farmacia.rede5.com.br` | 8080 | Postgres Main |
| **Farmácia FE** | `farmacia-frontend` | `farmacia.rede5.com.br` | 3000 | - |
| **ObraMarket BE** | `obramarket-backend` | `api.obramarket.rede5.com.br` | 8158 | Postgres Main |
| **ObraMarket BO** | `obramarket-backoffice` | `admin.obramarket.rede5.com.br` | 3000 | - |
| **ObraMarket FE** | `obramarket-frontend` | `obramarket.rede5.com.br` | 80 | - |
| **Q1Agenda BE** | `q1agenda-backend-dev` | `api-dev.q1agenda.com.br` | 8000 | Postgres Main |
| **Q1Agenda FE** | `q1agenda-frontend-dev` | `dev.q1agenda.com.br` | 3000 | - |
| **Rodízios BE** | `rodiziosdaqui-backend` | `api.rodiziosdaqui.rede5.com.br` | 8080 | Postgres Main |
| **Rodízios BO** | `rodiziosdaqui-backoffice` | `backoffice.rodiziosdaqui...` | 8082 | - |
| **Rodízios FE** | `rodiziosdaqui-frontend` | `rodiziosdaqui.rede5.com.br` | 3000 | - |
| **SaveInMed BE**| `saveinmed-backend-dev` | `api.saveinmed.com.br` | 8214 | Postgres Main |
| **SaveInMed BO**| `saveinmed-backoffice-dev` | `admin.saveinmed.com.br` | 3000 | - |
| **SaveInMed MK**| `saveinmed-marketplace-dev`| `app.saveinmed.com.br` | 3000 | - |
| **SaveInMed Site**| `saveinmed-website-dev` | `saveinmed.com.br` | 8000 | - |
| **Vestuário BE**| `vestuario-backend` | `api.vestuario.rede5.com.br` | 8000 | Postgres Main |
| **Vestuário FE**| `vestuario-frontend` | `vestuario.rede5.com.br` | 3000 | - |
## Infraestrutura de Dados
### PostgreSQL Main (`postgres-main`)
- **Versão**: 17-alpine
- **Exposição**: Interna (5432) e Externa via Traefik (TCP 27537).
- **Volume**: `/mnt/data/postgres-general`
### PostgreSQL Forgejo (`forgejo-db`)
- **Versão**: 16-alpine
- **Uso**: Exclusivo para o Forgejo.
- **Volume**: `/mnt/data/postgres-forgejo`
### Redis GoHorseJobs (`redis-gohorsejobs`)
- **Config**: Persistência ativada (`appendonly yes`), limite 128MB.
- **Exposição**: Interna (6379) e Externa via Traefik (TCP 26380).
- **Volume**: `/mnt/data/redis-gohorsejobs`
## Portas Públicas Publicadas (Node Ports)
Alguns containers publicam portas diretamente no host (além do Traefik), mas o acesso ideal é via domínio.
- **80/443**: Traefik (Web)
- **2323**: Forgejo SSH
- **12110/12112**: Farmácia
- **12120/12123**: RodíziosDaqui
- **8214**: SaveInMed Backend
- **12111/12113**: Vestuário

31
vps/nc1/README.md Normal file
View file

@ -0,0 +1,31 @@
# Documentação Infraestrutura NC1
Bem-vindo à documentação oficial da VPS **NC1**. A infraestrutura é baseada em containers (Podman) gerenciados via systemd (Quadlet), utilizando Traefik como proxy reverso.
## 🖥️ Acesso Rápido
- [Arquitetura do Sistema](./architecture.md) - Diagramas e fluxo de dados.
- [Inventário de Serviços](./services_inventory.md) - Lista de containers, portas e domínios.
- [Guia de Deploy](./deployment_guide.md) - Como publicar novos serviços.
## 📊 Especificações do Servidor
| Propriedade | Valor |
|-------------|-------|
| **Hostname** | v2202508247812376908 |
| **IP Público** | 185.194.141.70 |
| **OS** | AlmaLinux 10.1 (Heliotrope) |
| **Kernel** | Linux 5.x x86_64 |
| **CPU** | AMD EPYC-Rome Processor |
| **RAM** | 7.5 GB |
| **Disco** | 254 GB (SSD) |
## 🛠️ Stack Tecnológico
- **Runtime**: Podman (compatível com Docker).
- **Orquestração**: Quadlet (Systemd generator).
- **Proxy/LB**: Traefik v3.0.
- **Banco de Dados**: PostgreSQL (Compartilhado).
- **Cache**: Redis.
> **Nota:** Os arquivos de configuração dos containers (Quadlets) estão localizados em `/etc/containers/systemd/` (root) e `~/.config/containers/systemd/` (usuário).

126
vps/nc1/architecture.md Normal file
View file

@ -0,0 +1,126 @@
# Arquitetura do Sistema NC1
Este documento detalha a topologia dos serviços, fluxo de rede e componentes da infraestrutura.
## Diagrama de Arquitetura
O diagrama abaixo ilustra a comunicação entre o proxy reverso (Traefik), serviços de aplicação, bancos de dados e ferramentas de suporte.
```mermaid
flowchart LR
%% Nós Externos
Internet((Internet)) -->|HTTPS/443| T[Traefik Proxy]
%% Core Infrastructure
subgraph Support ["Infraestrutura de Suporte"]
direction TB
VW[Vaultwarden]
FG[Forgejo Git]
PG[(PostgreSQL)]
RD[(Redis)]
end
%% Core Services
subgraph Core ["Core Platform"]
CIG[Identity Gateway]
CPP[Platform Projects]
CDB[Core Dashboard]
end
%% SaveInMed Ecosystem
subgraph SaveInMed ["Ecosistema SaveInMed"]
SIMB[Backend API]
SIMM[Marketplace]
end
%% Q1 Connect Ecosystem
subgraph Q1 ["Q1 Connect"]
direction TB
subgraph Q1Apps ["Apps"]
Q1FOOD[Food Backend]
Q1VEST[Vestuário/Store]
Q1ABE[Agenda Backend]
Q1AFE[Agenda Frontend]
end
subgraph Q1Management ["Gestão"]
Q1BE[Total Backend]
Q1DB[Total Dashboard]
end
end
%% Sextando Ecosystem
subgraph Sextando ["Sextando"]
SXBE[Backend API]
SXFE[Frontend Web]
end
%% Invent Ecosystem
subgraph Invent ["Invent Finance"]
INVBE[Backend API]
INVFE[Frontend App]
end
%% Rotas do Traefik
T --> VW
T --> FG
T --> CIG
T --> CPP
T --> CDB
T --> SIMB
T --> SIMM
T --> INVBE
T --> INVFE
T --> Q1BE
T --> Q1DB
T --> Q1FOOD
T --> Q1VEST
T --> Q1ABE
T --> Q1AFE
T --> SXBE
T --> SXFE
%% Conexões de Banco de Dados (Link Styles)
linkStyle default stroke-width:2px,fill:none,stroke:gray;
%% Dependências de Dados
CIG -.-> PG
CPP -.-> PG
INVBE -.-> PG
Q1BE -.-> PG
Q1FOOD -.-> PG
Q1VEST -.-> PG
Q1ABE -.-> PG
SXBE -.-> PG
SIMB === PG
SIMB === RD
```
## Descrição dos Componentes
### 🌐 Gateway & Proxy
- **Traefik**: Ponto de entrada único (Entrypoint). Gerencia certificados SSL (Let's Encrypt), roteamento de host e load balancing. Escuta nas portas 80 (Redirect) e 443 (HTTPS).
### 🔐 Segurança & Identidade
- **Core Identity Gateway**: Responsável pela autenticação centralizada e gestão de tokens.
- **Vaultwarden**: Gerenciador de senhas para a equipe (compatível com Bitwarden).
### 🏥 SaveInMed
Plataforma principal de gestão médica e marketplace.
- **Backend API**: Serviço core, utiliza Redis para cache de sessões/dados e PostgreSQL para persistência.
- **Marketplace**: Interface de vendas e catálogo.
### 🛍️ Q1 Connect
Suíte de aplicativos de comércio e agendamento.
- **Total**: Backend administrativo e Dashboard.
- **Setoriais**: APIs específicas para Food, Vestuário/Store e Agenda.
### 🛒 Sextando & Vestuário
Plataformas de e-commerce. Backend em Go, Frontend em Node.js/React.
### 💰 Invent Finance
Sistema financeiro com separação clara entre Backend e Frontend.
## Infraestrutura de Dados
- **PostgreSQL**: Instância única compartilhada entre todos os serviços (exceto Vaultwarden que pode ter seu próprio banco ou schema).
- **Redis**: Sistema de cache em memória, utilizado intensivamente pelo SaveInMed para alta performance.

127
vps/nc1/deployment_guide.md Normal file
View file

@ -0,0 +1,127 @@
# Guia de Deploy e Manutenção - NC1
Este guia descreve o processo completo para implantar, atualizar e manter serviços na VPS NC1 utilizando Podman e Quadlet.
## 🚀 Adicionando um Novo Serviço
O **Quadlet** permite declarar containers como serviços `systemd`. Siga estes passos para criar um novo.
### 1. Preparação
Escolha onde o arquivo ficará:
- **Global (Root)**: `/etc/containers/systemd/` (Recomendado para infraestrutura core).
- **Usuário**: `~/.config/containers/systemd/` (Recomendado para aplicações).
### 2. Criar o Arquivo `.container`
Crie um arquivo com sufixo `.container`, por exemplo, `meu-app.container`.
```ini
[Unit]
Description=Meu App Exemplo
After=network-online.target
[Container]
# 1. Imagem Docker
Image=docker.io/minha-empresa/meu-app:latest
AutoUpdate=registry
# 2. Variáveis de Ambiente
Environment=PORT=3000
Environment=DB_HOST=postgres-main
# 3. Persistência (opcional)
Volume=/mnt/data/meu-app:/app:Z
# Explicação:
# - /mnt/data/meu-app : Pasta no Host (Servidor)
# - /app : Pasta dentro do Container
# - :Z : Configura permissão SELinux (Essencial no AlmaLinux)
# 4. Rede e Exposição (Traefik)
Network=web_proxy
Label=traefik.enable=true
# Roteamento de Host (URL)
Label=traefik.http.routers.meu-app.rule=Host(`app.rede5.com.br`)
Label=traefik.http.routers.meu-app.entrypoints=websecure
Label=traefik.http.routers.meu-app.tls.certresolver=myresolver
# Porta Interna do Container (Load Balancer)
Label=traefik.http.services.meu-app.loadbalancer.server.port=3000
# Middleware (Ex: Redirect HTTP->HTTPS) - Opcional se entrypoints já for websecure
# Label=traefik.http.middlewares.https-redirect.redirectscheme.scheme=https
[Install]
WantedBy=multi-user.target
```
### 3. Aplicar as Alterações
O systemd precisa ler o novo arquivo e gerar o serviço correspondente.
```bash
# Se criado como Root
sudo systemctl daemon-reload
sudo systemctl start meu-app
# Se criado como Usuário
systemctl --user daemon-reload
systemctl --user start meu-app
```
---
## 🔄 Atualizando um Serviço
Se a imagem estiver configurada com `AutoUpdate=registry`, o Podman pode atualizar automaticamente. Para fazer manual:
1. **Baixar nova imagem**: `podman pull docker.io/minha-empresa/meu-app:latest`
2. **Reiniciar serviço**: `systemctl restart meu-app`
---
## 🛠️ Troubleshooting
### Verificar Status do Serviço
```bash
systemctl status meu-app
```
### Ver Logs da Aplicação
```bash
# Follow logs em tempo real
journalctl -f -u meu-app
# Ver logs anteriores
journalctl -u meu-app -n 100
```
### O Container não sobe?
1. Verifique erros de sintaxe no arquivo `.container`:
```bash
/usr/libexec/podman/quadlet -dryrun
```
2. Verifique se a porta está em uso.
3. Verifique se a imagem existe e foi baixada.
### O domínio não responde (Erro 404/502)?
1. Verifique se o container está na rede `web_proxy`.
2. Confira se a `port` no Label do Traefik bate com a porta que a aplicação escuta internamente.
3. Veja os logs do Traefik: `journalctl -f -u traefik`
---
## 📂 Estrutura de Diretórios Recomendada
Mantenha os volumes organizados em `/mnt/data/`:
```text
/mnt/data/
├── postgres/ # Dados do Banco
├── redis/ # Dados do Cache
├── saveinmed/
│ ├── backend/
│ └── uploads/
└── [nome-do-projeto]/
└── [tipo-de-dado]/
```

218
vps/nc1/nc1.md Normal file
View file

@ -0,0 +1,218 @@
# NC1 VPS - Documentação de Infraestrutura
## Informações do Sistema
| Propriedade | Valor |
|-------------|-------|
| **Hostname** | v2202508247812376908 |
| **IP Público** | 185.194.141.70 |
| **Sistema Operacional** | AlmaLinux 10.1 (Heliotrope) |
| **Kernel** | Linux 5.x x86_64 |
| **CPU** | AMD EPYC-Rome Processor |
| **Memória RAM** | 7.5 GB |
| **Disco** | 254 GB (31 GB usado, ~13%) |
---
## Arquitetura de Containers
```mermaid
flowchart LR
T[Traefik]
PG[(PostgreSQL)]
RD[(Redis)]
FG[Forgejo]
VW[Vaultwarden]
subgraph Core
CIG[Identity Gateway]
CPP[Platform Projects]
CDB[Core Dashboard]
end
subgraph SaveInMed
SIMB[Backend]
SIMM[Marketplace]
end
subgraph Invent["Invent Finance"]
INVBE[Backend]
INVFE[Frontend]
end
subgraph Q1["Q1 Total/Food/Store"]
Q1BE[Total Backend]
Q1DB[Total Dashboard]
Q1FOOD[Food Backend]
Q1VEST[Vestuario Backend]
end
subgraph Q1Agenda ["Q1 Agenda"]
Q1ABE[Backend]
Q1AFE[Frontend]
end
subgraph Sextando
SXBE[Backend]
SXFE[Frontend]
end
T --> VW
T --> FG
T --> CIG
T --> CPP
T --> CDB
T --> SIMB
T --> SIMM
T --> INVBE
T --> INVFE
T --> Q1BE
T --> Q1DB
T --> Q1FOOD
T --> Q1VEST
T --> Q1ABE
T --> Q1AFE
T --> SXBE
T --> SXFE
CIG --> PG
CPP --> PG
INVBE --> PG
Q1BE --> PG
Q1FOOD --> PG
Q1VEST --> PG
Q1ABE --> PG
SXBE --> PG
SIMB --> PG
SIMB --> RD
```
> **Nota:** O cluster **Redis** é utilizado principalmente pelo **SaveInMed Backend** e outros serviços que requerem cache. Todos compartilham a mesma instância do **PostgreSQL**.
---
## Mapeamento de Domínios (HML/Dev)
| Serviço | URL / Domínio | Porta Interna |
|---------|---------------|---------------|
| **Core Identity** | `ig-dev.rede5.com.br` | 4000 |
| **Core Platform** | `platform-projects-core-dev.rede5.com.br` | 8080 |
| **SaveInMed Backend** | `api-dev.saveinmed.com.br` | 8214 |
| **SaveInMed Market** | `marketplace-dev.saveinmed.com.br` | 5173 |
| **Invent Backend** | `invent-api-dev.rede5.com.br` | 4763 |
| **Invent Frontend** | `invent-dev.rede5.com.br` | 3785 |
| **Q1 Total Backend** | `api-dev.q1-total.com.br` | 8000 |
| **Q1 Total Dash** | `dashboard-dev.q1-total.com.br` | 5173 |
| **Q1 Food Backend** | `api-dev.q1food.com` | 8003 |
| **Q1 Store/Vest** | `api-dev.q1store.me` | 8002 |
| **Q1 Agenda Backend** | `api-dev.q1agenda.com.br` | 8000* |
| **Q1 Agenda Frontend**| `dev.q1agenda.com.br` | 3000 |
| **Sextando API** | `api-dev.sextando.com.br` | 8080 |
| **Sextando Web** | `dev.sextando.com.br` | 3001 |
| **Vaultwarden** | `vault.rede5.com.br` | 80 |
---
## Containers Podman (Rodando)
| Container | Descrição |
|-----------|-----------|
| `traefik` | Reverse proxy e load balancer |
| `postgres-main` | Banco de dados PostgreSQL principal |
| `redis-saveinmed` | Cache Redis para SaveInMed |
| `forgejo` | Git server self-hosted |
| `vaultwarden` | Gerenciador de senhas |
| `core-identity-gateway-dev` | Core Identity Gateway (HML) |
| `core-platform-projects-core-dev` | Core Platform Projects (HML) |
| `core-dashboard-dev` | Core Dashboard (HML) |
| `saveinmed-backend-dev` | SaveInMed Backend (HML) |
| `saveinmed-marketplace-dev` | SaveInMed Marketplace (HML) |
| `invent-finance-backend-dev` | Invent Finance Backend (HML) |
| `invent-finance-frontend-dev` | Invent Finance Frontend (HML) |
| `sextando-backend-dev` | Sextando Backend (HML) |
| `sextando-frontend-dev` | Sextando Frontend (HML) |
| `vestuario-backend-dev` | Q1 Store/Vestuário (HML) |
| `food-backend-dev` | Q1 Food Backend (HML) |
| `q1-total-backend-dev` | Q1 Total Backend (HML) |
| `q1-total-dashboard-dev` | Q1 Total Dashboard (HML) |
| `q1agenda-backend-dev` | Q1 Agenda Backend (HML) |
| `q1agenda-frontend-dev` | Q1 Agenda Frontend (HML) |
| `pgadmin` | Administração PostgreSQL |
| `glances` | Monitoramento de sistema |
---
## Quadlet Files (Systemd Units)
Localização:
- Root: `/etc/containers/systemd/`
- User: `~/.config/containers/systemd/`
---
## Fluxo de Rede
```mermaid
flowchart LR
Internet((Internet)) -->|443/80| T[Traefik]
T -->|8080| VW[Vaultwarden]
T -->|3000| FG[Forgejo]
T -->|8214| SIMB[SaveInMed]
T -->|8002| Q1[Q1 Services]
PG[(PostgreSQL)]
RD[(Redis)]
SIMB --> PG
SIMB --> RD
Q1 --> PG
```
---
## Guia - Adicionar Novo Serviço (Quadlet)
Para adicionar um novo serviço nesta VPS, utilizamos o **Quadlet** (Systemd Generator para Podman). Isso garante que os containers iniciem automaticamente no boot e sejam gerenciados como serviços do sistema.
### 1. Criar arquivo .container
Crie um arquivo em `/etc/containers/systemd/` (para root) ou `~/.config/containers/systemd/` (para seu usuário). O nome do arquivo deve ser `seuservico.container`.
Exemplo: `novo-app-dev.container`
```ini
[Unit]
Description=Meu Novo App Dev
After=network-online.target
[Container]
Image=docker.io/minha-imagem:latest
# Se precisar declarar variáveis de ambiente
Environment=PORT=8080
# Conectar à rede do proxy
Network=web_proxy
# Labels para o Traefik (Expõe o serviço na web)
Label=traefik.enable=true
Label=traefik.http.routers.meu-app-dev.rule=Host(`meu-app-dev.rede5.com.br`)
Label=traefik.http.routers.meu-app-dev.entrypoints=websecure
Label=traefik.http.routers.meu-app-dev.tls.certresolver=myresolver
Label=traefik.http.services.meu-app-dev.loadbalancer.server.port=8080
[Install]
WantedBy=multi-user.target
```
### 2. Ativar o serviço
Após criar o arquivo, recarregue o daemon do systemd para gerar o arquivo de serviço, e então inicie:
```bash
# Se o arquivo estiver em /etc/containers/systemd/ (Root)
sudo systemctl daemon-reload
sudo systemctl start novo-app-dev
# Se estiver na home do usuário (Rootless)
systemctl --user daemon-reload
systemctl --user start novo-app-dev
```

View file

@ -0,0 +1,48 @@
# Inventário de Serviços NC1
## Tabela de Serviços e Domínios
| Container | URL Principal | Porta Interna | Banco de Dados | Linguagem/Stack |
|-----------|---------------|:-------------:|----------------|-----------------|
| **Traefik** | `n/a` | 80/443 | - | Go |
| **Vaultwarden** | `vault.rede5.com.br` | 80 | interna | Rust |
| **Forgejo** | `git.rede5.com.br` | 3000 | Postgres | Go |
| **Core Identity** | `ig-dev.rede5.com.br` | 4000 | Postgres | Node.js |
| **Platform Projects** | `platform-projects-core-dev.rede5.com.br` | 8080 | Postgres | Node.js |
| **Core Dash** | `dashboard-dev.q1-total.com.br`* | 5173 | - | Node.js/React |
| **SaveInMed BE** | `api-dev.saveinmed.com.br` | 8214 | Postgres + Redis | Node.js |
| **SaveInMed Market**| `marketplace-dev.saveinmed.com.br` | 5173 | - | Node.js/React |
| **Q1 Food** | `api-dev.q1food.com` | 8003 | Postgres | Go |
| **Q1 Store** | `api-dev.q1store.me` | 8002 | Postgres | Go |
| **Q1 Agenda BE** | `api-dev.q1agenda.com.br` | 8000 | Postgres | Python |
| **Q1 Agenda FE** | `dev.q1agenda.com.br` | 3000 | - | Node.js/React |
| **Sextando BE** | `api-dev.sextando.com.br` | 8080 | Postgres | Go |
| **Sextando FE** | `dev.sextando.com.br` | 3001 | - | Node.js/React |
| **Invent BE** | `invent-api-dev.rede5.com.br` | 4763 | Postgres | Node.js |
| **Invent FE** | `invent-dev.rede5.com.br` | 3785 | - | Node.js/Next |
> (*) Verificar se este domínio está correto ou compartilhado.
## Infraestrutura de Dados
### PostgreSQL
- **Container**: `postgres-main`
- **Versão**: 15 (aprox)
- **Porta**: 5432 (Rede Interna)
- **Volumes**: `/mnt/data/postgres:/var/lib/postgresql/data`
### Redis
- **Container**: `redis-saveinmed`
- **Porta**: 6379 (Rede Interna)
- **Uso Principal**: Cache de sessão SaveInMed.
## Volumes e Persistência
A maioria dos serviços utiliza volumes bind-mounted em `/mnt/data/`.
- **Caminho Base**: `/mnt/data/`
- **Exemplo**: `/mnt/data/saveinmed/backend:/app`
## Redes Podman
- **web_proxy**: Rede pública interna onde o Traefik roteia o tráfego. Todos os serviços expostos na web devem estar nesta rede.