A self-hosted, browser-based IDE platform for CS students — inspired by Replit. Each user gets an isolated Docker container running VS Code in the browser, with no local setup required.
Built for BitCamp 2026
Repl.it shifted away from being a free, student-friendly web IDE toward a paid AI platform. Monolith IDE fills that gap by providing a locally/school-server-hosted, open-source alternative where students can write and run code directly in the browser.
How it works:
- Students sign in with Google
- They create a project (choosing Python, Java, or C++)
- The app spins up a dedicated Docker container running code-server (VS Code in the browser)
- When the browser tab is closed, the container automatically stops
- Google SSO — OAuth 2.0 with PKCE; no passwords to manage
- Isolated containers — each project runs in its own Docker container
- Multi-language support — Python 3, Java 17, C++ (g++) pre-installed
- Auto-stop on idle — WebSocket heartbeat stops the container when the user disconnects
- Project dashboard — create, start, stop, and delete projects from a single page
- Full VS Code — code-server provides the complete VS Code editor experience in-browser
- Self-hosted — deploy on your own server; no third-party cloud required
| Layer | Technology |
|---|---|
| Backend | Python 3, FastAPI, Uvicorn |
| Templating | Jinja2 |
| Frontend | Vanilla HTML / CSS / JavaScript |
| Auth | Google OAuth 2.0 (PKCE) + JWT (HS256) |
| Database | SQLite (sqlite3) |
| Containers | Docker (Docker-out-of-Docker pattern) |
| IDE | code-server |
| Proxy | Nginx |
| Orchestration | Docker Compose |
- Python 3.11+
- Docker (running)
- A Google Cloud project with OAuth 2.0 credentials
git clone <repo-url>
cd replit_clonecp .env.example .envEdit .env and fill in the required values:
DOMAIN_URL=http://localhost:8000 # Your app's public URL
GOOGLE_CLIENT_ID=<your-client-id>
GOOGLE_CLIENT_SECRET=<your-client-secret>
JWT_SECRET=<random-secret-string>
DATABASE_URL=db/app.db # Use /app/data/data.db for Docker
CODE_SERVER_PASSWORD= # Optional password for code-serverIn your Google Cloud Console, add
<DOMAIN_URL>/api/googleAuthas an authorized redirect URI.
cd infra
./build_image.sh
cd ..This builds a Docker image (code-server-all) with Python 3, Java 17, and C++ pre-installed.
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
./run.shThe app will be available at http://localhost:8000.
# Configure .env first (set DOMAIN_URL to your public domain)
cd infra
./start.shThis builds all Docker images and starts the app via Docker Compose. To also start the Nginx reverse proxy:
docker compose --profile production up -dThe app will be served on port 80.
replit_clone/
├── app.py # FastAPI application & all routes
├── requirements.txt
├── run.sh # Dev server startup script
├── docker-compose.yml
├── .env.example
│
├── backend/
│ ├── auth.py # Google OAuth2 + PKCE + JWT
│ ├── db.py # SQLite database layer
│ └── schema.py # Pydantic models
│
├── infra/
│ ├── Dockerfile.code-server # User container image (Python + Java + C++ + code-server)
│ ├── Dockerfile.app # App container image
│ ├── Dockerfile.proxy # Nginx proxy image
│ ├── nginx.conf
│ ├── start.sh # Full bootstrap script
│ ├── build_image.sh # Build code-server image
│ ├── create_container.sh # Create a user container
│ ├── start_container.sh # Start a container
│ ├── stop_container.sh # Stop a container
│ ├── delete_container.sh # Remove a container
│ └── get_container_ip.sh # Resolve container IP
│
├── static/ # Frontend assets (CSS, JS)
├── templates/ # Jinja2 HTML templates
│ ├── home.html # Project dashboard
│ └── ide.html # IDE view (iframe + WebSocket)
└── db/
└── app.db # SQLite database (auto-created)
| Method | Path | Description |
|---|---|---|
GET |
/ |
Login / landing page |
GET |
/home |
Project dashboard (requires auth) |
GET |
/create |
New project form (requires auth) |
GET |
/ide/{containerUuid} |
IDE view for a container |
GET |
/api/googleRedirect |
Start Google OAuth flow |
GET |
/api/googleAuth |
Google OAuth callback |
GET |
/api/logout |
Clear session and redirect to login |
POST |
/api/createContainer |
Create a new project |
POST |
/api/startContainer/{containerUuid} |
Start a container |
POST |
/api/stopContainer/{containerUuid} |
Stop a container |
POST |
/api/deleteContainer/{containerUuid} |
Delete a container |
WS |
/ws/{containerUuid} |
Heartbeat WebSocket (auto-stops on disconnect) |
users
| Column | Type | Notes |
|---|---|---|
userId |
INTEGER PK | Auto-increment |
googleId |
TEXT UNIQUE | Google OAuth subject ID |
username |
TEXT | Display name from Google |
containers
| Column | Type | Notes |
|---|---|---|
containerId |
INTEGER PK | Auto-increment |
ownerId |
INTEGER | FK → users.userId |
containerUuid |
TEXT UNIQUE | Used as Docker container name |
name |
TEXT | User-provided project name |
language |
TEXT | python, java, cpp, or vscode |
status |
TEXT | stopped or running |
created_at |
TIMESTAMP | Set by SQLite |
Containers follow a Docker-out-of-Docker (DooD) pattern: the app container mounts /var/run/docker.sock and uses shell scripts to manage sibling containers on the host Docker daemon.
Container naming: replit-user-<containerUuid>
Each container runs code-server on port 8080. The Nginx proxy routes /container/<container_id>/<path> directly to the container's IP.
Open source. See LICENSE for details.