Skip to content

Commit 8126026

Browse files
Merge pull request #31 from ashirrwad/final
Upgraded UI, Fixed minor bugs, Added Instructions for Production
2 parents 8e103f7 + d48b5a5 commit 8126026

File tree

15 files changed

+268
-58
lines changed

15 files changed

+268
-58
lines changed

README.md

Lines changed: 119 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,15 @@ When ready, type:
4141

4242
```
4343
cd backend/Docker
44-
docker build -t playground-f .
44+
docker build -t playground-prod .
4545
```
4646

4747
To confirm that it worked, type `docker images` and you should see
48-
`playground-f` in the list of images under the `REPOSITORY` column, for example:
48+
`playground-prod` in the list of images under the `REPOSITORY` column, for example:
4949

5050
```
5151
REPOSITORY TAG IMAGE ID CREATED SIZE
52-
playground-f latest 8c2439e40e81 1 hour ago 201MB
52+
playground-prod latest 8c2439e40e81 1 hour ago 201MB
5353
```
5454

5555
Now move one directory up where we will set up the Python environment and the
@@ -95,7 +95,11 @@ curl \
9595
--location \
9696
--request POST '127.0.0.1:5000/run' \
9797
--header 'Content-Type: application/json' \
98-
--data-raw '{"code": "program hello\nprint *, \"Hello World New Line\"\nprint *, \"Hello Mars\"\nend program hello", "programInput": "", "libs": ""}'
98+
--data-raw '{
99+
"code": "program hello\r\n ! This is a comment line; it is ignored by the compiler\r\n print *, 'Hello, World!'\r\nend program hello\r\n",
100+
"programInput": "",
101+
"libs" : []
102+
}'
99103
```
100104

101105
If everything is set up correctly so far, you should get the following response:
@@ -133,3 +137,114 @@ playground.
133137

134138
Please report any issues or suggestions for improvement by opening a
135139
[new GitHub issue](https://github.com/fortran-lang/playground/issues/new).
140+
141+
## Production Guide
142+
This is a setup guide to host the server on AWS EC2. It's assuming you already have an account setup and know about free tier limitations.
143+
#### Setting up EC2
144+
1. Select the EC2 Launch Instance Wizard choose Ubuntu(22.04 x86) as your OS under AMI section.
145+
2. Choose t2.micro instance if you want to stay within free tier or your preferred instance type and head to the next section. Keep configuration as default.
146+
3. Select the storage you need, 20 GBs should be more than enough and it'll still stay under free tier. Go to next step and leave tags as default.
147+
4. Configure the security group as follows:
148+
![security group](https://imgur.com/a/zGTCN6F)
149+
5. Click next to choose your key pair.(You'll be connecting to SSH via this key so keep it safe, if you don't have one already generate a new one)
150+
151+
Now, we need to attach an Elastic IP to this instance, as instances are allocated only a dynamic IP, also free tier only allows 1 hour of use without an elastic IP.
152+
153+
1. Select Elastic IP in the navigation pane, and generate a new Elastic IP.
154+
2. Associate this Elastic IP to the instance you've just created.
155+
3. Go to your instance and copy this Elastic IP(you'll see it listed under the v4 IP address)
156+
157+
#### Setting up the EC2 instance
158+
1. Locate your key.pem file you generated in step 5 and connect to your server by using SSH:
159+
```
160+
sudo ssh -i <pem file> ubuntu@<Public IP of the EC2 instance>
161+
```
162+
2. Update your instance
163+
```sudo apt-get update```
164+
3. Install pip
165+
```sudo apt install python3-pip```
166+
4. Install nginx
167+
`sudo apt-get install nginx`
168+
5 Install node.js and npm using nvm.
169+
Get NVM
170+
``curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash`
171+
``
172+
Activate nvm
173+
`. ~/.nvm/nvm.sh`
174+
Install node
175+
`nvm install --lts`
176+
177+
#### Setting up the playground on VM
178+
1. Clone the repository
179+
`git clone https://github.com/fortran-lang/playground.git`
180+
2. Assign all read and write permissions to the project directory
181+
```sudo chmod 777 playground```
182+
```cd playground```
183+
3. Go to frontend directory`cd playground/frontend`, before we build a production version we need to replace our API calls with the public IP.
184+
a. Open App.js file which has our API call:
185+
`sudo nano playground/frontend/src/App.js`
186+
b. Replace the http://127.0.0.1:5000 url with http://{your public ip}:5000
187+
188+
4. Install modules `npm install`, create a build from those modules `npm run build`
189+
4. Create a directory for the frontend with the following command:
190+
`sudo mkdir /var/www/html/react`
191+
Next, copy all contents from the build directory to the react directory:
192+
`sudo cp -r /home/ubuntu/playground/frontend/build/* /var/www/html/react/`
193+
194+
5. To go on, set proper ownership of the react directory with the following command:
195+
`sudo chown -R www-data:www-data /var/www/html/react`
196+
6. Next, create an Nginx virtual host configuration file to host your React app.
197+
`nano /etc/nginx/conf.d/react.conf`
198+
add this to the file:
199+
`server {
200+
listen 80;
201+
listen [::]:80;
202+
root /var/www/html/react/;
203+
index index.html index.htm;
204+
# MODIFY SERVER_NAME EXAMPLE
205+
location / {
206+
try_files $uri $uri/ =404;
207+
}
208+
}`
209+
7. Restart nginx
210+
`systemctl restart nginx`
211+
212+
####Setting up Docker
213+
Refer this link for [setting up docker](https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository "setting up docker") (setup via repository).
214+
After successfully installing docker switch to the Docker directory `cd playground/backend/docker`
215+
and build the docker image `sudo docker build -t playground-prod .` .
216+
217+
#### Setting up the backend server
218+
1. Go to the backend folder `cd playground/backend`.
219+
2. Install pipenv to install packages from the pipfile
220+
`sudo pip install pipenv`
221+
3. Make a directory for virtual environment(this will be useful when setting up the service) using `mkdir .venv` and install all required modules using `pipenv install`
222+
4. Start the server using:
223+
```sudo pipenv run gunicorn --bind 0.0.0.0:5000 wsgi:app```
224+
225+
You'll now be able to use the app. You should also setup a service for the gunicorn server so that it starts automatically when the server boots.
226+
227+
#### Setting up the service
228+
1. Create a service file for our app `sudo nano /etc/systemd/system/backend.service`
229+
2. Write the following configuration:
230+
```
231+
[Unit]
232+
Description=Gunicorn instance to serve backend for playground
233+
After=network.target
234+
[Service]
235+
User=ubuntu
236+
Group=www-data
237+
WorkingDirectory=/home/ubuntu/playground/backend
238+
Environment="PATH=/home/ubuntu/playground/backend/.venv/bin"
239+
ExecStart=sudo /home/ubuntu/playground/backend/.venv/bin/gunicorn --workers 3 -b :5000 wsgi:app
240+
[Install]
241+
WantedBy=multi-user.target
242+
```
243+
Press Ctrl + X and save the file.
244+
3. Start the service using `sudo systemctl start backend`
245+
4. Then enable it so that it starts at boot:
246+
`sudo systemctl enable myproject`
247+
248+
Now, You'll can directly cater requests to the port and your app should work. I recommend using a
249+
reverse proxy for your requests by altering the nginx configuration and adding an endpoint
250+
for the API.

