Files
dealplustech/skills/easypanel-deploy/SKILL.md
Kunthawat Greethong 45961b8d76 refactor: Move Astro project to root directory
- Move all Astro files from dealplustech-astro/ to root
- Archive Next.js code in _nextjs-backup/
- Update .gitignore for Astro project
- Simplify project structure

This completes the migration from Next.js to Astro.
The Astro project is now at the root level.
2026-03-03 10:21:42 +07:00

12 KiB

🚀 Easypanel Deployment Skill

Skill ID: easypanel-deploy
Version: 2.0.0
Author: Deal Plus Tech DevOps
Last Updated: 2026-03-02


Overview

Automated deployment skill for deploying Astro, Next.js, Vite, and other web applications to Easypanel via API.


🔐 Authentication Setup

Store Your API Token

Option 1: Environment Variable (Recommended)

Add to your shell profile (~/.zshrc, ~/.bashrc, or ~/.profile):

export EASYPANEL_API_TOKEN="your-api-token-here"
export EASYPANEL_URL="http://110.164.146.46:3000"

Then reload:

source ~/.zshrc  # or source ~/.bashrc

Option 2: Credential File

Create ~/.easypanel/credentials:

mkdir -p ~/.easypanel
cat > ~/.easypanel/credentials << EOF
EASYPANEL_URL=http://110.164.146.46:3000
EASYPANEL_API_TOKEN=your-api-token-here
EASYPANEL_DEFAULT_PROJECT=default
EOF

chmod 600 ~/.easypanel/credentials

Option 3: Pass Token Directly

./deploy-easypanel.sh your-api-token

📋 Configuration File

Create easypanel.config.json in your project root:

{
  "easypanel": {
    "url": "http://110.164.146.46:3000",
    "project": "dealplustech",
    "app": {
      "name": "dealplustech-astro",
      "port": 4321,
      "image": "dealplustech-astro:latest"
    },
    "env": {
      "NODE_ENV": "production",
      "PORT": "4321",
      "HOST": "0.0.0.0"
    },
    "docker": {
      "context": ".",
      "dockerfile": "Dockerfile",
      "buildArgs": {}
    },
    "resources": {
      "cpu": "0.5",
      "memory": "512M",
      "storage": "1G"
    },
    "domain": {
      "enabled": false,
      "name": "dealplustech.co.th",
      "ssl": true
    }
  }
}

🎯 Usage

Quick Deploy

# Navigate to project
cd your-project

# Run deployment (uses token from environment)
easypanel-deploy

# Or pass token directly
easypanel-deploy --token your-api-token

Interactive Mode

easypanel-deploy --interactive

Deploy Specific Environment

easypanel-deploy --environment production
easypanel-deploy --environment staging

🔧 Commands

deploy - Deploy Application

easypanel-deploy deploy

# Options:
#   --token, -t     API token (or use EASYPANEL_API_TOKEN env)
#   --project, -p   Project name
#   --name, -n      Service name
#   --image, -i     Docker image
#   --port, -P      Container port
#   --env, -e       Environment variables (key=value)
#   --build         Force rebuild Docker image
#   --no-build      Skip Docker build
#   --dry-run       Show what would be deployed

status - Check Deployment Status

easypanel-deploy status

# Shows:
# - Service status (running/stopped/error)
# - Resource usage
# - Recent deployments
# - Exposed URLs

logs - View Service Logs

easypanel-deploy logs

# Options:
#   --lines, -n     Number of lines (default: 50)
#   --follow, -f    Follow logs in real-time
#   --since         Show logs since timestamp

restart - Restart Service

easypanel-deploy restart

stop - Stop Service

easypanel-deploy stop

delete - Delete Service

easypanel-deploy delete --force  # Force delete without confirmation

list - List All Services

easypanel-deploy list

# Options:
#   --project, -p   Filter by project
#   --format, -f    Output format (table/json)

info - Show Service Details

easypanel-deploy info

