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.
Server code:
Sunning the server on backend
,
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.
Building Backend container ,
Building executor container ,
Running both containers together,
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.
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
Post a Comment