Cloud Computing Project Documentation

Charan Gnanasekar Geetha

 

Dynamic Multi-Language Code Runner using Docker Containers

 

Introduction

The Dynamic Multi-Language Code Runner is a complete application that is built with containerization and can compile and execute code written in multiple programming languages, all while maintaining a secure and isolated environment. The goal of this project is to show how Docker can be used to unify different compiler environments into a single container while providing benefits such as scale, portability, and independence to any platform.

 

Objectives of part 1 – Backend setup

To develop and execute a backend service with Node.js and Express that accepts code and language from the frontend, handles the execution in a safe environment, and sends the output back.

Objectives:

·         Create a REST API endpoint (/run) where the user can run their code.

·         Implement code and language parameter input parsing.

·         With the help of CORS, we can allow the server to respond to the frontend

·         Run the shell commands using Node's child process.

·         Prepare the server to talk to the Docker runtime environment later.

 

Objectives of part 2 -- Docker environment setup

The objective is developing a Docker image that can run code in several programming languages that will run consistently and in isolation from the host machine.

objectives:

·         Build a Docker file with a base image using Ubuntu

·         Install compilers or/or interpreters for at least 25 programming languages. Languages may include C, C++, Java, Python, Go, Rust, PHP, Ruby, Kotlin, and others.

·         Build a run.sh script that can be used to run code from any of the languages that have been installed in the container.

·         Set up the Docker image to allow user code to be accepted through the backend layer and to run seamlessly in the container.

·         Test that each language runs successfully and correctly in the containerized application.

Objectives of part 3 – Frontend setup

To create a dynamic and responsive React.js frontend that allows users to enter code, select the language they want to run, and run the code using the backend API.

Objectives:

·         Create a single page user interface using the React components.

·         Create a code editor (text area) and a dropdown that lets the user select a coding language.

·         When the user clicks run code, connect the API in the front end to the backend API via using the fetch() or axios.

·         Render the output from the program or any error message on the same page in a neat way.

·         Use CSS Flexbox to style components such that it will align and be balanced in size.

Containers used:

Container Name: code-runner

- This container functions as the main runtime for executing user code in multiple programming languages.

- The container is based on Ubuntu 22.04 and contains all the required compilers and interpreters like GCC, G++, Java, Python, Node.js, Go, PHP, Ruby, etc.

- Built locally from a Dockerfile, and can be pushed to Docker Hub as:

your-dockerhub-username/code-runner-docker:latest

Container Name: node-backend

- This container acts as the backend server, processing API requests made by the frontend, and executing user code inside the code-runner environment.

- It is built on Node.js 20 LTS and Express.js with CORS enabled for frontend interaction.

- It is developed locally and can be pushed to Docker Hub as:

docker push charangg2005/code-runner-backend:latest

Container Name: Frontend (React Application)

- Built with React.js to provide the code editor, language selection, and output area.

- It makes a REST API call to interact with the backend.

- It is not yet containerized (will likely be added to Docker at some point).

 

Other Softwares used:

-          Docker: Used to create and run brand-new, isolated containers for each of the different environments—ensuring security, consistency, and ultimately portability across different systems. 

-          Node.js (v20): The runtime engine for the backend application that handles requests and executes commands. 

-          Express.js: The framework used in Node.js to define routes (like /run), which makes building a backend API easier and faster. 

-          React.js: The frontend framework that you used to design the code editor interface and create dynamic interactions. 

-          OS Ubuntu 22.04: Code-runner container's base operating system used to install all of the compilers on. 

-          Compilers: GCC / G++ was used for C and C++ language execution, while OpenJDK 17 was the compiler and runtime for Java programs. Python3 was an interpreter for Python scripts. 

-          Node.js & npm: These were used both for managing backend dependencies and running JavaScript code snippets in the container. 

-          Go, Rust, PHP, Ruby, Kotlin: A variety of additional languages were also supported as a part of the code-runner container. 

-          Git & GitHub: The best system for version control and storing your code online. 

-          Docker Hub: Where the modified container images live for shared or reuse. 

-          Visual Studio Code (VS Code): An IDE for developing, editing, running, and debugging your code. 

-          Postman (optional): This was a tool that you implemented as a way to test the API endpoints of the backend until you connected it to the frontend code. 

 

 

Architecture:

The architecture of the system contains three layers:

- Frontend Layer (React.js): It has an interface with a text editor where users can write code, choose a language, and click “Run”.

- Backend Layer (Node.js + Express): Accepts requests, identifies the language type, forwards the user’s code to Docker to execute, and returns the output.

- Execution Layer (Docker Container): Executes the user’s code in an isolated environment using the associated compiler or interpreter.

The Dynamic Multi-Language Code Runner's architecture embodies a modular, containerized structure. The React frontend allows the user to seamlessly interact with the system via an intuitive interface for the code they wish to input, which language they wish to run the code in, and to display the output. When a user clicks "Run Code," the front end makes an HTTP POST request to the backend server along with the source code and selected language as part of a JSON payload.

The backend server is built with Node.js and Express. Upon receiving the request, the server runs a shell command or a Docker process that executes the user’s code in a Docker container that has previously been configured. This Docker container is created from an Ubuntu base image with all compilers and interpreters required. The run.sh script identifies the language and calls the appropriate interpreter or compiler returning either output of the code execution or error. The output returned is in the form of JSON, which is then displayed in the frontend. The result is an online code execution platform that’s secure, efficient, and scalable.

 

Procedure:

Part 1 - Backend Setup

Steps Involved:

1. Initialize backend project using:

npm init -y

npm install express cors child_process

2. Create a server.js file and define the Express server.

3. Enable CORS to allow communication with frontend:

app.use(cors());

4. Define API endpoint /run to handle code and language input.

5. Test the backend locally using:

node server.js

6. Verify by visiting http://localhost:5000.

A screenshot of a computer program

AI-generated content may be incorrect.

A screenshot of a computer program

AI-generated content may be incorrect.

 

Server code:

 

A screen shot of a computer program

AI-generated content may be incorrect. 

A black screen with colorful text

AI-generated content may be incorrect.

 

Sunning the server on backend ,

A screen shot of a computer program

AI-generated content may be incorrect.


Part 2 - Docker Environment Setup

Steps Involved:

1. Create a Dockerfile with FROM ubuntu:22.04.

2. Install all compilers and tools:

     build-essential, openjdk-17-jdk, python3, nodejs, golang, rustc, php, ruby, kotlin, etc.

3. Copy languages.json and run.sh into the container.

4. Give execution permission using:

RUN chmod +x /run.sh

5. Build Docker image:

docker build -t code-runner .

6. Run container and test:

docker run -it code-runner

7. Verify by executing sample code inside container.

A screenshot of a computer program

AI-generated content may be incorrect.

 

Building Backend container ,

Building executor container ,

 

Running both containers together,

 

A screenshot of a computer

AI-generated content may be incorrect.

Part 3 – Frontend Development

Steps Involved:

1. Create React app:

npx create-react-app frontend

3. Modify App.js to include:

o   A language dropdown (25 languages).

o   A textarea for code input.

o   A “Run Code” button.

o   An output display section.

3. Connect to backend using:

fetch("http://localhost:5000/run", { method: "POST", body: JSON.stringify({ code, language }) });

4. Add styling using Flexbox for clean alignment.

5. Test by running:

npm start

6. Verify that the output displays correctly in browser.

A screenshot of a computer

AI-generated content may be incorrect.

A screenshot of a computer

AI-generated content may be incorrect.

A screenshot of a computer

AI-generated content may be incorrect.

and 20+ languages could be compiled and executed with this project using the docker containers.

 

Changes in the Containers:

·         Installed compilers/interpreters for over 25 languages.

·         Created run.sh for execution based on language.

·         Set Docker WORKDIR to /usr/src/app.

·         Provided execution access to shell scripts.

·         Connected with backend to provide the ability to execute code.

·         Provided ports that were necessary to connect the backend and frontend.

 

Docker Hub link – charangg2005/code_runner

 

Outcomes:

·         Ran code from multiple programming languages in a Docker container without an issue.

·         Successfully isolated the user code from the host OS completely.

·         Successfully created a full-stack application using React, Node.js, and Docker.

·         Proven that complete and functional communication between the front and backend using a REST API was achieved.

·         Verified that Docker can be a secure runtime environment for running arbitrary code.


Conclusion:

This project adeptly illustrates the effectiveness of Docker to create scalable language-agnostic execution environments. Through containerization and other modern web technologies, a real-life system emulating online coding sites is developed. The project builds on knowledge about RESTful APIs, software/frontend-backend integration, and deployment via DevOps. Future enhancements could include sandboxing, effective memory/time constraints, and file handling for digital submission.

 

Acknowledgements and References:

1. Docker Hub Base Images - Ubuntu, official Node.js images.

2. IIT Bombay Docker Tutorials - https://dockerlabs.collabnix.com

3. Stack Overflow, GitHub repos, and Docker Docs - For issue investigation and resolution, as well as performance tuning.

 

 

Comments