# Shows:
# - Configuration
# - Environment variables
# - Resource allocation
# - Deployment history

📁 Project Structure

your-project/
├── Dockerfile              # Required
├── easypanel.config.json   # Optional (uses defaults if missing)
├── .env                    # Optional (loaded as env vars)
├── .dockerignore           # Optional
└── deploy-easypanel.sh     # Deployment script (included in skill)

🔒 Security Best Practices

Token Storage

DO:

  • Use environment variables
  • Store in credential manager (1Password, Keychain)
  • Use .env files (gitignored)
  • Rotate tokens regularly

DON'T:

  • Commit tokens to Git
  • Share tokens in chat/clear text
  • Use tokens in CI/CD logs
  • Store in plain text files

Token Rotation

# Generate new token in Easypanel dashboard
# Update environment variable
export EASYPANEL_API_TOKEN="new-token"

# Test new token
easypanel-deploy status

# Revoke old token in Easypanel dashboard

🐳 Docker Configuration

Standard Dockerfile (Astro)

# Build Stage
FROM node:20-alpine AS builder

WORKDIR /app

COPY package*.json ./
RUN npm ci

COPY . .
RUN npm run build

# Production Stage
FROM node:20-alpine

WORKDIR /app

COPY package*.json ./
RUN npm ci --production

COPY --from=builder /app/dist ./dist
COPY --from=builder /app/public ./public

EXPOSE 4321

CMD ["npx", "astro", "preview", "--host", "0.0.0.0", "--port", "4321"]

Next.js Dockerfile

FROM node:20-alpine AS builder

WORKDIR /app

COPY package*.json ./
RUN npm ci

COPY . .
RUN npm run build

FROM node:20-alpine

WORKDIR /app

COPY package*.json ./
RUN npm ci --production

COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
COPY --from=builder /app/public ./public

EXPOSE 3000

ENV NODE_ENV=production
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"

CMD ["node", "server.js"]

Vite Dockerfile

FROM node:20-alpine AS builder

WORKDIR /app

COPY package*.json ./
RUN npm ci

COPY . .
RUN npm run build

FROM nginx:alpine

COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]

⚙️ Configuration Reference

easypanel.config.json

Property Type Default Description
easypanel.url string http://110.164.146.46:3000 Easypanel instance URL
easypanel.project string default Project name
easypanel.app.name string Project folder name Service name
easypanel.app.port number 3000 Container port
easypanel.app.image string {name}:latest Docker image name
easypanel.env object {} Environment variables
easypanel.docker.context string . Docker build context
easypanel.docker.dockerfile string Dockerfile Dockerfile path
easypanel.resources.cpu string "0.5" CPU allocation
easypanel.resources.memory string "512M" Memory allocation
easypanel.resources.storage string "1G" Storage allocation
easypanel.domain.enabled boolean false Enable custom domain
easypanel.domain.name string "" Custom domain name
easypanel.domain.ssl boolean true Enable SSL

🔍 Troubleshooting

API Connection Failed

# Test connection
curl -I http://110.164.146.46:3000

# Check if token is set
echo $EASYPANEL_API_TOKEN

# Test API with token
curl -H "Authorization: Bearer $EASYPANEL_API_TOKEN" \
  http://110.164.146.46:3000/api/trpc/setup.getStatus \
  --insecure

Docker Build Fails

# Build with verbose output
docker build --no-cache --progress=plain -t your-image:latest .

# Check Dockerfile syntax
hadolint Dockerfile

# Test build locally
docker run -p 4321:4321 your-image:latest

Service Won't Start

# Check logs
easypanel-deploy logs --lines 100

# Inspect service
easypanel-deploy info

# Restart service
easypanel-deploy restart

# Check resource allocation
easypanel-deploy info | grep -A 10 "Resources"

Token Expired/Invalid

# Generate new token in Easypanel dashboard
# Update environment variable
export EASYPANEL_API_TOKEN="new-token"

# Add to shell profile for persistence
echo 'export EASYPANEL_API_TOKEN="new-token"' >> ~/.zshrc
source ~/.zshrc

