A secure coding workspace with a LeetCode-style UI, Docker-isolated execution, and password-based authentication.
- Backend: Node.js, Express, TypeScript, PostgreSQL
- Frontend: React, Vite, Monaco Editor, React Router
- Execution: Docker (
python:3.9,node:18,gcc:12) - Auth: JWT (
httpOnlycookie)
- Sign up with full name, email, phone, password, confirm password
- Log in with email + password
- Authenticated coding workspace (
/app) - Monaco editor with language switcher:
pythonjavascriptccpp
- Secure code execution in Docker with CPU/memory/pid/network/time limits
- Built-in LeetCode problem bank and sample test cases
- User-scoped submissions history
Execution is never performed directly on the host.
Each run is sandboxed with:
--network none--read-only--tmpfs /tmp:rw,noexec,nosuid,size=64m--tmpfs /workspace:rw,exec,nosuid,nodev,size=64m--cap-drop ALL--security-opt no-new-privileges--pids-limit 64- CPU limit (
--cpus) - Memory limit (
--memory) - backend timeout kill (default
4000ms) - output cap and payload size validation
backend/
├── controllers/
├── middleware/
├── routes/
├── services/
├── utils/
└── src/
frontend/
├── components/
├── pages/
├── services/
└── src/
- Node.js 18+
- npm
- Docker Engine / Docker Desktop running
- Docker Compose v2
cd codeArenadocker pull python:3.9
docker pull node:18
docker pull gcc:12
docker pull postgres:16-alpinedocker compose up -d postgresThe backend now requires DB connectivity at startup.
cp backend/.env.example backend/.env
cp frontend/.env.example frontend/.envbackend/.env:
PORT=4000
EXECUTION_TIMEOUT_MS=4000
MAX_CODE_SIZE=20000
MAX_STDIN_SIZE=5000
MAX_OUTPUT_SIZE=20000
DOCKER_MEMORY_LIMIT=128m
DOCKER_CPU_LIMIT=0.5
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/code_exec
JWT_SECRET=replace-with-a-long-random-secret
FRONTEND_ORIGIN=http://localhost:5173
COOKIE_SECURE=false
AUTH_TOKEN_TTL_HOURS=24Notes:
- In production, set
COOKIE_SECURE=trueand provide a strongJWT_SECRET. FRONTEND_ORIGINsupports a comma-separated allowlist.
cd backend && npm install
cd ../frontend && npm install
cd ..cd backend
npm run devBackend URL: http://localhost:4000
cd frontend
npm run devFrontend URL: http://localhost:5173
/loginpublic/signuppublic/appauthenticated workspace
Route guards:
- unauthenticated users visiting
/appare redirected to/login - authenticated users visiting
/loginor/signupare redirected to/app
Base URL: http://localhost:4000
Returns service status and runtime checks.
Returns the built-in problem bank (currently ~20+ questions with test cases).
Request:
{
"fullName": "Jane Developer",
"email": "jane@example.com",
"phone": "+14155552671",
"password": "Str0ng!Pass",
"confirmPassword": "Str0ng!Pass"
}Validation rules:
fullName: 2-100 charsemail: valid format, normalized lowercasephone: normalized and validated to E.164password: 8-72 chars, uppercase, lowercase, digit, special charconfirmPassword: must matchpassword
Response: 201 with user and auth cookie.
Request:
{
"email": "jane@example.com",
"password": "Str0ng!Pass"
}Response: 200 with user and auth cookie.
Requires auth cookie. Returns current user.
Clears auth cookie.
Requires auth cookie.
Request:
{
"currentPassword": "Str0ng!Pass",
"email": "new-email@example.com",
"newPassword": "N3wStr0ng!Pass",
"confirmNewPassword": "N3wStr0ng!Pass"
}Rules:
currentPasswordis required for all account updates.emailis optional; when provided it must be valid and unique.newPasswordis optional; if provided,confirmNewPasswordis required and must match.
Protected via JWT cookie (httpOnly, sameSite=lax, TTL from AUTH_TOKEN_TTL_HOURS).
Request:
{
"language": "cpp",
"code": "#include <iostream>\nint main(){std::cout << \"Hello C++\\n\"; return 0;}",
"stdin": ""
}Supported languages:
pythonjavascriptccpp
Response:
{
"stdout": "Hello C++\n",
"stderr": "",
"status": "success",
"executionTimeMs": 130,
"truncated": false
}Status values:
successruntime_errortimeoutoutput_limit_exceededinternal_errorvalidation_error
Returns only the authenticated user’s submissions, newest first.
# 1) Signup (stores cookie)
curl -i -c cookie.txt -X POST http://localhost:4000/auth/signup \
-H "Content-Type: application/json" \
-d '{
"fullName": "Jane Developer",
"email": "jane@example.com",
"phone": "+14155552671",
"password": "Str0ng!Pass",
"confirmPassword": "Str0ng!Pass"
}'
# 2) Execute with auth cookie
curl -i -b cookie.txt -X POST http://localhost:4000/execute \
-H "Content-Type: application/json" \
-d '{
"language": "python",
"code": "print(input())",
"stdin": "hello"
}'
# 3) Fetch submission history
curl -i -b cookie.txt "http://localhost:4000/submissions?page=1&limit=10"cd backend && npm run build
cd ../frontend && npm run build- Backend fails at startup with DB error: ensure
docker compose up -d postgresis running andDATABASE_URLis correct. 401 Authentication required: log in again and ensure frontend usescredentials: 'include'.- Docker execution errors: verify Docker daemon is running and required images were pulled.