Skip to content

marcelobt/easypanel-skill

Repository files navigation

easypanel-skill

Validate License: MIT Version SKILL.md Python 3.8+ Code style Skills compatible

Um skill no formato Agent Skills para gerenciar instâncias Easypanel via API tRPC — deploy, backup, migração, monitoring. Funciona em Claude Code, Claude.ai, Cursor, Codex CLI, Gemini CLI e outros agentes que suportam o padrão SKILL.md.

Documentação online: https://marcelobt.github.io/easypanel-skill/

O que faz

Capacidade Como
Sanity-check check.py valida URL+TOKEN+permissão+capacidade em 1 comando (exit codes consistentes)
Deploy / Restart / Stop curl direto na API tRPC, schemas documentados
Inspect Projects, services (todos os tipos), domains, monitoring (CPU/RAM/disco)
Backup de config backup_cli.py dump — snapshot JSON de todos os projetos/serviços/domínios/schedules
Restore de config backup_cli.py apply — recria do zero (com dry-run por padrão)
Migração entre instâncias migrate_cli.py plan — transformações (rename hosts/projetos, regenerar secrets, mapear storage providers)
Backup de dados API nativa do Easypanel (databaseBackups.* + volumeBackups.*) — documentado

Todos os procedures listados foram descobertos e validados contra uma instância real. Schemas são extraídos das respostas zod do servidor, não chutados.

Prompts que disparam o skill (Claude Code, Claude.ai etc.)

Use linguagem natural — o agente vai detectar o contexto e carregar o skill automaticamente:

Diagnóstico e monitoring

  • "verifica meu easypanel" / "está tudo ok no painel?" → roda check.py
  • "como está o servidor?" / "meu Easypanel tá com problema de memória?" → monitorOld.getSystemStats
  • "quem é o usuário deste token?" → auth.getUser
  • "liste meus projetos do painel" → projects.listProjects

Deploy e gestão de serviços

  • "deploya o chatwoot" → services.app.deployService no chatwoot
  • "reinicia o n8n do projeto X" → restartService
  • "para o serviço de teste" / "liga o serviço Y" → stop/startService
  • "qual a config atual do meu app api?" → inspectService
  • "adiciona DEBUG=true no env do chatwoot" → read-modify-write seguro do env
  • "muda a imagem do nginx pra 1.27" → updateSourceImage

Domínios

  • "adiciona o domínio app.minhaempresa.com no service web" → createDomain + setPrimaryDomain
  • "lista os domínios do projeto X" → listDomains
  • "remove esse domínio antigo" → deleteDomain (com confirmação)

Backup

  • "faz backup completo do painel" → backup_cli.py dump
  • "backup só pra commit no git (sem secrets)" → dump --mask-secrets
  • "compara meu backup de ontem com o estado atual" → backup_cli.py diff
  • "o que mudou desde o último backup?" → idem
  • "setup um cron de backup diário" → ajuda com /etc/cron.daily/...

Migração

  • "clona meu prod pra criar um staging" → migrate_cli.py plan com renames + apply
  • "migra esse projeto pro servidor novo na hetzner" → fluxo completo source→plan→apply→deploy
  • "compara source e target depois da migração" → migrate_cli.py compare
  • "undo essa migração" → migrate_cli.py undo (destrói projetos criados)
  • "gera um plano de migração com hosts e secrets novos" → plan + transformações

Bancos de dados

  • "qual a senha do meu postgres do chatwoot?" → services.postgres.inspectService (sensível!)
  • "expõe o postgres na porta 5432" → exposeService
  • "habilita o pgWeb pro banco X" → enablePgWeb
  • "agenda backup diário do banco às 2h" → createDatabaseBackup schedule
  • "roda backup do banco agora" → runDatabaseBackup
  • "restaura o backup mais recente do postgres" → restoreDatabaseBackup

Diagnóstico de problemas

  • "meu chatwoot não está subindo, o que tem de errado?" → getServiceError + actions.listActions
  • "quais foram os últimos 10 deploys?" → actions.listActions
  • "cancela essa ação em andamento" → actions.killAction

Instalação rápida

Claude Code (pessoal)

git clone https://github.com/marcelobt/easypanel-skill.git
cd easypanel-skill
make install        # copia easypanel/ pra ~/.claude/skills/

Claude Code (projeto)

cd seu-projeto
git submodule add https://github.com/marcelobt/easypanel-skill.git .claude/skill-source
ln -s skill-source/easypanel .claude/skills/easypanel
git commit -am "Add easypanel skill"

Outras opções: make help lista todos os targets. Veja easypanel/INSTALL.md para Cursor, Codex, Gemini, OpenClaw e Claude.ai.

Quickstart

export EASYPANEL_URL='https://painel.exemplo.com'
export EASYPANEL_TOKEN='<token-de-Settings-API>'

# Sanity-check (exit 0 = ok)
python3 ~/.claude/skills/easypanel/references/check.py

# Backup completo de config
python3 ~/.claude/skills/easypanel/references/backup_cli.py dump -o backup-$(date +%Y%m%d).json

# Comparar backup com estado atual
python3 ~/.claude/skills/easypanel/references/backup_cli.py diff backup-*.json

# Restaurar config (dry-run por padrão)
python3 ~/.claude/skills/easypanel/references/backup_cli.py apply backup.json
python3 ~/.claude/skills/easypanel/references/backup_cli.py apply backup.json --confirm