# Verify
easypanel-deploy status

📊 Monitoring

Check Service Health

easypanel-deploy status

# Output:
# ✅ Service: dealplustech-astro
#    Status: Running
#    Uptime: 2 days, 4 hours
#    CPU: 12%
#    Memory: 256MB / 512MB
#    URL: http://dealplustech-astro.easypanel.app

View Metrics

easypanel-deploy metrics

# Shows:
# - CPU usage over time
# - Memory usage
# - Network traffic
# - Request count

Setup Alerts

easypanel-deploy alert --cpu 80 --memory 80 --email admin@example.com

🔄 CI/CD Integration

GitHub Actions

name: Deploy to Easypanel

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    
    steps:
      - uses: actions/checkout@v3
      
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '20'
      
      - name: Install dependencies
        run: npm ci
      
      - name: Build
        run: npm run build
      
      - name: Build Docker image
        run: docker build -t dealplustech-astro:latest .
      
      - name: Deploy to Easypanel
        run: |
          curl -X POST "$EASYPANEL_URL/api/trpc/services.app.deploy" \
            -H "Content-Type: application/json" \
            -H "Authorization: Bearer $EASYPANEL_API_TOKEN" \
            -d '{"input":{"json":{"projectName":"dealplustech","serviceName":"dealplustech-astro"}}}' \
            --insecure
        env:
          EASYPANEL_URL: ${{ secrets.EASYPANEL_URL }}
          EASYPANEL_API_TOKEN: ${{ secrets.EASYPANEL_API_TOKEN }}

GitLab CI

deploy:
  stage: deploy
  image: docker:20
  services:
    - docker:20-dind
  
  script:
    - docker build -t dealplustech-astro:latest .
    - docker push $CI_REGISTRY_IMAGE:latest
    - |
      curl -X POST "$EASYPANEL_URL/api/trpc/services.app.deploy" \
        -H "Authorization: Bearer $EASYPANEL_API_TOKEN" \
        -d '{"input":{"json":{"projectName":"dealplustech","serviceName":"dealplustech-astro"}}}' \
        --insecure
  
  only:
    - main

📞 Support & Resources

Documentation

Getting Help

  1. Check troubleshooting section
  2. Review service logs: easypanel-deploy logs
  3. Check Easypanel dashboard
  4. Contact DevOps team

🎓 Examples

Deploy Astro Project

cd astro-project
easypanel-deploy deploy \
  --project dealplustech \
  --name my-astro-site \
  --port 4321

Deploy Next.js Project

cd nextjs-project
easypanel-deploy deploy \
  --project dealplustech \
  --name my-next-app \
  --port 3000 \
  --env NODE_ENV=production \
  --env NEXT_PUBLIC_API_URL=https://api.example.com

Deploy Vite Project

cd vite-project
easypanel-deploy deploy \
  --project dealplustech \
  --name my-vite-app \
  --port 80 \
  --image nginx:alpine

Multi-Environment Setup

# Deploy to staging
easypanel-deploy deploy \
  --project dealplustech \
  --name my-app-staging \
  --env NODE_ENV=staging \
  --env DATABASE_URL=staging-db-url

# Deploy to production
easypanel-deploy deploy \
  --project dealplustech \
  --name my-app-production \
  --env NODE_ENV=production \
  --env DATABASE_URL=production-db-url

Checklist for New Projects

  • Create Dockerfile for project
  • Add easypanel.config.json (optional)
  • Set EASYPANEL_API_TOKEN environment variable
  • Test local Docker build: docker build -t test:latest .
  • Test locally: docker run -p 4321:4321 test:latest
  • Deploy: easypanel-deploy deploy
  • Verify: easypanel-deploy status
  • Setup custom domain (optional)
  • Enable SSL (optional)
  • Configure monitoring/alerts

Skill Version: 2.0.0
Last Updated: 2026-03-02
Status: Production Ready
API Version: Easypanel 2.24.0