A lightweight Go HTTP service that compiles and executes participant code for the Recoding Exercise Platform.
Live at: https://code-runner-cpqt.onrender.com
When a participant clicks Run in the coding editor, the platform sends their Go code to this service. The runner:
- Validates the API key
- Writes the code to a temporary directory
- Runs
go runwith a 10-second timeout - Captures stdout, stderr, and exit code
- Returns the result as JSON
- Cleans up the temp directory
The banner file (standard.txt) is automatically injected as stdin by the main app for ASCII art exercises — participants read it via os.Stdin without needing file I/O.
Execute Go code.
Headers:
Authorization: Bearer <RUNNER_API_KEY>
Content-Type: application/json
Request:
{
"code": "package main\nimport \"fmt\"\nfunc main(){fmt.Println(\"hello\")}",
"language": "go",
"stdin": ""
}Response:
{
"stdout": "hello\n",
"stderr": "",
"exit_code": 0,
"compile_output": ""
}Returns {"status":"ok"}. Used by Render for health checks.
Status page showing the server is online with endpoint documentation.
| Limit | Value |
|---|---|
| Code size | 64 KB |
| Output size | 64 KB |
| Execution timeout | 10 seconds |
| Supported languages | Go only |
All requests to /run require a Bearer token:
Authorization: Bearer <RUNNER_API_KEY>
Set RUNNER_API_KEY as an environment variable on Render. The main app reads the same key from its RUNNER_API_KEY env var and sends it automatically.
Generate a key:
openssl rand -base64 32- Go to render.com → New → Web Service
- Connect
github.com/jvcByte/code-runner - Runtime: Docker
- Add environment variable:
RUNNER_API_KEY=<your-secret> - Deploy
After deploy, set in the main app:
RUNNER_URL=https://your-service.onrender.com
RUNNER_API_KEY=<same-secret># Build and run
go build -o runner . && ./runner
# Server starts on :3001
# Test
curl -X POST http://localhost:3001/run \
-H "Content-Type: application/json" \
-d '{"code":"package main\nimport \"fmt\"\nfunc main(){fmt.Println(\"hello\")}","language":"go","stdin":""}'main.go — Entry point, server setup, route registration
internal/
executor/
executor.go — Runs go code in temp dir with timeout and output limits
handlers/
run.go — POST /run — validates request, calls executor, returns JSON
health.go — GET /health — returns {"status":"ok"}
index.go — GET / — HTML status page with server rack icon
middleware/
auth.go — Bearer token authentication (skipped if RUNNER_API_KEY unset)
logger.go — Structured JSON request logging (IP, agent, status, duration)
All requests are logged as structured JSON to stdout (visible in Render's log viewer):
{"time":"2026-04-14T10:00:00Z","level":"INFO","msg":"request","method":"POST","path":"/run","status":200,"ip":"1.2.3.4","agent":"...","duration":"523ms"}Log levels:
INFO— successful requests (2xx)WARN— client errors (4xx) and execution timeoutsERROR— server errors (5xx) and execution failures
- Render free tier sleeps after 15 minutes of inactivity — first request after idle will be slow (~30s cold start)
- No sandboxing beyond the 10s timeout and output limits — code runs as the server process user
- Only Go is supported; other languages return an error response