A full-stack, containerized Cloud Integrated Development Environment (IDE) built with React, Node.js / Express, Socket.IO, and Docker. CloudIDE allows users to create sandboxed development workspaces, edit files in real-time with Monaco Editor, run commands in a web-based interactive terminal, and execute Jupyter Notebooks.
- User Authentication: Secure user signup and login utilizing JSON Web Tokens (JWT) and bcrypt hashing.
- Containerized Sandboxes: Spawns isolated Docker containers for each development workspace dynamically.
- Supported Environments:
- Node.js (
node:alpine) - Python (
python:3.12-slim) - Java (
eclipse-temurinv8, v11, v17) - Jupyter Notebooks (
jupyter/scipy-notebook)
- Node.js (
- Full-featured Editor: Embedded Monaco Editor with syntax highlighting, auto-completion, and customizable settings.
- Interactive Terminal: Web terminal powered by Xterm.js attached directly to the sandboxed container via WebSockets (Socket.IO) with ANSI escape and resize support.
- Real-time File Tree: Dynamic directory tree explorer that syncs in real-time across the client and server filesystem using Chokidar watch events.
- Jupyter Integration: Fully embedded Jupyter Notebook interface running inside an iframe, preconfigured to bypass iframe CSP/XSRF restrictions.
- Workspace Port Forwarding: Automatically binds exposed container ports to dynamically allocated host ports, allowing developers to preview their web applications.
- Export Workspaces: Clean packaging and downloading of the user's workspace as a
.ziparchive, omitting bulky dependencies (node_modules,.git) but retaining vital configuration files.
The following diagram illustrates how the frontend editor, backend server, Docker sandboxes, and file system interact:
graph TD
%% Styling Definitions
classDef clientStyle fill:#3b82f6,stroke:#1d4ed8,stroke-width:2px,color:#fff;
classDef serverStyle fill:#10b981,stroke:#047857,stroke-width:2px,color:#fff;
classDef dockerStyle fill:#06b6d4,stroke:#0891b2,stroke-width:2px,color:#fff;
classDef dbStyle fill:#f59e0b,stroke:#d97706,stroke-width:2px,color:#fff;
%% Nodes
subgraph Client [Browser / Client Frontend]
Monaco[Monaco Editor]
Xterm[Xterm.js Terminal]
FileTree[File Tree Explorer]
JupyterIFrame[Jupyter IFrame]
end
subgraph Server [Backend Server - Node/Express]
Express[Express REST API]
SocketIO[Socket.IO Server]
Watcher[Chokidar FS Watcher]
Dockerode[Dockerode API Client]
end
subgraph HostFS [Host File System]
Workspaces[./server/workspaces]
end
subgraph DockerHost [Docker Engine Host]
subgraph Containers [Active Sandbox Containers]
NodeCont[Node Workspace Container]
JupyterCont[Jupyter Notebook Container]
end
end
subgraph Database [Database]
MongoDB[(MongoDB)]
end
%% Connections
Monaco -.->|HTTP / REST| Express
FileTree -.->|HTTP / REST| Express
%% Real-time Socket.IO communication
Xterm <==>|Socket.IO: terminal write/output| SocketIO
Monaco <==>|Socket.IO: file read/write/save| SocketIO
FileTree <==>|Socket.IO: directory modifications| SocketIO
%% Server orchestration
Express -->|Auth / Metadata| MongoDB
Express -->|Start Jupyter Container| Dockerode
SocketIO -->|Setup Container / Attach Stream| Dockerode
%% File System Interactions
Watcher -->|Watch Workspace Directory| Workspaces
Watcher -.->|File Changed Event| SocketIO
Workspaces -->|Bind Mount Workspace| Containers
%% Container Interactions
Dockerode -->|Manage & Run| Containers
SocketIO <==>|Attach TTY Streams| NodeCont
JupyterIFrame <==>|Direct HTTP Iframe Connection| JupyterCont
%% Apply Classes
class Monaco,Xterm,FileTree,JupyterIFrame clientStyle;
class Express,SocketIO,Watcher,Dockerode serverStyle;
class NodeCont,JupyterCont,Containers dockerStyle;
class MongoDB dbStyle;
- Framework: React 19, Vite (build engine)
- Styling: Tailwind CSS v4, Lucide React
- Editor:
@monaco-editor/react - Terminal:
@xterm/xterm,@xterm/addon-fit - Real-Time/API:
socket.io-client,axios, React Router DOM v7
- Runtime: Node.js, Express.js (v5)
- Real-Time: Socket.IO
- Database: MongoDB via Mongoose
- Containerization: Dockerode (Docker API Client)
- File System: Chokidar (FS watcher), Archiver (Zip packaging)
- Security:
jsonwebtoken,bcrypt
Before running the application, make sure you have the following installed and running:
- Node.js (v18 or higher)
- MongoDB (Local instance or MongoDB Atlas connection string)
- Docker Engine / Docker Desktop (Must be running and accessible via system sockets):
- Windows: Docker Desktop must be running. The backend connects via the Named Pipe:
//./pipe/docker_engine. - macOS / Linux: Docker daemon running on the standard Unix socket:
/var/run/docker.sock.
- Windows: Docker Desktop must be running. The backend connects via the Named Pipe:
git clone <repository-url>
cd cloudideNavigate to the server directory and install dependencies:
cd server
npm installCreate a .env file in the server directory:
PORT=3000
MONGO_URI=mongodb://localhost:27017/cloudide
ACCESS_TOKEN_SECRET=your_jwt_access_secret_key
REFRESH_TOKEN_SECRET=your_jwt_refresh_secret_keyNavigate to the client directory and install dependencies:
cd ../client
npm installEnsure the client points to the backend server. By default, configuration is set up to interact with the backend at http://localhost:3000.
From the server directory:
# Production mode
npm start
# Development mode (with nodemon auto-restart)
npm run devFrom the client directory:
# Start development server
npm run devOpen http://localhost:5173 in your browser.
cloudide/
βββ client/ # React frontend application
β βββ public/ # Static public assets
β βββ src/
β β βββ components/ # UI components (sidebar, tree, editor, terminal)
β β βββ context/ # React context (Auth context)
β β βββ pages/ # Login, Register, Dashboard, Workspace pages
β β βββ utils/ # Helpers, socket configuration
β β βββ App.jsx # App router configuration
β β βββ main.jsx # App entry point
β βββ tailwind.config.js # Tailwind CSS configuration
β βββ vite.config.js # Vite build configuration
β
βββ server/ # Express backend server
β βββ controllers/ # Route controllers (Auth, etc.)
β βββ middlewares/ # Express middlewares (JWT authentication)
β βββ models/ # Mongoose database models (User, Project)
β βββ routes/ # Express endpoint routing
β βββ workspaces/ # Local workspace storage directory (mounted to Docker containers)
β βββ index.js # Express & Socket.IO server entrypoint
β βββ package.json # Server configuration & script files
POST /api/auth/register- Create a new user account.POST /api/auth/login- Authenticate a user and return tokens.
POST /api/createProject- Create a new project workspace directory with a specified environment.GET /api/listProjects- Retrieve list of projects belonging to the logged-in user.GET /api/getProjectFileTree- Fetch recursive directory structure of a project workspace.GET /api/getContainerEnvironments- Fetch a list of supported container runtime environments.GET /api/downloadUserProject- Zips and downloads project files.DELETE /api/deleteProject- Stops associated containers, removes files, and deletes project records.POST /api/startJupyterProject- Starts a containerized Jupyter server instance.
Requires authentication JWT token passed in the Socket auth payload, and workspace details (projectId, projectName, env) passed in query parameters.
terminal:write- Sends terminal keystroke input to the container shell.terminal:resize- Notifies container of terminal column and row sizing.file:read- Requests contents of a file in the workspace.file:write- Saves changes / writes content to a file.file:delete- Deletes a file from the workspace.file:rename- Renames / moves a file.create:dir- Creates a new subdirectory.
container-ready- Notifies client that container is up and running. Returns the forwarded port and host URL.terminal:output- Sends stdout/stderr stream from the container command shell to xterm.js.file:content- Returns the text content of a requested file.file:changed- Real-time notification of files added/edited/removed in the container workspace directory.file:saved/file:deleted/file:renamed/dir:created- Response notifications for file operations.file:error/dir:error- Error messages when file operations fail.
Each workspace environment is completely sandboxed:
- Files are stored on the host system under
./server/workspaces/<userId>/<projectId>and bind-mounted to/workspace/<projectName>(Node/Java/Python) or/home/jovyan/work(Jupyter) inside the container. - File system checks (
getSafePath) prevent directory traversal attacks (e.g. attempting to read../../etc/passwd). - Containers run with limited resources and automatic/manual cleanup upon disconnect or workspace deletion.


