Dify foi removido 06-03-2026. Skills brainstorm/discover ainda referenciam-no no corpo. Bump v1.2 + nota top-of-file. Reescrita workflow para próxima sessão. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
13 KiB
name, description
| name | description |
|---|---|
| easypanel-api | 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
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 |
# 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) |
# 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
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
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:
— dominios so via UI do EasyPanelservices.app.updateDomains— nao encontradoservices.app.updateMounts— nao encontradoservices.app.updatePorts
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 |
# Listar dominios
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 para servico
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"
}
}}'
Nota: O id pode ser qualquer string unica (cuid ou slug). O certificateResolver deve ser "letsencrypt" para HTTPS com certificado automatico, ou "" para dominios internos.
Monitor API
# 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
# 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
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:
#!/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
-
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. -
Sem suporte nativo a NFS/CIFS — O EasyPanel nao suporta drivers de volume remotos (NFS, CIFS, etc.) directamente via API. Para volumes partilhados, e necessario criar o volume Docker manualmente com o driver adequado e depois referencia-lo.
-
Permissões — Volumes criados via API pertencem a
root:rootpor defeito. Containers que correm com utilizador não-root podem ter problemas de permissões. Workaround: usarcommandnoupdateAdvancedpara corrigir permissões no arranque. -
Substituicao total — Mounts sao geridos via UI do EasyPanel. O endpoint
updateMountsNAO foi encontrado na versao instalada. Configurar mounts directamente na interface web.
Workarounds conhecidos
# 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
volumesobrebind— mais portável e compatível com Swarm - Usar
filepara 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
Seguranca
ATENCAO: services.app.inspectService retorna TODAS as variaveis de ambiente em texto limpo, incluindo passwords, tokens API e credenciais de base de dados. Nunca incluir output bruto de inspectService em reports, logs ou comentarios. Sanitizar sempre antes de mostrar ao utilizador.
Campos sensiveis tipicos no env: DB_PASS, API_TOKEN, SERVER_PASS, GATEWAY_PASS, EASYPANEL_API_TOKEN.
Anti-Patterns
| Anti-Pattern | Risco | Alternativa |
|---|---|---|
| Expor API externamente | Seguranca critica | Usar apenas via SSH localhost |
| Hardcode token | Leak de credenciais | Usar /etc/easypanel/.api-token |
| Nao validar response | Erros silenciosos | Verificar result.data.json |
POST sem Content-Type |
Request falha | Sempre incluir header |
| Mostrar output de inspectService | Expoe passwords em texto limpo | Sanitizar env vars |
Ficheiros de Referência
| Ficheiro | Conteúdo |
|---|---|
| references/services-api.md | Endpoints de servicos com curl completo (create, inspect, deploy, stop/start/restart, destroy) |
| references/service-config-api.md | Endpoints de configuracao (source, env, resources, build, deploy, domains, backup BD) |
Healing Log
Registo de erros conhecidos e como evitá-los. Lido automaticamente antes de executar.
{"date":"","issue":"","fix":"","source":"user|auto"}
Adicionar nova linha após cada erro corrigido.