Contester is a platform for programming contests. Admins publish contests with stdin/stdout problems and hidden tests. Participants solve them in Python, JavaScript, Java or C++ in the browser. A sandboxed judge checks every submission on the server, and the standings update from the verdicts.
| Contests | Standings | Leaderboard |
|---|---|---|
![]() |
![]() |
![]() |
- Online judge. Submissions run in Piston sandboxes against hidden tests, with time and memory limits. Verdicts: accepted, wrong answer, time and memory limit exceeded, runtime and compilation errors. "Run" tries a solution on custom input first.
- Contests. Upcoming, live and past rounds, registration, ICPC-style standings (points, then penalty minutes), and practice after the end.
- Accounts. E-mail verification, password reset, profile, password change, logout on all devices and account deletion.
- Admin pages. Contests, problems with Markdown statements, test cases and rejudging.
- Discussions on every problem, a global leaderboard and public profiles with recent activity.
Requirements: Docker with Compose v2.24 or later. The judge container runs privileged; see docs/deployment.md.
git clone https://github.com/oiibar/Contester.git && cd Contester
cp .env.example .env # set DB_PASSWORD to a random string
docker compose up -d --build
docker compose run --rm piston-install # judge runtimes, about 1 GB, first time only
docker compose --profile seed run --rm seed # demo contests, problems and users
scripts/smoke.sh| What | Where |
|---|---|
| App | http://localhost:3200 |
| Demo logins | alice@contester.dev (participant), admin@contester.dev (admin); password Demo-password-1 |
| Outgoing mail (Mailpit) | http://localhost:8027 |
| API docs (Swagger UI) | http://localhost:3200/api/docs |
| Metrics | docker compose --profile observability up -d, then Grafana at http://localhost:3201 |
flowchart LR
browser((Browser)) --> web[web: nginx + React SPA]
web -->|/api| api[api: Spring Boot]
api --> db[(PostgreSQL)]
api -->|private network| piston[Piston sandbox]
- Frontend: React 19, TypeScript, Vite, Redux Toolkit Query, Monaco editor, SCSS.
- Backend: Java 21, Spring Boot 4, Spring Security (server-side sessions, CSRF), Spring Session JDBC, Flyway, Hibernate and JDBC.
- Judge: submissions are queued in PostgreSQL (
FOR UPDATE SKIP LOCKED). Workers in the API run the tests in Piston, with retries and recovery. - Operations: Docker Compose, Caddy (HTTPS) in production, Prometheus, Grafana, GitHub Actions.
Details: architecture and the decision records.
| Topic | |
|---|---|
| Architecture | Containers, modules, request and judging flows |
| API | Endpoints, errors, authentication |
| Database | Schema, indexes, seed data |
| Judge | Languages, verdicts, sandbox, limits |
| Security | Threat model and controls (reporting) |
| Testing | Test suites and how to run them |
| Performance | Load tests and query measurements |
| Deployment | Production setup and releases |
| Runbook | Operations and incidents |
| Disaster recovery | Backups and restore |
| Audit | What was wrong with the first prototype |
See CONTRIBUTING.md for running the backend and frontend outside Docker, and for the checks to run before a pull request:
cd backend && ./mvnw verify
cd frontend && npm run lint && npm run typecheck && npm testVersion 1.0.0 is ready for release; see CHANGELOG.md. No license has been chosen yet, so all rights are reserved by the author until one is added.



