A web application for online judge (algorithm questions), built with a modern tech stack including Next.js, NestJS, PostgreSQL, and Rust.
- 🔗 Separated frontend, backend, and judging system
- 🧑💻 User-friendly interface for solving and submitting coding problems
- 🔐 User authentication and role-based access control
- 💬 Blog system for sharing knowledge
- 📚 Problem management for admins (create, edit, delete problems)
- 📊 Submission statistics and user activity tracking
- 🏆 Contest system with real-time ranking
- 🖥️ Dedicated Admin Dashboard included
- 🌙 Light/Dark mode support
- 🌐 Internationalization support (i18n)
- 📦 Fully containerized with Docker Compose for easy deployment
- ❗ Multi-judger system with RabbitMQ job queue for handling submission requests
- 🔒 Secure code execution using isolation techniques
- 🗃️ Test case storage using MinIO (S3-compatible object storage)
- 🔄 Real-time communication using WebSocket
- 📧 Email notifications for account verification and system updates
- 🎨 Rich text editor for problem descriptions and blog posts
FloatPoint-OJ/
├── client/ # Frontend (Next.js)
├── server/ # Backend API (NestJS)
├── judger/ # Automated judging system (Rust)
├── docker-compose.yml # Orchestrates services using Docker
├── Dockerfile.* # Docker configuration for each service
└── README.md
- Framework: Next.js 15 (App Router)
- Language: TypeScript
- Styling: Tailwind CSS v4
- Components: Shadcn UI
- State Management: React Hooks
- Rich Text Editor: Tiptap
- Code Editor: CodeMirror
- Forms: React Hook Form + Zod
- HTTP Client: Axios
- Framework: NestJS
- Language: TypeScript
- Database: PostgreSQL with TypeORM
- Authentication: JWT + Passport.js
- Message Queue: RabbitMQ
- Judger State Storage: Redis
- File Storage: MinIO (S3-compatible)
- Validation: Class Validator
- Documentation: Swagger
- Language: Rust
- Database: PostgreSQL with SQLx
- Message Queue: RabbitMQ (lapin crate)
- File Storage: MinIO (AWS SDK for Rust)
- Sandbox: Docker with isolate for secure execution and isolation
This project uses the following third-party services:
- Google Client API — Used for authentication via Google OAuth 2.0
- SMTP Server — Email service for user verification
- Docker and Docker Compose
- Node.js (v18 or higher) - for local development
- Rust (latest stable) - for local development of judger
git clone https://github.com/nourist/FloatPoint-OJ.git
cd FloatPoint-OJCreate a .env file in the root directory and define the necessary environment variables.
| Variable | Description | Default | Required |
|---|---|---|---|
MAIL_USER |
SMTP server username | None | ✅ |
MAIL_PASS |
SMTP server password | None | ✅ |
MAIL_FROM_EMAIL |
Sender email address | None | ✅ |
GOOGLE_CLIENT_ID |
Google OAuth client ID | None | ✅ |
JWT_SECRET |
JWT secret key | secretKey |
These are the values you must set for the app to function. For local development you may use test credentials (Mailtrap, dev Google OAuth), but change secrets for production.
These variables have sensible defaults; set them in the root .env for deployment.
| Variable | Description | Default |
|---|---|---|
DB_USER |
Database username | postgres |
DB_PASS |
Database password | postgres |
DB_NAME |
Database name | postgres |
DB_HOST |
Database host | localhost (Docker: postgres) |
DB_PORT |
Database port | 5432 |
| Variable | Description | Default |
|---|---|---|
MINIO_ACCESS_KEY |
MinIO access key | minioadmin |
MINIO_SECRET_KEY |
MinIO secret key | minioadmin |
MINIO_ENDPOINT |
MinIO endpoint | localhost (Docker: minio) |
MINIO_PORT |
MinIO port | 9000 |
| Variable | Description | Default |
|---|---|---|
RABBITMQ_USER |
RabbitMQ username | guest |
RABBITMQ_PASS |
RabbitMQ password | guest |
RABBITMQ_HOST |
RabbitMQ host | localhost (Docker: rabbitmq) |
RABBITMQ_PORT |
RabbitMQ port | 5672 |
| Variable | Description | Default |
|---|---|---|
REDIS_PASSWORD |
Redis password | redispass |
REDIS_HOST |
Redis host | localhost (Docker: redis) |
REDIS_PORT |
Redis port | 6379 |
| Variable | Description | Default |
|---|---|---|
NODE_ENV |
Application environment | development |
PORT |
Server port | 4000 |
CLIENT_URL |
Frontend URL for CORS | http://localhost:3000 |
JWT_EXPIRES_IN |
JWT token expiration | 7d |
SALT_ROUNDS |
Bcrypt salt rounds | 10 |
MAIL_HOST |
SMTP server host | smtp.mailtrap.com |
MAIL_PORT |
SMTP server port | 587 |
| Variable | Description | Default |
|---|---|---|
NEXT_PUBLIC_API_URL |
Backend API URL | http://localhost:4000 |
API_URL |
Backend API URL used for server components | http://localhost:4000 (Docker: http://server:4000) |
docker-compose up --buildNote on Environment Variables with Docker:
-
Docker Compose will use default values for environment variables not explicitly set in your
.envfile. -
Required variables (like
MAIL_USER,MAIL_PASS,MAIL_FROM_EMAIL, andNEXT_PUBLIC_GOOGLE_CLIENT_ID) must still be set. -
By default Docker Compose runs 2 judger instances with
JUDGER_IDset to1and2. -
For production deployment, always override default secrets and keys.
-
Variables that differ between Docker and manual setup:
- Database host:
postgres(Docker) vs.localhost(manual) - MinIO endpoint:
minio(Docker) vs.localhost(manual) - RabbitMQ host:
rabbitmq(Docker) vs.localhost(manual) - Redis host:
redis(Docker) vs.localhost(manual) - Api URL:
http://server:4000(Docker) vs.http://localhost:4000(manual)
- Database host:
- Frontend: http://localhost:3000
- API: http://localhost:4000
- MinIO Console: http://localhost:9001
- RabbitMQ Management: http://localhost:15672
If you prefer to run services manually for development:
- Install PostgreSQL, MinIO, RabbitMQ, and Redis.
- Configure each service with the appropriate settings from the development environment variable tables below.
- Configure an SMTP service (e.g., Mailtrap for development).
- Set the required email environment variables:
MAIL_USER,MAIL_PASS, andMAIL_FROM_EMAILin the server service's.envfile.
- Create a Google OAuth client ID for Google login and set
NEXT_PUBLIC_GOOGLE_CLIENT_IDinclient/.env.
Place these .env files inside each service directory when running services locally.
| Variable | Description | Required |
|---|---|---|
NEXT_PUBLIC_API_URL |
Backend API URL | Optional (defaults to http://localhost:4000) |
API_URL |
Backend API URL used for server components | Optional (defaults to http://localhost:4000) |
NEXT_PUBLIC_GOOGLE_CLIENT_ID |
Google OAuth client ID | ✅ Required |
| Variable | Description | Required |
|---|---|---|
NODE_ENV |
Application environment | Optional (defaults to development) |
PORT |
Server port | Optional (defaults to 4000) |
CLIENT_URL |
Frontend URL for CORS | Optional (defaults to http://localhost:3000) |
JWT_SECRET |
JWT secret key | Optional (defaults to secretKey) |
JWT_EXPIRES_IN |
JWT token expiration | Optional (defaults to 7d) |
SALT_ROUNDS |
Bcrypt salt rounds | Optional (defaults to 10) |
DB_HOST |
Database host | Optional (defaults to localhost) |
DB_PORT |
Database port | Optional (defaults to 5432) |
DB_USER |
Database username | Optional (defaults to postgres) |
DB_PASS |
Database password | Optional (defaults to postgres) |
DB_NAME |
Database name | Optional (defaults to postgres) |
RABBITMQ_HOST |
RabbitMQ host | Optional (defaults to localhost) |
RABBITMQ_PORT |
RabbitMQ port | Optional (defaults to 5672) |
RABBITMQ_USER |
RabbitMQ username | Optional (defaults to guest) |
RABBITMQ_PASS |
RabbitMQ password | Optional (defaults to guest) |
MAIL_HOST |
SMTP server host | Optional (defaults to smtp.mailtrap.com) |
MAIL_PORT |
SMTP server port | Optional (defaults to 587) |
MAIL_USER |
SMTP server username | ✅ Required |
MAIL_PASS |
SMTP server password | ✅ Required |
MAIL_FROM_EMAIL |
Sender email address | ✅ Required |
MINIO_ENDPOINT |
MinIO endpoint | Optional (defaults to localhost) |
MINIO_PORT |
MinIO port | Optional (defaults to 9000) |
MINIO_ACCESS_KEY |
MinIO access key | Optional (defaults to minioadmin) |
MINIO_SECRET_KEY |
MinIO secret key | Optional (defaults to minioadmin) |
REDIS_HOST |
Redis host | Optional (defaults to localhost) |
REDIS_PORT |
Redis port | Optional (defaults to 6379) |
REDIS_PASSWORD |
Redis password | Optional (defaults to redispass) |
| Variable | Description | Required |
|---|---|---|
JUDGER_ID |
Unique identifier for the judger instance (number from 0 to 255) |
✅ Required |
DB_HOST |
Database host | Optional (defaults to localhost) |
DB_USER |
Database username | Optional (defaults to postgres) |
DB_PASS |
Database password | Optional (defaults to postgres) |
DB_NAME |
Database name | Optional (defaults to postgres) |
MINIO_ENDPOINT |
MinIO endpoint | Optional (defaults to localhost) |
MINIO_ACCESS_KEY |
MinIO access key | Optional (defaults to minioadmin) |
MINIO_SECRET_KEY |
MinIO secret key | Optional (defaults to minioadmin) |
RABBITMQ_HOST |
RabbitMQ host | Optional (defaults to localhost) |
RABBITMQ_USER |
RabbitMQ username | Optional (defaults to guest) |
RABBITMQ_PASS |
RabbitMQ password | Optional (defaults to guest) |
# Judger Service
cd judger
# Create .env file with required variables from the Judger Service table
cargo run# Server Service
cd server
# Create .env file with required variables from the Server Service table
npm install
npm run dev# Client Service
cd client
# Create .env file with required variables from the Client Service table
npm install
npm run devAnd much more for you to explore...
Contributions are welcome! Please feel free to submit a pull request or open an issue for any bugs or suggestions.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a pull request
This project is licensed under the MIT License.
I know that this project still has many bugs and the design is a mess. However, I'm happy with my final product.
This project is created and maintained by Nourist. If you enjoy this tool, feel free to give it a star on GitHub!