Dentro do Claude Code, basta usar os prompts listados acima — o agente carrega o skill automaticamente.

Estrutura

easypanel/                       # o skill em si (esse folder vai pra ~/.claude/skills/)
├── SKILL.md                     # entry point, instruções pro agente
├── INSTALL.md                   # como instalar em cada plataforma
└── references/
    ├── check.py                 # sanity-check (sempre rode primeiro)
    ├── backup_cli.py            # dump/list/diff/apply de config (--json supported)
    ├── migrate_cli.py           # plan/compare/deploy-all/undo (--json supported)
    ├── safe_update.py           # wrapper Python pra writes seguros
    ├── backup_restore.md        # guia completo de backup
    ├── migration.md             # guia de migração server-to-server
    ├── operations.md            # receitas curl pra ops comuns
    └── probe_schemas.md         # como descobrir endpoints novos (seguro!)

Exit codes (todos os CLIs)

Code Significado
0 OK
1 Erro genérico
2 Auth (token inválido/expirado)
3 Network (servidor inalcançável)
4 Validação (input/schema)
5 Setup faltando (env vars)

Modo machine-readable

Comandos de leitura suportam --json pra encadear via jq:

# Está saudável?
python3 references/check.py --json | jq -e '.exit_code == 0'

# Quantos serviços tem o backup?
python3 references/backup_cli.py list backup.json --json | jq '.totals.services'

# Tem divergências entre backup e prod?
python3 references/backup_cli.py diff backup.json --json | jq '.diff_count'

⚠� Aviso crítico — mutations no Easypanel são PUT-like

Esse é o achado mais importante do skill (descoberto na pior maneira possível):

Quase todas as mutations update* aceitam input mínimo (apenas projectName+serviceName) e silenciosamente APAGAM/RESETAM os campos não fornecidos.

Exemplos práticos:

  • services.app.updateEnv sem env → env vai pra string vazia
  • services.app.updateDeploy sem deploy: {command, replicas, ...} → command/replicas viram null
  • services.app.updateSourceImage substitui qualquer source anterior (image, github, dockerfile)

Por isso o skill nunca prova mutations com input dummy em produção. O padrão sempre é:

  1. inspectService → lê o estado completo
  2. Modifica apenas o que precisa mudar
  3. Envia tudo (incluindo o que não mudou) na mutation

Veja easypanel/references/safe_update.py para um wrapper que aplica esse padrão automaticamente.

Design decisions

  • Stdlib-only: nenhum pip install. Tudo roda só com Python 3.8+ stdlib + curl. Skills devem ser portáteis.
  • Read-modify-write em todas as mutations: nunca envia parcial.
  • Dry-run por padrão: apply só executa com --confirm explícito.
  • Exit codes consistentes: pra Claude Code (ou bash scripts) distinguir auth-fail vs network-fail vs validation-fail.
  • $CLAUDE_SKILL_DIR: scripts referenciados resolvem path corretamente em qualquer scope (personal, project, plugin).
  • Schemas validados: todo schema neste skill veio de um servidor real, não de adivinhação. Onde os docs oficiais são silentes, eu li o bundle JS do painel.

Limitações conhecidas

  1. Mounts não são restauráveis via API — não há updateMounts exposto na API tRPC.
  2. Deploy tokens regeneram em qualquer apply/restore — CI/CD precisa do novo URL.
  3. Storage provider IDs são por-servidor — use --map-storage em migrações.
  4. Restore de volume não tem endpoint API — precisa SSH/Docker direto.
  5. metrics.* opcional — requer setup de Prometheus; o skill usa monitorOld.* por padrão.

Veja easypanel/references/migration.md para a lista completa.

Examples

Em examples/ você encontra outputs sintéticos (sanitizados) dos comandos:

Empacotando o skill (pra distribuir)

make package        # gera easypanel.skill (zip)

Releases automáticos: criar uma tag vX.Y.Z dispara o workflow que builda o .skill e cria um release no GitHub com ele anexado:

git tag -a v0.2.0 -m "Add feature X"
git push origin v0.2.0

CI / Validação

GitHub Actions roda em cada push:

  • Valida frontmatter YAML do SKILL.md
  • Checa consistência VERSION ↔ frontmatter
  • Lint Python (py_compile)
  • Smoke tests (check.py offline, --help dos CLIs)
  • Build do .skill e upload como artifact
  • Em tags v*: cria release com o .skill anexado
  • Em push pra main: republica o GitHub Pages

Veja .github/workflows/validate.yml.

Contribuindo

PRs bem-vindos. �reas onde ajuda seria útil:

  • Mais exemplos de uso real (cron de backup, GitOps deploy)
  • Endpoints ainda não cobertos (services.compose.*, services.wordpress.* plugins/themes)
  • Tradução do SKILL.md pra inglês
  • Testes automatizados contra uma instância de teste

Veja CONTRIBUTING.md.

Changelog

Veja CHANGELOG.md.

License

MIT. Veja LICENSE.

Reconhecimentos

Esse projeto é uma engenharia reversa amigável da API tRPC interna do Easypanel. Não é afiliado ao projeto Easypanel oficial.

About

Skill para gerenciar Easypanel via Claude Code, Claude.ai, Cursor e outros agentes

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors