A distributed, production-ready code execution platform that safely executes and returns code output across multiple programming languages. Built with a microservices architecture using Node.js, Redis, and Docker.
The system consists of three main components:
- API Layer: Express.js server handling job submissions and status queries
- Message Queue: Redis-based job queue for distributed processing
- Worker Services: Scalable workers that execute code in isolated environments
✨ Multi-Language Support
- Java, JavaScript, TypeScript, Python, Rust
🔄 Async Job Processing
- Non-blocking job submissions with UUID tracking
- Poll-based status checking system
🐳 Docker Ready
- Multi-stage builds for optimized images
- Docker Compose for local development
🔐 CORS Protected
- Whitelist-based origin validation
- Security-first approach
⚡ Scalable Architecture
- Horizontal scaling with multiple workers
- Redis message queue for job distribution
- 5-minute result caching
- Node.js 20+
- Docker & Docker Compose (recommended)
- Redis (included in Docker Compose)
docker-compose upThis starts:
- Redis on
6379 - API on
3000 - Worker service
-
Install dependencies:
npm install cd worker && npm install
-
Start Redis:
redis-server
-
Start API server:
npm run dev
-
Start worker (in another terminal):
cd worker && npm run dev
POST /set-job
Content-Type: application/json
{
"user": "john_doe",
"filename": "hello",
"language": "python",
"code": "print('Hello World')",
"extension": "py"
}Response:
{
"status": "push-success",
"message": "Job submitted successfully",
"data": {
"jobId": "550e8400-e29b-41d4-a716-446655440000"
}
}GET /status/:jobIdPending Response:
{
"status": "pending",
"message": "Your Job is under Construction"
}Completed Response:
{
"status": "pop-success",
"message": "Job Execution Successful",
"data": {
"jobId": "550e8400-e29b-41d4-a716-446655440000",
"response": {
"status": "Success",
"output": "Hello World"
}
}
}| Language | Extension |
|---|---|
| Java | .java |
| JavaScript | .js |
| TypeScript | .ts |
| Python | .py |
| Rust | .rs |
code-executor/
├── src/
│ ├── index.ts # API server
│ └── job.ts # Job model
├── worker/
│ ├── src/
│ │ ├── index.ts # Worker service
│ │ └── libs.ts # Execution logic
│ ├── Dockerfile # Worker container
│ ├── package.json # Worker dependencies
│ └── tsconfig.json
├── docker-compose.yml # Local environment setup
├── Dockerfile # API container
├── package.json # API dependencies
└── README.md
| Variable | Default | Description |
|---|---|---|
REDIS_URL |
redis://localhost:6379 |
Redis connection string |
npm run build
cd worker && npm run buildAPI Layer:
npm run dev- Start with hot reloadnpm run build- Build TypeScriptnpm start- Run compiled code
Worker:
npm run build- Build TypeScriptnpm start- Start worker
- Runtime: Node.js 20 (Alpine Linux)
- Language: TypeScript 5
- API: Express.js 5
- Message Queue: Redis 4
- Container: Docker & Docker Compose
- Utilities: UUID, CORS
- Client submits code via
/set-jobendpoint - Job is serialized and pushed to Redis queue
- Available worker picks up the job
- Code is written to isolated file system
- Language-specific command executes the code
- Output is cached in Redis (10 minutes TTL)
- Client polls
/status/:jobIdfor results - Execution artifacts are cleaned up
Code execution has a 5-second timeout to prevent hanging processes.
Job results are cached in Redis for 10 minutes after completion.
Feel free to fork and submit pull requests for improvements.
Saish Mungase
@saishmungase
ISC
