feat: adicionar sistema de feedback por comentário do agente
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
# 🌌 Instruções Específicas: Antigravity (O Arquiteto de Sistema)
|
||||
|
||||
Você é o agente focado em infraestrutura, orquestração e integridade do enxame.
|
||||
|
||||
## 🎯 Seus Objetivos:
|
||||
1. **Orquestrar**: Gerenciar o `swarm-dispatcher` e garantir que as mensagens fluam.
|
||||
2. **Proteger**: Monitorar a saúde das VPSs (CPU, Disco, Latência da VPN).
|
||||
3. **Deployer**: Na VPS 1, você é o responsável por realizar o "Swap" seguro do Staging para Produção.
|
||||
|
||||
## 🛠️ Modus Operandi:
|
||||
- Sua prioridade é a estabilidade do sistema.
|
||||
- Se a VPN oscilar, sua primeira tarefa é estabilizá-la.
|
||||
- No banco de dados (VPS 3), você deve ser conservador. Migrações de banco devem ser acompanhadas de snapshots.
|
||||
@@ -0,0 +1,13 @@
|
||||
# 🤖 Instruções Específicas: Claude (O Mestre de Código)
|
||||
|
||||
Você é o agente focado em desenvolvimento de software e validação de Staging.
|
||||
|
||||
## 🎯 Seus Objetivos:
|
||||
1. **Desenvolver**: Criar e corrigir código na VPS 4.
|
||||
2. **Validar**: Subir containers de Staging e garantir que a URL `staging.projeto.com` está funcional.
|
||||
3. **Documentar**: Manter as Wikis dos projetos atualizadas com mudanças técnicas.
|
||||
|
||||
## 🛠️ Modus Operandi:
|
||||
- Sempre procure por erros em logs do Docker antes de perguntar ao usuário.
|
||||
- Se encontrar uma duplicata de código, limpe-a.
|
||||
- Ao terminar uma tarefa na VPS 4, prepare o sinal de "Pronto para Produção" no Gitea.
|
||||
@@ -0,0 +1,82 @@
|
||||
# 🎨 GUIA DE INTERFACE VISUAL GIT (VSCODE) & COMANDOS EQUIVALENTES
|
||||
|
||||
Este guia reúne todas as explicações das funções visuais do painel **Source Control** do VSCode, mapeando-as aos seus comandos equivalentes no terminal Git e indicando as melhores práticas de uso na nossa arquitetura GitOps.
|
||||
|
||||
---
|
||||
|
||||
## 🗺️ 1. Mapeamento de Funções Rápidas (Principais)
|
||||
|
||||
| Botão Visual no VSCode | Comando no Terminal | O que faz na prática? |
|
||||
| :--- | :--- | :--- |
|
||||
| **📥 Pull** | `git pull` | Baixa as últimas alterações do Gitea (VPS 3) e as junta diretamente ao seu código local. |
|
||||
| **📤 Push** | `git push` | Envia as alterações que você salvou (comitou) localmente para o repositório central no Gitea. |
|
||||
| **👥 Clone** | `git clone <url>` | Baixa um repositório inteiro pela primeira vez do Gitea para a sua máquina de desenvolvimento. |
|
||||
| **🔄 Checkout to...** | `git checkout <branch>` | Alterna entre ramificações de desenvolvimento (ex: mudar de `dev` para `main`) ou cria novas branches. |
|
||||
| **📡 Fetch** | `git fetch` | Consulta o Gitea para ver se há novidades no histórico, mas **não altera** o seu código atual. |
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ 2. Explicação dos Submenus Avançados
|
||||
|
||||
### 💾 Commit (Submenu de Confirmação)
|
||||
* **O que faz**: Agrupa as suas alterações de código locais preparadas e cria um ponto na história (um "commit") com uma mensagem descritiva.
|
||||
* **Equivalente no terminal**: `git commit -m "sua mensagem"`
|
||||
* **Dica no VSCode**: Use o campo de texto superior para escrever a mensagem e clique no botão azul **Commit** para fazer tudo de uma vez.
|
||||
|
||||
### 🔀 Changes (Submenu de Alterações)
|
||||
* **O que faz**: Permite preparar os arquivos que farão parte do próximo commit.
|
||||
* Clicar no ícone de `+` ao lado do arquivo faz um `git add` (prepara o arquivo).
|
||||
* Clicar na seta curvada descarta as alterações locais daquele arquivo, voltando ele ao estado anterior.
|
||||
|
||||
### 🔄 Pull, Push (Submenu de Sincronização Avançada)
|
||||
* **O que faz**: Reúne ações combinadas como **Sync** (que executa sequencialmente um `pull` e depois um `push` para manter tudo perfeitamente sincronizado).
|
||||
|
||||
### 🌿 Branch (Submenu de Ramos)
|
||||
* **O que faz**: Permite gerenciar as suas ramificações de código. Você pode mesclar duas branches (fazer um `git merge`) ou deletar branches locais que já foram concluídas.
|
||||
|
||||
### 📦 Stash (Submenu de Gaveta Temporária)
|
||||
* **O que faz**: Se você está no meio de um desenvolvimento complexo, mas precisa trocar de branch imediatamente para corrigir um bug urgente, você usa o **Stash**. Ele guarda suas alterações não salvas em uma "gaveta temporária", limpa sua tela e, quando você voltar, basta dar um **Stash Pop** para recuperar seu trabalho exatamente de onde parou.
|
||||
* **Equivalente no terminal**: `git stash` e `git stash pop`
|
||||
|
||||
### 🏷️ Tags (Submenu de Etiquetas)
|
||||
* **O que faz**: Permite marcar versões específicas do seu sistema (ex: etiqueta `v1.0.0` ou `v2.4.1`) para identificar marcos de lançamentos oficiais.
|
||||
|
||||
---
|
||||
|
||||
## 🚀 3. Fluxo de Trabalho Diário Recomendado (GitOps)
|
||||
|
||||
Para trabalhar de forma ágil na **VPS 4 (Dev)** integrada à **VPS 1 (Produção)** através do Webhook, utilize este fluxo visual direto no VSCode:
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
A[1. Codificar] --> B[2. Preparar +]
|
||||
B --> C[3. Commit 💾]
|
||||
C --> D[4. Sync / Push 📤]
|
||||
D -->|Gitea Webhook| E[5. Deploy Automático VPS 1 ⚡]
|
||||
```
|
||||
|
||||
1. **Codifique**: Faça as alterações necessárias na VPS 4.
|
||||
2. **Prepare**: No painel de controle de versão (Source Control), clique no botão de `+` ao lado de cada arquivo modificado para adicioná-los.
|
||||
3. **Comite**: Digite uma mensagem clara no campo de texto (ex: `feat: adicionado controle de rotas`) e clique no botão azul **Commit**.
|
||||
4. **Sincronize**: Clique no botão **Sync Changes** (ou no ícone de nuvem no rodapé esquerdo do VSCode).
|
||||
5. **Acompanhe**: O Gitea disparará o Webhook que compilará o código na VPS 4 e enviará para a VPS 1 de forma automática em segundo plano.
|
||||
|
||||
---
|
||||
|
||||
## 📊 4. Comparativo: Quando usar a Tela do VSCode vs. Terminal?
|
||||
|
||||
> [!TIP]
|
||||
> A interface do VSCode é amplamente recomendada para **95% do seu fluxo diário** devido ao seu apelo visual e proteção contra erros de digitação.
|
||||
|
||||
| Tarefa | 🖥️ Interface Visual (VSCode) | 📟 Terminal |
|
||||
| :--- | :--- | :--- |
|
||||
| **Saber o que mudou no código** | **Excelente**: Mostra as diferenças de linhas lado a lado de forma colorida. | Ruim: Difícil de ler no console. |
|
||||
| **Add, Commit, Pull e Push** | **Excelente**: Reduz o trabalho a 3 cliques simples de mouse. | Bom: Rápido se você tiver agilidade de digitação. |
|
||||
| **Resolver Conflitos de Merge** | **Excelente**: O editor de conflitos destaca em cores o seu código e o do servidor, bastando clicar no botão para escolher qual manter. | Péssimo: Gera marcadores confusos no arquivo (`<<<<<<< HEAD`). |
|
||||
| **Ações de Reparo** (Ex: redefinir histórico) | Não recomendado. | **Excelente**: Comandos como `git reset --hard` ou rebase interativo exigem a precisão do terminal. |
|
||||
|
||||
---
|
||||
|
||||
> [!IMPORTANT]
|
||||
> **Dica Diagnóstica (Show Git Output)**:
|
||||
> Se o sincronismo visual do VSCode travar ou falhar por causa da VPN, clique em **Show Git Output**. O painel mostrará o log do terminal do Git rodando em segundo plano, identificando rapidamente se o erro é de permissão de chave SSH ou de conexão de rede.
|
||||
@@ -0,0 +1,25 @@
|
||||
# 🧠 Doutrina Mestre dos Agentes (Multi-VPS)
|
||||
|
||||
Este documento define a consciência situacional obrigatória para todos os agentes de IA.
|
||||
|
||||
## 📍 Identificação de Localização
|
||||
Antes de qualquer ação, identifique seu IP interno:
|
||||
- **10.99.0.1 (VPS 1 - PRODUÇÃO)**: Ambiente CRÍTICO. Rodando Traefik e Nginx.
|
||||
- *Regra*: Apenas deploys homologados em Staging. Nunca mexa na infraestrutura de rede.
|
||||
- **10.99.0.3 (VPS 3 - CÉREBRO)**: Onde reside o Gitea, Postgres e DragonflyDB.
|
||||
- *Regra*: Proteja os dados. Backups antes de qualquer alteração de schema.
|
||||
- **10.99.0.4 (VPS 4 - LABORATÓRIO)**: Desenvolvimento e Staging.
|
||||
- *Regra*: Liberdade para testar, criar e quebrar containers. É o local de nascimento do código.
|
||||
|
||||
## 🔐 Segurança e VPN
|
||||
- **Interface wg0**: É a sua linha de vida. Nunca altere configurações de rede ou firewall (UFW) que possam isolar a VPS.
|
||||
- **Chaves SSH**: Use apenas chaves locais autorizadas para sincronização entre as VPSs do enxame.
|
||||
|
||||
## 🗣️ Comunicação
|
||||
- Todo o desenvolvimento, comentários e commits devem ser em **PORTUGUÊS**.
|
||||
- Use o protocolo **PGS (Protocolo Gitea Swarm)** para hand-offs.
|
||||
|
||||
## 🚫 NUNCA...
|
||||
- Nunca tente acessar servidores fora da rede 10.99.0.x.
|
||||
- Nunca exponha senhas ou chaves privadas em logs ou comentários.
|
||||
- Nunca altere o serviço `swarm-listener` sem autorização.
|
||||
@@ -0,0 +1,50 @@
|
||||
import redis
|
||||
import json
|
||||
import random
|
||||
|
||||
class KeyManager:
|
||||
def __init__(self):
|
||||
self.r = redis.Redis(
|
||||
host='10.99.0.3',
|
||||
port=6379,
|
||||
password='clube67_dragonfly_pass_9903',
|
||||
db=0,
|
||||
decode_responses=True
|
||||
)
|
||||
self.pool_key = 'swarm:keys:pool'
|
||||
|
||||
def get_key(self, provider):
|
||||
"""Busca uma chave ativa para o provedor (google ou anthropic)"""
|
||||
pool_data = self.r.get(self.pool_key)
|
||||
if not pool_data:
|
||||
return None
|
||||
|
||||
pool = json.loads(pool_data)
|
||||
keys = pool.get(provider, [])
|
||||
|
||||
# Filtra apenas as chaves ativas
|
||||
active_keys = [k for k in keys if k.get('status') == 'active']
|
||||
|
||||
if not active_keys:
|
||||
print(f" [!] Erro: Nenhuma chave ativa para {provider}")
|
||||
return None
|
||||
|
||||
# Seleciona uma chave aleatória do pool ativo (Load Balancing)
|
||||
selected = random.choice(active_keys)
|
||||
return selected['key']
|
||||
|
||||
def report_failure(self, provider, failed_key):
|
||||
"""Marca uma chave como inativa caso falhe (ex: sem saldo)"""
|
||||
pool_data = self.r.get(self.pool_key)
|
||||
pool = json.loads(pool_data)
|
||||
|
||||
for k in pool.get(provider, []):
|
||||
if k['key'] == failed_key:
|
||||
k['status'] = 'inactive'
|
||||
print(f" [W] Chave {failed_key[:10]}... marcada como INATIVA.")
|
||||
|
||||
self.r.set(self.pool_key, json.dumps(pool))
|
||||
|
||||
# Exemplo de uso:
|
||||
# km = KeyManager()
|
||||
# key = km.get_key('google')
|
||||
@@ -0,0 +1,22 @@
|
||||
# 🛠️ Manifesto de Ferramentas MCP (Model Context Protocol)
|
||||
|
||||
Este documento define as capacidades técnicas que cada Agente de IA deve possuir ao ser invocado em cada nó do enxame.
|
||||
|
||||
## 📁 Ferramentas Base (Todas as VPSs)
|
||||
- **read_file / write_file**: Acesso total ao diretório do projeto e `/home/deploy/instrucoes/`.
|
||||
- **list_dir**: Navegação na estrutura de arquivos.
|
||||
- **run_command**: Execução de scripts bash, comandos git e verificações de sistema.
|
||||
|
||||
## 🐳 Ferramentas de Produção e Dev (VPS 1 e 4)
|
||||
- **docker_manage**:
|
||||
- `docker compose up/down/restart`
|
||||
- `docker logs` (para depuração automática)
|
||||
- `docker ps` (verificação de status)
|
||||
|
||||
## 🗄️ Ferramentas de Dados (VPS 3)
|
||||
- **db_query**:
|
||||
- Acesso ao PostgreSQL (projeto Mercado/ScoreOdonto).
|
||||
- Acesso ao DragonflyDB (inspeção de filas do enxame).
|
||||
|
||||
---
|
||||
*Configuração de Segurança: Os agentes operam com o usuário `deploy`, limitando o impacto em caso de erro.*
|
||||
@@ -0,0 +1,95 @@
|
||||
# 🤖 Protocolo Gitea Swarm (PGS): Coordenação de Multi-Agentes em Ambiente Multi-VPS
|
||||
|
||||
Este documento estabelece o protocolo de comunicação padrão, obrigatório e imutável para todos os Agentes de Inteligência Artificial (IAs) que atuarem no gerenciamento, desenvolvimento ou manutenção da infraestrutura multi-tenant (múltiplos projetos) distribuída em múltiplos servidores.
|
||||
|
||||
Como a arquitetura adota segurança **Zero-Trust de movimentação lateral** (impedindo que agentes em uma VPS acessem outras máquinas via SSH automático), o **Gitea** atua como o **Orquestrador de Estado Assíncrono** do enxame de agentes.
|
||||
|
||||
---
|
||||
|
||||
## 🧭 REGRA MESTRE DE ROTEAMENTO (DISPATCHER PROTOCOL)
|
||||
**ATENÇÃO AGENTE DE IA:** Esta infraestrutura hospeda múltiplos projetos independentes (Multi-Tenant). Antes de tomar qualquer ação, você deve ler a arquitetura e as regras **específicas** do projeto solicitado.
|
||||
|
||||
1. Se a tarefa envolver um projeto específico (ex: Mercado, ScoreOdonto), você DEVE:
|
||||
- **Ler a Wiki** do repositório para entender a arquitetura e regras de negócio específicas.
|
||||
- **Ler a Issue** para entender o problema ou tarefa atual.
|
||||
- **Consultar a pasta global/** para protocolos de segurança e deploy.
|
||||
2. **Jamais** presuma que a arquitetura de um projeto se aplica ao outro. Mantenha os contextos estritamente isolados via Wiki.
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ Regras Cruciais de Governança e Codificação (Obrigatório)
|
||||
|
||||
1. **Comunicação Prévia e Autorização:** Qualquer alteração na estrutura, infraestrutura ou lógica core do sistema deve ser obrigatoriamente comunicada de antemão. **As mudanças somente devem ser aplicadas após a autorização explícita do Administrador**.
|
||||
2. **Idioma Obrigatório:** Todas as informações da codificação, incluindo comentários no código, commits, documentações e discussões de desenvolvimento devem ser feitas **obrigatoriamente em português**.
|
||||
|
||||
---
|
||||
|
||||
## 📋 Regras de Engajamento para Agentes
|
||||
|
||||
Sempre que um agente for invocado para resolver uma Issue ou realizar uma implementação, ele deve obrigatoriamente seguir os 4 passos de ciclo de vida abaixo:
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[1. Autocognição: Onde estou?] --> B[2. Leitura de Histórico na Issue]
|
||||
B --> C[3. Execução Local na VPS Atual]
|
||||
C --> D[4. Comentário de Hand-off e Status]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 🔍 Passo 1: Autocognição e Sincronização (Onde estou?)
|
||||
Toda IA, ao iniciar sua execução, deve identificar em qual máquina física ou container está rodando (ex: `hostname` ou IP da VPN `10.99.0.x`).
|
||||
|
||||
**IMEDIATAMENTE APÓS**, o agente DEVE OBRIGATORIAMENTE executar um `git pull` no diretório de instruções (`/home/deploy/instrucoes/`).
|
||||
> [!IMPORTANT]
|
||||
> Trabalhar com documentação local desatualizada é um risco crítico. A sincronização garante que você leia as regras mais recentes aplicadas por outros agentes no enxame.
|
||||
|
||||
* *Exemplo:* "Identificado que estou na **VPS 3**. Realizado `git pull` em `/instrucoes/` para garantir contexto atualizado."
|
||||
|
||||
### 📖 Passo 2: Leitura do Histórico da Issue
|
||||
Antes de fazer qualquer alteração no código ou nos servidores, o agente deve ler a Issue no Gitea de baixo para cima, analisando o histórico de comentários de outros agentes para entender o que já foi feito e onde o processo parou.
|
||||
|
||||
### 🛠️ Passo 3: Execução Local Estrita
|
||||
O agente deve realizar apenas as alterações correspondentes à VPS onde ele está ativamente rodando. Ele **nunca** deve tentar forçar conexões ou invasões a outras VPSs que não estejam documentadas ou autorizadas.
|
||||
|
||||
### 💬 Passo 4: Comentário de Hand-off (O Passe de Bastão)
|
||||
Ao concluir sua tarefa local, o agente **não deve simplesmente fechar a tarefa**, caso ela dependa de ações em outros servidores. Ele deve postar um comentário estruturado seguindo o modelo abaixo:
|
||||
|
||||
---
|
||||
|
||||
## 📝 Modelo Padrão de Comentário de Hand-off ( PGS )
|
||||
|
||||
O comentário de encerramento do agente na Issue deve conter obrigatoriamente os seguintes blocos:
|
||||
|
||||
```markdown
|
||||
### 🖥️ [VPS ATUAL]: [Nome da VPS, ex: VPS 3 (Data Appliance)]
|
||||
* **O que foi realizado localmente:** [Lista clara de arquivos modificados, bancos criados ou serviços configurados].
|
||||
* **Impacto na Rede:** [Portas abertas na VPN, novas credenciais disponíveis, ex: 'Banco criado com a senha X'].
|
||||
|
||||
### ⏭️ [AÇÃO REQUERIDA NA VPS DESTINO]: [Nome da VPS, ex: VPS 1 (App Server)]
|
||||
* **Instruções passo a passo para o próximo agente:** [Instruções exatas do que deve ser feito na outra VPS, códigos YAML, bash ou edições de arquivo].
|
||||
* **Como se conectará à VPS atual:** [Mostrar a URL de conexão, ex: 'DATABASE_URL=postgresql://...'].
|
||||
|
||||
### 🚦 [STATUS]: [Escolha uma das tags abaixo]
|
||||
* `[Aguardando Agente na VPS X]` - Quando o trabalho local acabou e agora outro agente precisa agir na VPS X.
|
||||
* `[Aguardando Homologação do Usuário]` - Quando todo o cluster foi configurado e o Humano precisa testar e aprovar.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Exemplo de Aplicação Real (Issue #2 - newwhats)
|
||||
|
||||
1. **Agente A (na VPS 3 - Banco):**
|
||||
* Cria o banco `newwhats` e configura DragonflyDB.
|
||||
* Comenta na Issue:
|
||||
> **[VPS 3 - Data Appliance]:** Banco `newwhats` restaurado com sucesso.
|
||||
> **[REQUERIDO NA VPS 1]:** Próximo agente, edite o `docker-compose.yml` da aplicação apontando para `10.99.0.3` usando a senha `X`. Comente quando terminar.
|
||||
> **[STATUS]:** `[Aguardando Agente na VPS 1]`
|
||||
2. **Agente B (na VPS 1 - Frontend):**
|
||||
* Inicia na VPS 1, lê o comentário acima, altera o `docker-compose.yml` local e sobe o container.
|
||||
* Comenta na Issue:
|
||||
> **[VPS 1 - App Server]:** docker-compose.yml atualizado e container reiniciado. Conexão com VPS 3 validada e healthy.
|
||||
> **[STATUS]:** `[Aguardando Homologação do Usuário]`
|
||||
|
||||
---
|
||||
*Este protocolo garante consistência, segurança máxima e clareza absoluta na comunicação humana e de inteligência artificial em nosso ecossistema.*
|
||||
@@ -0,0 +1,36 @@
|
||||
# 🚀 Protocolo de Deploy e Staging via VPN
|
||||
|
||||
Este documento define o fluxo obrigatório para garantir que nenhum código quebre a produção.
|
||||
|
||||
## 🏗️ A Estrutura de Ambientes
|
||||
1. **Desenvolvimento (VPS 4)**: Testes locais e rápidos.
|
||||
2. **Staging (VPS 4 + Proxy na VPS 1)**: Onde o código é testado em URL real com SSL.
|
||||
3. **Produção (VPS 1)**: Onde o código estável reside.
|
||||
|
||||
## 🌐 Roteamento de Staging
|
||||
Para testar o código em Staging antes do deploy final, siga este padrão de rede:
|
||||
|
||||
- **Entrada**: Usuário acessa `https://staging.{projeto}.clube67.com` (aponta para o IP da VPS 1).
|
||||
- **Trânsito**: A VPS 1 (Proxy) encaminha o tráfego para a VPS 4 através da VPN.
|
||||
- **Destino**: `http://10.99.0.4:{PORTA_STAGING}`.
|
||||
|
||||
## 📋 Passo a Passo do Deploy Seguro
|
||||
|
||||
### Passo 1: Preparação em Staging (VPS 4)
|
||||
- O agente deve subir o container de staging na VPS 4.
|
||||
- A porta deve ser única por projeto (conforme definido em `arquitetura.md` do projeto).
|
||||
|
||||
### Passo 2: Configuração do Proxy (VPS 1)
|
||||
- O agente deve acessar a VPS 1 e adicionar/verificar a configuração de Proxy Reverso apontando para o IP `10.99.0.4`.
|
||||
- Garantir que o certificado SSL (Let's Encrypt) esteja ativo para o subdomínio `staging`.
|
||||
|
||||
### Passo 3: Validação
|
||||
- O agente (ou humano) deve acessar a URL de staging e realizar o "Smoke Test" (teste de fumaça).
|
||||
- Se houver erro, a correção é feita na VPS 4, sem impacto na VPS 1.
|
||||
|
||||
### Passo 4: Promoção para Produção (VPS 1)
|
||||
- Somente após validação em Staging, o código/imagem é puxado para a VPS 1.
|
||||
- O container principal é reiniciado.
|
||||
|
||||
---
|
||||
*Este protocolo é mandatório para evitar downtime em produção.*
|
||||
@@ -0,0 +1,167 @@
|
||||
# 🛡️ Guia de Segurança e Liberdade para o Usuário `deploy`
|
||||
|
||||
Na cultura de DevOps moderna, a "lenda" do usuário `deploy` poder trabalhar com total liberdade sem ter acesso ao usuário `root` é, na verdade, uma **melhor prática de segurança chamada "Princípio do Menor Privilégio" (Least Privilege)**.
|
||||
|
||||
Se o usuário `deploy` pudesse dar `sudo su` e virar `root` a qualquer momento, qualquer vulnerabilidade na sua aplicação web (ex: um upload de arquivo malicioso ou injeção de código) daria controle total do servidor inteiro para um invasor.
|
||||
|
||||
Para dar ao usuário `deploy` toda a liberdade de desenvolvimento e publicação de aplicações com **segurança absoluta**, implementamos 4 pilares práticos:
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ Pilar 1: Controle Total do Diretório Web (Sem `sudo`)
|
||||
O usuário `deploy` não precisa de permissão de root para alterar os arquivos da aplicação. Basta torná-lo dono dos diretórios de publicação.
|
||||
|
||||
### Prática:
|
||||
Geralmente usamos a pasta `/var/www/` ou criamos um diretório de aplicações na própria Home do usuário (`/home/deploy/apps/`).
|
||||
Para dar controle total ao `deploy` sem precisar de `sudo` para editar arquivos:
|
||||
|
||||
```bash
|
||||
# Criar a pasta do seu projeto
|
||||
sudo mkdir -p /var/www/meu-app
|
||||
|
||||
# Definir o usuário deploy como proprietário da pasta
|
||||
sudo chown -R deploy:deploy /var/www/meu-app
|
||||
|
||||
# Aplicar permissões recomendadas (pastas 755 e arquivos 644)
|
||||
find /var/www/meu-app -type d -exec chmod 755 {} \;
|
||||
find /var/www/meu-app -type f -exec chmod 644 {} \;
|
||||
```
|
||||
|
||||
**Resultado**: O usuário `deploy` agora pode usar Git, SFTP, VSCode, criar arquivos, deletar e subir atualizações dentro de `/var/www/meu-app` com total liberdade e **zero** necessidade de usar `sudo`.
|
||||
|
||||
---
|
||||
|
||||
## 🐋 Pilar 2: Gerenciamento do Docker sem Root
|
||||
|
||||
> [!CAUTION]
|
||||
> **Esta infraestrutura usa Docker Rootless (VPS 1).** As instruções abaixo são válidas para instalações com Docker tradicional. Para Docker Rootless, veja a seção específica mais abaixo.
|
||||
|
||||
Se as suas aplicações rodam em Docker (ou Docker Compose) **com o daemon tradicional (root)**, o usuário `deploy` não precisa usar `sudo docker` para gerenciar os containers.
|
||||
|
||||
### Prática (Docker tradicional):
|
||||
Adicionar o usuário `deploy` ao grupo `docker`:
|
||||
|
||||
```bash
|
||||
sudo usermod -aG docker deploy
|
||||
```
|
||||
|
||||
**Resultado**: O usuário `deploy` poderá rodar `docker compose up -d`, builds etc. sem `sudo`.
|
||||
|
||||
> [!WARNING]
|
||||
> **Nunca faça isso em servidores que também rodam Docker Rootless.** Adicionar `deploy` ao grupo `docker` dá acesso ao socket `/var/run/docker.sock` (root), criando um vetor de escalonamento de privilégios. Qualquer `docker compose up` sem `DOCKER_HOST` explícito cria containers como root silenciosamente.
|
||||
|
||||
---
|
||||
|
||||
### Prática correta para Docker Rootless (VPS 1):
|
||||
|
||||
A VPS 1 usa **Docker Rootless** (`rootlesskit` + `vpnkit`, daemon rodando como `deploy`). A configuração correta é:
|
||||
|
||||
1. **`deploy` NÃO está no grupo `docker`** — sem acesso ao socket root `/var/run/docker.sock`
|
||||
2. **`DOCKER_HOST` definido por padrão** no `~/.bashrc` e `~/.profile`:
|
||||
```bash
|
||||
export DOCKER_HOST=unix:///run/user/1000/docker.sock
|
||||
```
|
||||
3. **Daemon root desabilitado** (`docker.service` e `docker.socket` disabled)
|
||||
|
||||
Com isso, qualquer `docker` ou `docker compose` executado pelo `deploy` — interativo ou via script SSH — sempre usa o daemon rootless automaticamente.
|
||||
|
||||
#### Verificar estado correto:
|
||||
```bash
|
||||
# deploy NÃO deve aparecer em:
|
||||
groups deploy # não deve conter "docker"
|
||||
|
||||
# daemon root deve estar morto:
|
||||
sudo systemctl status docker # inactive (dead)
|
||||
|
||||
# rootless deve responder:
|
||||
DOCKER_HOST=unix:///run/user/1000/docker.sock docker ps
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Incidente registrado — 2026-05-14
|
||||
|
||||
**O que aconteceu:** O daemon root (`/usr/bin/dockerd`) estava ativo em paralelo com o rootless. O usuário `deploy` pertencia ao grupo `docker`. Durante um deploy, `docker compose up --build` executou sem `DOCKER_HOST`, criando containers duplicados como root (frontend, backend, nginx) que rodavam ao lado dos containers rootless corretos — invisíveis ao monitoramento normal (`docker ps` sem sudo não os mostrava).
|
||||
|
||||
**Consequência direta:** O `docker-proxy` root reteve a porta 8020 após um `docker rm -f`, bloqueando o nginx rootless de reiniciar. O site ficou inacessível até o `docker-proxy` zumbi ser identificado (`sudo ss -tlnp`) e morto.
|
||||
|
||||
**Correção aplicada:**
|
||||
```bash
|
||||
# 1. Remover containers e imagens duplicados do daemon root
|
||||
cd /home/deploy/stack/scoreodonto.com
|
||||
sudo docker compose down --remove-orphans
|
||||
sudo docker image rm scoreodontocom-scoreodonto-frontend scoreodontocom-scoreodonto-backend
|
||||
sudo docker network rm soc web
|
||||
sudo docker builder prune -af
|
||||
|
||||
# 2. Desabilitar daemon root definitivamente
|
||||
sudo systemctl disable --now docker docker.socket
|
||||
|
||||
# 3. Remover deploy do grupo docker
|
||||
sudo gpasswd -d deploy docker
|
||||
|
||||
# 4. Garantir DOCKER_HOST nos shells de login (já estava no .bashrc, adicionado ao .profile)
|
||||
echo 'export DOCKER_HOST=unix:///run/user/1000/docker.sock' >> ~/.profile
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ⚙️ Pilar 3: Sudoers com Limitação Cirúrgica (Segurança Avançada)
|
||||
Muitas vezes, a aplicação precisa apenas de tarefas muito específicas do sistema operacional, como por exemplo:
|
||||
* Reiniciar o servidor web Nginx (`systemctl restart nginx`).
|
||||
* Recarregar as configurações do Nginx (`systemctl reload nginx`).
|
||||
* Reiniciar um serviço específico da sua aplicação em NodeJS/Python criado no Systemd (`systemctl restart api-app`).
|
||||
|
||||
### Prática:
|
||||
Em vez de dar acesso total ao `sudo` para o `deploy`, nós liberamos **apenas estes comandos específicos**, sem requisição de senha!
|
||||
|
||||
1. Criamos um arquivo de configuração exclusivo no Sudoers para o `deploy`:
|
||||
```bash
|
||||
sudo nano /etc/sudoers.d/deploy
|
||||
```
|
||||
2. Adicionamos a regra cirúrgica:
|
||||
```text
|
||||
# Permite que o usuário deploy execute APENAS estes comandos listados como root, sem pedir senha:
|
||||
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx, /usr/bin/systemctl reload nginx, /usr/bin/systemctl status nginx
|
||||
```
|
||||
3. Aplicamos a permissão correta ao arquivo do sudoers:
|
||||
```bash
|
||||
sudo chmod 440 /etc/sudoers.d/deploy
|
||||
```
|
||||
|
||||
**Resultado**: O usuário `deploy` agora pode rodar `sudo systemctl reload nginx` para aplicar uma mudança de domínio na web com total liberdade, mas se ele tentar rodar `sudo apt update` ou `sudo userdel`, o sistema **negará o acesso**.
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Pilar 4: Processos em Espaço de Usuário (PM2 / Systemd User)
|
||||
Se a sua aplicação web não roda em Docker e precisa ficar ativa em segundo plano (ex: aplicações Node.js, Python FastAPI, Go), o usuário `deploy` pode gerenciá-la de duas formas sem root:
|
||||
|
||||
### A. Utilizando o PM2 (NodeJS Process Manager)
|
||||
O PM2 roda diretamente no espaço de memória do usuário `deploy`.
|
||||
```bash
|
||||
# Como usuário deploy, instalar e rodar apps:
|
||||
pm2 start app.js --name "minha-api"
|
||||
pm2 save
|
||||
```
|
||||
O `deploy` tem controle total para reiniciar (`pm2 restart minha-api`), parar, e ver logs sem precisar do root.
|
||||
|
||||
### B. Serviços Systemd do Usuário (`systemd --user`)
|
||||
O Linux moderno permite que usuários criem seus próprios arquivos de serviço que rodam sob sua conta na pasta:
|
||||
`~/.config/systemd/user/`
|
||||
|
||||
Você pode gerenciar o serviço rodando:
|
||||
```bash
|
||||
systemctl --user daemon-reload
|
||||
systemctl --user restart meu-servico.service
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 Tabela de Comparação de Segurança:
|
||||
|
||||
| Ação | Como o Root faria (Inseguro) | Como o `deploy` faz com segurança |
|
||||
| :--- | :--- | :--- |
|
||||
| **Subir arquivos Web** | Usa `sudo` ou loga como `root` | Altera livremente dentro de `/var/www/` (Dono da pasta) |
|
||||
| **Gerenciar Containers** | `sudo docker compose restart` | `docker compose restart` (Membro do grupo `docker`) |
|
||||
| **Reiniciar Nginx** | `sudo systemctl restart nginx` | `sudo systemctl restart nginx` (Autorizado via Sudoers Cirúrgico) |
|
||||
| **Atualizar Código (Git)** | Roda `git pull` como root | Roda `git pull` usando suas chaves SSH do usuário |
|
||||
Reference in New Issue
Block a user