Getting Started
Pomelo
What is Pomelo?
Pomelo is an open-source competitive programming contest platform for hosting coding contests with automated code evaluation powered by Judge0.
It provides the pieces needed to run a local contest environment, including a participant-facing web app, an Express API, admin tooling, and Docker services for the backing stack.
Use this documentation to install dependencies, configure environment variables, start the services, and troubleshoot setup issues.
Installation
Run the following command to automatically install and set up Pomelo:
During Installation
When you run the installation script, it will prompt you to select which version of Pomelo to install (defaults to the latest release).
Next Steps
Once the installation finishes and the Pomelo daemon is running, you can start the entire platform with:
To access the built-in administrator interface to manage your instance, simply run:
Workspace Setup
Follow these steps to set up the Pomelo workspace on your local machine.
Prerequisites
The Pomelo stack requires specific system tools to run locally and build. Make sure the following are installed:
- Node.js (
node): Required for the Next.js frontend and Express backend. - Bun (
bun): Used specifically to compile the CLI and Daemon binaries. - pnpm: The strict package manager used across the monorepo workspace.
- Docker & Docker Compose: Required for the database and Judge0 execution environment.
1. Clone the repository
Clone the repository to your local machine:
2. Install workspace dependencies
Run pnpm install at the repository root to install all workspace dependencies.
3. Start development services
Run pnpm dev to start the Next.js frontend, Express API, and local code-gen watchers.
WARNING: This only starts the Node.js services. The developer must also manually start the backing infrastructure containers (MongoDB, Postgres, Redis, Judge0) for the platform to function. See the Docker Setup section for instructions.
Environment Variables
Developers must copy the template .env.example file to .env before running the stack.
Development Variables
| Variable | Default Value | Description |
|---|---|---|
AUTH_SECRET | (required) | Long random secret used by NextAuth for session encryption. |
PORT | 8080 | Port the Express API listens on. |
MONGODB_URI | mongodb://localhost:27017/pomelo | MongoDB connection string. |
JUDGE0_URL | http://judge0-server:2358 | URL configuration for the Judge0 execution engine. |
DOMAIN | localhost:3000 | Frontend domain used by the Next.js client. |
PROTOCOL | http | Protocol for the frontend app. |
BACKEND_URL | http://localhost:8080 | URL used by server-side code to call the backend. |
POSTGRES_PASSWORD | (required) | Password for the PostgreSQL database used by Judge0. |
REDIS_PASSWORD | (required) | Password for the Redis queue used by Judge0. |
Dev Setup
Docker Setup
Pomelo includes Docker Compose definitions in docker/app/ and docker/judge0/. Use the following command to start the backing services for local development.
Start the Docker dev stack
docker compose --project-name pomelo --env-file .env \
-f docker/app/docker-compose.dev.yaml \
-f docker/judge0/docker-compose.dev.yaml \
--project-directory . up mongo judge0-server judge0-workers -d Services
mongo MongoDB database for contest and user data.
server Express API for auth, contests, and submissions.
client Participant-facing web app.
seed Seeds MongoDB with initial data, then exits.
judge0-server Judge0 core server for code execution.
judge0-workers Judge0 worker processes.
judge0-db PostgreSQL for Judge0 internal state.
judge0-redis Redis for Judge0 job queuing.
Stop containers
Remove volumes
Local Installation
Packaging Script
The script at scripts/package.sh compiles the workspace into a standalone build.tar.gz archive containing only pre-built artifacts.
Usage
Run the script without arguments to create the default archive:
Or specify a custom output filename:
Installation Script
The script at scripts/install.sh deploys Pomelo to a host machine under /opt/pomelo.
Usage
To install from a local tarball:
Uninstalling
To cleanly remove the installation:
Admin Tooling
Pomelo CLI
The admin directory contains the source for the administrator tooling.
The CLI and daemon are written in TypeScript and compiled into single-file executables using Bun. You must have Bun installed to compile these tools from source.
Daemon
pomelod is the background orchestrator daemon for Pomelo. Once installed, it monitors contest states and manages background tasks.
Systemd Policy
During installation, Pomelo sets up a persistent systemd service for the daemon at /etc/systemd/system/pomelod.service.
This policy ensures that the daemon automatically starts on boot and restarts on failure. If systemd is unavailable on the host system or the installation is not run as root, the daemon will start as a standard non-persistent background process instead.
CLI
pomelo is the terminal utility for administrators. It is symlinked to /usr/local/bin/pomelo during installation and provides a centralized way to interact with the platform services.
Commands
| Command | Description |
|---|---|
pomelo start | Starts all Pomelo backend services. |
pomelo stop | Stops the running Pomelo services. |
pomelo restart | Restarts the Pomelo services. |
pomelo status | Checks the status of the daemon and Docker containers. |
pomelo logs | Streams logs from the running services. |
pomelo ui | Opens the web admin dashboard on port 8462. |
pomelo uninstall | Uninstalls Pomelo and cleans up the systemd service. |
CLI Development
This section covers how to work on the CLI locally, which is located in the @pomelo/admin package.
Viewing the UI
To start the Vite UI on port 8462:
Building Binaries
To compile the TypeScript files into pomelo and pomelod binaries using Bun:
Hot-Swapping (Testing Local CLI)
You can test local changes by running the hot-swap script.
WARNING: This script requires sudo privileges. You must have already installed Pomelo to /opt/pomelo using install.sh first. This script only copies the newly built binaries over the existing installation and restarts the pomelod systemd service.
Troubleshooting
Common Issues
Open the issue that matches what you are seeing, then compare the guidance with your local setup.
Toolchain pnpm install fails
Confirm pnpm 10.0.0 or newer is installed.
Confirm Node.js is installed.
Confirm Git is available in PATH.
Environment pnpm dev fails
Confirm .env exists and matches .env.example.
Confirm AUTH_SECRET is set to a non-empty value.
Confirm MONGODB_URI points to a running MongoDB instance.
Confirm JUDGE0_URL points to a running Judge0 server.
Containers Docker Compose fails
Confirm Docker and Docker Compose v2 are installed.
Confirm .env exists in the repository root.
Confirm POSTGRES_PASSWORD and REDIS_PASSWORD are set.
Run the Docker Compose command from the repo root directory.
Database Backend cannot connect to MongoDB
Verify MONGODB_URI is correct and reachable.
Confirm the mongo container or service is running.
Check logs with docker logs pomelo-mongo-1.
Judge0 Judge0 jobs fail or time out
Verify JUDGE0_URL is correct.
Confirm judge0-server and judge0-workers are running.
Confirm judge0-db and judge0-redis are healthy.
API Reference
Authentication API
The Pomelo frontend uses NextAuth for authentication. API routes enforce authentication using the following middleware:
| Middleware | Description |
|---|---|
requireAuth() | Enforces standard authentication for routes. |
isAdmin | Enforces admin-only access for elevated routes. |
Contests API
Endpoints for managing and participating in contests.
| Method | Endpoint | Description |
|---|---|---|
POST | /api/contests/join | Validates a join code and returns a contestId. |
GET | /api/contests/:id | Fetches public contest landing data. |
POST | /api/contests/start | Initializes an attempt session for a user. |
GET | /api/contests/:id/data | Fetches the active questions and test data for an ongoing attempt. |
POST | /api/contests/:id/end | Submits the final test and locks the session. |
GET | /api/contests/:id/leaderboard | Admin-only route to view ranked scores. |
Submissions API
Endpoints for handling code execution and test submissions.
| Method | Endpoint | Description |
|---|---|---|
POST | /api/contests/:id/run | Performs a dry-run code execution against sample test cases. |
POST | /api/submit | The unified submission endpoint for all question types. |