---
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
---

# 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 <project-name> <domain> [--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
# Obter token
TOKEN=$(cat /etc/easypanel/.api-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":"PROJECT_NAME"}}'

# Criar serviço app
curl -s -X POST "http://localhost:3000/api/trpc/services.app.createService" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"json":{"projectName":"PROJECT_NAME","serviceName":"app"}}'

# Configurar dominio (namespace domains.*, NAO services.app.*)
curl -s -X POST "http://localhost:3000/api/trpc/domains.createDomain" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"json":{
    "id":"PROJECT_NAME-app",
    "https":true,
    "host":"DOMAIN",
    "path":"/",
    "middlewares":[],
    "certificateResolver":"letsencrypt",
    "wildcard":false,
    "destinationType":"service",
    "serviceDestination":{
      "protocol":"http",
      "port":3000,
      "path":"/",
      "projectName":"PROJECT_NAME",
      "serviceName":"app"
    }
  }}'

# Configurar Git source (params RAIZ, NAO dentro de source)
# Para repos Gitea privados, incluir token no URL
curl -s -X POST "http://localhost:3000/api/trpc/services.app.updateSourceGit" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"json":{
    "projectName":"PROJECT_NAME",
    "serviceName":"app",
    "repo":"https://ealmeida:GITEA_TOKEN@git.descomplicar.pt/ealmeida/REPO",
    "ref":"main",
    "path":"/"
  }}'
```

### 5. Push to Gitea (opcional)

```bash
# Criar repo via MCP Gitea
mcp__gitea__create_repo({
  name: PROJECT_NAME,
  private: false,
  auto_init: false
})

# Add remote and push
git remote add origin git@git.descomplicar.pt:ORG/PROJECT_NAME.git
git push -u origin main
```

### 6. Output Summary

```
✅ Project scaffolded: PROJECT_NAME

📁 Structure created:
   - Dockerfile (multi-stage, 3 layers, ~80MB final image)
   - docker-compose.yml (Traefik configured for DOMAIN)
   - Health endpoint: src/routes/health.ts
   - CI/CD: .gitea/workflows/deploy.yml
   - README.md (deploy guide + troubleshooting)

🔧 Configuration:
   - Domain: DOMAIN
   - Port: 3000
   - Node.js: 22-alpine
   - Health check: GET /health

📦 Next Steps:
   1. cd PROJECT_NAME
   2. npm install
   3. cp .env.example .env.local && edit .env.local
   4. npm run dev (test locally)
   5. git push origin main (trigger deploy)

📚 Documentation:
   - README.md: Quick start
   - Checklist: Use /easypanel-validate before deploy

🚀 EasyPanel Setup:
   1. Create service → Custom (Docker Compose)
   2. Connect repository: git.descomplicar.pt/ORG/PROJECT_NAME
   3. Set environment variables (copy from .env.example)
   4. Create webhook (for CI/CD)
   5. Deploy

⏱️ Estimated setup time: 5min (vs 30min manual)
```

## Database Support (--db)

### PostgreSQL

Adiciona ao docker-compose.yml:

```yaml
services:
  db:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_DB: ${DB_NAME}
      POSTGRES_USER: ${DB_USER}
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - traefik

volumes:
  postgres_data:
```

Adiciona a .env.example:
```
DATABASE_URL=postgresql://${DB_USER}:${DB_PASSWORD}@db:5432/${DB_NAME}
```

### MySQL

Similar ao PostgreSQL, usando `mysql:8-alpine`.

## Type Support (--type)

### nodejs (default)
- Node.js 22-alpine
- TypeScript + ESM
- tsx para dev
- Express boilerplate

### python (futuro)
- Python 3.12-alpine
- FastAPI boilerplate
- poetry para dependencies
- uvicorn para server

### go (futuro)
- Go 1.21-alpine
- Gin ou Echo boilerplate
- Multi-stage build (builder + runtime)
- Binário estático

## API Endpoints Usados

Ver skill `/easypanel-api` para documentação completa.

| Acção | Endpoint | Verificado |
|-------|----------|:----------:|
| Criar projecto | `POST projects.createProject` | Sim |
| Criar serviço | `POST services.app.createService` | Sim |
| Configurar dominio | `POST domains.createDomain` | Sim |
| Configurar Git source | `POST services.app.updateSourceGit` | Sim |
| Configurar GitHub source | `POST services.app.updateSourceGithub` | Sim |
| Deploy inicial | `POST services.app.deployService` | Sim |

**Endpoints que NAO existem:** `saveDomains`, `saveGithubSource` — usar `domains.createDomain` e `updateSourceGit`/`updateSourceGithub`.

## Validation

Após scaffold, executar automaticamente:
```bash
/easypanel-validate
```

Se score < 9/10, reportar issues.

## Templates Base

Usar templates de:
`/media/ealmeida/Dados/Dev/Docs/EasyPanel-Deploy-Research/`

- TEMPLATE_Dockerfile_NodeJS_MultiStage
- TEMPLATE_docker-compose.yml
- TEMPLATE_gitea-workflow-deploy.yml
- TEMPLATE_health-endpoint.ts

## Customização

User pode customizar após scaffold:
- Port (default 3000)
- Node version (default 22)
- Package manager (npm, pnpm, yarn)
- Framework (Express, Fastify, Koa)

## Checklist Execução

- [ ] Verificar nome projecto válido (lowercase, no spaces)
- [ ] Verificar domain válido (DNS format)
- [ ] Criar estrutura pastas
- [ ] Gerar Dockerfile multi-stage
- [ ] Gerar docker-compose.yml com Traefik labels
- [ ] Criar health endpoint
- [ ] Gerar .dockerignore
- [ ] Gerar .gitignore
- [ ] Gerar .env.example
- [ ] Criar package.json com scripts
- [ ] Gerar tsconfig.json (se TS)
- [ ] Criar CI/CD workflow
- [ ] Gerar README.md
- [ ] Git init
- [ ] Git commit inicial
- [ ] Executar /easypanel-validate
- [ ] Output summary com next steps

---

**Versão:** 1.0.0 | **Autor:** Descomplicar® | **Data:** 2026-02-04

## Metadata (Desk CRM Task #65)

```
Tarefa: SKL: /easypanel-init - Scaffold EasyPanel Project
Milestone: 294 (Skills Claude Code)
Tags: skill(79), stackworkflow(75), claude-code(81), activo(116)
Responsáveis: Emanuel(1), AikTop(25)
Status: 4 (Em progresso) → 5 (Concluído)
```

---

**/** @author Descomplicar® | @link descomplicar.pt | @copyright 2026 **/

---

## Healing Log

Registo de erros conhecidos e como evitá-los. Lido automaticamente antes de executar.

```jsonl
{"date":"","issue":"","fix":"","source":"user|auto"}
```

*Adicionar nova linha após cada erro corrigido.*
