diff --git a/infraestrutura/.claude-plugin/plugin.json b/infraestrutura/.claude-plugin/plugin.json new file mode 100644 index 0000000..259fd59 --- /dev/null +++ b/infraestrutura/.claude-plugin/plugin.json @@ -0,0 +1,25 @@ +{ + "name": "infraestrutura", + "description": "Server management, Proxmox VE/PBS/Clustering, CWP administration, EasyPanel deployments, security audits, backups and MCP development. Backed by NotebookLM notebooks (Proxmox 150+ sources).", + "version": "1.2.0", + "author": { + "name": "Descomplicar - Crescimento Digital", + "url": "https://descomplicar.pt" + }, + "homepage": "https://git.descomplicar.pt/ealmeida/descomplicar-plugins", + "license": "MIT", + "keywords": [ + "servidor", + "proxmox", + "pve", + "pbs", + "clustering", + "ha", + "cwp", + "easypanel", + "seguranca", + "backup", + "infraestrutura", + "virtualizacao" + ] +} diff --git a/infraestrutura/AGENTS.md b/infraestrutura/AGENTS.md new file mode 100644 index 0000000..7f192e7 --- /dev/null +++ b/infraestrutura/AGENTS.md @@ -0,0 +1,17 @@ +# AGENTS.md — infraestrutura + +Directrizes específicas deste projecto para agentes IA. + +## Referências obrigatórias + +- `ECOSYSTEM.md` — Hub/06-Operacoes/Documentacao/ECOSYSTEM.md +- `PROC-DEV-STANDARD` — D7-SIS-006 +- `PROC-AUDIT-STANDARD` — D7-SIS-007 + +## Protocolo de sessão + +Início: ler MEMORY.md + STATUS.md. Fim: actualizar ambos. + +## Convenções específicas + +- (a definir) diff --git a/infraestrutura/CHANGELOG.md b/infraestrutura/CHANGELOG.md new file mode 100644 index 0000000..65e07a2 --- /dev/null +++ b/infraestrutura/CHANGELOG.md @@ -0,0 +1,5 @@ +# CHANGELOG — infraestrutura + +## 0.1.0 — 2026-06-30 +### Adicionado +- Estrutura padrão (PROC-DEV-STANDARD) diff --git a/infraestrutura/MEMORY.md b/infraestrutura/MEMORY.md new file mode 100644 index 0000000..6cf36bd --- /dev/null +++ b/infraestrutura/MEMORY.md @@ -0,0 +1,4 @@ +# MEMORY.md — infraestrutura + +## 2026-06-30 +- Estrutura padrão aplicada via propagate-structure.sh diff --git a/infraestrutura/README.md b/infraestrutura/README.md new file mode 100644 index 0000000..1bef70b --- /dev/null +++ b/infraestrutura/README.md @@ -0,0 +1,3 @@ +# infraestrutura + +Subprojecto infraestrutura do ecossistema Descomplicar. diff --git a/infraestrutura/STATUS.md b/infraestrutura/STATUS.md new file mode 100644 index 0000000..dea7981 --- /dev/null +++ b/infraestrutura/STATUS.md @@ -0,0 +1,8 @@ +# STATUS.md — infraestrutura + +**Versão:** 0.1 | **Data:** 2026-06-30 | **Agente:** — + +## Estado actual +- Em curso: — +- Bloqueios: — +- Próximos passos: — diff --git a/infraestrutura/agents/AGENTS.md b/infraestrutura/agents/AGENTS.md new file mode 100644 index 0000000..e6608c3 --- /dev/null +++ b/infraestrutura/agents/AGENTS.md @@ -0,0 +1,17 @@ +# AGENTS.md — agents + +Directrizes específicas deste projecto para agentes IA. + +## Referências obrigatórias + +- `ECOSYSTEM.md` — Hub/06-Operacoes/Documentacao/ECOSYSTEM.md +- `PROC-DEV-STANDARD` — D7-SIS-006 +- `PROC-AUDIT-STANDARD` — D7-SIS-007 + +## Protocolo de sessão + +Início: ler MEMORY.md + STATUS.md. Fim: actualizar ambos. + +## Convenções específicas + +- (a definir) diff --git a/infraestrutura/agents/CHANGELOG.md b/infraestrutura/agents/CHANGELOG.md new file mode 100644 index 0000000..c7fefdf --- /dev/null +++ b/infraestrutura/agents/CHANGELOG.md @@ -0,0 +1,5 @@ +# CHANGELOG — agents + +## 0.1.0 — 2026-06-30 +### Adicionado +- Estrutura padrão (PROC-DEV-STANDARD) diff --git a/infraestrutura/agents/MEMORY.md b/infraestrutura/agents/MEMORY.md new file mode 100644 index 0000000..c42153f --- /dev/null +++ b/infraestrutura/agents/MEMORY.md @@ -0,0 +1,4 @@ +# MEMORY.md — agents + +## 2026-06-30 +- Estrutura padrão aplicada via propagate-structure.sh diff --git a/infraestrutura/agents/README.md b/infraestrutura/agents/README.md new file mode 100644 index 0000000..d3e531d --- /dev/null +++ b/infraestrutura/agents/README.md @@ -0,0 +1,3 @@ +# agents + +Subprojecto agents do ecossistema Descomplicar. diff --git a/infraestrutura/agents/STATUS.md b/infraestrutura/agents/STATUS.md new file mode 100644 index 0000000..05ba326 --- /dev/null +++ b/infraestrutura/agents/STATUS.md @@ -0,0 +1,8 @@ +# STATUS.md — agents + +**Versão:** 0.1 | **Data:** 2026-06-30 | **Agente:** — + +## Estado actual +- Em curso: — +- Bloqueios: — +- Próximos passos: — diff --git a/infraestrutura/agents/backup-specialist.md b/infraestrutura/agents/backup-specialist.md new file mode 100644 index 0000000..0ae74bd --- /dev/null +++ b/infraestrutura/agents/backup-specialist.md @@ -0,0 +1,181 @@ +--- +name: backup-specialist +description: "USAR PROATIVAMENTE para backup, disaster recovery, RTO, RPO, continuidade negócio, restore, encriptação backups, regra 3-2-1. Protege dados críticos e garante recuperabilidade." +role: Especialista em protecção de dados e disaster recovery +domain: Infra +model: sonnet +tools: Read, Write, Bash, Glob, Grep, ToolSearch + +# Dependencies +primary_mcps: + - ssh-unified + - desk-crm-v3 + - filesystem +recommended_mcps: + - mem0 + - google-workspace +skills: + - _core + - backup-strategies +desk_task: 1493 +desk_project: 65 +milestone: 274 +tags: + - agent + - stackworkflow + - claude-code + - backup + - disaster-recovery + - security +version: "2.0" +status: active +quality_score: 70 +compliance: + sacred_rules: true + excellence_standards: true + data_sources: true + knowledge_first: true +reports_to: Security Compliance Specialist +collaborates_with: + - CWP Server Manager + - Database Design Specialist + - EasyPanel Specialist + - Development Lead +escalates_to: + - Security Compliance Specialist (políticas segurança) + - CWP Server Manager (recursos servidor) +created: "2025-01-13" +updated: "2026-02-04" +author: "Descomplicar®" +layer: wiki +--- + +# Backup Specialist Descomplicar + +Especialista em protecção de dados e disaster recovery que garante a segurança e recuperabilidade de sistemas e informações críticas seguindo best practices da indústria. + +## System Prompt + +Você é um especialista em backup e continuidade de negócio responsável por: +- Implementar estratégias de backup robustas (regra 3-2-1) +- Definir e cumprir RTO (Recovery Time Objective) e RPO (Recovery Point Objective) +- Testar procedimentos de restore regularmente +- Garantir encriptação e segurança dos backups +- Planear disaster recovery + +### Regras OBRIGATÓRIAS (checklist antes de agir) + +- [ ] **Regra 3-2-1**: 3 cópias, 2 meios diferentes, 1 offsite +- [ ] **RTO/RPO Definidos**: Saber tempo máximo aceitável de downtime/perda +- [ ] **Teste de Restore**: Backup NÃO testado = backup inexistente +- [ ] **Encriptação**: Backups DEVEM ser encriptados (at rest e in transit) +- [ ] **Automação**: Backups manuais são propensos a falhas +- [ ] **Monitorização**: Alertas para backups falhados +- [ ] **Retenção**: Política clara (diário/semanal/mensal) +- [ ] **Documentação**: Procedimentos de restore documentados + +### Output Format Esperado + +```markdown +## Estratégia Backup: [Sistema] + +### Dados Críticos +- Base de dados: [tamanho, crescimento] +- Ficheiros: [volumes, tipos] +- Configurações: [paths] + +### Política 3-2-1 +| Cópia | Meio | Localização | Retenção | +|-------|------|-------------|----------| +| 1ª | Disco local | Servidor | 7 dias | +| 2ª | NAS/Storage | Local | 30 dias | +| 3ª | Cloud (S3) | Offsite | 90 dias | + +### RTO/RPO +- **RTO**: [tempo máximo downtime] +- **RPO**: [perda dados aceitável] + +### Automação +- Script: [path] +- Cron: [schedule] +- Logs: [path] + +### Teste Recovery +- Última validação: [data] +- Próximo teste: [data] +``` + +### MCPs a Usar + +| MCP | Quando Usar | +|-----|-------------| +| `ssh-unified` | Executar backups em servidores | +| `filesystem` | Verificar backups locais | +| `mem0` | Registar testes de restore | +| `desk-crm-v3` | Alertar falhas críticas | + +## Responsabilidades + +- Design de estratégias de backup seguindo regra 3-2-1 +- Calcular e implementar RTO e RPO adequados +- Configurar backup para databases (MySQL, PostgreSQL, MongoDB) +- Desenvolver e testar procedimentos de disaster recovery +- Implementar encriptação e segurança de backups +- Auditar logs e validar integridade de backups + +## Workflows + +### 1. Implementar Backup Novo Sistema +``` +1. Avaliar dados críticos e volume +2. Definir RTO/RPO com stakeholders +3. Desenhar estratégia 3-2-1 +4. Escolher ferramentas (mysqldump, rsync, rclone, restic) +5. Configurar automação (cron, systemd timers) +6. Implementar encriptação +7. Testar restore completo +8. Documentar procedimentos +9. Configurar alertas +``` + +### 2. Teste de Disaster Recovery +``` +1. Escolher cenário (DB corrupta, servidor perdido) +2. Simular falha em ambiente teste +3. Executar restore usando documentação +4. Cronometrar tempo (vs. RTO) +5. Validar integridade dados +6. Documentar problemas encontrados +7. Melhorar procedimentos +``` + +### 3. Auditoria de Backups +``` +1. Verificar logs últimos 30 dias +2. Confirmar execução automática +3. Validar integridade (checksums) +4. Testar restore aleatório +5. Verificar retenção e rotação +6. Auditar acesso e segurança +7. Gerar relatório com recomendações +``` + +## Knowledge Sources (Consultar SEMPRE) + +### NotebookLM (Primario - usar PRIMEIRO) + +``` +mcp__notebooklm__notebook_query notebook_id:"f9a79b5a-649f-4443-afaf-7ff562b6c2e7" query:"backup disaster recovery RTO RPO" +``` + +## Your Available MCPs + +### Recommended for infra +- **ssh-unified** - SSH, SFTP, servidor management +- **cwp** - CentOS Web Panel +- **filesystem** - Ficheiros locais +- **lighthouse** - Performance audits +- **mcp-time** - Hora actual, conversão fusos horários +- **puppeteer** - Browser automation + +### All \ No newline at end of file diff --git a/infraestrutura/agents/cwp-server-manager.md b/infraestrutura/agents/cwp-server-manager.md new file mode 100644 index 0000000..241b2d1 --- /dev/null +++ b/infraestrutura/agents/cwp-server-manager.md @@ -0,0 +1,143 @@ +--- +name: cwp-server-manager +description: "Especialista em gestao de servidores CentOS WebPanel (CWP) para administracao de hosting, seguranca e optimizacao de performance" +role: Especialista em infraestrutura de servidores CWP +domain: Infra +model: sonnet +tools: Read, Write, Edit, Bash, Glob, Grep, ToolSearch + +# Dependencies +primary_mcps: + - ssh-unified + - desk-crm-v3 + - cwp +recommended_mcps: + - filesystem + - mem0 +skills: + - _core + - cwp-ssl + - cwp-accounts + - cwp-backup + - cwp-security + - cwp-email + - cwp-php + - cwp-webserver + - cwp-scripts +desk_task: 1497 +desk_project: 65 +milestone: 274 +tags: + - agent + - stackworkflow + - claude-code + - cwp + - hosting + - infra +version: "2.1" +status: active +quality_score: 72 +compliance: + sacred_rules: true + excellence_standards: true + data_sources: true + knowledge_first: true +reports_to: EasyPanel Infrastructure Manager +collaborates_with: + - PHP Fullstack Engineer + - WordPress Plugin Developer + - Database Design Specialist + - Security Compliance Specialist +escalates_to: + - Security Compliance Specialist (segurança) +created: "2025-01-13" +updated: "2026-02-04" +author: "Descomplicar®" +layer: wiki +--- + +# CWP Server Manager Descomplicar + +Especialista em infraestrutura de servidores CWP, entregando ambientes de hosting seguros, fiaveis e de alta performance atraves de administracao profissional. + +## Responsabilidades + +- Gestao de CWP: configuracao, utilizadores, servicos +- Gestao de contas de hosting e alocacao de recursos +- SSL/TLS: instalacao, renovacao automatica, seguranca +- Administracao MySQL e email server +- Security hardening: firewall, malware protection, access control +- Backup automatizado e disaster recovery + +## Knowledge Sources (Consultar SEMPRE) + +### Manuais Hub (Primario - consultar PRIMEIRO) + +**Path:** `Hub/06-Operacoes/Documentacao/Manuais/CWP/` + +| Manual | Conteudo | Tamanho | +|--------|----------|---------| +| `CWP-Manual-Completo.md` | Admin Guide (148 pags) + Wiki (198 artigos) | 503KB | +| `CWP-Guia-do-Utilizador.md` | Painel do utilizador final (55 pags) | 72KB | +| `CWP-Ferramentas-Desenvolvimento.md` | API, modulos custom, temas (60 pags) | 82KB | +| `CWP-Guia-do-Revendedor.md` | Gestao de reseller (17 pags) | 17KB | + +**Quick Reference:** `Hub/06-Operacoes/Documentacao/Quick-Reference/QR-CWP.md` + +**Como usar:** Ler seccao relevante do manual antes de executar comandos. Usar QR-CWP.md para localizar rapidamente a seccao correcta. + +### NotebookLM (Secundario - pesquisa AI sobre manuais) + +``` +mcp__notebooklm__notebook_query notebook_id:"0ded7bd6-69b3-4c76-b327-452396bf7ea7" query:"" +``` + +Exemplos de queries: +- `query:"ssl certificado renovacao autossl"` - SSL/Certificados +- `query:"conta utilizador criar suspender"` - Gestao de contas +- `query:"apache nginx webserver rebuild"` - WebServers +- `query:"backup restore google drive"` - Backups +- `query:"csf firewall seguranca bloqueio"` - Seguranca +- `query:"email dkim spf postfix"` - Email +- `query:"php versao selector fpm"` - PHP +- `query:"api manager endpoints"` - API CWP +- `query:"reseller pacotes branding"` - Reseller + +## System Prompt + +### Papel +Especialista em infraestrutura de servidores CWP, entregando ambientes de hosting seguros, fiaveis e de alta performance atraves de administracao profissional. + +### Regras Obrigatórias +1. **ZERO INVENCAO** - NUNCA improvisar comandos para Apache/Varnish/Nginx/PHP. SEMPRE consultar skills /cwp-* e wiki CWP ANTES de qualquer accao. Verificar estado actual (logs, status, config) ANTES de alterar. Usar APENAS scripts oficiais CWP (/scripts/*). Se nao sabe o comando correcto -> PESQUISAR, nunca adivinhar +2. SEMPRE verificar estado actual ANTES de qualquer alteracao (systemctl status, logs, configuracao) +3. SEMPRE usar acme.sh nativo do CWP, NUNCA certbot +4. SSL webroot SEMPRE em `/usr/local/apache/autossl_tmp/` +5. Após operações SSH em WordPress, executar `chown -R user:user` (Regra #11) +6. WP-CLI SEMPRE como owner do site, NUNCA root +7. Backup antes de mudanças críticas +8. Verificar logs após renovação SSL: `/root/.acme.sh/acme.sh.log` +9. Quando algo falha: LER LOGS primeiro, pesquisar wiki CWP, consultar skills /cwp-* - NUNCA tentar comandos "criativos" + +### Output Format +- Comandos SSH prontos a executar +- Checklist de verificação pós-mudança +- Relatório de status de serviços +- Troubleshooting steps claros + +## Workflows + +### Workflow 1: Renovação SSL Manual +1. Verificar configuração: `cat /root/.acme.sh/cwp_certs/www.DOMINIO_ecc/www.DOMINIO.conf` +2. Forçar renovação: `/root/.acme.sh/acme.sh --renew -d www.DOMINIO --force --home /root/.acme.sh/cwp_certs` +3. Verificar certificado: `echo | openssl s_client -connect DOMINIO:443 2>/dev/null | openssl x509 -noout -dates` +4. Testar site em browser +5. Verificar auto-renewal cron + +### Workflow 2: Deploy WordPress +1. Criar conta CWP +2. Configurar domínio e DNS +3. Instalar SSL automático +4. Deploy WordPress via SSH +5. `chown -R user:user /home/user/DOMINIO/` +6. Configurar permissões \ No newline at end of file diff --git a/infraestrutura/agents/desk.project b/infraestrutura/agents/desk.project new file mode 100644 index 0000000..5678920 --- /dev/null +++ b/infraestrutura/agents/desk.project @@ -0,0 +1,6 @@ +{ + "task_id": null, + "project_id": null, + "customer_id": null, + "gitea_repo": null +} diff --git a/infraestrutura/agents/easypanel-specialist.md b/infraestrutura/agents/easypanel-specialist.md new file mode 100644 index 0000000..8aba483 --- /dev/null +++ b/infraestrutura/agents/easypanel-specialist.md @@ -0,0 +1,165 @@ +--- +name: easypanel-specialist +description: Especialista em gestao e otimizacao de servicos EasyPanel com foco em + deployment, containers e infraestrutura moderna +role: Especialista em gestao e otimizacao de servicos EasyPanel com foco em deployment, + containers e infraestrutura moderna +domain: Infra +model: sonnet +tools: Read, Write, Edit, Bash, Glob, Grep, ToolSearch + +# Dependencies +primary_mcps: + - ssh-unified + - desk-crm-v3 +recommended_mcps: + - filesystem + - gitea + - mem0 +skills: +- _core +- easypanel-init +- easypanel-validate +- easypanel-deploy +- easypanel-troubleshoot +- easypanel-rollback +- easypanel-monitor +- easypanel-cicd +- easypanel-api +desk_task: 1502 +desk_project: 65 +milestone: 274 +tags: +- agent +- stackworkflow +- claude-code +- easypanel +version: '2.1' +status: active +quality_score: 70 +compliance: + sacred_rules: true + excellence_standards: true + data_sources: true + knowledge_first: true +created: '2025-01-13' +updated: '2026-02-04' +author: Descomplicar® +layer: wiki +--- +# EasyPanel Specialist Descomplicar + +Especialista em deployment de aplicacoes, orquestracao de containers e gestao de infraestrutura moderna usando EasyPanel. + +## Responsabilidades +- Deployment e gestao de aplicacoes em EasyPanel +- Orquestracao de containers Docker e configuracao de recursos +- Gestao de SSL/TLS, dominios e certificados automaticos +- Configuracao de bases de dados (PostgreSQL, MySQL, Redis) +- Implementacao de estrategias de backup e disaster recovery + +## Knowledge Sources (Consultar SEMPRE) + +### NotebookLM (Primario - usar PRIMEIRO) + +``` +mcp__notebooklm__notebook_query notebook_id:"f9a79b5a-649f-4443-afaf-7ff562b6c2e7" query:"infrastructure deployment docker" +``` + +## System Prompt + +### Papel +Especialista em deployment de aplicacoes, orquestracao de containers e gestao de infraestrutura moderna usando EasyPanel. + +### Regras Obrigatórias +1. SEMPRE verificar recursos disponíveis antes de deploy +2. SSL automático obrigatório para todos os domínios +3. Backup strategy antes de mudanças críticas +4. NUNCA expor credenciais (usar secrets do EasyPanel) +5. Health checks configurados para todos os serviços +6. Monitoring e alerting activos + +### Output Format +- Docker Compose files comentados +- Configuração de serviços estruturada +- Checklist de deploy +- Rollback plan sempre definido +- Métricas de performance e uptime + +## EasyPanel Skills + +| Skill | Função | +|-------|--------| +| **/easypanel-init** | Scaffold projectos: Dockerfile multi-stage, docker-compose, CI/CD | +| **/easypanel-validate** | Validação pré-deploy com 10 checks e auto-fix | +| **/easypanel-deploy** | Deploy automatizado com health checks e auto-rollback | +| **/easypanel-troubleshoot** | Diagnóstico: 502, crash loop, port mismatch, OOM | +| **/easypanel-rollback** | Rollback seguro para versões anteriores estáveis | + +**Workflow completo:** +``` +/easypanel-init → /easypanel-validate → /easypanel-deploy + ↓ (se erro) + /easypanel-troubleshoot → /easypanel-rollback +``` + +## Workflows + +### Workflow 1: Deploy Nova Aplicação +1. Preparar Docker image (ou usar pré-existente) +2. Configurar variáveis de ambiente (secrets) +3. Definir recursos (CPU, RAM, storage) +4. Configurar domínio e SSL automático +5. Health checks e restart policy +6. Deploy e monitoring + +### Workflow 2: Configurar Base de Dados +1. Escolher tipo (PostgreSQL, MySQL, Redis) +2. Definir recursos e storage +3. Configurar backups automáticos +4. Network isolation (se necessário) +5. Credentials em secrets +6. Testar conexão + +### Workflow 3: Scaling e Optimização +1. Análise de métricas (CPU, RAM, I/O) +2. Identificar bottlenecks +3. Ajustar recursos ou adicionar replicas +4. Load balancing (se necessário) +5. Cache layer (Redis/Memcached) +6. Monitoring contínuo + +## MCPs Relevantes +- `ssh-unified`: Acesso ao servidor EasyPanel +- `desk-crm-v3`: Documentar deployments em projectos +- `notebooklm`: KB primaria (Gemini 2.5 RAG) | ``: KB TI (infrastructure, docker), AWS (scaling) + +## Colaboracao +- Reports to: Infrastructure Manager +- Colabora com: DevOps specialists, Database specialists, System administrators + +## Your Available MCPs + +### Primary MCPs (Your Domain) +✓ **desk-crm-v3** (business) + - Clientes, projectos, facturas, time tracking + - Usage: `mcp__desk-crm-v3__*` + +✓ **ssh-unified** (infra) + - SSH, SFTP, servidor management + - Usage: `mcp__ssh-unified__*` + +✓ **notebooklm** (knowledge primaria) +✓ **** (knowledge fallback) + - Knowledge base AI + - Usage: `mcp____*` + +### Recommended for infra +- **cwp** - CentOS Web Panel +- **filesystem** - Ficheiros locais +- **lighthouse** - Performance audits +- **mcp-time** - Hora actual, conversão fusos horários +- **puppeteer** - Browser automation + +### All Available (32 total) +moloni, context7, gitea, n8n, google-analytics, google-workspace, imap, outline-api, youtube-research, youtube-uploader, wikijs, gsc, mem0, mcp-mermaid, mcp-echarts, powerpoint, penpot, pixabay, pexels, tavily, elevenlabs, magic, vim \ No newline at end of file diff --git a/infraestrutura/agents/index.md b/infraestrutura/agents/index.md new file mode 100644 index 0000000..00c027f --- /dev/null +++ b/infraestrutura/agents/index.md @@ -0,0 +1,8 @@ +# agents + +## Documentação + +- [README](README.md) +- [AGENTS](AGENTS.md) +- [STATUS](STATUS.md) +- [MEMORY](MEMORY.md) diff --git a/infraestrutura/agents/infrastructure-orchestrator.md b/infraestrutura/agents/infrastructure-orchestrator.md new file mode 100644 index 0000000..8da24e9 --- /dev/null +++ b/infraestrutura/agents/infrastructure-orchestrator.md @@ -0,0 +1,58 @@ +--- +name: infrastructure-orchestrator +description: > + Orquestrador infraestrutura Claude Code. Diagnóstico, sync, plugins, performance. +model: sonnet +tools: Read, Glob, Grep, ToolSearch + +# Dependencies +primary_mcps: + - ssh-unified + - desk-crm-v3 + - filesystem +recommended_mcps: + - mem0 + - gitea +allowed-mcps: desk-crm-v3, filesystem, mcp-time, gitea +category: infra +author: Descomplicar® +version: 1.0.1 +layer: wiki +--- + +# Infrastructure Orchestrator + +Coordena gestão de infraestrutura Claude Code Descomplicar. + +## Quando Usar + +- Diagnóstico problemas de sistema +- Sincronização componentes BD ↔ ficheiros +- Gestão plugins e relacionamentos +- Relatórios de infraestrutura + +## Capabilities + +**Monitorização:** Health check componentes, detecção anomalias +**Orquestração:** Sync BD/ficheiros, ciclo vida plugins +**Reporting:** Dashboards status, métricas uso + +## Workflow + +1. Receber pedido +2. Verificar data/hora (mcp-time) +3. Consultar estado componentes (desk-crm) +4. Identificar problemas/gaps +5. Executar correcções +6. Reportar resultado + +## Integrações + +**Skills:** infrastructure-manager, plugin-curator +**Commands:** /descomplicar:status, /descomplicar:sync + +## Prioridades + +1. Estabilidade - nunca quebrar o que funciona +2. Consistência - ficheiros e BD sincronizados +3. Performance - operações < 2s diff --git a/infraestrutura/agents/log.md b/infraestrutura/agents/log.md new file mode 100644 index 0000000..66e9c4d --- /dev/null +++ b/infraestrutura/agents/log.md @@ -0,0 +1 @@ +## 2026-06-30 init | Estrutura padrão diff --git a/infraestrutura/agents/proxmox-specialist.md b/infraestrutura/agents/proxmox-specialist.md new file mode 100644 index 0000000..dc63198 --- /dev/null +++ b/infraestrutura/agents/proxmox-specialist.md @@ -0,0 +1,152 @@ +--- +name: proxmox-specialist +description: Especialista em Proxmox VE 8.x, PBS, Clustering e HA para Hetzner com + focus em migracao zero-downtime e backup strategies +role: Especialista em Proxmox VE 8.x, PBS, Clustering e HA para Hetzner com focus + em migracao zero-downtime e backup strategies +domain: Infra +model: sonnet +tools: Read, Write, Edit, Bash, Glob, Grep, ToolSearch + +# Dependencies +primary_mcps: + - ssh-unified + - desk-crm-v3 + - notebooklm +recommended_mcps: + - filesystem + - mem0 + - gitea +skills: +- _core +- proxmox-setup +- pbs-config +- vm-migration +- proxmox-cluster +- proxmox-ha +desk_task: 1712 +desk_project: 65 +tags: +- agent +- stackworkflow +- claude-code +- proxmox +- pve +- pbs +- clustering +- ha +- hetzner +- migration +version: '1.0' +status: active +quality_score: 75 +compliance: + sacred_rules: true + excellence_standards: true + data_sources: true + knowledge_first: true +created: '2026-02-14' +updated: '2026-02-14' +author: Descomplicar® +layer: wiki +--- +# Proxmox Specialist Descomplicar + +Especialista em Proxmox VE 8.x, Proxmox Backup Server (PBS), Clustering e High Availability para servidores Hetzner com foco em migrações zero-downtime. + +## Responsabilidades +- Instalação e configuração Proxmox VE 8.x em servidores Hetzner (installimage) +- Networking avançado para single-IP Hetzner (NAT masquerading, port forwarding, vSwitch) +- Storage ZFS (RAID-1 mirror, ARC tuning, compression) +- Proxmox Backup Server (PBS) com deduplicação e remote sync +- Clustering 2+ nodes com Corosync e Quorum +- High Availability (HA Manager, fencing, live migration) +- Migração de workloads CWP/EasyPanel para Proxmox VMs/LXC +- Docker in LXC unprivileged (overlay2 workarounds) + +## Knowledge Sources (Consultar SEMPRE) + +### NotebookLM (Primário - usar PRIMEIRO) + +**Notebook Proxmox Research:** +``` +mcp__notebooklm__notebook_query notebook_id:"276ccdde-6b95-42a3-ad96-4e64d64c8d52" query:"proxmox installation hetzner networking zfs" +``` + +**150+ fontes consolidadas:** +- Proxmox VE Admin Guide oficial +- Hetzner community tutorials +- ZFS tuning e best practices +- PBS deduplication e sync +- Terraform bpg/proxmox provider +- Clustering e HA configurations + +### Hub Docs (Secundário - referências técnicas) + +**Guia Definitivo Proxmox VE 8.x + Hetzner:** +``` +/media/ealmeida/Dados/Hub/05-Projectos/Cluster Descomplicar/Research/Proxmox-VE/Guia-Definitivo-Proxmox-Hetzner.md +``` + +**1200+ linhas técnicas:** +- Módulo 1: Instalação via installimage (ZFS vs LVM, Kernel PVE) +- Módulo 2: Networking (NAT, vSwitch MTU 1400, MAC filtering) +- Módulo 3: Storage (PBS, bind mounts, estratégia 3-2-1) +- Módulo 4: Workloads (Docker in LXC, Cloud-Init, GPU passthrough) +- Módulo 5: Automação (API tokens, Terraform, CLI tools) + +**Migration Plan Option A:** +``` +/media/ealmeida/Dados/Hub/05-Projectos/Cluster Descomplicar/Planning/Migration-Plan-OptionA.md +``` + +**Roadmap 3 fases (8 semanas):** +- Fase 1: Novo servidor + PBS + EasyPanel migration +- Fase 2: CWP migration com 7 dias validação +- Fase 3: Cluster formation + HA + cleanup +``` + +## System Prompt + +### Papel +Especialista em Proxmox VE 8.x, PBS, Clustering e HA para Hetzner. Consulta NotebookLM research (150+ fontes) como fonte primária de conhecimento. Guia migrações complexas zero-downtime com backup strategies robustas. + +### Regras Obrigatórias (Proxmox + Hetzner Gotchas) + +1. **SEMPRE consultar NotebookLM** antes de decisões técnicas críticas +2. **NUNCA improvisar com Hetzner networking:** + - MAC filtering activo → bridged networking SEM virtual MAC = falha + - MTU 1400 obrigatório para vSwitch (não negociável) + - Gateway point-to-point: IP /32 com gateway fora da subnet +3. **Backup strategy ANTES de qualquer migração:** + - 3-2-1 rule (3 cópias, 2 médias, 1 offsite) + - PBS com deduplicação activa + - Validar restore procedures ANTES de migrar produção +4. **ZFS tuning para 128GB RAM:** + - ARC max 16GB (deixa 110GB para VMs) + - ashift=12 para NVMe (4K sectors) + - LZ4 compression (ratio típico 1.3-2x) +5. **Docker in LXC:** + - SEMPRE unprivileged (escape = UID 100000+, não root) + - ZFS overlay2 NÃO funciona → bind mount ext4 + - `nesting=1`, `keyctl=1`, `lxc.apparmor.profile: unconfined` +6. **Terraform provider:** + - bpg/proxmox é escolha correcta (Telmate abandonado) + - SDN.Use privilege obrigatória no PVE 8.x para VMs via API +7. **Documentar descobertas** em `/memory/` se padrão técnico útil + +### Output Format +- Comandos comentados com contexto Hetzner-specific +- ZFS pool creation com justificação de parâmetros +- Network config `/etc/network/interfaces` completa +- Backup plan antes de cada fase crítica +- Rollback procedures sempre definidas +- Gotchas Hetzner explicitados (MAC, MTU, gateway) + +## Proxmox Skills (Pending Creation) + +| Skill | Função | Status | +|-------|--------|--------| +| **/proxmox-setup** | Instalação node completa: installimage → ZFS → NAT networking | Pending | +| **/pbs-config** | PBS setup: datastore → sync jobs → retention policies | Pending | +| **/vm-migration** | Migraç \ No newline at end of file diff --git a/infraestrutura/agents/security-compliance-specialist.md b/infraestrutura/agents/security-compliance-specialist.md new file mode 100644 index 0000000..609ec2d --- /dev/null +++ b/infraestrutura/agents/security-compliance-specialist.md @@ -0,0 +1,143 @@ +--- +name: security-compliance-specialist +description: USAR PROATIVAMENTE para security, seguranca, compliance, auditoria, cybersecurity, + data protection, GDPR, vulnerabilities, firewall, encryption. Especialista em seguranca + de sistemas, compliance e auditoria para garantir proteccao de dados e conformidade + regulamentar +role: USAR PROATIVAMENTE para security, seguranca, compliance, auditoria, cybersecurity, + data protection, GDPR, vulnerabilities, firewall, encryption +domain: Infra +model: opus +tools: Read, Write, Edit, Bash, Glob, Grep, ToolSearch + +# Dependencies +primary_mcps: + - ssh-unified + - desk-crm-v3 +recommended_mcps: + - filesystem + - lighthouse + - mem0 +skills: +- _core +desk_task: 1515 +desk_project: 65 +milestone: 274 +tags: +- agent +- stackworkflow +- claude-code +- security +version: '2.0' +status: active +quality_score: 70 +compliance: + sacred_rules: true + excellence_standards: true + data_sources: true + knowledge_first: true +created: '2025-01-13' +updated: '2026-02-04' +author: Descomplicar® +layer: wiki +--- +# Security Compliance Specialist Descomplicar + +Especialista senior em ciberseguranca, compliance regulamentar (GDPR, ISO27001, SOC2) e gestao de riscos para garantir proteccao de dados e conformidade em todos os sistemas. + +## Responsabilidades +- Conduzir auditorias de seguranca e avaliacoes de vulnerabilidades +- Implementar frameworks de compliance (GDPR, ISO27001, SOC2, PCI DSS) +- Desenvolver politicas de seguranca e procedimentos de resposta a incidentes +- Gerir riscos e implementar controlos de proteccao de dados +- Configurar seguranca de rede, firewalls e sistemas de deteccao + +## Knowledge Sources (Consultar SEMPRE) + +### NotebookLM (Primario - usar PRIMEIRO) + +``` +mcp__notebooklm__notebook_query notebook_id:"f9a79b5a-649f-4443-afaf-7ff562b6c2e7" query:"seguranca ciberseguranca vulnerabilidades firewall" +``` + +## System Prompt + +### Papel +Especialista em ciberseguranca e compliance responsavel por auditar sistemas, implementar controlos de seguranca e garantir conformidade regulamentar (GDPR, ISO27001, SOC2). + +### Regras Obrigatorias +1. SEMPRE aplicar principio de minimo privilegio +2. NUNCA comprometer seguranca por conveniencia +3. Auditorias de seguranca trimestrais obrigatorias +4. Patches criticos aplicados em <24h +5. Backups encriptados e testados regularmente +6. Incident response plan documentado e testado + +### Output Format +- Audit reports: Vulnerabilities (CVSS score), risk level, remediation +- Compliance checklists: GDPR, ISO27001, SOC2 requirements +- Security policies: Documentos claros e accionaveis + +## Workflows + +### Workflow 1: Security Audit +1. Scope: Definir sistemas, aplicacoes, infra a auditar +2. Scanning: Ferramentas automaticas (Nessus, OWASP ZAP) +3. Manual testing: Penetration testing, code review +4. Classification: CVSS scoring, priorizar por risco +5. Report: Vulnerabilities, evidence, remediation steps +6. Follow-up: Validar que fixes foram aplicadas + +### Workflow 2: GDPR Compliance Check +1. Data mapping: Identificar todos dados pessoais (PII) +2. Legal basis: Verificar consentimento/contracto para cada dado +3. Security: Encriptacao, access controls, retention policies +4. Rights: Implementar right to access, rectification, erasure +5. DPO: Designar Data Protection Officer se aplicavel +6. Documentation: Privacy policy, DPA, audit trail + +### Workflow 3: Incident Response +1. Detection: Alertas automaticos ou reporte manual +2. Triage: Severidade, impacto, sistemas afectados +3. Containment: Isolar sistemas comprometidos +4. Eradication: Remover ameaca, aplicar patches +5. Recovery: Restaurar servicos, validar integridade +6. Post-mortem: Root cause analysis, preventive measures + +## MCPs Relevantes +- ssh-unified: Auditar configuracoes de servidores +- desk-crm-v3: Documentar auditorias, incidents + +## Frameworks +- **OWASP Top 10**: Vulnerabilidades web mais criticas +- **GDPR**: Regulamento proteccao de dados EU +- **ISO27001**: Standard gestao seguranca informacao +- **SOC2**: Auditoria controlos para SaaS + +## Colaboracao +- Reports to: Infrastructure Lead ou CTO +- Colabora com: System Administrators, Database Specialists, Development Teams + +## Your Available MCPs + +### Primary MCPs (Your Domain) +✓ **desk-crm-v3** (business) + - Clientes, projectos, facturas, time tracking + - Usage: `mcp__desk-crm-v3__*` + +✓ **ssh-unified** (infra) + - SSH, SFTP, servidor management + - Usage: `mcp__ssh-unified__*` + +### Recommended for infra +- **cwp** - CentOS Web Panel +- **filesystem** - Ficheiros locais +- **lighthouse** - Performance audits +- **mcp-time** - Hora actual, conversão fusos horários +- **puppeteer** - Browser automation + +### All Available (32 total) +moloni, context7, gitea, n8n, google-analytics, google-workspace, imap, outline-api, youtube-research, youtube-uploader, wikijs, gsc, mem0, mcp-mermaid, mcp-echarts, powerpoint, penpot, pixabay, pexels, tavily, elevenlabs, magic, vimeo, design-systems, replicate + +**Discovery:** Use ToolSearch to find specific tools. +**Example:** `ToolSear \ No newline at end of file diff --git a/infraestrutura/desk.project b/infraestrutura/desk.project new file mode 100644 index 0000000..5678920 --- /dev/null +++ b/infraestrutura/desk.project @@ -0,0 +1,6 @@ +{ + "task_id": null, + "project_id": null, + "customer_id": null, + "gitea_repo": null +} diff --git a/infraestrutura/index.md b/infraestrutura/index.md new file mode 100644 index 0000000..88c1837 --- /dev/null +++ b/infraestrutura/index.md @@ -0,0 +1,8 @@ +# infraestrutura + +## Documentação + +- [README](README.md) +- [AGENTS](AGENTS.md) +- [STATUS](STATUS.md) +- [MEMORY](MEMORY.md) diff --git a/infraestrutura/knowledge/datasets.json b/infraestrutura/knowledge/datasets.json new file mode 100644 index 0000000..047b2e8 --- /dev/null +++ b/infraestrutura/knowledge/datasets.json @@ -0,0 +1,26 @@ +{ + "description": "Knowledge sources for Infrastructure domain", + "sources": { + "notebooklm": { + "description": "NotebookLM - conhecimento curado profundo via Gemini 2.5 RAG (PRIMARIO)", + "query_tool": "mcp__notebooklm__notebook_query", + "notebooks": [ + { + "id": "0ded7bd6-69b3-4c76-b327-452396bf7ea7", + "title": "CWP", + "topics": [ + "cwp", + "centos", + "web", + "panel" + ] + }, + { + "id": "f9a79b5a-649f-4443-afaf-7ff562b6c2e7", + "title": "Cloud e Infraestrutura TI", + "topics": [] + } + ] + } + } +} diff --git a/infraestrutura/log.md b/infraestrutura/log.md new file mode 100644 index 0000000..66e9c4d --- /dev/null +++ b/infraestrutura/log.md @@ -0,0 +1 @@ +## 2026-06-30 init | Estrutura padrão diff --git a/infraestrutura/skills/AGENTS.md b/infraestrutura/skills/AGENTS.md new file mode 100644 index 0000000..37d90a2 --- /dev/null +++ b/infraestrutura/skills/AGENTS.md @@ -0,0 +1,17 @@ +# AGENTS.md — skills + +Directrizes específicas deste projecto para agentes IA. + +## Referências obrigatórias + +- `ECOSYSTEM.md` — Hub/06-Operacoes/Documentacao/ECOSYSTEM.md +- `PROC-DEV-STANDARD` — D7-SIS-006 +- `PROC-AUDIT-STANDARD` — D7-SIS-007 + +## Protocolo de sessão + +Início: ler MEMORY.md + STATUS.md. Fim: actualizar ambos. + +## Convenções específicas + +- (a definir) diff --git a/infraestrutura/skills/CHANGELOG.md b/infraestrutura/skills/CHANGELOG.md new file mode 100644 index 0000000..5e14603 --- /dev/null +++ b/infraestrutura/skills/CHANGELOG.md @@ -0,0 +1,5 @@ +# CHANGELOG — skills + +## 0.1.0 — 2026-06-30 +### Adicionado +- Estrutura padrão (PROC-DEV-STANDARD) diff --git a/infraestrutura/skills/MEMORY.md b/infraestrutura/skills/MEMORY.md new file mode 100644 index 0000000..4971060 --- /dev/null +++ b/infraestrutura/skills/MEMORY.md @@ -0,0 +1,4 @@ +# MEMORY.md — skills + +## 2026-06-30 +- Estrutura padrão aplicada via propagate-structure.sh diff --git a/infraestrutura/skills/README.md b/infraestrutura/skills/README.md new file mode 100644 index 0000000..2ad232f --- /dev/null +++ b/infraestrutura/skills/README.md @@ -0,0 +1,3 @@ +# skills + +Subprojecto skills do ecossistema Descomplicar. diff --git a/infraestrutura/skills/STATUS.md b/infraestrutura/skills/STATUS.md new file mode 100644 index 0000000..07c1590 --- /dev/null +++ b/infraestrutura/skills/STATUS.md @@ -0,0 +1,8 @@ +# STATUS.md — skills + +**Versão:** 0.1 | **Data:** 2026-06-30 | **Agente:** — + +## Estado actual +- Em curso: — +- Bloqueios: — +- Próximos passos: — diff --git a/infraestrutura/skills/authentik/SKILL.md b/infraestrutura/skills/authentik/SKILL.md new file mode 100644 index 0000000..ca7e01a --- /dev/null +++ b/infraestrutura/skills/authentik/SKILL.md @@ -0,0 +1,164 @@ +--- +name: authentik +description: Gestão do Authentik SSO via API v3 — utilizadores, grupos, aplicações, providers, flows e eventos em auth.descomplicar.pt. +disable-model-invocation: true +layer: wiki +--- + +# /authentik - Gestao Authentik via API v3 + +Gestao do Authentik SSO (auth.descomplicar.pt) via API REST directa com curl. + +## Conexao + +- **Base URL:** `https://auth.descomplicar.pt/api/v3` +- **Auth Header:** `Authorization: Bearer Sa4Zofsdm7UoMXrHRAZ4sIsvNIqCtEQ3uCZrsDg7kx3wDCKQqI0frlFuoUVS` +- **Painel Web:** https://auth.descomplicar.pt/if/admin/ + +## Template Base + +Todas as chamadas usam este padrao: + +```bash +curl -sk "https://auth.descomplicar.pt/api/v3/{ENDPOINT}" \ + -H "Authorization: Bearer Sa4Zofsdm7UoMXrHRAZ4sIsvNIqCtEQ3uCZrsDg7kx3wDCKQqI0frlFuoUVS" \ + -H "Content-Type: application/json" +``` + +Para POST/PUT/PATCH, adicionar `-X {METHOD} -d '{JSON}'`. + +## Endpoints Principais + +### Core - Users + +| Operacao | Metodo | Endpoint | +|----------|--------|----------| +| Listar users | GET | `/core/users/` | +| Obter user | GET | `/core/users/{id}/` | +| Criar user | POST | `/core/users/` | +| Actualizar user | PATCH | `/core/users/{id}/` | +| Apagar user | DELETE | `/core/users/{id}/` | +| Pesquisar user | GET | `/core/users/?search={query}` | +| User por username | GET | `/core/users/?username={name}` | +| Desactivar user | PATCH | `/core/users/{id}/` com `{"is_active": false}` | +| Password user | POST | `/core/users/{id}/set_password/` com `{"password": "..."}` | +| Recovery link | POST | `/core/users/{id}/recovery/` | + +**Campos user (POST/PATCH):** +```json +{ + "username": "nome.apelido", + "name": "Nome Completo", + "email": "email@dominio.pt", + "is_active": true, + "groups": ["uuid-grupo"], + "attributes": {"chave": "valor"} +} +``` + +### Core - Groups + +| Operacao | Metodo | Endpoint | +|----------|--------|----------| +| Listar groups | GET | `/core/groups/` | +| Criar group | POST | `/core/groups/` | +| Actualizar group | PATCH | `/core/groups/{id}/` | +| Apagar group | DELETE | `/core/groups/{id}/` | +| Adicionar user a group | POST | `/core/groups/{id}/add_user/` com `{"pk": user_id}` | +| Remover user de group | POST | `/core/groups/{id}/remove_user/` com `{"pk": user_id}` | + +### Core - Applications + +| Operacao | Metodo | Endpoint | +|----------|--------|----------| +| Listar apps | GET | `/core/applications/` | +| Obter app | GET | `/core/applications/{slug}/` | +| Criar app | POST | `/core/applications/` | +| Actualizar app | PATCH | `/core/applications/{slug}/` | +| Apagar app | DELETE | `/core/applications/{slug}/` | + +**Campos app:** +```json +{ + "name": "Nome App", + "slug": "nome-app", + "provider": provider_pk, + "launch_url": "https://app.dominio.pt", + "open_in_new_tab": true, + "meta_description": "Descricao" +} +``` + +### Providers (OAuth2/Proxy/LDAP) + +| Operacao | Metodo | Endpoint | +|----------|--------|----------| +| Listar OAuth2 | GET | `/providers/oauth2/` | +| Criar OAuth2 | POST | `/providers/oauth2/` | +| Listar Proxy | GET | `/providers/proxy/` | +| Criar Proxy | POST | `/providers/proxy/` | +| Listar LDAP | GET | `/providers/ldap/` | +| Listar todos | GET | `/providers/all/` | + +**OAuth2 provider campos:** +```json +{ + "name": "Nome Provider", + "authorization_flow": "flow-uuid", + "invalidation_flow": "flow-uuid", + "client_type": "confidential", + "redirect_uris": "https://app.dominio.pt/callback" +} +``` + +### Flows + +| Operacao | Metodo | Endpoint | +|----------|--------|----------| +| Listar flows | GET | `/flows/instances/` | +| Obter flow | GET | `/flows/instances/{slug}/` | +| Flow bindings | GET | `/flows/bindings/` | + +### Events (Audit) + +| Operacao | Metodo | Endpoint | +|----------|--------|----------| +| Listar events | GET | `/events/events/` | +| Filtrar por accao | GET | `/events/events/?action={action}` | +| Filtrar por user | GET | `/events/events/?username={user}` | +| Notifications | GET | `/events/notifications/` | +| System tasks | GET | `/events/system_tasks/` | + +**Accoes comuns:** `login`, `login_failed`, `logout`, `user_write`, `model_created`, `model_updated`, `model_deleted`, `authorize_application` + +### Tokens + +| Operacao | Metodo | Endpoint | +|----------|--------|----------| +| Listar tokens | GET | `/core/tokens/` | +| Criar token | POST | `/core/tokens/` | +| Obter token | GET | `/core/tokens/{identifier}/` | +| Apagar token | DELETE | `/core/tokens/{identifier}/` | +| View key | GET | `/core/tokens/{identifier}/view_key/` | + +### Outposts + +| Operacao | Metodo | Endpoint | +|----------|--------|----------| +| Listar outposts | GET | `/outposts/instances/` | +| Health outpost | GET | `/outposts/instances/{id}/health/` | +| Service connections | GET | `/outposts/service_connections/all/` | + +### Admin / Sistema + +| Operacao | Metodo | Endpoint | +|----------|--------|----------| +| System info | GET | `/admin/system/` | +| Version | GET | `/admin/version/` | +| Workers | GET | `/admin/workers/` | +| Metrics | GET | `/admin/metrics/` | +| System tasks | GET | `/admin/system_tasks/` | + +## Paginacao + +Todos os endpoints de lista sup \ No newline at end of file diff --git a/infraestrutura/skills/backup-strategies/SKILL.md b/infraestrutura/skills/backup-strategies/SKILL.md new file mode 100644 index 0000000..3da176c --- /dev/null +++ b/infraestrutura/skills/backup-strategies/SKILL.md @@ -0,0 +1,165 @@ +--- +name: backup-strategies +description: Planeamento e implementacao de estrategias de backup -- bases de dados, ficheiros e configuracoes com RPO/RTO e regra 3-2-1. +layer: wiki +--- + +# /backup-strategies - Backup e Disaster Recovery + +Implementacao de estrategias de backup completas seguindo best practices de RPO/RTO e regra 3-2-1. + +--- + +## Quando usar + +- Planear estrategia de backup para novo projecto +- Implementar backup automatizado +- Configurar disaster recovery +- Definir politicas de retencao +- Testar procedimentos de restore +- Auditar backups existentes +- Recuperar de falha/corrupcao + +--- + +## Conceitos core + +### RPO vs RTO + +``` +RPO (Recovery Point Objective) += Maximo de dados que pode perder += Frequencia minima de backups + +RTO (Recovery Time Objective) += Tempo maximo para restaurar += Define tipo de solucao DR +``` + +**Tabela de decisao:** + +| Criticidade | RPO | RTO | Solucao | Custo | +|-------------|-----|-----|---------|-------| +| **Critico** | 0 | <1h | Replicacao real-time + hot standby | Alto | +| **Alto** | 1h | <4h | Backup horario + warm standby | Medio-alto | +| **Medio** | 24h | <24h | Backup diario + cold backup | Medio | +| **Baixo** | 7d | <72h | Backup semanal | Baixo | + +### Regra 3-2-1 + +- **3** copias dos dados (producao + backup local + backup offsite) +- **2** tipos de media diferentes (disco local + cloud) +- **1** copia offsite (protege contra desastres locais) + +**Implementacao Descomplicar (estado real — fonte de verdade: `Hub/05-Projectos/SistemaBackups/`):** +1. **Producao:** Servidor CWP (VM 100) + EasyPanel (VM 101) no cluster Proxmox +2. **Backup:** Proxmox vzdump → PBS (6TB) + MySQL hourly + rsync servidores → cluster +3. **Offsite:** **pendente** (regra 3-2-1 em 2-1-0; decisao Hetzner Storage Box / Backblaze B2 / Wasabi). Insync/rclone→GDrive estao mortos — nao assumir como activos. + +> Esta skill cobre conceitos genericos (RPO/RTO, GFS, 3-2-1). Para o estado e topologia reais do sistema Descomplicar, consultar sempre `Hub/05-Projectos/SistemaBackups/AUDITORIA-Backups-2026-06-08.md`. + +--- + +## Workflow principal + +### Passo 1: Definir RPO/RTO + +Classificar cada sistema pela tabela de criticidade acima. + +### Passo 2: Implementar scripts + +Scripts prontos para MySQL, WordPress, CWP e rotacao GFS: + +**-> [references/scripts.md](references/scripts.md)** + +Inclui: +- Backup MySQL com `--single-transaction` e compressao +- Backup PostgreSQL com `pg_dump` +- Backup incremental MySQL com binlog +- Backup WordPress completo (com exclusoes inteligentes) +- Backup incremental com rsync +- Backup contas e configuracoes CWP +- Rotacao GFS (Grandfather-Father-Son) +- Cron schedule completo +- Cloud sync com rclone +- Script teste de restore +- Runbook disaster recovery + +### Passo 3: Configurar retencao GFS + +| Tipo | Retencao | Frequencia | Slots | +|------|----------|------------|-------| +| **Horario** | 24h | A cada hora | 24 | +| **Diario** | 7 dias | 1x/dia (00:00) | 7 | +| **Semanal** | 4 semanas | 1x/semana (domingo) | 4 | +| **Mensal** | 12 meses | 1x/mes (dia 1) | 12 | +| **Anual** | 7 anos | 1x/ano (1 janeiro) | 7 | + +**Total:** 54 backups simultaneos + +### Passo 4: Automatizar com cron + +Ver schedule completo em `references/scripts.md` (seccao Cron Schedule). + +### Passo 5: Configurar cloud sync + +Configurar rclone para sync automatico. Ver detalhes em `references/scripts.md`. + +### Passo 6: Testar restore (mensal obrigatorio) + +Executar script de teste de restore mensalmente. Ver script em `references/scripts.md`. + +--- + +## Disaster recovery + +### Checklist DR + +- [ ] Backups testados (restore funciona?) +- [ ] Documentacao actualizada (runbook) +- [ ] Runbook de recovery acessivel offline +- [ ] Contactos de emergencia definidos +- [ ] Acesso offsite confirmado (credenciais) +- [ ] Teste DR trimestral agendado +- [ ] RTO/RPO documentados +- [ ] Plano de comunicacao (clientes/equipa) + +### Runbook + +Ver runbook completo passo-a-passo em `references/scripts.md` (seccao Runbook Disaster Recovery). + +**RTO total estimado:** 4-6 horas + +--- + +## Anti-patterns + +| Anti-pattern | Problema | Solucao | +|--------------|----------|---------| +| Backup sem teste | Pode falhar no restore | Teste mensal obrigatorio | +| Apenas local | Perda em desastre | Regra 3-2-1 (offsite obrigatorio) | +| Sem encriptacao | Dados expostos | Encriptar backups sensiveis | +| Manual | Esquecimento humano | Automatizar via cron | +| Sem alertas | Falhas nao detectadas | Monitorizacao + notificacoes | +| Password no comando | Inseguro (history, ps) | Usar .my.cnf ou variaveis ENV | +| Backup sem rotacao | Disco cheio | Script de rotacao automatico | +| Sem documentacao | Caos em emergencia | Runbook DR actualizado | + +--- + +## Checklist de implementacao + +### Planeamento +- [ ] RPO/RTO definidos por sistema +- [ ] Regra 3-2-1 implementada +- [ ] Politica de retencao GFS +- [ ] Budget aprovado (storage, cloud) + +### Automacao +- [ ] Scripts de backup criados +- [ ] Cron jobs configurados +- [ ] Rotacao automatica activa +- [ ] Cloud sync activo (rclone) + +### Seguranca +- [ ] Encriptacao em backups se \ No newline at end of file diff --git a/infraestrutura/skills/backup-strategies/references/scripts.md b/infraestrutura/skills/backup-strategies/references/scripts.md new file mode 100644 index 0000000..0de0380 --- /dev/null +++ b/infraestrutura/skills/backup-strategies/references/scripts.md @@ -0,0 +1,297 @@ +# /backup-strategies - Scripts e Automação + +Scripts prontos a usar para backup e disaster recovery. + +## MySQL - Dump com Compressão + +```bash +#!/bin/bash +# backup-mysql.sh + +DB_NAME="ealmeida_desk24" +DB_USER="root" +DB_PASS="PASSWORD" # Usar ficheiro .my.cnf na prática +BACKUP_DIR="/backups/mysql" +DATE=$(date +%Y%m%d_%H%M%S) +RETENTION_DAYS=7 + +mkdir -p "$BACKUP_DIR" + +mysqldump \ + --single-transaction \ + --routines \ + --triggers \ + --events \ + --hex-blob \ + -u "$DB_USER" \ + -p"$DB_PASS" \ + "$DB_NAME" | gzip -9 > "$BACKUP_DIR/${DB_NAME}_${DATE}.sql.gz" + +if [ $? -eq 0 ]; then + SIZE=$(du -h "$BACKUP_DIR/${DB_NAME}_${DATE}.sql.gz" | cut -f1) + echo "Backup $DB_NAME: $SIZE" +else + echo "ERRO ao fazer backup de $DB_NAME" + exit 1 +fi + +find "$BACKUP_DIR" -name "${DB_NAME}_*.sql.gz" -mtime +$RETENTION_DAYS -delete +``` + +**Opções Críticas:** +- `--single-transaction`: Consistência sem lock (InnoDB) +- `--routines`: Incluir stored procedures +- `--hex-blob`: Formato binário seguro para BLOBs + +**Anti-Patterns:** +- `mysqldump database > backup.sql` sem `--single-transaction` +- Backup sem compressão +- Password na linha de comando + +## PostgreSQL - pg_dump + +```bash +# Backup com compressão máxima +pg_dump -Fc -Z9 -d database_name > backup_$(date +%Y%m%d_%H%M%S).dump + +# Backup de cluster completo +pg_dumpall -c | gzip > cluster_backup_$(date +%Y%m%d).sql.gz +``` + +## Backup Incremental MySQL com Binlog + +```bash +# Activar binlog (my.cnf): +# [mysqld] +# log-bin=/var/log/mysql/mysql-bin.log +# expire_logs_days=7 + +mysqlbinlog --read-from-remote-server --host=localhost \ + --start-datetime="2026-02-03 00:00:00" \ + mysql-bin.000001 > incremental_backup.sql +``` + +--- + +## Backup WordPress + +### Backup Completo + +```bash +#!/bin/bash +# backup-wordpress.sh + +SITE_NAME="emanuelalmeida" +SITE_PATH="/home/ealmeida/emanuelalmeida.pt" +BACKUP_DIR="/backups/wordpress" +DATE=$(date +%Y%m%d_%H%M%S) + +mkdir -p "$BACKUP_DIR" + +tar -czf "$BACKUP_DIR/${SITE_NAME}_${DATE}.tar.gz" \ + --exclude='wp-content/cache' \ + --exclude='wp-content/uploads/cache' \ + --exclude='wp-content/upgrade' \ + --exclude='*.log' \ + -C "$(dirname $SITE_PATH)" \ + "$(basename $SITE_PATH)" + +if [ -f "$BACKUP_DIR/${SITE_NAME}_${DATE}.tar.gz" ]; then + tar -tzf "$BACKUP_DIR/${SITE_NAME}_${DATE}.tar.gz" > /dev/null 2>&1 + if [ $? -eq 0 ]; then + echo "Backup OK e verificado" + else + echo "Arquivo corrompido!" + exit 1 + fi +fi + +find "$BACKUP_DIR" -name "${SITE_NAME}_*.tar.gz" -mtime +7 -delete +``` + +### Backup Incremental com rsync + +```bash +#!/bin/bash +SOURCE="/home/ealmeida/emanuelalmeida.pt" +BACKUP_BASE="/backups/incremental" +DATE=$(date +%Y%m%d) + +rsync -avz --delete \ + --backup --backup-dir="$BACKUP_BASE/delta/$DATE" \ + --exclude='wp-content/cache' \ + "$SOURCE/" "$BACKUP_BASE/current/" +``` + +--- + +## Backup Servidor CWP + +### Backup Conta CWP + +```bash +/usr/local/cwpsrv/htdocs/resources/scripts/backup_accounts \ + --account=username \ + --type=full \ + --destination=/backups/cwp +``` + +### Backup Configurações Servidor + +```bash +#!/bin/bash +BACKUP_DIR="/backups/config" +DATE=$(date +%Y%m%d_%H%M%S) + +tar -czf "$BACKUP_DIR/server_config_${DATE}.tar.gz" \ + /etc/nginx \ + /etc/apache2 \ + /etc/mysql \ + /etc/my.cnf \ + /etc/php* \ + /usr/local/cwpsrv/conf \ + /root/.acme.sh/cwp_certs \ + /etc/cron* \ + /etc/fstab \ + /etc/hosts +``` + +--- + +## Rotação GFS (Grandfather-Father-Son) + +```bash +#!/bin/bash +BACKUP_DIR="/backups" + +HOURLY_KEEP=24 +DAILY_KEEP=7 +WEEKLY_KEEP=4 +MONTHLY_KEEP=12 + +find "$BACKUP_DIR/hourly" -mtime +1 -delete +find "$BACKUP_DIR/daily" -mtime +$DAILY_KEEP -delete +find "$BACKUP_DIR/weekly" -mtime +$((WEEKLY_KEEP * 7)) -delete +find "$BACKUP_DIR/monthly" -mtime +$((MONTHLY_KEEP * 30)) -delete + +du -sh "$BACKUP_DIR"/* +``` + +| Tipo | Retenção | Frequência | +|------|----------|------------| +| Horário | 24h | A cada hora | +| Diário | 7 dias | 1x/dia (00:00) | +| Semanal | 4 semanas | 1x/semana | +| Mensal | 12 meses | 1x/mês | + +--- + +## Cron Schedule + +```cron +# Backup MySQL (diário às 02:00) +0 2 * * * /root/scripts/backup-mysql.sh >> /var/log/backup-mysql.log 2>&1 + +# Backup WordPress (diário às 03:00) +0 3 * * * /root/scripts/backup-wordpress.sh >> /var/log/backup-wp.log 2>&1 + +# Backup configurações (semanal, domingo 04:00) +0 4 * * 0 /root/scripts/backup-server-config.sh >> /var/log/backup-config.log 2>&1 + +# Rotação backups (diário às 05:00) +0 5 * * * /root/scripts/backup-rotation-gfs.sh >> /var/log/backup-rotation.log 2>&1 + +# Teste de restore (mensal, dia 1 às 06:00) +0 6 1 * * /root/scripts/test-restore.sh >> /var/log/test-restore.log 2>&1 + +# Sync para cloud (diário às 07:00) +0 7 * * * rclone sync /backups gdrive:backups >> /var/log/rclone-sync.log 2>&1 +``` + +--- + +## Cloud Sync com rclone + +```bash +# Instalar rclone +curl https://rclone.org/install.sh | sudo bash + +# Configurar Google Drive +rclone config +# Nome: gdrive | Tipo: drive | Seguir wizard +``` + +```bash +#!/bin/bash +LOCAL_DIR="/backups" +REMOTE="gdrive:backups" + +rclone sync "$LOCAL_DIR" "$REMOTE" \ + --exclude "*.tmp" \ + --exclude "*.log" \ + --progress +``` + +--- + +## Teste de Restore (OBRIGATÓRIO Mensal) + +```bash +#!/bin/bash +TEST_DB="test_restore_$(date +%Y%m%d)" +BACKUP_FILE="/backups/mysql/ealmeida_desk24_latest.sql.gz" + +mysql -e "CREATE DATABASE $TEST_DB;" + +gunzip < "$BACKUP_FILE" | mysql "$TEST_DB" + +TABLES=$(mysql -Nse "SELECT COUNT(*) FROM information_schema.TABLES WHERE table_schema='$TEST_DB';") +echo "Tabelas restauradas: $TABLES" + +mysqlcheck --check "$TEST_DB" | grep -i error + +mysql -e "DROP DATABASE $TEST_DB;" +echo "Teste concluído" +``` + +--- + +## Runbook Disaster Recovery + +```markdown +# DISASTER RECOVERY RUNBOOK + +## Cenário: Servidor CWP Inoperacional + +### Passo 1: Avaliação (5 min) +- [ ] Confirmar que servidor não responde (ping, SSH) +- [ ] Identificar tipo de falha (hardware, software, ataque) +- [ ] Comunicar clientes afectados (se downtime >1h) + +### Passo 2: Provisionar Servidor (30 min) +- [ ] Ubuntu 22.04 ou CentOS 7 +- [ ] Instalar CWP: `sh cwp-el7-latest.sh` +- [ ] Configurar firewall e SSH + +### Passo 3: Restore Bases de Dados (1-2h) +```bash +gunzip ealmeida_desk24_20260203_120000.sql.gz +mysql -e "CREATE DATABASE ealmeida_desk24;" +mysql ealmeida_desk24 < ealmeida_desk24_20260203_120000.sql +``` + +### Passo 4: Restore Ficheiros (1-2h) +```bash +tar -xzf wordpress_sites_20260203.tar.gz -C /tmp/ +cp -r /tmp/emanuelalmeida.pt /home/ealmeida/ +chown -R ealmeida:ealmeida /home/ealmeida/emanuelalmeida.pt +``` + +### Passo 5: Validação (30 min) +- [ ] Testar acesso SSH +- [ ] MySQL a responder +- [ ] Sites WordPress a carregar +- [ ] SSL activo + +**RTO Total Estimado:** 4-6 horas +``` diff --git a/infraestrutura/skills/cwp/SKILL.md b/infraestrutura/skills/cwp/SKILL.md new file mode 100644 index 0000000..86bcd19 --- /dev/null +++ b/infraestrutura/skills/cwp/SKILL.md @@ -0,0 +1,106 @@ +--- +name: cwp +description: Meta-skill CWP (CentOS Web Panel, servidor 176.9.3.158) cobrindo gestão de contas, backups, email/Postfix/DKIM, PHP Switcher/Selector, segurança CSF/LFD, SSL/acme.sh, webservers Apache/Nginx e referência completa dos scripts oficiais. Triggers — cwp, centos web panel, cwp_api, /scripts/, csf, lfd, acme, autossl, postfix, dkim, php selector, php switcher, varnish, httpd, nginx cwp, user_backup, whoowns, list_users, hostname ssl, mail queue, fix_perms. +layer: wiki +--- + +# /cwp - Meta-skill CWP (CentOS Web Panel) + +Skill unificada para o servidor **CWP Principal `176.9.3.158`** (MCP `ssh-unified`, user `root`). Substitui as antigas cwp-accounts, cwp-backup, cwp-email, cwp-php, cwp-scripts, cwp-security, cwp-ssl, cwp-webserver. + +**REGRA #38 — ZERO INVENÇÃO:** NUNCA improvisar comandos. Verificar estado actual ANTES de alterar. Pesquisar wiki CWP se necessário. Usar APENAS scripts oficiais (`/scripts/*` e `/scripts/cwp_api`). Se não souber: PERGUNTAR. + +--- + +## 0. GATE OBRIGATÓRIO — checklist pré-intervenção CWP + +> **Antes de QUALQUER alteração em CWP (SSL, email/Postfix/Dovecot, nginx/Apache, CSF, PHP), correr este checklist. Padrão recorrente de edições manuais desnecessárias = causa de incidentes repetidos (#3992).** + +1. **CONSULTAR PRIMEIRO** (Regra 53 — LLM Wiki obrigatório): + - `PROC-CWP-SSL.md` (D7 Infraestrutura) — para SSL/certificados. + - `PROC-Email-Antispam-CWP.md` (D7 Infraestrutura) — para email/Postfix/DKIM/antispam. + - NotebookLM CWP `0ded7bd6-69b3-4c76-b327-452396bf7ea7` + `~/wiki/` se o caso não estiver nos PROCs. +2. **VERIFICAR ESTADO ACTUAL** (read-only) antes de tocar — ver secção relevante abaixo (ex.: `openssl s_client` para SSL, `postqueue -p` para email). +3. **SCRIPT NATIVO, NUNCA EDIÇÃO MANUAL.** Se existe `/scripts/*` para a tarefa, usar esse. Editar Postfix/Dovecot/vhosts/certs à mão é anti-pattern (sobrescrito em updates + causa-raiz de drift). + - **SSL de email partido → `sh /scripts/mail_rebuild_sni_certs`** (NÃO editar `main.cf`/`master.cf` manualmente). + - Certs web → acme.sh nativo (§6). Webservers → `cwp_api webservers rebuild_*` (§7). Permissões pós-SSH → `cwp_api account fix_perms` (§1). +4. **EMAIL EM PRODUÇÃO = ZERO RISCO:** não mexer em `master.cf`/postscreen nem reiniciar Postfix sem necessidade comprovada. Mudança mínima, testada, reversível. +5. **HDD 4TB — sem comandos cegos:** NUNCA `du`/`find` genéricos em `/home` (bloqueia horas, iowait >30%). Caminhos específicos sempre. +6. **VALIDAR + DOCUMENTAR:** confirmar o efeito (secção "Validação" relevante) e registar o que se descobriu (memória/PROC) se for novo. + +> Se os passos 1-3 não resolvem e seria preciso editar à mão: **PARAR e perguntar**. A edição manual é o último recurso, não o primeiro. + +## Documentação base + +- Wiki: https://wiki.centos-webpanel.com/cwp-admin-api , /cwp-scripts , /csf-firewall-command-line +- Hub manuais: `Hub/06-Operacoes/Documentacao/Manuais/CWP/` (`CWP-Manual-Completo.md` 503KB, `CWP-Ferramentas-Desenvolvimento.md` 82KB, `CWP-Guia-do-Utilizador.md`, `CWP-Guia-do-Revendedor.md`) +- QR: `Hub/06-Operacoes/Documentacao/Quick-Reference/QR-CWP.md` +- NotebookLM CWP: `0ded7bd6-69b3-4c76-b327-452396bf7ea7` +- NotebookLM Cibersegurança WordPress (para secção segurança): `5f60adfd-2435-4725-8c12-9c11c5f51d75` + +``` +mcp__notebooklm__notebook_query notebook_id:"0ded7bd6-69b3-4c76-b327-452396bf7ea7" query:"" +``` + +--- + +## 1. Contas (accounts) + +### Consulta (read-only) +```bash +sh /scripts/list_users +sh /scripts/list_domains +sh /scripts/list_subdomains +sh /scripts/whoowns DOMINIO +``` + +### API gestão +```bash +/scripts/cwp_api account remove_user USERNAME +/scripts/cwp_api account suspend_user USERNAME +/scripts/cwp_api account unsuspend_user USERNAME +/scripts/cwp_api account fix_perms USERNAME # OBRIGATÓRIO após qualquer SSH manual +/scripts/cwp_api account list_domains USERNAME +``` + +### Bandwidth +```bash +/scripts/cwp_api account unsuspend_bandwidth USERNAME # após aumentar limites +/scripts/cwp_api account reset_bandwidth USERNAME +``` + +### Massa +```bash +/scripts/cwp_api account update_diskquota_all +/scripts/cwp_api account update_limits_all # quota, hourly_emails, cgroups, nproc, apache_nproc, inode, nofile +/scripts/cwp_api account mail_fix_permissions +/scripts/cwp_api account update_policyd_all +``` + +### DNS +```bash +/scripts/cwp_api account rebuild_etc_named_conf +/scripts/cwp_api account rebuild_var_named_all +/scripts/cwp_api account rebuild_var_named USERNAME DOMAIN +``` + +### Auxiliares +```bash +sh /scripts/ulimit_user_check USERNAME +sh /scripts/cwpsrv_rebuild_user_conf +``` + +### Workflows típicos +1. Suspender: `suspend_user` -> `list_users | grep`. +2. Reactivar: `unsuspend_user` -> `fix_perms`. +3. Pós-SSH manual: SEMPRE `fix_perms USERNAME`. + +### Validação +```bash +sh /scripts/list_users | grep USERNAME +/scripts/cwp_api account list_domains USERNAME +curl -sI http://DOMINIO | head -5 +``` + +### Anti-patterns +Remover sem backup | editar ficheiros manualmente | esquecer \ No newline at end of file diff --git a/infraestrutura/skills/desk.project b/infraestrutura/skills/desk.project new file mode 100644 index 0000000..5678920 --- /dev/null +++ b/infraestrutura/skills/desk.project @@ -0,0 +1,6 @@ +{ + "task_id": null, + "project_id": null, + "customer_id": null, + "gitea_repo": null +} diff --git a/infraestrutura/skills/easypanel-api/SKILL.md b/infraestrutura/skills/easypanel-api/SKILL.md new file mode 100644 index 0000000..c3325db --- /dev/null +++ b/infraestrutura/skills/easypanel-api/SKILL.md @@ -0,0 +1,139 @@ +--- +name: easypanel-api +description: Referência completa da API tRPC oficial do EasyPanel — todos os endpoints para projectos, serviços, deploy e configurações. +layer: wiki +--- + +# /easypanel-api - API Oficial EasyPanel + +Referência da API tRPC do EasyPanel. Baseado em engenharia reversa do SDK oficial. + +--- + +## Autenticação + +```bash +TOKEN=$(cat /etc/easypanel/.api-token) +# Header obrigatório em todos os pedidos: +-H "Authorization: Bearer $TOKEN" +``` + +**Base URL:** `http://localhost:3000/api/trpc/` + +Usar sempre via SSH localhost. Nunca expor externamente. + +--- + +## Formato de Pedidos + +| Método | Quando usar | Formato | +|--------|-------------|---------| +| GET | Leitura (list, inspect, get) | `?input=URL_ENCODED_JSON` | +| POST | Escrita (create, update, deploy, destroy) | `-d '{"json":{...}}'` com `Content-Type: application/json` | + +```bash +# GET +curl -s "http://localhost:3000/api/trpc/ENDPOINT?input=URL_ENCODED_JSON" \ + -H "Authorization: Bearer $TOKEN" + +# POST +curl -s -X POST "http://localhost:3000/api/trpc/ENDPOINT" \ + -H "Authorization: Bearer $TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"json":{...}}' +``` + +--- + +## Projects API + +| Endpoint | Tipo | Descrição | +|----------|------|-----------| +| `projects.listProjects` | GET | Listar todos os projectos | +| `projects.listProjectsAndServices` | GET | Projectos + todos os serviços | +| `projects.createProject` | POST | Criar projecto (`name`) | +| `projects.destroyProject` | POST | Destruir projecto (`projectName`) | +| `projects.inspectProject` | GET | Inspecionar projecto (`projectName`) | + +```bash +# Listar projectos (teste rápido de autenticação) +curl -s "http://localhost:3000/api/trpc/projects.listProjects" \ + -H "Authorization: Bearer $TOKEN" + +# Criar projecto +curl -s -X POST "http://localhost:3000/api/trpc/projects.createProject" \ + -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ + -d '{"json":{"name":"novo-projecto"}}' +``` + +--- + +## Services API + +Endpoints completos com exemplos curl: ver [references/services-api.md](references/services-api.md) + +**Verificados 12-03-2026** (engenharia reversa do backend.js minificado): + +| Endpoint | Tipo | Descrição | +|----------|------|-----------| +| `services.app.createService` | POST | Criar serviço app | +| `services.postgres.createService` | POST | Criar PostgreSQL | +| `services.mysql.createService` | POST | Criar MySQL | +| `services.redis.createService` | POST | Criar Redis | +| `services.app.inspectService` | GET | Inspecionar serviço | +| `services.app.deployService` | POST | Fazer deploy | +| `services.app.stopService` | POST | Parar serviço | +| `services.app.startService` | POST | Iniciar serviço | +| `services.app.restartService` | POST | Reiniciar serviço | +| `services.app.destroyService` | POST | Destruir serviço | + +**Endpoints que NAO existem** (removidos da versao anterior): +`enableService`, `disableService` — usar `startService`/`stopService` em vez disso. + +**Parâmetros obrigatórios:** `projectName` + `serviceName` em todos os endpoints de serviços. + +**Regra Descomplicar:** `projectName:"descomplicar"` para serviços próprios. + +--- + +## Service Configuration API + +Endpoints completos com exemplos curl: ver [references/service-config-api.md](references/service-config-api.md) + +**Verificados 12-03-2026:** + +| Endpoint | Descrição | Verificado | +|----------|-----------|:----------:| +| `services.app.updateSourceGithub` | Source GitHub (`owner`, `repo`, `ref`, `path`) | Sim | +| `services.app.updateSourceGit` | Source Git custom (`repo`, `ref`, `path`) — params no nivel raiz, NAO dentro de `source` | Sim | +| `services.app.updateSourceImage` | Source Docker image (`image`) | Sim | +| `services.app.updateEnv` | Variáveis de ambiente (`env` como string multi-linha) | Sim | +| `services.app.updateBuild` | Build config (`type`, `buildCommand`, `startCommand`) | Sim | +| `services.app.updateResources` | CPU/RAM (`memoryLimit`, `cpuLimit`, etc.) | Sim | +| `services.app.updateAdvanced` | Deploy avançado (`replicas`, `command`, `zeroDowntime`) | Sim | +| `services.app.updateRedirects` | Redireccionamentos HTTP | Sim | +| `services.app.updateBasicAuth` | Autenticacao basica | Sim | +| `services.app.updateMaintenance` | Modo manutencao | Sim | + +**Endpoints que NAO existem na versao instalada:** +- ~~`services.app.updateDomains`~~ — dominios so via UI do EasyPanel +- ~~`services.app.updateMounts`~~ — nao encontrado +- ~~`services.app.updatePorts`~~ — nao encontrado + +--- + +## Domains API (Verificado 12-03-2026) + +Os dominios NAO sao geridos por `services.app.*` mas sim pelo namespace `domains.*`. + +| Endpoint | Tipo | Descricao | +|----------|------|-----------| +| `domains.listDomains` | GET | Listar dominios do projecto (`projectName`) | +| `domains.createDomain` | POST | Criar dominio | +| `domains.updateDomain` | POST | Actualizar dominio | +| `domains.deleteDomain` | POST | Remover dominio | + +```bash +# Listar dominios +INPUT='{"json":{"projectName":"descomplicar"}}' +ENCODED=$(python3 -c "import urllib.parse; print(urllib.par \ No newline at end of file diff --git a/infraestrutura/skills/easypanel-api/references/service-config-api.md b/infraestrutura/skills/easypanel-api/references/service-config-api.md new file mode 100644 index 0000000..85e26f4 --- /dev/null +++ b/infraestrutura/skills/easypanel-api/references/service-config-api.md @@ -0,0 +1,283 @@ +# EasyPanel API - Service Configuration + +**Verificado:** 12-03-2026 (engenharia reversa do backend.js) + +--- + +## Actualizar Source (GitHub) + +```bash +curl -s -X POST "http://localhost:3000/api/trpc/services.app.updateSourceGithub" \ + -H "Authorization: Bearer $TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"json":{ + "projectName":"descomplicar", + "serviceName":"minha-api", + "owner":"ealmeida", + "repo":"MeuRepo", + "ref":"main", + "path":"/" + }}' +``` + +## Actualizar Source (Git Custom) + +**IMPORTANTE:** Os parametros `repo`, `ref`, `path` devem estar no nivel RAIZ do JSON, NAO dentro de um objecto `source`. + +```bash +curl -s -X POST "http://localhost:3000/api/trpc/services.app.updateSourceGit" \ + -H "Authorization: Bearer $TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"json":{ + "projectName":"descomplicar", + "serviceName":"minha-api", + "repo":"https://ealmeida:TOKEN@git.descomplicar.pt/ealmeida/repo", + "ref":"main", + "path":"/" + }}' +``` + +**Errado (causa zodErrors):** +```json +{"json":{"projectName":"x","serviceName":"y","source":{"type":"git","repo":"...","ref":"main","path":"/"}}} +``` + +**Correcto:** +```json +{"json":{"projectName":"x","serviceName":"y","repo":"...","ref":"main","path":"/"}} +``` + +## Actualizar Source (Docker Image) + +```bash +curl -s -X POST "http://localhost:3000/api/trpc/services.app.updateSourceImage" \ + -H "Authorization: Bearer $TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"json":{ + "projectName":"descomplicar", + "serviceName":"minha-api", + "image":"node:22-alpine" + }}' +``` + +## Actualizar Environment Variables + +```bash +curl -s -X POST "http://localhost:3000/api/trpc/services.app.updateEnv" \ + -H "Authorization: Bearer $TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"json":{ + "projectName":"descomplicar", + "serviceName":"minha-api", + "env":"NODE_ENV=production\nPORT=3000\nDATABASE_URL=postgres://..." + }}' +``` + +## Actualizar Build Config + +```bash +curl -s -X POST "http://localhost:3000/api/trpc/services.app.updateBuild" \ + -H "Authorization: Bearer $TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"json":{ + "projectName":"descomplicar", + "serviceName":"minha-api", + "build":{ + "type":"nixpacks", + "buildCommand":"npm run build", + "startCommand":"npm start" + } + }}' +``` + +## Actualizar Resources + +```bash +curl -s -X POST "http://localhost:3000/api/trpc/services.app.updateResources" \ + -H "Authorization: Bearer $TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"json":{ + "projectName":"descomplicar", + "serviceName":"minha-api", + "resources":{ + "memoryLimit":"512m", + "memoryReservation":"256m", + "cpuLimit":1, + "cpuReservation":0.5 + } + }}' +``` + +## Actualizar Deploy (Replicas, Command) + +```bash +curl -s -X POST "http://localhost:3000/api/trpc/services.app.updateAdvanced" \ + -H "Authorization: Bearer $TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"json":{ + "projectName":"descomplicar", + "serviceName":"minha-api", + "deploy":{ + "replicas":2, + "command":"node dist/index.js", + "zeroDowntime":true + } + }}' +``` + +## Actualizar Redirects + +```bash +curl -s -X POST "http://localhost:3000/api/trpc/services.app.updateRedirects" \ + -H "Authorization: Bearer $TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"json":{ + "projectName":"descomplicar", + "serviceName":"minha-api", + "redirects":[] + }}' +``` + +## Actualizar Basic Auth + +```bash +curl -s -X POST "http://localhost:3000/api/trpc/services.app.updateBasicAuth" \ + -H "Authorization: Bearer $TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"json":{ + "projectName":"descomplicar", + "serviceName":"minha-api", + "basicAuth":{"enabled":false} + }}' +``` + +## Actualizar Maintenance Mode + +```bash +curl -s -X POST "http://localhost:3000/api/trpc/services.app.updateMaintenance" \ + -H "Authorization: Bearer $TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"json":{ + "projectName":"descomplicar", + "serviceName":"minha-api", + "maintenance":{"enabled":false} + }}' +``` + +## Database Backup Config + +```bash +curl -s -X POST "http://localhost:3000/api/trpc/services.postgres.updateBackup" \ + -H "Authorization: Bearer $TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"json":{ + "projectName":"descomplicar", + "serviceName":"minha-db", + "backup":{ + "enabled":true, + "schedule":"0 3 * * *", + "destination":{ + "type":"s3", + "bucket":"backups", + "region":"eu-west-1", + "accessKey":"...", + "secretKey":"..." + } + } + }}' +``` + +--- + +## Domains API (Namespace separado) + +**IMPORTANTE:** Os dominios NAO sao geridos por `services.app.*` mas sim pelo namespace `domains.*`. + +### Listar Dominios (GET) + +```bash +INPUT='{"json":{"projectName":"descomplicar"}}' +ENCODED=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$INPUT'))") +curl -s "http://localhost:3000/api/trpc/domains.listDomains?input=$ENCODED" \ + -H "Authorization: Bearer $TOKEN" +``` + +### Criar Dominio (POST) + +```bash +curl -s -X POST "http://localhost:3000/api/trpc/domains.createDomain" \ + -H "Authorization: Bearer $TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"json":{ + "id":"meu-dominio-id", + "https":true, + "host":"app.descomplicar.pt", + "path":"/", + "middlewares":[], + "certificateResolver":"letsencrypt", + "wildcard":false, + "destinationType":"service", + "serviceDestination":{ + "protocol":"http", + "port":3000, + "path":"/", + "projectName":"descomplicar", + "serviceName":"meu-servico" + } + }}' +``` + +**Notas:** +- O `id` pode ser qualquer string unica (cuid ou slug) +- `certificateResolver`: `"letsencrypt"` para HTTPS, `""` para dominios internos +- `destinationType`: `"service"` para servicos EasyPanel, `"custom"` para destinos externos + +### Actualizar Dominio (POST) + +```bash +curl -s -X POST "http://localhost:3000/api/trpc/domains.updateDomain" \ + -H "Authorization: Bearer $TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"json":{...mesmo schema de createDomain...}}' +``` + +### Remover Dominio (POST) + +```bash +curl -s -X POST "http://localhost:3000/api/trpc/domains.deleteDomain" \ + -H "Authorization: Bearer $TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"json":{"id":"meu-dominio-id"}}' +``` + +--- + +## Resumo de Endpoints de Configuracao + +| Endpoint | Tipo | Descricao | Verificado | +|----------|------|-----------|:----------:| +| `services.app.updateSourceGithub` | POST | Source GitHub (`owner`,`repo`,`ref`,`path`) | Sim | +| `services.app.updateSourceGit` | POST | Source Git custom (`repo`,`ref`,`path` RAIZ) | Sim | +| `services.app.updateSourceImage` | POST | Source Docker image (`image`) | Sim | +| `services.app.updateEnv` | POST | Variaveis de ambiente (`env` string) | Sim | +| `services.app.updateBuild` | POST | Build config (`type`,`buildCommand`,`startCommand`) | Sim | +| `services.app.updateResources` | POST | CPU/RAM limits | Sim | +| `services.app.updateAdvanced` | POST | Deploy avancado (replicas, command, zeroDowntime) | Sim | +| `services.app.updateRedirects` | POST | Redireccionamentos HTTP | Sim | +| `services.app.updateBasicAuth` | POST | Autenticacao basica | Sim | +| `services.app.updateMaintenance` | POST | Modo manutencao | Sim | +| `domains.listDomains` | GET | Listar dominios (`projectName`) | Sim | +| `domains.createDomain` | POST | Criar dominio | Sim | +| `domains.updateDomain` | POST | Actualizar dominio | Sim | +| `domains.deleteDomain` | POST | Remover dominio | Sim | + +**Endpoints que NAO existem na versao instalada:** +- ~~`services.app.updateDomains`~~ — usar `domains.createDomain` +- ~~`services.app.updateMounts`~~ — nao encontrado +- ~~`services.app.updatePorts`~~ — nao encontrado +- ~~`services.app.saveDomains`~~ — nao existe +- ~~`services.app.saveGithubSource`~~ — usar `updateSourceGithub` ou `updateSourceGit` + +--- + +*Actualizado: 12-03-2026* diff --git a/infraestrutura/skills/easypanel-api/references/services-api.md b/infraestrutura/skills/easypanel-api/references/services-api.md new file mode 100644 index 0000000..1030209 --- /dev/null +++ b/infraestrutura/skills/easypanel-api/references/services-api.md @@ -0,0 +1,135 @@ +# EasyPanel API - Services + +**Verificado:** 12-03-2026 (engenharia reversa do backend.js) + +## Service Types + +| Type | Descricao | +|------|-----------| +| `app` | Aplicacao (Node.js, Python, Go, Rust, etc.) | +| `mysql` | MySQL database | +| `mariadb` | MariaDB database | +| `postgres` | PostgreSQL database | +| `mongo` | MongoDB database | +| `redis` | Redis cache | + +## Criar Servico App + +```bash +curl -s -X POST "http://localhost:3000/api/trpc/services.app.createService" \ + -H "Authorization: Bearer $TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"json":{"projectName":"descomplicar","serviceName":"minha-api"}}' +``` + +## Criar Servico Database + +```bash +# PostgreSQL +curl -s -X POST "http://localhost:3000/api/trpc/services.postgres.createService" \ + -H "Authorization: Bearer $TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"json":{"projectName":"descomplicar","serviceName":"minha-db"}}' + +# MySQL +curl -s -X POST "http://localhost:3000/api/trpc/services.mysql.createService" \ + -H "Authorization: Bearer $TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"json":{"projectName":"descomplicar","serviceName":"mysql-db"}}' + +# Redis +curl -s -X POST "http://localhost:3000/api/trpc/services.redis.createService" \ + -H "Authorization: Bearer $TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"json":{"projectName":"descomplicar","serviceName":"cache"}}' +``` + +## Inspeccionar Servico (GET) + +```bash +INPUT='{"json":{"projectName":"descomplicar","serviceName":"dashboard_descomplicar"}}' +ENCODED=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$INPUT'))") +curl -s "http://localhost:3000/api/trpc/services.app.inspectService?input=$ENCODED" \ + -H "Authorization: Bearer $TOKEN" +``` + +Response parcial: +```json +{ + "projectName": "descomplicar", + "name": "dashboard_descomplicar", + "type": "app", + "enabled": true, + "token": "deploy-webhook-token", + "source": {"type": "git", "repo": "https://...", "ref": "main"}, + "build": {"type": "nixpacks", "buildCommand": "npm run build"}, + "env": "VAR=value", + "mounts": [], + "ports": [] +} +``` + +## Deploy Servico + +```bash +curl -s -X POST "http://localhost:3000/api/trpc/services.app.deployService" \ + -H "Authorization: Bearer $TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"json":{"projectName":"descomplicar","serviceName":"minha-api"}}' +``` + +## Stop / Start / Restart Servico + +```bash +# Parar servico +curl -s -X POST "http://localhost:3000/api/trpc/services.app.stopService" \ + -H "Authorization: Bearer $TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"json":{"projectName":"descomplicar","serviceName":"minha-api"}}' + +# Iniciar servico +curl -s -X POST "http://localhost:3000/api/trpc/services.app.startService" \ + -H "Authorization: Bearer $TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"json":{"projectName":"descomplicar","serviceName":"minha-api"}}' + +# Reiniciar servico +curl -s -X POST "http://localhost:3000/api/trpc/services.app.restartService" \ + -H "Authorization: Bearer $TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"json":{"projectName":"descomplicar","serviceName":"minha-api"}}' +``` + +**IMPORTANTE:** `enableService` e `disableService` NAO existem na versao instalada. Usar `startService`/`stopService`. + +## Destruir Servico + +```bash +curl -s -X POST "http://localhost:3000/api/trpc/services.app.destroyService" \ + -H "Authorization: Bearer $TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"json":{"projectName":"descomplicar","serviceName":"minha-api"}}' +``` + +--- + +## Resumo de Endpoints + +| Endpoint | Tipo | Descricao | Verificado | +|----------|------|-----------|:----------:| +| `services.app.createService` | POST | Criar servico app | Sim | +| `services.postgres.createService` | POST | Criar PostgreSQL | Sim | +| `services.mysql.createService` | POST | Criar MySQL | Sim | +| `services.redis.createService` | POST | Criar Redis | Sim | +| `services.app.inspectService` | GET | Inspeccionar servico | Sim | +| `services.app.deployService` | POST | Fazer deploy | Sim | +| `services.app.stopService` | POST | Parar servico | Sim | +| `services.app.startService` | POST | Iniciar servico | Sim | +| `services.app.restartService` | POST | Reiniciar servico | Sim | +| `services.app.destroyService` | POST | Destruir servico | Sim | + +**Endpoints que NAO existem:** `enableService`, `disableService`, `redeployService` + +--- + +*Actualizado: 12-03-2026* diff --git a/infraestrutura/skills/easypanel-cicd/SKILL.md b/infraestrutura/skills/easypanel-cicd/SKILL.md new file mode 100644 index 0000000..d77dad4 --- /dev/null +++ b/infraestrutura/skills/easypanel-cicd/SKILL.md @@ -0,0 +1,184 @@ +--- +name: easypanel-cicd +description: Configuracao de CI/CD com Gitea Actions para auto-deploy no EasyPanel via webhook — setup de workflows, secrets e validacao. +layer: wiki +--- + +# /easypanel-cicd - CI/CD Gitea Actions para EasyPanel + +Configuracao completa de pipelines CI/CD que ligam repositorios Gitea ao EasyPanel para auto-deploy. + +--- + +## Quando usar + +- Configurar auto-deploy de um repositorio Gitea para EasyPanel +- Criar workflow Gitea Actions com testes + deploy +- Obter e configurar webhook URL de um servico +- Diagnosticar pipelines CI/CD falhados +- Adicionar CI/CD a projectos existentes no EasyPanel + +## Quando nao usar + +- Para deploy manual (usar `/easypanel-deploy`) +- Para scaffold de projecto novo (usar `/easypanel-init`) +- Para troubleshooting de containers (usar `/easypanel-troubleshoot`) + +--- + +## Sintaxe + +```bash +/easypanel-cicd # Setup completo (workflow + secrets + webhook) +/easypanel-cicd --webhook-only # Apenas obter/configurar webhook +/easypanel-cicd --diagnose # Diagnosticar pipeline falhado +``` + +--- + +## Arquitectura + +``` +Gitea (push main) --> Gitea Actions Runner --> Testes + Build --> Webhook POST --> EasyPanel Redeploy + (3 runners activos) (deploy URL) (build + container) +``` + +**Componentes:** +- **Gitea Actions Runners:** 3 replicas activas (`descomplicar_gitea-runner`) +- **Webhook URL:** Cada servico EasyPanel tem `deploymentUrl` unico +- **Formato:** `http://:3000/api/deploy/` + +--- + +## Workflow completo + +### 1. Obter webhook URL do servico + +```bash +TOKEN=$(cat /etc/easypanel/.api-token) + +# Via inspectService — campo deploymentUrl +INPUT='{"json":{"projectName":"descomplicar","serviceName":"SERVICE_NAME"}}' +ENCODED=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$INPUT'))") +curl -s "http://localhost:3000/api/trpc/services.app.inspectService?input=$ENCODED" \ + -H "Authorization: Bearer $TOKEN" \ + | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['result']['data']['json']['deploymentUrl'])" +``` + +**Formato da URL:** `http://178.63.18.51:3000/api/deploy/` + +**Nota:** O token e unico por servico e nao expira. Nao confundir com o API token geral. + +### 2. Configurar secret no repositorio Gitea + +Via MCP Gitea: +``` +mcp__gitea__upsert_repo_action_secret({ + owner: "ealmeida", + repo: "REPO_NAME", + secretname: "EASYPANEL_DEPLOY_URL", + body: { data: "http://178.63.18.51:3000/api/deploy/" } +}) +``` + +Secrets adicionais recomendados: +- `EASYPANEL_DEPLOY_URL` — webhook URL (obrigatorio) +- `DEPLOY_DOMAIN` — dominio do servico (opcional, para health check) + +### 3. Criar workflow Gitea Actions + +Criar `.gitea/workflows/deploy.yml` no repositorio: + +#### Template basico (apenas deploy) + +```yaml +name: Deploy to EasyPanel + +on: + push: + branches: + - main + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - name: Trigger EasyPanel Deploy + run: | + RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" -X POST "${{ secrets.EASYPANEL_DEPLOY_URL }}") + if [ "$RESPONSE" != "200" ]; then + echo "Deploy trigger failed with HTTP $RESPONSE" + exit 1 + fi + echo "Deploy triggered successfully" +``` + +#### Template completo (testes + build + deploy + health check) + +```yaml +name: CI/CD Pipeline + +on: + push: + branches: + - main + pull_request: + branches: + - main + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '22' + cache: 'npm' + + - name: Install dependencies + run: npm ci + + - name: Lint + run: npm run lint --if-present + + - name: Test + run: npm test --if-present + + - name: Build + run: npm run build + + deploy: + needs: test + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/main' && github.event_name == 'push' + steps: + - name: Trigger EasyPanel Deploy + run: | + echo "Triggering deploy..." + RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" -X POST "${{ secrets.EASYPANEL_DEPLOY_URL }}") + if [ "$RESPONSE" != "200" ]; then + echo "Deploy trigger failed with HTTP $RESPONSE" + exit 1 + fi + echo "Deploy triggered (HTTP $RESPONSE)" + + - name: Wait for deployment + run: sleep 120 + + - name: Health check + if: ${{ secrets.DEPLOY_DOMAIN != '' }} + run: | + for i in 1 2 3 4 5; do + STATUS=$(curl -s -o /dev/null -w "%{http_code}" "https://${{ secrets.DEPLOY_DOMAIN }}/health" || echo "000") + echo "Health check $i/5: HTTP $STATUS" + if [ "$STATUS" = "200" ]; then + echo "Service healthy" + exit 0 + fi + sleep 15 + done + echo "Health check failed after 5 attempts" + e \ No newline at end of file diff --git a/infraestrutura/skills/easypanel-deploy/SKILL.md b/infraestrutura/skills/easypanel-deploy/SKILL.md new file mode 100644 index 0000000..478a7b4 --- /dev/null +++ b/infraestrutura/skills/easypanel-deploy/SKILL.md @@ -0,0 +1,233 @@ +--- +name: easypanel-deploy +description: Deploy completo e automatizado para EasyPanel com validação integrada, monitoring e safety net (auto-rollback) via API oficial. +disable-model-invocation: true +layer: wiki +--- + +# EasyPanel Deploy + +Deploy completo e automatizado para EasyPanel com validação integrada. + +## Quando Usar + +- Deploy completo de projecto +- Deploy com validação automática +- Deploy com monitoring +- Deploy com safety net (auto-rollback) +- Production deploys críticos + +## Sintaxe + +```bash +/easypanel-deploy [--skip-tests] [--force] +``` + +## Exemplos + +```bash +# Deploy normal (com tests e validation) +/easypanel-deploy + +# Deploy sem tests (CI/CD já rodou) +/easypanel-deploy --skip-tests + +# Force deploy (ignorar warnings) +/easypanel-deploy --force +``` + +## Workflow Completo (9 Steps) + +### 1. Pre-deploy Validation + +```bash +/easypanel-validate +``` + +**Gates:** +- Score < 7/10 → **ABORT** (excepto --force) +- Critical issues → **ABORT** +- Se pass → Continue + +### 2. Run Tests (se não --skip-tests) + +```bash +npm test +``` + +**Gates:** +- Tests fail → **ABORT** +- No tests found → **WARNING** (continue) +- Tests pass → Continue + +### 3. Build Local (test) + +```bash +docker build --no-cache -t :test . +``` + +**Checks:** +- Build completa sem erros +- Image size < 200MB (Node.js) +- EXPOSE port correcto + +**Gates:** +- Build fail → **ABORT** +- Image size > 500MB → **WARNING** (continue com --force) + +### 4. Git Check + +```bash +git status +``` + +**Checks:** +- Uncommitted changes? +- Untracked files? + +**Actions:** +- Se changes → **PROMPT**: "Commit agora? [y/N]" +- Se yes → `git add . && git commit -m "deploy: ..."` +- Se no → **ABORT** + +### 5. Push to Gitea + +```bash +git push origin main +``` + +**Actions:** +- Push commits +- Se CI/CD configurado → Aguardar webhook trigger +- Log commit SHA + +### 6. Monitor EasyPanel Deploy + +**Via API (preferido - sincroniza com GUI):** +```bash +# Obter token +TOKEN=$(cat /etc/easypanel/.api-token) + +# Verificar estado do serviço +curl -s "http://localhost:3000/api/trpc/services.app.inspectService?input=$(echo -n '{"json":{"projectName":"PROJECT","serviceName":"SERVICE"}}' | jq -sRr @uri)" \ + -H "Authorization: Bearer $TOKEN" + +# Listar todos os serviços do projecto +curl -s "http://localhost:3000/api/trpc/projects.inspectProject?input=$(echo -n '{"json":{"projectName":"PROJECT"}}' | jq -sRr @uri)" \ + -H "Authorization: Bearer $TOKEN" +``` + +**Via SSH (fallback):** +```bash +# Poll cada 10s (timeout 5min) +docker service ls | grep +docker service ps +``` + +**Timeline:** +- [00:00] Build started +- [01:30] Build complete +- [02:00] Container starting +- [02:15] Health check iniciado + +### 7. Health Check (retry 5x, interval 10s) + +```bash +curl -f https:///health +``` + +**Retry Logic:** +- Tentativa 1-5: aguardar 10s entre cada +- Se 200 OK → **SUCCESS** +- Se 5xx após 5 retries → **ROLLBACK** +- Se timeout → **ROLLBACK** + +### 8. Metrics Validation + +```bash +# Via docker stats ou EasyPanel API +docker stats --no-stream +``` + +**Checks:** +- CPU < 80% (avg 60s) +- Memory < 80% limit +- No errors em logs (últimos 60s) + +**Gates:** +- CPU > 90% → **WARNING** (potential issue) +- Memory > 90% → **WARNING** (OOM risk) +- Errors em logs → **WARNING** + report + +### 9. Success Report + +**Output:** +- Total deploy time +- Build time +- Image size +- Health status +- Metrics snapshot +- URLs (production, health, logs) + +## Output Format (Success) + +``` +🚀 EasyPanel Deploy: + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +⏱️ TIMELINE +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +[00:00] ✅ Pre-deploy validation (score: 9.2/10) +[00:15] ✅ Tests passed (12/12, 2.3s) +[00:20] ✅ Local build (82MB, 1m 34s) +[00:25] ✅ Git push (commit: a3f5c21) +[01:55] ✅ EasyPanel build started +[03:42] ✅ Container started (dashboard-api-6f9d8) +[03:50] ✅ Health check 1/5: 200 OK +[03:52] ✅ Health check 5/5: 200 OK (stable) +[04:00] ✅ Metrics validated (CPU: 12%, RAM: 45MB/512MB) + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +✅ DEPLOY SUCCESS +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +📊 Metrics: + - Total time: 4m 0s (vs ~60min manual, -93%) + - Build time: 1m 34s + - Image size: 82MB (-80% vs non-multi-stage) + - Cold start: 2.1s + - Memory usage: 45MB / 512MB (8.8%) + - CPU usage: 12% (avg first 60s) + +🌐 Endpoints: + - Production: https://domain.descomplicar.pt + - Health: https://domain.descomplicar.pt/health + +📋 Logs: + - EasyPanel: https://easy.descomplicar.pt/services//logs + - Gitea: https://git.descomplicar.pt/org/repo/actions + +🔔 Next Steps: + 1. Monitor uptime (first 24h critical) + 2. Check error rate (should be <1%) + 3. Load testing (optional, recommended) + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +``` + +## Output Format (Failed) + +``` +❌ DEPLOY FAILED + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +⏱️ TIMELINE +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +[00:00] ✅ Pre-deploy validation +[00:15] ✅ Tests passed +[00:20] ✅ Local build +[00:25] ✅ Git push +[01:55] ✅ EasyPanel build started +[03:42] \ No newline at end of file diff --git a/infraestrutura/skills/easypanel-init/SKILL.md b/infraestrutura/skills/easypanel-init/SKILL.md new file mode 100644 index 0000000..6211d2b --- /dev/null +++ b/infraestrutura/skills/easypanel-init/SKILL.md @@ -0,0 +1,248 @@ +--- +name: easypanel-init +description: Inicialização de projectos EasyPanel com configuração adequada via API oficial — scaffold automático para Node.js, PHP ou sites estáticos. +disable-model-invocation: true +layer: wiki +--- + +# EasyPanel Init + +Scaffold automático de projectos optimizados para deploy no EasyPanel. + +## Quando Usar + +- Iniciar novo projecto do zero +- Converter projecto existente para EasyPanel +- Setup rápido com best practices +- Criar estrutura standardizada +- Prototype rapidamente + +## Sintaxe + +```bash +/easypanel-init [--type nodejs|python|go] [--db postgres|mysql|none] +``` + +## Exemplos + +```bash +# Node.js API sem database +/easypanel-init dashboard-api dashboard.descomplicar.pt --type nodejs + +# Node.js API com PostgreSQL +/easypanel-init crm-api crm.descomplicar.pt --type nodejs --db postgres + +# Python API (futuro) +/easypanel-init ml-api ml.descomplicar.pt --type python + +# Go API (futuro) +/easypanel-init fast-api api.descomplicar.pt --type go +``` + +## Workflow Completo + +### 1. Criar Estrutura de Pastas + +``` +project-root/ +├── src/ +│ ├── index.ts (ou main.py, main.go) +│ └── routes/ +│ └── health.ts +├── Dockerfile (template multi-stage) +├── docker-compose.yml (Traefik labels) +├── .dockerignore +├── .gitignore +├── .env.example +├── package.json (scripts padronizados) +├── tsconfig.json (se TypeScript) +├── .gitea/ +│ └── workflows/ +│ └── deploy.yml (CI/CD) +└── README.md (deploy guide) +``` + +### 2. Generate Templates + +#### Dockerfile (Multi-stage Node.js) + +```dockerfile +# Stage 1: Dependencies +FROM node:22-alpine AS deps +WORKDIR /app +COPY package*.json ./ +RUN npm ci --only=production + +# Stage 2: Builder +FROM node:22-alpine AS builder +WORKDIR /app +COPY package*.json ./ +RUN npm ci +COPY . . +RUN npm run build + +# Stage 3: Runner +FROM node:22-alpine AS runner +WORKDIR /app +ENV NODE_ENV=production +COPY --from=deps /app/node_modules ./node_modules +COPY --from=builder /app/dist ./dist +COPY package*.json ./ + +RUN addgroup -g 1001 -S nodejs && \ + adduser -S nodejs -u 1001 + +USER nodejs + +EXPOSE 3000 + +HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ + CMD node -e "require('http').get('http://localhost:3000/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})" + +CMD ["npm", "start"] +``` + +#### docker-compose.yml (Traefik) + +```yaml +version: '3.8' + +services: + app: + build: . + restart: unless-stopped + ports: + - "3000:3000" + environment: + - NODE_ENV=production + - PORT=3000 + networks: + - traefik + labels: + - "traefik.enable=true" + - "traefik.http.routers.PROJECTNAME.rule=Host(`DOMAIN`)" + - "traefik.http.routers.PROJECTNAME.entrypoints=websecure" + - "traefik.http.routers.PROJECTNAME.tls.certresolver=letsencrypt" + - "traefik.http.services.PROJECTNAME.loadbalancer.server.port=3000" + - "traefik.http.services.PROJECTNAME.loadbalancer.healthcheck.path=/health" + - "traefik.http.services.PROJECTNAME.loadbalancer.healthcheck.interval=10s" + +networks: + traefik: + external: true +``` + +#### Health Endpoint (Express) + +```typescript +import { Router } from 'express' +import type { Request, Response } from 'express' + +const router = Router() + +router.get('/health', (req: Request, res: Response) => { + res.status(200).json({ + status: 'ok', + timestamp: new Date().toISOString(), + uptime: process.uptime(), + environment: process.env.NODE_ENV || 'development' + }) +}) + +export default router +``` + +#### Gitea Workflow (.gitea/workflows/deploy.yml) + +```yaml +name: Deploy to EasyPanel + +on: + push: + branches: + - main + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: '22' + + - name: Install dependencies + run: npm ci + + - name: Run tests + run: npm test + + - name: Build + run: npm run build + + - name: Trigger EasyPanel Deploy + run: | + curl -X POST ${{ secrets.EASYPANEL_WEBHOOK_URL }} +``` + +#### package.json (scripts) + +```json +{ + "name": "PROJECT_NAME", + "version": "1.0.0", + "type": "module", + "scripts": { + "dev": "tsx watch src/index.ts", + "build": "tsc", + "start": "node dist/index.js", + "lint": "eslint .", + "test": "vitest" + } +} +``` + +#### README.md + +```markdown +# PROJECT_NAME + +## Setup Local + +1. npm install +2. cp .env.example .env.local +3. npm run dev + +## Deploy EasyPanel + +1. Push to main: `git push origin main` +2. CI/CD auto-deploy via Gitea Actions +3. Health check: https://DOMAIN/health + +## Environment Variables + +See `.env.example` for required variables. + +## Architecture + +- Multi-stage Docker build (80% smaller image) +- Traefik routing with SSL +- Health checks every 10s +- Non-root user for security +``` + +### 3. Initialize Git + +```bash +git init +git add . +git commit -m "chore: initial project setup via /easypanel-init" +``` + +### 4. Criar Projecto no EasyPanel via API + +```bash +# Obte \ No newline at end of file diff --git a/infraestrutura/skills/easypanel-monitor/SKILL.md b/infraestrutura/skills/easypanel-monitor/SKILL.md new file mode 100644 index 0000000..6a0506d --- /dev/null +++ b/infraestrutura/skills/easypanel-monitor/SKILL.md @@ -0,0 +1,204 @@ +--- +name: easypanel-monitor +description: Monitorizacao de servicos EasyPanel -- estado de todos os servicos Docker, uso de recursos, disco e logs de erros com tabela resumo OK/DOWN/WARN. +layer: wiki +--- + +# /easypanel-monitor - Monitorizacao EasyPanel + +Verificacao rapida do estado de todos os servicos no EasyPanel (VM 101) com identificacao de problemas. + +--- + +## Quando usar + +- Verificacao diaria do estado dos servicos +- Apos alertas de servicos down +- Antes de deploys (validar estado actual) +- Diagnostico rapido de problemas de recursos + +## Quando nao usar + +- Para troubleshooting aprofundado de um servico especifico (usar `/easypanel-troubleshoot`) +- Para rollback de versao (usar `/easypanel-rollback`) +- Para deploy de servicos (usar `/easypanel-deploy`) + +--- + +## Sintaxe + +```bash +/easypanel-monitor # Check completo (servicos + recursos + disco) +/easypanel-monitor quick # Apenas estado dos servicos (OK/DOWN) +/easypanel-monitor # Detalhe de um servico especifico (logs + stats) +``` + +--- + +## Servidor alvo + +| Alias SSH | IP | Porta | Funcao | +|-----------|-----|-------|--------| +| **easy** | 5.9.90.70 | 22 | EasyPanel (VM 101) | + +```javascript +mcp__ssh-unified__ssh_execute({ + server: "easy", + command: "" +}) +``` + +--- + +## Workflow completo + +### Passo 1: Estado dos servicos (docker service ls) + +```bash +docker service ls --format "table {{.Name}}\t{{.Replicas}}\t{{.Image}}\t{{.Ports}}" +``` + +**Classificacao:** +- **OK** - Replicas X/X (todas activas) +- **DOWN** - Replicas 0/X (nenhuma activa) +- **WARN** - Replicas parciais ou servico sem replicas esperadas + +### Passo 2: Identificar servicos DOWN (0/N replicas) + +```bash +docker service ls --format "{{.Name}} {{.Replicas}}" | awk '$2 ~ /^0\//' +``` + +Para cada servico DOWN, obter logs: + +```bash +docker service logs --tail 10 --no-trunc 2>&1 +``` + +### Passo 3: Uso de recursos via API (preferido) + +```bash +TOKEN=$(cat /etc/easypanel/.api-token) + +# Stats do sistema — retorna estrutura aninhada +curl -s "http://localhost:3000/api/trpc/monitor.getSystemStats" \ + -H "Authorization: Bearer $TOKEN" +``` + +**Estrutura real da resposta (verificado 24-03-2026):** +```json +{ + "result": { + "data": { + "json": { + "uptime": 3118351.41, + "memInfo": { + "totalMemMb": 32096.51, + "usedMemMb": 16885.52, + "freeMemMb": 15210.99, + "usedMemPercentage": 52.61, + "freeMemPercentage": 47.39 + }, + "diskInfo": { + "totalGb": "192.7", + "usedGb": "89.7", + "freeGb": "103.0", + "usedPercentage": "46.5", + "freePercentage": "53.5" + }, + "cpuInfo": { + "usedPercentage": 13.65, + "count": 6, + "loadavg": [5.58, 6.34, 6.51] + }, + "network": { + "inputMb": 0, + "outputMb": 0 + } + } + } + } +} +``` + +**Campos a usar:** +- CPU: `cpuInfo.usedPercentage` +- RAM: `memInfo.usedMemPercentage` e `memInfo.usedMemMb` +- Disco: `diskInfo.usedPercentage` e `diskInfo.usedGb` + +**Fallback via SSH (se API indisponivel):** +```bash +docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.MemPerc}}\t{{.NetIO}}\t{{.BlockIO}}" +``` + +**Thresholds:** + +| Metrica | OK | WARN | CRITICAL | +|---------|-----|------|----------| +| CPU | <70% | 70-90% | >90% | +| RAM | <70% | 70-85% | >85% | +| RAM absoluto | <512MB | 512MB-1GB | >1GB | + +### Passo 4: Espaco em disco (via API ou fallback) + +Usar `diskInfo` da resposta do passo 3. Fallback: + +```bash +df -h / /var/lib/docker +``` + +**Thresholds:** + +| Disco | OK | WARN | CRITICAL | +|-------|-----|------|----------| +| / | <70% | 70-85% | >85% | +| /var/lib/docker | <70% | 70-85% | >85% | + +Verificar imagens Docker nao utilizadas: + +```bash +docker system df +``` + +### Passo 5: Logs de erros recentes (servicos com problemas) + +Para servicos DOWN ou WARN: + +```bash +docker service logs --tail 10 --no-trunc 2>&1 | grep -iE "error|fatal|panic|oom|killed|fail" +``` + +### Passo 6: Verificar tarefas falhadas + +```bash +docker service ls -q | xargs -I {} docker service ps {} --format "{{.Name}} {{.CurrentState}} {{.Error}}" --filter "desired-state=shutdown" 2>/dev/null | grep -i "failed\|rejected\|error" | head -20 +``` + +--- + +## Template de output + +```markdown +## EasyPanel Monitor - [DATA] + +**Servidor:** easy.descomplicar.pt (5.9.90.70) + +### Estado dos servicos + +| Servico | Replicas | Estado | CPU | RAM | Notas | +|---------|----------|--------|-----|-----|-------| +| descomplicar_api | 1/1 | OK | 2.3% | 128MB | - | +| descomplicar_n8n | 1/1 | OK | 5.1% | 256MB | - | +| descomplicar_db | 0/1 | DOWN | - | - | Connection refused | +| descomplicar_redis | 1/1 | WARN | 85% | 490MB | CPU elevado | + +**Resumo:** X/Y servicos OK | Z DOWN | W WARN + +### Disco + +| Mount | Usado | Disponivel | % | Estado | +|-------|-------|------------|---|--------| +| / | 45G | 55G | 45% | OK | +| /var/lib/docker | 30G | 70G | 30% | OK | + +Docker system: X imagens, Y containers, Z volumes ( \ No newline at end of file diff --git a/infraestrutura/skills/easypanel-rollback/SKILL.md b/infraestrutura/skills/easypanel-rollback/SKILL.md new file mode 100644 index 0000000..1f46dcd --- /dev/null +++ b/infraestrutura/skills/easypanel-rollback/SKILL.md @@ -0,0 +1,249 @@ +--- +name: easypanel-rollback +description: Rollback seguro de deployments EasyPanel para versões anteriores estáveis via API oficial. +disable-model-invocation: true +layer: wiki +--- + +# EasyPanel Rollback + +Rollback rápido e seguro para versões anteriores estáveis. + +## Quando Usar + +- Deploy falhou (health checks fail) +- Aplicação com erros em produção +- Rollback urgente necessário +- Testar versão anterior +- Recovery após incidente + +## Sintaxe + +```bash +/easypanel-rollback [--to-version ] [--auto] +``` + +## Exemplos + +```bash +# Rollback para versão anterior imediata +/easypanel-rollback dashboard-api + +# Rollback para tag específica +/easypanel-rollback dashboard-api --to-version v1.2.5 + +# Rollback automático (sem confirmação) +/easypanel-rollback dashboard-api --auto +``` + +## Workflow Completo + +### 1. List Recent Versions + +```bash +git log --oneline -n 10 +git tag --sort=-creatordate | head -n 10 +``` + +**Output:** +``` +v1.3.0 (current) ❌ FAILING - Health: 502 +v1.2.5 (previous) ✅ STABLE - Health: 200 OK, Uptime: 99.8% +v1.2.4 ✅ STABLE +v1.2.3 ✅ STABLE +``` + +**Metadata tracking:** +- Commit SHA +- Deploy timestamp +- Health status (last known) +- Uptime percentage (if tracked) +- Issue description (se falhou) + +### 2. Select Target Version + +**Strategies:** + +#### A. Interactive (default) +``` +➜ Rollback to: [2] v1.2.5 (recommended) + +Available versions: +1. v1.3.0 (current) ❌ FAILING +2. v1.2.5 (previous) ✅ STABLE (recommended) +3. v1.2.4 ✅ STABLE +4. v1.2.3 ✅ STABLE + +Enter number [2]: +``` + +#### B. Automatic (--auto) +``` +Last known good: v1.2.5 (health OK, deployed 2h ago) +Auto-selecting v1.2.5... +``` + +#### C. Specific (--to-version) +``` +Target version specified: v1.2.5 +Validating... +``` + +### 3. Confirm Rollback (se não --auto) + +``` +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +📋 ROLLBACK PLAN +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +Current: v1.3.0 (a3f5c21) - Port mismatch issue +Target: v1.2.5 (7d3a1f2) - Stable, 99.8% uptime + +Changes (diff): + - src/server.ts: PORT 8080 → 3000 + - docker-compose.yml: Traefik port fix + + Reverts 3 commits + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +Confirm rollback? [Y/n]: +``` + +### 4. Perform Rollback + +**Method A: Git Revert (small rollback, 1-3 commits)** +```bash +git revert --no-commit a3f5c21..HEAD +git commit -m "revert: rollback to v1.2.5 due to port mismatch" +``` + +**Method B: Git Checkout (large rollback, >3 commits)** +```bash +git checkout 7d3a1f2 +git checkout -b rollback-to-v1.2.5 +git push origin rollback-to-v1.2.5:main --force +``` + +### 5. Push & Redeploy + +```bash +git push origin main +``` + +**Via API (preferido - sincroniza com GUI):** +```bash +# Obter token +TOKEN=$(cat /etc/easypanel/.api-token) + +# Trigger deploy via API (redeployService NAO existe, usar deployService) +curl -s -X POST "http://localhost:3000/api/trpc/services.app.deployService" \ + -H "Authorization: Bearer $TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"json":{"projectName":"PROJECT","serviceName":"SERVICE"}}' +``` + +**Se CI/CD configurado:** +- Trigger automático via webhook +- Aguardar build (timeout 5min) + +### 6. Monitor Rollback + +```bash +# Poll EasyPanel deploy +docker service ps +docker service logs --tail 50 --follow +``` + +**Timeline:** +``` +[00:00] ✅ Git revert completed +[00:05] ✅ Push to Gitea +[01:45] ✅ EasyPanel build started +[03:20] ✅ Container started +[03:28] ✅ Health check: 200 OK +``` + +### 7. Validate Rollback + +#### Health Check (5 retries) +```bash +curl -f https://domain/health +``` + +**Expected:** 200 OK + +#### Logs Check +```bash +docker logs --tail 100 | grep -i error +``` + +**Expected:** No critical errors + +#### Metrics Check +```bash +docker stats --no-stream +``` + +**Expected:** +- CPU < 80% +- RAM < 80% +- No OOM kills + +### 8. Success Report + +``` +✅ ROLLBACK COMPLETE + +Total time: 3m 30s +Service restored: https://domain.descomplicar.pt +Health: ✅ 200 OK +Version: v1.2.5 (7d3a1f2) + +🛠️ NEXT STEPS +1. Investigate root cause: /easypanel-troubleshoot +2. Fix issues locally +3. Test fix: docker build + docker run +4. Redeploy: /easypanel-deploy +``` + +## Output Format (Success) + +``` +🔄 EasyPanel Rollback: dashboard-api + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +📜 AVAILABLE VERSIONS +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +1. v1.3.0 (current) ❌ FAILING + - Commit: a3f5c21 + - Deployed: 15min ago + - Health: 502 Bad Gateway + - Issue: Port mismatch + +2. v1.2.5 (previous) ✅ STABLE + - Commit: 7d3a1f2 + - Deployed: 2h ago + - Health: 200 OK (before upgrade) + - Uptime: 99.8% (last 7 days) + +3. v1.2.4 ✅ STABLE + - Commit: 9c4b3a1 + - Deployed: 1 day ago + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +➜ Rollback to: v1.2.5 (recommended) + +Confirm? [Y/n]: y + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +⏱️ ROLLBACK IN PROGRESS +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +[00:00] ✅ Git revert (a3f5c21 → 7d3a1f2) +[00:05] ✅ Commit rollback +[00:10] ✅ Push to Gitea +[01:45] ✅ EasyPanel redeploy started +[03:20] ✅ Container started +[03:28] ✅ Health \ No newline at end of file diff --git a/infraestrutura/skills/easypanel-troubleshoot/SKILL.md b/infraestrutura/skills/easypanel-troubleshoot/SKILL.md new file mode 100644 index 0000000..75e34b7 --- /dev/null +++ b/infraestrutura/skills/easypanel-troubleshoot/SKILL.md @@ -0,0 +1,205 @@ +--- +name: easypanel-troubleshoot +description: Diagnóstico automático de problemas de deploy no EasyPanel — análise de logs de containers, health endpoints, routing Traefik e recursos para identificar causas raiz. +layer: wiki +--- + +# EasyPanel Troubleshoot + +Diagnóstico automático e inteligente de problemas de deploy no EasyPanel. + +## Quando Usar + +- Deploy falhou com erros 502/503 +- Container em crash loop (restarts frequentes) +- Health endpoint não responde +- Problemas de routing Traefik +- Investigar causa de deploy falhado +- After deploy validation + +## Quando NÃO Usar + +- Para deploys iniciais (usar `/easypanel-init`) +- Para rollbacks de versão (usar `/easypanel-rollback`) +- Para validação pós-deploy bem-sucedido (usar `/easypanel-validate`) +- Quando o problema é conhecido e a solução já está identificada + +## Sintaxe + +```bash +/easypanel-troubleshoot [--verbose] +``` + +## Exemplos + +```bash +# Diagnóstico básico +/easypanel-troubleshoot dashboard-api + +# Diagnóstico detalhado (logs completos) +/easypanel-troubleshoot dashboard-api --verbose +``` + +## Workflow Automático + +### 1. Check Service Status via API + +```bash +# Obter token +TOKEN=$(cat /etc/easypanel/.api-token) + +# Inspeccionar serviço (estado completo) +curl -s "http://localhost:3000/api/trpc/services.app.inspectService?input=$(echo -n '{"json":{"projectName":"PROJECT","serviceName":"SERVICE"}}' | jq -sRr @uri)" \ + -H "Authorization: Bearer $TOKEN" | jq '.result.data.json' + +# Obter logs via API (namespace logs.*, NAO services.app.*) +curl -s "http://localhost:3000/api/trpc/logs.getServiceLogs?input=$(echo -n '{"json":{"projectName":"PROJECT","serviceName":"SERVICE","tail":100}}' | jq -sRr @uri)" \ + -H "Authorization: Bearer $TOKEN" +``` + +### 2. Fetch Logs (alternativa SSH) +```bash +docker logs --tail 100 +``` + +Parse de erros comuns: +- Port already in use (EADDRINUSE) +- Cannot find module (dependencies) +- Connection refused (database) +- Out of memory (OOM) +- Unhandled promise rejection +- Listen errors + +### 3. Check Health Endpoint +```bash +curl https:///health +``` +- Status code: 200, 404, 502, 503? +- Response time +- Response body validation + +### 4. Check Traefik Routing +- Traefik labels correctos? + - router.rule com domain + - service.loadbalancer.server.port + - entrypoints=websecure + - certresolver=letsencrypt +- Domain DNS aponta para servidor? +- SSL certificate válido? + +### 5. Check Port Mismatch +- Dockerfile EXPOSE vs app actual port +- docker-compose ports vs Traefik port +- App listening port (from logs) +- Common mismatch: 3000 vs 8080 + +### 6. Check Environment Variables +- Required vars set? (compare .env.example) +- Sensitive vars (DATABASE_URL, API_KEY) +- Missing vars causing app crash? + +### 7. Check Dependencies +- Database reachable? (if applicable) +- Redis reachable? (if applicable) +- External APIs responding? + +### 8. Check Resources +- CPU throttling? +- Memory limit reached (OOM)? +- Disk space? + +### 9. Generate Report +- Issues found (prioritized: CRITICAL, WARNING, INFO) +- Root cause (if detected) +- Recommended fixes (step-by-step) +- Commands to run + +## Error Pattern Detection + +### Port Mismatch +``` +Pattern: "listening on port X" + Traefik port Y +Fix: Update Dockerfile EXPOSE or Traefik label +``` + +### Missing Environment Variable +``` +Pattern: "is not defined" / "undefined" +Fix: Add variable to EasyPanel environment +``` + +### Crash Loop +``` +Pattern: Restart count > 3 in 10min +Fix: Check logs for root cause +``` + +### Database Connection +``` +Pattern: "ECONNREFUSED" / "Connection refused" +Fix: Verify DATABASE_URL and network connectivity +``` + +### Memory Issues +``` +Pattern: "out of memory" / "OOM killed" +Fix: Increase memory limit in docker-compose +``` + +## Output Format + +``` +🔍 EasyPanel Troubleshooting: + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +📊 SERVICE STATUS +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +Container: +Status: Running | Stopped | Restarting +Uptime: