Skip to content

llOrtegall/java-online

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

☕ Java Online Playground

Un entorno de ejecución de código Java en línea, construido con Node.js, TypeScript, Docker y React. Este proyecto permite ejecutar código Java de forma segura en contenedores aislados directamente desde el navegador.

Nota: Este proyecto fue creado con fines educativos como parte de mi portafolio de desarrollo. No cuenta con derechos reservados y está disponible para aprendizaje y referencia.

🚀 Características

  • Ejecución segura de código Java: Utiliza contenedores Docker aislados con límites de recursos
  • API REST: Backend construido con Express y TypeScript
  • Límites de recursos: Control de memoria (128MB), CPU (0.5 cores) y timeout (5 segundos)
  • Detección automática de código: Envuelve automáticamente snippets simples en una clase Main
  • Frontend moderno: Interfaz de usuario construida con React y Vite
  • Arquitectura en contenedores: Completamente dockerizada con Docker Compose
  • Proxy inverso: Nginx para enrutamiento y servir archivos estáticos

🏗️ Arquitectura

┌─────────────────┐
│   Nginx Proxy   │
│   (Port 80)     │
└────────┬────────┘
         │
    ┌────┴────────────────────┐
    │                         │
┌───▼──────┐          ┌───────▼────────┐
│ Frontend │          │    Backend     │
│  (React) │          │  (Node.js/TS)  │
└──────────┘          └───────┬────────┘
                              │
                      ┌───────▼────────┐
                      │  Docker Socket │
                      │  Java Runner   │
                      └────────────────┘

Componentes

  • Frontend: React + Vite + TypeScript
  • Backend: Node.js + Express + TypeScript
  • Java Runner: Contenedor Docker con OpenJDK 21
  • Nginx: Proxy inverso y servidor de archivos estáticos
  • Red: Red Docker personalizada (ortega-net)

📋 Requisitos Previos

  • Docker (v20.10+)
  • Docker Compose (v2.0+)
  • Node.js (v22+) - solo para desarrollo local
  • NPM o Bun

🛠️ Instalación

1. Clonar el repositorio

git clone https://github.com/llOrtegall/java-online.git
cd java-online

2. Crear la red Docker

docker network create ortega-net

3. Construir la imagen del runner de Java

cd backend
npm run docker:build

4. Construir y levantar los servicios

cd ..
docker compose up -d --build

🎯 Uso

API Endpoints

Health Check

GET /health

Respuesta:

{
  "status": "ok",
  "service": "java-playground-backend"
}

Verificar Docker

GET /check-docker

Respuesta:

{
  "dockerAvailable": true,
  "imageReady": true,
  "message": "Docker image ready",
  "dockerImagesStdout": "3f1ca98236d2\n",
  "dockerImagesStderr": ""
}

Ejecutar código Java

POST /execute
Content-Type: application/json

{
  "code": "System.out.println(\"Hello World!\");"
}

Respuesta exitosa:

{
  "success": true,
  "output": "Hello World!\n",
  "executionTime": 1684
}

Respuesta con error:

{
  "success": false,
  "error": "error: ';' expected\n...",
  "executionTime": 525
}

Ejemplos de código

Código simple (se envuelve automáticamente)

System.out.println("Hello from Java!");
int x = 10;
int y = 20;
System.out.println("Sum: " + (x + y));

Clase completa

public class Main {
    public static void main(String[] args) {
        for(int i = 1; i <= 5; i++) {
            System.out.println("Number: " + i);
        }
    }
}

🔧 Desarrollo Local

Backend

cd backend
npm install
npm run dev

El servidor se iniciará en http://localhost:4000

Frontend

cd frontend
npm install
npm run dev

El frontend se iniciará en http://localhost:5173

📁 Estructura del Proyecto

java-online/
├── backend/
│   ├── src/
│   │   ├── index.ts              # Servidor Express principal
│   │   ├── services/
│   │   │   └── javaExecutor.ts   # Lógica de ejecución de Java
│   │   └── types/
│   │       └── index.ts          # Definiciones de tipos
│   ├── Dockerfile                # Imagen del backend
│   ├── Dockerfile.java-runner    # Imagen del runner de Java
│   ├── build-docker-image.sh     # Script de construcción
│   ├── package.json
│   └── tsconfig.json
├── frontend/
│   ├── src/
│   │   ├── App.tsx               # Componente principal
│   │   ├── main.tsx              # Punto de entrada
│   │   └── assets/
│   ├── public/
│   ├── nginx.conf                # Configuración de Nginx
│   ├── package.json
│   └── vite.config.ts
├── docker-compose.yaml           # Orquestación de servicios
└── README.md

🔒 Seguridad

El proyecto implementa varias medidas de seguridad para la ejecución de código:

  • Contenedores aislados: Cada ejecución corre en un contenedor Docker separado
  • Límites de recursos:
    • Memoria: 128MB
    • CPU: 0.5 cores
    • PIDs: 50 procesos máximo
    • Timeout: 5 segundos
  • Límite de código: Máximo 10,000 caracteres
  • Limpieza automática: Los archivos temporales se eliminan después de cada ejecución
  • Sin persistencia: Los contenedores se destruyen después de la ejecución (--rm)

🐳 Docker

Imágenes utilizadas

  • Backend: node:22-alpine con Docker CLI
  • Java Runner: openjdk:21-slim
  • Nginx: nginx:stable-alpine3.21

Volúmenes

  • /var/run/docker.sock: Socket de Docker para ejecutar contenedores desde el backend
  • /tmp:/tmp: Directorio temporal compartido para archivos Java

Variables de entorno

PORT=4000  # Puerto del backend

📊 Scripts Disponibles

Backend

npm run dev          # Modo desarrollo con hot-reload
npm run build        # Compilar TypeScript a JavaScript
npm start            # Iniciar servidor en producción
npm run docker:build # Construir imagen del runner de Java
npm run docker:check # Verificar imagen del runner
npm run setup        # Configuración inicial completa

Frontend

npm run dev          # Servidor de desarrollo
npm run build        # Compilar para producción
npm run preview      # Vista previa de la build
npm run lint         # Ejecutar ESLint

🚨 Solución de Problemas

El backend no detecta la imagen de Java

# Verificar que la imagen existe
docker images | grep java-runner

# Reconstruir la imagen
cd backend && npm run docker:build

Error "Cannot find module '/app/dist/index.js'"

# Reconstruir el backend
docker compose build java-backend
docker compose up -d java-backend

Timeout en la ejecución

El timeout por defecto es de 5 segundos. Para código que requiere más tiempo, ajusta el valor en backend/src/index.ts:

const result = await javaExecutor.executeJavaCode(code, {
  timeout: 10000,  // 10 segundos
  memoryLimit: '128m',
  cpus: '0.5',
});

🤝 Contribuciones

Este proyecto es principalmente educativo, pero las contribuciones son bienvenidas. Si deseas mejorar el código:

  1. Fork el proyecto
  2. Crea una rama para tu feature (git checkout -b feature/amazing-feature)
  3. Commit tus cambios (git commit -m 'Add some amazing feature')
  4. Push a la rama (git push origin feature/amazing-feature)
  5. Abre un Pull Request

📝 Licencia

Este proyecto fue creado con fines educativos y está disponible libremente para aprendizaje y referencia. No cuenta con derechos reservados.

Uso educativo: Puedes usar, modificar y distribuir este código para propósitos de aprendizaje.

👨‍💻 Autor

llOrtegall

🙏 Agradecimientos

  • OpenJDK por el compilador y runtime de Java
  • Docker por la tecnología de contenedores
  • Node.js y Express por el framework del backend
  • React y Vite por las herramientas de frontend
  • La comunidad de código abierto

⭐ Si este proyecto te fue útil para aprender, considera darle una estrella en GitHub!

About

Proyecto para practicar java online v21

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published