A production-ready distributed computing platform that transforms idle workstations into a coordinated network of worker nodes. Designed for teams needing to distribute computational tasks across available hardware without complex infrastructure.
- Overview
- Quick Start
- Architecture
- Installation
- Usage
- API Reference
- Configuration
- Deployment
- Troubleshooting
CMD Executor is a distributed command execution system consisting of:
- Central Server (Next.js) - Web UI, job orchestration, worker management
- Worker Agents (Node.js) - Execute tasks on remote machines
- Web Interface (React) - Submit commands, monitor progress, view results
✅ Distributed Execution - Commands run on remote workers, not the server
✅ Auto-Registration - Workers register automatically with persistent IDs
✅ Health Monitoring - Real-time heartbeat detection
✅ Job Queue - FIFO job assignment with fair distribution
✅ File Transfer - ZIP upload support for project dependencies
✅ Real-time Output - Stream stdout/stderr as jobs execute
✅ Persistent Storage - MongoDB for jobs and results
✅ Caching Layer - Redis for performance
✅ Authentication - JWT + HMAC token support
✅ Cross-Platform - Windows, macOS, Linux support
- Build Distribution - Distribute compilation across multiple machines
- Test Execution - Run test suites in parallel
- Batch Processing - Process large datasets across available hardware
- Resource Optimization - Leverage idle workstations
- CI/CD Integration - Distributed job execution for pipelines
- Node.js 18.x or higher
- npm or yarn
- MongoDB (local or remote)
- Redis (optional, for caching)
git clone <repo-url>
cd cmd-executor
npm installCreate .env.local:
# Database
MONGODB_URI=mongodb://localhost:27017
MONGODB_DB=cmd_executor
# Redis (optional)
REDIS_URL=redis://localhost:6379
# Security
JWT_SECRET=your-random-secret-key-here
WORKER_TOKEN_SECRET=another-secret-key
JWT_EXPIRES_IN=24h
# CORS
ALLOWED_ORIGINS=http://localhost:3000,http://localhost:3001npm run dev
# Server runs on http://localhost:3000node worker-agent.js --server http://localhost:3000
# Worker registers and waits for jobs- Open
http://localhost:3000 - Click "Distributed" mode
- Upload a ZIP file with your project
- Enter command:
npm testornpm run build - Click "Execute"
- View real-time results
┌─────────────────────────────────────────────────────────────────────┐
│ WEB INTERFACE (React) │
│ ┌──────────────┬──────────────┬──────────────┬──────────────────┐ │
│ │ File Upload │ Command Form │ Job Status │ Real-time Output │ │
│ │ (ZIP files) │ (Direct Mode)│ (Polling) │ (WebSocket) │ │
│ └──────────────┴──────────────┴──────────────┴──────────────────┘ │
└────────────────────┬────────────────────────────────────────────────┘
│
┌────▼────────────────────────────────────────┐
│ CENTRAL SERVER (Next.js + Express) │
├───────────────────────────────────────────┤
│ • Worker Registry & Management │
│ • Job Queue & Assignment │
│ • File Storage (Uploaded ZIPs) │
│ • Result Aggregation │
│ • Authentication & Rate Limiting │
│ • Real-time Output Streaming │
└────┬──────────────────────────────────────┘
│
┌────────────┼────────────┐
│ │ │
┌────▼────┐ ┌───▼─────┐ ┌──▼───────┐
│MongoDB │ │ Redis │ │ File │
│(Jobs) │ │(Cache) │ │ Storage │
│(Results)│ │ │ │(Uploads) │
└─────────┘ └─────────┘ └──────────┘
│
│ HTTP (Pull Model)
│
┌────┴───────────────────────────────────────┐
│ WORKER AGENTS (Node.js) │
│ ┌──────────────────────────────────────┐ │
│ │ Machine 1: Windows [Idle] │ │
│ │ • Auto-register on startup │ │
│ │ • Poll for jobs every 5s │ │
│ │ • Execute commands │ │
│ │ • Stream output back to server │ │
│ │ • Cleanup temp files │ │
│ └──────────────────────────────────────┘ │
│ ┌──────────────────────────────────────┐ │
│ │ Machine 2: macOS [Busy] │ │
│ │ • Processing job from queue │ │
│ └──────────────────────────────────────┘ │
│ ┌──────────────────────────────────────┐ │
│ │ Machine 3: Linux [Idle] │ │
│ │ • Waiting for assignments │ │
│ └──────────────────────────────────────┘ │
└────────────────────────────────────────────┘
src/
├── app/
│ ├── api/
│ │ ├── auth/ # JWT validation, token generation
│ │ ├── workers/ # Worker registration, heartbeat, list
│ │ ├── jobs/ # Job submission, status, results
│ │ ├── files/ # File upload, download
│ │ └── execute/ # Direct execution (legacy)
│ ├── components/ # React components
│ ├── login/ # Authentication UI
│ └── page.tsx # Main dashboard
├── lib/
│ ├── auth.ts # JWT/HMAC authentication
│ ├── config.ts # Environment configuration
│ ├── types.ts # TypeScript interfaces
│ ├── db/
│ │ ├── mongodb.ts # MongoDB connection & queries
│ │ └── redis.ts # Redis client & caching
│ └── jobs.ts # Job management logic
├── middleware.ts # Request preprocessing
└── (additional files)
worker-agent.js
├── Initialization
│ ├── Generate unique workerId
│ ├── Detect system info (CPU, RAM, OS)
│ └── Register with server
├── Job Loop (runs every 5 seconds)
│ ├── Poll server for new job
│ ├── Download file if needed
│ ├── Extract ZIP
│ ├── Execute command
│ ├── Stream output in real-time
│ ├── Upload results
│ └── Cleanup temp files
└── Heartbeat (every 30 seconds)
├── Report worker status
└── Confirm availability
# Install dependencies
npm install
# Create database (MongoDB local)
mongod --dbpath ./data
# Start development server
npm run dev
# In another terminal, start worker
node worker-agent.js --server http://localhost:3000See deployment section below for Docker, Kubernetes, and cloud deployment guides.
- Dashboard - View all registered workers and job queue
- Submit Job - Upload files and enter execution command
- Monitor Progress - Real-time stdout/stderr streaming
- View Results - Download execution results and logs
# Start worker
node worker-agent.js \
--server http://localhost:3000 \
--token <worker-token> \
--max-parallel 2
# Options:
# --server Server URL (required)
# --token Worker token for authentication (optional)
# --max-parallel Number of parallel jobs (default: 1)
# --timeout Job timeout in seconds (default: 3600)curl -X POST http://localhost:3000/api/workers/register \
-H "Content-Type: application/json" \
-d '{
"workerId": "worker-001",
"hostname": "desktop-pc",
"cpuCount": 8
}'Response:
{
"success": true,
"token": "eyJhbGc..."
}curl -X POST http://localhost:3000/api/jobs/submit \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"command": "npm test",
"fileUrl": "https://server/uploads/project.zip",
"workingDirectory": "project",
"timeout": 600
}'Response:
{
"jobId": "job-12345",
"status": "queued",
"createdAt": "2026-01-25T10:30:00Z"
}curl http://localhost:3000/api/jobs/status?jobId=job-12345Response:
{
"jobId": "job-12345",
"status": "running",
"workerId": "worker-001",
"stdout": "Running tests...\n",
"stderr": "",
"progress": 45
}curl -X GET http://localhost:3000/api/jobs/get-job \
-H "x-worker-token: <token>"Response:
{
"jobId": "job-12345",
"command": "npm test",
"fileUrl": "https://server/uploads/project.zip",
"timeout": 600
}| Method | Endpoint | Description |
|---|---|---|
| POST | /api/workers/register |
Register a new worker |
| GET | /api/workers/list |
List all workers |
| GET | /api/workers/[workerId] |
Get worker details |
| DELETE | /api/workers/[workerId] |
Unregister worker |
| POST | /api/workers/heartbeat |
Send heartbeat |
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/jobs/submit |
Submit new job |
| GET | /api/jobs/status |
Get job status |
| GET | /api/jobs/list |
List jobs |
| GET | /api/jobs/get-job |
Get next job (worker) |
| POST | /api/jobs/submit-result |
Submit job result |
| POST | /api/jobs/stream-output |
Stream output |
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/files/upload |
Upload ZIP file |
| GET | /api/files/download/[fileId] |
Download file |
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/auth/login |
User login |
| POST | /api/auth/logout |
User logout |
| POST | /api/auth/refresh |
Refresh token |
# Database
MONGODB_URI=mongodb://user:pass@host:27017
MONGODB_DB=cmd_executor
# Redis (optional)
REDIS_URL=redis://:password@localhost:6379/0
# Security
JWT_SECRET=secret-key-min-32-chars-long
WORKER_TOKEN_SECRET=worker-secret-key
JWT_EXPIRES_IN=24h
# CORS & Origin
ALLOWED_ORIGINS=http://localhost:3000,https://example.com
ENFORCE_TLS=false
# OIDC/OAuth (optional)
OIDC_ISSUER=https://issuer.example.com
OIDC_CLIENT_ID=client-id
OIDC_CLIENT_SECRET=client-secret
# Logging
LOG_LEVEL=info
DEBUG=cmd-executor:*{
_id: ObjectId,
workerId: "worker-001",
hostname: "desktop-pc",
cpuCount: 8,
totalMemoryMb: 16384,
status: "online", // online, offline, error
lastHeartbeat: ISODate("2026-01-25T10:30:00Z"),
registeredAt: ISODate("2026-01-25T09:00:00Z"),
metadata: {
osType: "Windows",
nodeVersion: "18.17.0",
tags: ["test", "build"]
}
}{
_id: ObjectId,
jobId: "job-12345",
command: "npm test",
fileUrl: "https://server/uploads/project.zip",
status: "completed", // queued, running, completed, failed
workerId: "worker-001",
createdAt: ISODate("2026-01-25T10:30:00Z"),
startedAt: ISODate("2026-01-25T10:30:05Z"),
completedAt: ISODate("2026-01-25T10:35:00Z"),
stdout: "test output...",
stderr: "",
exitCode: 0,
timeout: 600,
result: {
success: true,
duration: 295,
lines: 1250
}
}# Build image
docker build -t cmd-executor:latest .
# Run server
docker run -p 3000:3000 \
-e MONGODB_URI=mongodb://mongo:27017 \
-e REDIS_URL=redis://redis:6379 \
cmd-executor:latest
# Run worker
docker run \
-e SERVER_URL=http://server:3000 \
cmd-executor:latest node worker-agent.jsversion: '3.8'
services:
server:
build: .
ports:
- "3000:3000"
environment:
MONGODB_URI: mongodb://mongo:27017
REDIS_URL: redis://redis:6379
depends_on:
- mongo
- redis
mongo:
image: mongo:latest
volumes:
- mongo-data:/data/db
redis:
image: redis:latest
worker-1:
build: .
command: node worker-agent.js --server http://server:3000
environment:
SERVER_URL: http://server:3000
depends_on:
- server
volumes:
mongo-data:Problem: Worker keeps getting "Unauthorized" error
Solution:
- Check server is running:
curl http://localhost:3000/api/health - Verify network connectivity:
ping server-hostname - Check logs:
node worker-agent.js --debug
Problem: Jobs stay in "queued" status
Solution:
- Verify workers are registered:
curl http://localhost:3000/api/workers/list - Check worker logs for errors
- Ensure ZIP files are accessible
- Verify job timeout isn't too short
Problem: Worker process consuming too much RAM
Solution:
- Reduce
--max-parallelflag - Increase job timeout to allow cleanup
- Monitor with
node --max-old-space-size=4096 worker-agent.js
Problem: Can't see real-time output
Solution:
- Check WebSocket connectivity
- Verify ALLOWED_ORIGINS includes client URL
- Check browser console for errors
- Ensure job is actually running (check status endpoint)
Problem: "Failed to connect to MongoDB"
Solution:
- Verify MongoDB is running:
mongo --version - Check connection string:
mongodb://localhost:27017 - Verify authentication credentials
- Check firewall rules
cmd-executor/
├── src/ # Next.js application
│ ├── app/ # App router
│ │ ├── api/ # API routes
│ │ ├── components/ # React components
│ │ └── page.tsx # Main page
│ ├── lib/ # Utilities
│ │ ├── db/ # Database setup
│ │ ├── auth.ts # Authentication
│ │ └── types.ts # TypeScript definitions
│ └── middleware.ts # Next.js middleware
├── electron/ # Electron app (optional GUI)
├── public/ # Static files
├── worker-agent.js # Worker executable
├── package.json # Dependencies
├── tsconfig.json # TypeScript config
├── next.config.ts # Next.js config
├── eslint.config.mjs # Linting rules
├── postcss.config.mjs # CSS processing
└── .env.local # Environment variables
- Authentication: All API endpoints require JWT or HMAC tokens
- Rate Limiting: Redis-based rate limiting on all endpoints
- CORS: Configured for allowed origins only
- TLS/HTTPS: Enforced in production (see
ENFORCE_TLS) - Token Rotation: Implement regular token refresh
- File Uploads: Validate ZIP files before processing
- Command Sanitization: No shell injection prevention (run in isolated environment)
- Connection Pooling: MongoDB connection reuse
- Redis Caching: Job results cached for 1 hour
- Lazy Loading: Components load on demand
- Compression: gzip enabled for responses
- CDN: Serve static files from CDN in production
- Fork repository
- Create feature branch:
git checkout -b feature/name - Commit changes:
git commit -am 'Add feature' - Push to branch:
git push origin feature/name - Submit pull request
MIT - See LICENSE file for details
- Documentation: See
/docsfolder - Issues: GitHub Issues
- Discussions: GitHub Discussions
- Email: support@example.com
- Distributed worker support
- Real-time output streaming
- Job queue management
- Worker health monitoring
- Initial release
- Direct command execution
- Basic web UI
This is a custom distributed system. For improvements:
- Test changes locally with multiple workers
- Update documentation
- Add test cases to
CHECKLIST.md - Document Phase 3 implications
Custom implementation - no external license restrictions apply.
- API questions: See API_REFERENCE.md
- Architecture questions: See PHASE_2_README.md
- Code structure: See IMPLEMENTATION_GUIDE.md
- Quick commands: See QUICK_REFERENCE.md
- Completeness: See CHECKLIST.md
- Read: QUICK_REFERENCE.md for quick commands
- Run:
npm run dev && node worker-agent.jsin separate terminals - Test: Use web UI at http://localhost:3000
- Monitor: Check logs and use
/api/workers/registerendpoint - Plan: Phase 3 improvements based on your needs
Phase 2 is complete and ready for production! 🎉
For support, refer to the documentation files or the source code comments.