--- 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 [--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 domínio curl -s -X POST "http://localhost:3000/api/trpc/services.app.saveDomains" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"json":{"projectName":"PROJECT_NAME","serviceName":"app","domains":[{"host":"DOMAIN"}]}}' # Configurar Git source curl -s -X POST "http://localhost:3000/api/trpc/services.app.saveGithubSource" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"json":{"projectName":"PROJECT_NAME","serviceName":"app","owner":"ORG","repo":"REPO","ref":"refs/heads/main","autoDeploy":true}}' ``` ### 5. Optional: Push to Gitea ```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 ``` ### 5. 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 | |-------|----------| | Criar projecto | `POST projects.createProject` | | Criar serviço | `POST services.app.createService` | | Configurar domínio | `POST services.app.saveDomains` | | Configurar Git source | `POST services.app.saveGithubSource` | | Deploy inicial | `POST services.app.deployService` | ## 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 **/ --- ## Quando NÃO Usar - Para tarefas fora do domínio de especialização desta skill - Quando outra skill mais específica está disponível - Para operações que requerem confirmação manual do utilizador