exec-d (Codeforces Online Judge)
Production-grade, Codeforces-style online judge — Turborepo monorepo, BullMQ queue, Docker sandboxes, and an integrated Socratic AI tutor.
Overview
exec-d is a production-grade online judge built as a high-performance Turborepo monorepo. It compiles and evaluates untrusted code in locked-down, network-isolated Docker sandboxes, queues evaluation jobs asynchronously via BullMQ + Redis, measures real-time execution runtime and peak memory consumption, streams deterministic verdicts to users, and features an integrated Socratic AI Competitive Programming Tutor powered by the Vercel AI SDK and Google Gemini 3.1 Flash Lite.
The platform supports C++20, Python 3, Java 21, and JavaScript (Node.js) with the same compiler flags and I/O conventions used by Codeforces and CodeChef.
<900ms
AI Response Latency
Gemini 3.1 Flash Lite
Deterministic
Verdict Accuracy
Bit-exact output compare
Network: none
Sandbox Isolation
256MB RAM cap
30+
Problems Seeded
Classic CP problems
Demo
Exec AI — Socratic Tutor
Exec AI is an embedded AI assistant built directly into the problem workspace tab. Rather than acting as a code generator, it operates as a Socratic competitive programming coach.
On every query, Exec AI automatically ingests:
- The live Monaco editor code and selected language
- Problem title, description, constraints, input/output specs, and sample test cases
- Current submission verdict (ACCEPTED, TLE, CE, RE, WA)
- Diagnostic error stack traces or compiler output logs
When asked for code, it generates full main-program entrypoints matching real CP standards — stdin reading → processing → stdout writing — not just standalone snippets.
System Architecture
Complete system topology showing how requests flow from the frontend browser through the API, queue, worker, container sandbox, database, and AI service.
Submission Lifecycle
When a user clicks Submit, the code travels through a multi-stage async pipeline. The frontend polls for the verdict while the worker evaluates each test case inside an isolated Docker container.
Try the Sandbox
Simulate the Docker sandbox execution pipeline directly in your browser. Pick a language, submit, and watch the job flow from BullMQ queue → Docker container → verdict.
Database Schema
The schema is powered by Prisma 7 connected to PostgreSQL. Users submit code against Problems; each Problem has TestCases and an AI conversation thread per user.
Docker Sandboxing
exec-d evaluates untrusted user code inside locked Docker containers with strict security constraints:
- 011. Network Isolation —
NetworkMode: "none"completely disables all network interfaces. User code cannot make HTTP requests, open sockets, or exfiltrate data.
- 012. Resource Constraints — Hard memory caps enforced via Docker memory limits (256MB max). CPU quota limits (1.0 core) preventing CPU starvation attacks.
- 013. Execution Timeout — Per-testcase wall-clock timeouts. If code runs beyond
timeLimit(2000ms default), the container process receivesSIGKILLand returns TIME_LIMIT_EXCEEDED.
- 014. Ephemeral Filesystem — Tar archives stream code and inputs into isolated temporary paths (
/app). No persistence between runs.
- 015. Compilation Grace Buffer — Traps
g++(#include <bits/stdc++.h>) andjavaccompilation times so heavyweight header builds do not trigger false TLE failures.
Language Support
| Language | Compiler / Interpreter | Entrypoint Pattern | Notes |
|---|---|---|---|
| C++20 | g++ -O2 -std=c++20 | #include <bits/stdc++.h> int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); } | +3500ms grace buffer for header compilation |
| Python 3 | python3 (3.12) | import sys def main(): ... if __name__ == '__main__': main() | Fast I/O via sys.stdin.read().split() |
| Java 21 | javac & java | public class Main { public static void main(String[] args) ... } | 256MB RAM cap with -Xmx192m JVM flag |
| JavaScript | node (v20+) | const fs = require('fs'); function main() { ... } main(); | Sync I/O via fs.readFileSync(0, 'utf-8') |
API Reference
Full REST API — all endpoints are available at https://exec-d.avinashk47.me/api/v1.
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| GET | /api/v1/health | No | System health check |
| POST | /api/v1/auth/register | No | Register new user { email, passwd } |
| POST | /api/v1/auth/login | No | Login and return JWT { email, passwd } |
| GET | /api/v1/auth/me | JWT | Get authenticated user profile & solve stats |
| GET | /api/v1/problems | No | List all active problems |
| GET | /api/v1/problems/:slug | No | Get problem details & sample test cases |
| POST | /api/v1/problems | Admin | Create a new problem with test cases |
| POST | /api/v1/ai/chat | No | Exec AI Socratic assistant |
| POST | /api/v1/submission | JWT | Submit code to queue { slug, language, code } |
| GET | /api/v1/submission/:id | JWT | Poll verdict, runtime, memory for a submission |
| GET | /api/v1/submissions | JWT | List submission history for authenticated user |
Monorepo Structure
exec-d/
├── apps/
│ ├── web/ # Next.js 16 (Turbopack) Frontend
│ │ ├── app/ # App Router pages
│ │ ├── components/ # Monaco Editor, Exec AI Chat UI, Navigation
│ │ └── lib/ # Auth context, API client
│ ├── api/ # Express 5 REST API
│ │ └── src/ # Routes: auth, problems, submission, ai
│ └── worker/ # BullMQ Async Worker Engine
│ └── src/ # Docker sandbox runner, testcase loop
├── packages/
│ ├── db/ # Prisma 7 schema, migrations, 30-problem seed
│ ├── contracts/ # Shared Zod validation schemas
│ ├── eslint-config/ # Monorepo ESLint config
│ └── typescript-config/ # Shared tsconfig bases
├── ecosystem.config.cjs # PM2 Process Manager config
├── turbo.json # Turborepo task pipeline
└── pnpm-workspace.yamlCI/CD Pipeline
Deployed to an Oracle Cloud VM (Ubuntu) behind Nginx with Let's Encrypt TLS. Three PM2 processes run concurrently:
- exec-d-api — Express backend on port 8080
- exec-d-web — Next.js production build on port 3000
- exec-d-worker — Independent BullMQ consumer running Docker containers