backend/Docker/Dockerfile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,8 @@ RUN git clone https://github.com/fortran-lang/stdlib.git
2525
WORKDIR /fortran/playground/libraries/stdlib
2626
RUN git checkout stdlib-fpm
2727
WORKDIR /fortran/playground
28+
COPY fpm.toml /fortran/playground/fpm.toml
29+
COPY main.f90 /fortran/playground/app/main.f90
30+
RUN /fortran/fpm build
31+
32+

backend/Docker/fpm.toml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
name = "playground"
2+
author = "Ashirwad Mishra"
3+
maintainer = "ashirwad.golu@gmail.com"
4+
5+
[build]
6+
auto-executables = true
7+
auto-tests = true
8+
auto-examples = true
9+
10+
[install]
11+
library = false
12+
13+
[dependencies.stdlib]
14+
path = "libraries/stdlib"

backend/Docker/main.f90

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
program sample
2+
print*, "Sample Program"
3+
end program sample

backend/Pipfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@ docker = "*"
99
flask-cors = "*"
1010
pyyaml = "*"
1111
tomlkit = "*"
12+
gunicorn = "*"
1213

1314
[dev-packages]

backend/app.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
# Starting container
1818
client = docker.from_env()
19-
container = client.containers.run("playground-f", tty=True, detach=True, network_disabled=True, mem_limit="16g")
19+
container = client.containers.run("playground-prod", tty=True, detach=True, network_disabled=True)
2020

2121
#Converting tutorial YAML
2222
with open('tutorial.yml', 'r') as file:
@@ -80,7 +80,11 @@ def run_code():
8080
edit_file(data["code"], data["programInput"], data["libs"])
8181
code_result = execute_code_in_container()
8282
if code_result.output[0] == None:
83+
print(code_result.output)
8384
output = jsonify({"executed": ""})
85+
if '<ERROR>' in code_result.output[1].decode():
86+
output = jsonify({"executed" : code_result.output[1].decode()})
87+
8488
return output, 202
8589
output = jsonify({"executed": code_result.output[0].decode()})
8690
print(code_result.output)
@@ -90,4 +94,4 @@ def run_code():
9094

9195

9296
if __name__ == "__main__":
93-
app.run(debug=True)
97+
app.run(host='0.0.0.0')

backend/wsgi.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from app import app
2+
if __name__=='__main__':
3+
app.run()

frontend/src/App.css

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,26 @@
3737
}
3838

3939
.options{
40+
4041
display: flex;
42+
flex-direction: column;
43+
width: 4em;
4144

4245
}
4346

4447
.output-formmating{
4548
white-space: pre-wrap;
4649

47-
}
50+
}
51+
52+
.tutButton {
53+
display: flex;
54+
justify-content: space-between;
55+
}
56+
57+
.selector{
58+
display: flex;
59+
align-items: center;
60+
margin: 2px;
61+
}
62+

0 commit comments

Comments
 (0)