Files
Emanuel Almeida 6b3a6f2698 feat: refactor 30+ skills to Anthropic progressive disclosure pattern
- All SKILL.md files now <500 lines (avg reduction 69%)
- Detailed content extracted to references/ subdirectories
- Frontmatter standardised: only name + description (Anthropic standard)
- New skills: brand-guidelines, spec-coauthor, report-templates, skill-creator
- Design skills: anti-slop guidelines, premium-proposals reference
- Removed non-standard frontmatter fields (triggers, version, author, category)

Plugins affected: infraestrutura, marketing, dev-tools, crm-ops, gestao,
core-tools, negocio, perfex-dev, wordpress, design-media

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 15:05:03 +00:00

279 lines
10 KiB
Markdown

---
name: easypanel-api
description: Referência completa da API tRPC oficial do EasyPanel — todos os endpoints para projectos, serviços, deploy e configurações.
---
# /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)
| 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.enableService` | POST | Activar serviço |
| `services.app.disableService` | POST | Desactivar serviço |
| `services.app.destroyService` | POST | Destruir serviço |
**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)
| Endpoint | Descrição |
|----------|-----------|
| `services.app.updateSourceGithub` | Source GitHub (`owner`, `repo`, `ref`, `path`) |
| `services.app.updateSourceGit` | Source Git custom (`repo`, `ref`, `path`) |
| `services.app.updateSourceImage` | Source Docker image (`image`) |
| `services.app.updateEnv` | Variáveis de ambiente (`env` como string multi-linha) |
| `services.app.updateDomains` | Domínios (`domains[]` com `host`, `https`, `port`) |
| `services.app.updateMounts` | Volumes (`mounts[]` com `type`, `name`, `mountPath`) |
| `services.app.updatePorts` | Portas TCP/UDP (`ports[]` com `published`, `target`, `protocol`) |
| `services.app.updateResources` | CPU/RAM (`memoryLimit`, `cpuLimit`, etc.) |
| `services.app.updateBuild` | Build config (`type`, `buildCommand`, `startCommand`) |
| `services.app.updateAdvanced` | Deploy avançado (`replicas`, `command`, `zeroDowntime`) |
| `services.postgres.updateBackup` | Backup BD para S3 |
---
## Monitor API
```bash
# Stats do sistema
curl -s "http://localhost:3000/api/trpc/monitor.getSystemStats" \
-H "Authorization: Bearer $TOKEN"
# Stats de serviço (URL encode necessário)
# input: {"json":{"projectName":"descomplicar","serviceName":"api"}}
curl -s "http://localhost:3000/api/trpc/monitor.getServiceStats?input=..." \
-H "Authorization: Bearer $TOKEN"
# Stats Docker tasks
curl -s "http://localhost:3000/api/trpc/monitor.getDockerTaskStats" \
-H "Authorization: Bearer $TOKEN"
```
---
## Logs API
```bash
# Logs de serviço (tail=100)
# input: {"json":{"projectName":"descomplicar","serviceName":"api","tail":100}}
curl -s "http://localhost:3000/api/trpc/logs.getServiceLogs?input=..." \
-H "Authorization: Bearer $TOKEN"
```
---
## Settings API
| Endpoint | Tipo | Descrição |
|----------|------|-----------|
| `settings.getServerIp` | GET | IP do servidor |
| `settings.getPanelDomain` | GET | Domínio do painel |
| `settings.setPanelDomain` | POST | Definir domínio (`domain`) |
| `settings.getLetsEncryptEmail` | GET | Email Let's Encrypt |
| `settings.setLetsEncryptEmail` | POST | Definir email (`email`) |
| `settings.restartTraefik` | POST | Reiniciar Traefik |
| `settings.restartEasypanel` | POST | Reiniciar EasyPanel |
| `settings.pruneDockerImages` | POST | Limpar imagens Docker |
---
## URL Encoding para GET
```bash
INPUT='{"json":{"projectName":"descomplicar","serviceName":"api"}}'
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"
```
---
## Wrapper Script
Criar `/usr/local/bin/easypanel-api`:
```bash
#!/bin/bash
TOKEN=$(cat /etc/easypanel/.api-token)
BASE="http://localhost:3000/api/trpc"
if [ -z "$2" ]; then
curl -s "$BASE/$1" -H "Authorization: Bearer $TOKEN"
else
curl -s -X POST "$BASE/$1" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "$2"
fi
```
Uso: `easypanel-api projects.listProjects`
---
## Checklist de Uso
- [ ] SSH para servidor `easy`
- [ ] `TOKEN=$(cat /etc/easypanel/.api-token)`
- [ ] Testar: `curl -s ".../projects.listProjects" -H "Authorization: Bearer $TOKEN"`
- [ ] Usar endpoints conforme documentado
- [ ] Validar resposta em `result.data.json`
---
## Limitações de Mounts
O EasyPanel usa Docker Swarm internamente. Isto impõe limitações nos mounts que diferem do Docker standalone.
### Tipos de mount suportados
| Tipo | API `type` | Comportamento | Limitações |
|------|-----------|---------------|------------|
| **Volume mount** | `volume` | Volume gerido pelo Docker Swarm | Funciona bem. Dados persistem no nó. Sem acesso directo ao filesystem do host |
| **Bind mount** | `bind` | Monta directório do host no container | **Limitado no Swarm** — só funciona se o serviço estiver fixo a um nó específico |
| **File mount** | `file` | Monta ficheiro individual (config) | Funciona. Ideal para ficheiros de configuração |
### Limitações críticas
1. **Bind mounts no Swarm** — O Docker Swarm não garante que o container corra sempre no mesmo nó. Um bind mount (`type: "bind"`) aponta para um path no host, mas se o container migrar para outro nó, esse path pode não existir. O EasyPanel mitiga isto parcialmente por correr num único nó, mas a limitação arquitectural mantém-se.
2. **Sem suporte nativo a NFS/CIFS** — A API `updateMounts` não suporta drivers de volume remotos (NFS, CIFS, etc.) directamente. Para volumes partilhados, é necessário criar o volume Docker manualmente com o driver adequado e depois referenciá-lo.
3. **Permissões** — Volumes criados via API pertencem a `root:root` por defeito. Containers que correm com utilizador não-root podem ter problemas de permissões. Workaround: usar `command` no `updateAdvanced` para corrigir permissões no arranque.
4. **Substituição total**`updateMounts` substitui **todos** os mounts existentes. Para adicionar um mount, é preciso primeiro obter os mounts actuais via `inspectService` e enviar a lista completa com o novo mount incluído.
### Workarounds conhecidos
```bash
# 1. Obter mounts actuais antes de adicionar novo
INSPECT=$(curl -s "http://localhost:3000/api/trpc/services.app.inspectService?input=..." \
-H "Authorization: Bearer $TOKEN")
# Extrair mounts existentes do JSON e adicionar o novo
# 2. Volume com permissões corrigidas — usar initCommand
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":{
"command":"chown -R 1000:1000 /app/data && node dist/index.js"
}
}}'
# 3. Volume Docker manual com driver NFS (fora da API)
docker volume create --driver local \
--opt type=nfs \
--opt o=addr=192.168.1.10,rw \
--opt device=:/export/data \
vol-nfs-data
# Depois referenciar na API:
# {"type":"volume","name":"vol-nfs-data","mountPath":"/app/data"}
```
### Recomendações
- **Preferir `volume`** sobre `bind` — mais portável e compatível com Swarm
- **Usar `file`** para configs individuais (nginx.conf, .env, etc.)
- **Inspeccionar antes de actualizar** — a API substitui a lista inteira de mounts
- **Documentar volumes manuais** — volumes criados fora da API não aparecem no painel EasyPanel até serem referenciados por um serviço
---
## Anti-Patterns
| Anti-Pattern | Risco | Alternativa |
|--------------|-------|-------------|
| Expor API externamente | Segurança crítica | Usar apenas via SSH localhost |
| Hardcode token | Leak de credenciais | Usar `/etc/easypanel/.api-token` |
| Não validar response | Erros silenciosos | Verificar `result.data.json` |
| POST sem `Content-Type` | Request falha | Sempre incluir header |
---
## Ficheiros de Referência
| Ficheiro | Conteúdo |
|----------|----------|
| [references/services-api.md](references/services-api.md) | Endpoints de serviços com curl completo (create, inspect, deploy, enable/disable, destroy) |
| [references/service-config-api.md](references/service-config-api.md) | Endpoints de configuração (source, env, domains, mounts, ports, resources, build, deploy, backup BD) |