-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdependencies.txt
471 lines (332 loc) · 10.4 KB
/
dependencies.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
========================================================= JENKINS WITH CI/CD ============================================================
Here’s a step-wise guide to set up a Python application with tests using *pytest, integrate it with Jenkins, and connect it to GitHub webhooks using **ngrok*.
---
### Step-Wise Guide:
#### *1. Set Up Jenkins*
1. *Install Jenkins*:
- Download and install Jenkins.
- Ensure Jenkins is running locally, e.g., on port 8080.
2. *Install Plugins*:
- Go to *Manage Jenkins > Manage Plugins > Available Tab*.
- Install the following plugins:
- *GitHub Integration Plugin*
- *Pipeline Plugin*
3. *Create a Pipeline Job*:
- Go to *Jenkins Dashboard > New Item > Pipeline*.
- Name the job, e.g., GitHub_Webhook_Test_Pipeline.
- Choose from Build triggers Github hook trigger for GITsce pooling
---
#### *2. Create Python Application and Tests*
1. *Set Up Project Structure*:
plaintext
my_python_app/
├── app/
│ ├── __init__.py
│ ├── main.py
├── tests/
│ ├── __init__.py
│ ├── test_main.py
├── requirements.txt
├── Jenkinsfile
├── pytest.ini
├── README.md
2. *Sample Python Code (Application)*: app/main.py
python
def add(a, b):
"""Adds two numbers."""
return a + b
def subtract(a, b):
"""Subtracts two numbers."""
return a - b
3. *Sample Tests (Using pytest)*: tests/test_main.py
python
from app.main import add, subtract
def test_add():
assert add(3, 5) == 8
assert add(-1, 1) == 0
def test_subtract():
assert subtract(10, 5) == 5
assert subtract(0, 5) == -5
4. *Requirements File*: requirements.txt
plaintext
pytest
5. *pytest Configuration File*: pytest.ini
plaintext
[pytest]
addopts = -v
testpaths = tests
---
#### *3. Configure Jenkins Pipeline*
1. *Jenkinsfile*: Jenkinsfile
pipeline {
agent any
stages {
stage('Clone Repository') {
steps {
git branch: 'main', url: 'https://github.com/username/my_python_app.git'
}
}
stage('Install Dependencies') {
steps {
sh 'pip install -r requirements.txt'
}
}
stage('Run Tests') {
steps {
sh 'pytest'
}
}
}
}
2. *Commit and Push*:
- Commit the Jenkinsfile and Python project to a GitHub repository.
---
#### *4. Configure Ngrok*
1. *Download ngrok*:
- Download and install ngrok from [ngrok.com](https://ngrok.com/).
- wget https://bin.equinox.io/c/bNyj1mQVY4c/ngrok-v3-stable-linux-amd64.tgz
- sudo tar xvzf ./ngrok-v3-stable-linux-amd64.tgz -C /usr/local/bin
2. *Authenticate ngrok*:
bash
ngrok authtoken <your-authtoken>
3. *Run ngrok*:
bash
ngrok http 8080
Copy the HTTPS URL (e.g., https://<random-subdomain>.ngrok.io).
---
#### *5. Configure GitHub Webhook*
1. Go to your repository’s *Settings > Webhooks*.
2. Click *Add Webhook*.
3. Set the *Payload URL*:
https://<random-subdomain>.ngrok.io/github-webhook/
4. Set *Content Type* to application/json.
5. Select the event: *Just the push event*.
6. Save the webhook.
---
#### *6. Run the Pipeline*
1. Push any change to the repository.
echo "# New change" >> README.md
git add .
git commit -m "Testing webhook"
git push origin main
2. GitHub will send a webhook to Jenkins via the ngrok URL.
3. Jenkins will:
- Clone the repository.
- Install dependencies.
- Run the pytest tests.
4. View results in Jenkins.
---
### Example Output:
#### *Jenkins Console Output*
[Pipeline] Start of Pipeline
[Pipeline] stage (Clone Repository)
Cloning repository...
[Pipeline] stage (Install Dependencies)
Installing pytest...
[Pipeline] stage (Run Tests)
Running pytest...
tests/test_main.py::test_add PASSED
tests/test_main.py::test_subtract PASSED
Now your setup is complete with a Python app, pytest for testing, Jenkins for CI/CD, and GitHub webhooks for automation!
(LINUX COMMANDS)
hostname -I --> ip address
whoami ---> username
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#Q3 SSH REMOTE-LOCAL CONNECTION
ssh-keygen -t rsa -b 2048
ssh-copy-id username@ip
--create a test.sh in remote system
ssh username@ip 'bash ~/test.sh'
To transfer file from remote to local: (write this command in a script file--> script.sh)
scp "username@ip":"filename_remote" "filename_local"
Then run the script file ---> bash script.sh
To send file from local to remote: (write this command in a script file--> script.sh)
scp "filename_local" "username@ip":"filename_remote"
Then run the script file ---> bash script.sh
to install SSH(if not present):
sudo apt install openssh-server
sudo systemctl start ssh
sudo systemctl enable ssh
sudo apt install openjdk-17-jdk
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
#Q4 DOCKER
(!CHANGES!) THERE ARE TWO COMMANDS (sudo snap install docker and sudo apt install docker.io)
sudo snap install docker.io
docker build -t myapp .
###############################################################################################
If u see docker.sock error, cd ../.. (return to base directory)
cd /var
cd /run
sudo chmod 666 docker.sock
(!CHANGES!) (This can be modified to sudo chmod 666 /var/run/docker.sock)
Another way to solve permission error
sudo usermod -aG docker$USER
newgrp docker
################################################################################################
docker run -d -p 5000:5000 myapp
docker tag myapp/app deepsh0203/app:latest
docker push deepsh0203/app:latest
docker pull deepsh0203/app:latest
Incase if Docker push,pull mentioned in question
deepsh0203 is Dockerhub username, create one for u
myapp-repo name
app-image name
app.py :
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return "Hello from Flask!"
if __name__ == "__main__":
app.run(host="0.0.0.0",port=5000)
(!CHANGES!) (You can add endpoints if u want)
CODE2 app.py (GET METHOD):
from flask import Flask,jsonify
app = Flask(__name__)
students = [
{"id":1,"name":"Dennis","age":20,"Major":"Computer Science"},
{"id": 2, "name": "Harish", "age": 20, "major": "Mathematics"},
{"id": 3, "name": "Badri", "age": 20, "major": "Machine Learning"}
]
@app.route("/")
def home():
return "Hello World"
@app.route("/students",methods=["GET"])
def getStudents():
return jsonify(students)
@app.route("/students/<int:studentId>",methods=["GET"])
def getStudent(studentId):
student=None
for i in students:
if i["id"]==studentId:
student=i
break
if student!=None:
return jsonify(student)
else:
return jsonify({"error":"Student not found"}),404
if __name__=='__main__':
app.run("0.0.0.0",5000)
Dockerfile:
# Use the official Python image
FROM python:3.9
# Set the working directory in the container
WORKDIR /app
# Copy the current directory contents into the container
COPY . /app
# Install any needed packages specified in requirements.txt
RUN pip install -r requirements.txt
# Make port 5000 available to the world outside this container
EXPOSE 5000
# Define environment variable
ENV NAME=FlaskApp
# Run app.py when the container launches
CMD ["python", "app.py"]
requirements.txt:
Flask==2.3.3
Werkzeug==2.3.3
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#Q6 LOAD BALANCING
========================================================LOGIC 1============================================================================
app.py:
from flask import Flask, jsonify
import os
app = Flask(__name__)
@app.route('/')
def index():
return jsonify({
"message": "Hello from Flask instance",
"instance": os.getenv('INSTANCE_NAME', 'Unknown')
})
if __name__ == "__main__":
app.run(host='0.0.0.0', port=5000)
docker-compose.yml:
version: '3.8'
services:
flask1:
image: flask-app
environment:
- INSTANCE_NAME=Flask_Instance_1
ports:
- "5001:5000"
flask2:
image: flask-app
environment:
- INSTANCE_NAME=Flask_Instance_2
ports:
- "5002:5000"
flask3:
image: flask-app
environment:
- INSTANCE_NAME=Flask_Instance_3
ports:
- "5003:5000"
Dockerfile:
# Use Python as the base image
FROM python:3.9-slim
# Set the working directory
WORKDIR /app
# Copy files to the container
COPY . .
# Install dependencies
RUN pip install flask
# Expose the Flask port
EXPOSE 5000
# Start the Flask app
CMD ["python", "app.py"]
Commands to run:
sudo apt-get install nginx
sudo apt-get install apache2-utils
docker build -t flask-app .
docker-compose up -d
nginx.conf:
#user nobody;
worker_processes 1;
#pid logs/nginx.pid;
events {}
http {
log_format minimal '$remote_addr $upstream_addr';
access_log <create a custom access.log file in your folder> (eg: /Users/akash/load/custom_access.log) ;
create a custom.log file in your folder
upstream flask_backend {
server localhost:5001;
server localhost:5002;
server localhost:5003;
}
server {
listen 80;
location / {
proxy_pass http://flask_backend;
}
}
}
===============================================================LOGIC 2=====================================================================
sudo apt-get install nginx
sudo apt-get install apache2-utils
docker build -t flaskapp5 .
docker run -d -p 5001:5000 flaskapp5
docker run -d -p 5002:5000 flaskapp5
docker run -d -p 5003:5000 flaskapp5
ab -n 1000 -c 100 http://localhost:5001/ (takes more time)
code /etc/nginx/nginx.conf
sudo chmod o+w /etc/nginx/nginx.conf
sudo rm /etc/nginx/sites-enabled/default
sudo nginx -t
sudo systemctl restart nginx
curl http://localhost/
ab -n 1000 -c 100 http://localhost/ (takes lesser time)
docker logs containerID
When a text editor or vsc opens, type this:
http {
upstream flaskapp {
server localhost:5001;
server localhost:5002;
server localhost:5003;
}
server {
listen 80;
location / {
proxy_pass http://flaskapp;
}
}
}