Compare commits
No commits in common. "main" and "master" have entirely different histories.
58
README.md
Normal file
58
README.md
Normal file
@ -0,0 +1,58 @@
|
||||
# Docker Web Application
|
||||
|
||||
## Prerequisites
|
||||
- Docker installed on the system.
|
||||
|
||||
## Application Description
|
||||
This is a simple Flask web application running inside a Docker container. The app accepts user input via a form and displays the submitted data.
|
||||
|
||||
## Docker Setup
|
||||
|
||||
1. **Preparation**
|
||||
Run the following command to set up the environment:
|
||||
```bash
|
||||
./prepare-app.sh
|
||||
```
|
||||
|
||||
2. **Start the Application**
|
||||
Start the application with:
|
||||
```bash
|
||||
./start-app.sh
|
||||
```
|
||||
The app will be available at: [http://localhost:5000](http://localhost:5000)
|
||||
|
||||
3. **Stop the Application**
|
||||
To stop the application:
|
||||
```bash
|
||||
./stop-app.sh
|
||||
```
|
||||
|
||||
4. **Remove the Application**
|
||||
To remove all Docker containers, networks, and volumes:
|
||||
```bash
|
||||
./remove-app.sh
|
||||
```
|
||||
|
||||
## Working Example
|
||||
1. Prepare the application:
|
||||
```bash
|
||||
./prepare-app.sh
|
||||
```
|
||||
2. Start the app:
|
||||
```bash
|
||||
./start-app.sh
|
||||
```
|
||||
3. Visit [http://localhost:5000](http://localhost:5000) in a browser.
|
||||
|
||||
4. Stop the app:
|
||||
```bash
|
||||
./stop-app.sh
|
||||
```
|
||||
|
||||
5. Remove the app:
|
||||
```bash
|
||||
./remove-app.sh
|
||||
```
|
||||
|
||||
## Conclusion
|
||||
This application demonstrates Docker containerization of a Flask app with basic form handling.
|
18
docker-compose.yml
Normal file
18
docker-compose.yml
Normal file
@ -0,0 +1,18 @@
|
||||
version: '3.8'
|
||||
services:
|
||||
flask-app:
|
||||
build: .
|
||||
ports:
|
||||
- "5000:5000"
|
||||
networks:
|
||||
- flask-network
|
||||
restart: unless-stopped
|
||||
# You can add other services here, like a database if required
|
||||
|
||||
networks:
|
||||
flask-network:
|
||||
driver: bridge
|
||||
|
||||
volumes:
|
||||
flask-data:
|
||||
driver: local
|
21
dockerfile
Normal file
21
dockerfile
Normal file
@ -0,0 +1,21 @@
|
||||
# Use an official Python runtime as a parent image
|
||||
FROM python:3.8-slim
|
||||
|
||||
# Set the working directory inside the container
|
||||
WORKDIR /app
|
||||
|
||||
# Copy the current directory contents into the container at /app
|
||||
COPY . /app
|
||||
|
||||
# Install Flask
|
||||
RUN pip install --no-cache-dir flask
|
||||
|
||||
# Set the environment variable for Flask
|
||||
ENV FLASK_APP=testapp.py
|
||||
ENV FLASK_RUN_HOST=0.0.0.0
|
||||
|
||||
# Expose port 5000 for the Flask app
|
||||
EXPOSE 5000
|
||||
|
||||
# Run the Flask application
|
||||
CMD ["flask", "run", "--host=0.0.0.0", "--port=5000"]
|
11
prepare-app.sh
Executable file
11
prepare-app.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Create a Docker network
|
||||
echo "Creating Docker network..."
|
||||
docker network create flask-network
|
||||
|
||||
# Create a named volume for persistent storage (for example, for database)
|
||||
echo "Creating Docker volume..."
|
||||
docker volume create flask-data
|
||||
|
||||
echo "Preparation complete!"
|
15
remove-app.sh
Executable file
15
remove-app.sh
Executable file
@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Remove the Flask app container
|
||||
echo "Removing Flask app container..."
|
||||
docker rm flask-app
|
||||
|
||||
# Remove Docker network
|
||||
echo "Removing Docker network..."
|
||||
docker network rm flask-network
|
||||
|
||||
# Remove Docker volume
|
||||
echo "Removing Docker volume..."
|
||||
docker volume rm flask-data
|
||||
|
||||
echo "App removed successfully!"
|
9
start-app.sh
Executable file
9
start-app.sh
Executable file
@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Start the Flask app container
|
||||
echo "Starting Flask app container..."
|
||||
docker run -d --restart unless-stopped --name flask-app --network flask-network -p 5000:5000 flask-app
|
||||
|
||||
# Optionally, start any additional services (like a database) here if needed
|
||||
|
||||
echo "App is running at http://localhost:5000"
|
9
stop-app.sh
Executable file
9
stop-app.sh
Executable file
@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Stop the Flask app container
|
||||
echo "Stopping Flask app container..."
|
||||
docker stop flask-app
|
||||
|
||||
# Optionally, stop other services like the database here
|
||||
|
||||
echo "App stopped successfully!"
|
26
testapp.py
Normal file
26
testapp.py
Normal file
@ -0,0 +1,26 @@
|
||||
from flask import Flask, render_template, request
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route('/', methods=['GET', 'POST'])
|
||||
def home():
|
||||
if request.method == 'POST':
|
||||
college_name = request.form['college_name']
|
||||
student_name = request.form['student_name']
|
||||
course_name = request.form['course_name']
|
||||
year_of_study = request.form['year_of_study']
|
||||
|
||||
return f"College: {college_name}, Student: {student_name}, Course: {course_name}, Year: {year_of_study}"
|
||||
|
||||
return '''
|
||||
<form method="POST">
|
||||
College Name: <input type="text" name="college_name"><br>
|
||||
Student Name: <input type="text" name="student_name"><br>
|
||||
Course Name: <input type="text" name="course_name"><br>
|
||||
Year of Study: <input type="text" name="year_of_study"><br>
|
||||
<input type="submit" value="Submit">
|
||||
</form>
|
||||
'''
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(debug=True, host="0.0.0.0", port=5000) # This allows the app to run inside the container
|
@ -1,9 +0,0 @@
|
||||
FROM python:3.9-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY app/ .
|
||||
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
CMD ["python", "main.py"]
|
32
z1/README.md
32
z1/README.md
@ -1,32 +0,0 @@
|
||||
# Flask + PostgreSQL Kubernetes Deployment
|
||||
|
||||
This project deploys a Flask web application with a PostgreSQL backend using Kubernetes.
|
||||
|
||||
## 🛠 Structure
|
||||
|
||||
- `app/`: Flask source code (`main.py`, `requirements.txt`)
|
||||
- `k8s/`: Kubernetes manifests for deployments, services, namespace, etc.
|
||||
- `Dockerfile`: Builds the Flask app image
|
||||
- `prepare-app.sh`: Builds Docker image and prepares volumes
|
||||
- `start-app.sh`: Applies all Kubernetes objects
|
||||
- `stop-app.sh`: Deletes all Kubernetes resources
|
||||
- `statefulset.yaml`: Defines StatefulSet, PV, and PVC
|
||||
|
||||
## 🚀 Steps to Deploy
|
||||
|
||||
1. **Prepare the application:**
|
||||
```bash
|
||||
./prepare-app.sh
|
||||
|
||||
|
||||
hafzal03@LAPTOP-ELUS3HGM:~/mypro/z2$ kubectl get pods -n webapp-namespace
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
flask-app-6b844bf6-cq9t6 1/1 Running 0 8m37s
|
||||
postgres-644fc4c86d-l9h4f 1/1 Running 0 14m
|
||||
hafzal03@LAPTOP-ELUS3HGM:~/mypro/z2$ minikube service flask-service -n webapp-namespace
|
||||
|
||||
minikube service flask-service -n webapp-namespace
|
||||
|
||||
kubectl get pods -n webapp-namespace
|
||||
|
||||
kubectl rollout restart deployment flask-app -n webapp-namespace
|
@ -1,81 +0,0 @@
|
||||
from flask import Flask, request, jsonify, render_template_string
|
||||
import psycopg2
|
||||
import os
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
def get_db_connection():
|
||||
return psycopg2.connect(
|
||||
host=os.environ.get("POSTGRES_HOST"),
|
||||
database=os.environ.get("POSTGRES_DB"),
|
||||
user=os.environ.get("POSTGRES_USER"),
|
||||
password=os.environ.get("POSTGRES_PASSWORD"),
|
||||
port=os.environ.get("POSTGRES_PORT", 5432),
|
||||
)
|
||||
|
||||
def init_db():
|
||||
conn = get_db_connection()
|
||||
cur = conn.cursor()
|
||||
cur.execute("""
|
||||
CREATE TABLE IF NOT EXISTS students (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
room_number TEXT NOT NULL,
|
||||
faculty TEXT NOT NULL
|
||||
);
|
||||
""")
|
||||
conn.commit()
|
||||
cur.close()
|
||||
conn.close()
|
||||
|
||||
@app.route("/")
|
||||
def index():
|
||||
return "<h1>Welcome!</h1><p>Go to /add to add a student, /students to view all.</p>"
|
||||
|
||||
# HTML Form + POST Submission
|
||||
@app.route("/add", methods=["GET", "POST"])
|
||||
def add_student():
|
||||
if request.method == "POST":
|
||||
name = request.form.get("name")
|
||||
room_number = request.form.get("room_number")
|
||||
faculty = request.form.get("faculty")
|
||||
|
||||
if not name or not room_number or not faculty:
|
||||
return "All fields are required!", 400
|
||||
|
||||
conn = get_db_connection()
|
||||
cur = conn.cursor()
|
||||
cur.execute("INSERT INTO students (name, room_number, faculty) VALUES (%s, %s, %s)", (name, room_number, faculty))
|
||||
conn.commit()
|
||||
cur.close()
|
||||
conn.close()
|
||||
return "<p>Student added successfully!</p><a href='/add'>Add another</a>"
|
||||
|
||||
# HTML form
|
||||
return render_template_string("""
|
||||
<h2>Add Student</h2>
|
||||
<form method="post">
|
||||
Name: <input name="name"><br>
|
||||
Room Number: <input name="room_number"><br>
|
||||
Faculty: <input name="faculty"><br>
|
||||
<input type="submit" value="Add Student">
|
||||
</form>
|
||||
""")
|
||||
|
||||
# View all students
|
||||
@app.route("/students", methods=["GET"])
|
||||
def get_students():
|
||||
conn = get_db_connection()
|
||||
cur = conn.cursor()
|
||||
cur.execute("SELECT id, name, room_number, faculty FROM students")
|
||||
rows = cur.fetchall()
|
||||
cur.close()
|
||||
conn.close()
|
||||
|
||||
return jsonify([
|
||||
{"id": row[0], "name": row[1], "room_number": row[2], "faculty": row[3]} for row in rows
|
||||
])
|
||||
|
||||
if __name__ == "__main__":
|
||||
init_db()
|
||||
app.run(host="0.0.0.0", port=8000)
|
@ -1,5 +0,0 @@
|
||||
Flask==2.0.1
|
||||
Werkzeug==2.0.3
|
||||
psycopg2-binary==2.9.1
|
||||
python-dotenv==0.19.0
|
||||
Jinja2==3.0.3
|
@ -1,32 +0,0 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: flask-app
|
||||
namespace: webapp-namespace
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: flask
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: flask
|
||||
spec:
|
||||
containers:
|
||||
- name: flask
|
||||
image: flask-app:latest
|
||||
imagePullPolicy: Never
|
||||
ports:
|
||||
- containerPort: 8000
|
||||
env:
|
||||
- name: POSTGRES_HOST
|
||||
value: postgres
|
||||
- name: POSTGRES_DB
|
||||
value: mydatabase
|
||||
- name: POSTGRES_USER
|
||||
value: myuser
|
||||
- name: POSTGRES_PASSWORD
|
||||
value: mypassword
|
||||
- name: POSTGRES_PORT
|
||||
value: "5432"
|
@ -1,12 +0,0 @@
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: migrate
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: migrator
|
||||
image: myapp:latest
|
||||
command: ["python", "manage.py", "migrate"]
|
||||
restartPolicy: Never
|
@ -1,4 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: webapp-namespace
|
@ -1,57 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: postgres-pvc
|
||||
namespace: webapp-namespace
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: postgres
|
||||
namespace: webapp-namespace
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: postgres
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: postgres
|
||||
spec:
|
||||
containers:
|
||||
- name: postgres
|
||||
image: postgres:13
|
||||
env:
|
||||
- name: POSTGRES_DB
|
||||
value: mydatabase
|
||||
- name: POSTGRES_USER
|
||||
value: myuser
|
||||
- name: POSTGRES_PASSWORD
|
||||
value: mypassword
|
||||
ports:
|
||||
- containerPort: 5432
|
||||
volumeMounts:
|
||||
- name: postgres-storage
|
||||
mountPath: /var/lib/postgresql/data
|
||||
volumes:
|
||||
- name: postgres-storage
|
||||
persistentVolumeClaim:
|
||||
claimName: postgres-pvc
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: postgres
|
||||
namespace: webapp-namespace
|
||||
spec:
|
||||
selector:
|
||||
app: postgres
|
||||
ports:
|
||||
- port: 5432
|
@ -1,13 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: flask-service
|
||||
namespace: webapp-namespace
|
||||
spec:
|
||||
selector:
|
||||
app: flask
|
||||
type: NodePort
|
||||
ports:
|
||||
- port: 8000
|
||||
targetPort: 8000
|
||||
nodePort: 30080 # <-- Changed this
|
@ -1,10 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "Building Docker image for Flask app..."
|
||||
docker build -t flask-app:latest .
|
||||
|
||||
echo "Creating Minikube image cache (if using Minikube)..."
|
||||
eval $(minikube docker-env)
|
||||
docker build -t flask-app:latest .
|
||||
|
||||
echo "Preparation complete."
|
@ -1,18 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "Creating Namespace..."
|
||||
kubectl apply -f k8s/namespace.yaml
|
||||
|
||||
echo "Creating Persistent Volumes and StatefulSet..."
|
||||
kubectl apply -f k8s/statefulset.yaml -n webapp-namespace
|
||||
|
||||
echo "Deploying PostgreSQL..."
|
||||
kubectl apply -f k8s/postgres-deployment.yaml -n webapp-namespace
|
||||
|
||||
echo "Deploying Flask App..."
|
||||
kubectl apply -f k8s/deployment.yaml -n webapp-namespace
|
||||
|
||||
echo "Creating Service..."
|
||||
kubectl apply -f k8s/service.yaml -n webapp-namespace
|
||||
|
||||
echo "All resources have been applied."
|
@ -1,18 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "Deleting Flask App Deployment..."
|
||||
kubectl delete -f k8s/deployment.yaml -n webapp-namespace
|
||||
|
||||
echo "Deleting Flask Service..."
|
||||
kubectl delete -f k8s/service.yaml -n webapp-namespace
|
||||
|
||||
echo "Deleting PostgreSQL Deployment and PVC..."
|
||||
kubectl delete -f k8s/postgres-deployment.yaml -n webapp-namespace
|
||||
|
||||
echo "Deleting StatefulSet and PVs..."
|
||||
kubectl delete -f k8s/statefulset.yaml -n webapp-namespace
|
||||
|
||||
echo "Deleting Namespace..."
|
||||
kubectl delete -f k8s/namespace.yaml
|
||||
|
||||
echo "All resources have been deleted."
|
@ -1,9 +0,0 @@
|
||||
FROM python:3.9-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY app/ .
|
||||
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
CMD ["python", "main.py"]
|
138
z2/README.md
138
z2/README.md
@ -1,138 +0,0 @@
|
||||
# Flask + PostgreSQL Kubernetes WebApp
|
||||
|
||||
A lightweight full-stack web application powered by **Flask** and **PostgreSQL**, containerized with **Docker**, and deployed on **Kubernetes (Minikube)** using custom `Namespace`, `Deployment`, `StatefulSet`, and `Services`. Designed to demonstrate a production-like cloud-native architecture.
|
||||
|
||||
---
|
||||
|
||||
## Project Structure
|
||||
|
||||
```bash
|
||||
z2/
|
||||
├── app/
|
||||
│ ├── main.py # Flask application logic
|
||||
│ └── requirements.txt # Python dependencies
|
||||
├── k8s/
|
||||
│ ├── namespace.yaml # Custom namespace
|
||||
│ ├── deployment.yaml # Flask app deployment
|
||||
│ ├── postgres-deployment.yaml # PostgreSQL StatefulSet + PVC + Service
|
||||
│ ├── migrate-job.yaml # Migration job (optional)
|
||||
│ ├── service.yaml # Flask NodePort Service
|
||||
├── Dockerfile # For building Flask app image
|
||||
├── prepare-app.sh # Script: Build & tag Docker image
|
||||
├── start-app.sh # Script: Apply all Kubernetes configs
|
||||
├── stop-app.sh # Script: Delete all resources
|
||||
└── README.md # Project documentation
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## How It Works
|
||||
|
||||
1. **Prepare the Environment**
|
||||
```bash
|
||||
./prepare-app.sh
|
||||
```
|
||||
- Builds and tags Docker image locally
|
||||
- Prepares persistent volume (PVC) for PostgreSQL
|
||||
|
||||
2. **Deploy the Application**
|
||||
```bash
|
||||
./start-app.sh
|
||||
```
|
||||
- Creates namespace, StatefulSet, Deployments, Services
|
||||
|
||||
3. **Access the Web App**
|
||||
```bash
|
||||
minikube service flask-service -n webapp-namespace
|
||||
```
|
||||
- Opens the app in your browser (NodePort)
|
||||
|
||||
4. **Stop and Clean Everything**
|
||||
```bash
|
||||
./stop-app.sh
|
||||
```
|
||||
- Deletes all created Kubernetes resources
|
||||
|
||||
---
|
||||
|
||||
## Technologies Used
|
||||
|
||||
| Tool | Purpose |
|
||||
|----------------|------------------------------|
|
||||
| Flask | Web framework (Python) |
|
||||
| PostgreSQL | Relational database |
|
||||
| Docker | Containerization |
|
||||
| Kubernetes | Container orchestration |
|
||||
| Minikube | Local Kubernetes environment |
|
||||
|
||||
---
|
||||
|
||||
## Health Checks
|
||||
|
||||
To ensure resilience and uptime, Kubernetes probes can be added:
|
||||
|
||||
```yaml
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 8000
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 8000
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
```
|
||||
|
||||
Add a `/health` route to your `main.py`:
|
||||
```python
|
||||
@app.route('/health')
|
||||
def health():
|
||||
return "OK", 200
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Problem | Solution |
|
||||
|-------------------------------------|--------------------------------------------------------------------------|
|
||||
| ❌ `ImagePullBackOff` or `ErrImagePull` | Make sure image is built locally with `docker build -t flask-app .` and you're using `imagePullPolicy: Never` |
|
||||
| ❌ App not accessible | Check service type is `NodePort`, port 30080 is exposed, and run `minikube service flask-service -n webapp-namespace` |
|
||||
| ❌ Database errors | Ensure PostgreSQL pod is running (`kubectl get pods -n webapp-namespace`), check PVC and env vars |
|
||||
| ❌ "command not found: kubectl" | Install `kubectl` and make sure it’s configured with `minikube` context |
|
||||
| ❌ Connection refused errors | Check that `POSTGRES_HOST` matches the service name (`postgres`) and app waits until DB is ready |
|
||||
|
||||
---
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
- Use Helm for templated deployments
|
||||
- Add database migrations (Alembic / Flask-Migrate)
|
||||
- CI/CD integration with GitLab or GitHub Actions
|
||||
- Add Redis or caching layer
|
||||
- Auto-scaling and HorizontalPodAutoscaler
|
||||
|
||||
|
||||
|
||||
## Author
|
||||
|
||||
**Hafzal Ahamed Hasan Mohamed**
|
||||
TUKE, Faculty of Electrical Engineering and Informatics
|
||||
Git: [git.kemt.fei.tuke.sk/hh304ug/zkt25](https://git.kemt.fei.tuke.sk/hh304ug/zkt25)
|
||||
|
||||
|
||||
hafzal03@LAPTOP-ELUS3HGM:~/mypro/z2$ kubectl get pods -n webapp-namespace
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
flask-app-6b844bf6-cq9t6 1/1 Running 0 8m37s
|
||||
postgres-644fc4c86d-l9h4f 1/1 Running 0 14m
|
||||
hafzal03@LAPTOP-ELUS3HGM:~/mypro/z2$ minikube service flask-service -n webapp-namespace
|
||||
|
||||
minikube service flask-service -n webapp-namespace
|
||||
|
||||
kubectl get pods -n webapp-namespace
|
||||
|
||||
kubectl rollout restart deployment flask-app -n webapp-namespace
|
@ -1,81 +0,0 @@
|
||||
from flask import Flask, request, jsonify, render_template_string
|
||||
import psycopg2
|
||||
import os
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
def get_db_connection():
|
||||
return psycopg2.connect(
|
||||
host=os.environ.get("POSTGRES_HOST"),
|
||||
database=os.environ.get("POSTGRES_DB"),
|
||||
user=os.environ.get("POSTGRES_USER"),
|
||||
password=os.environ.get("POSTGRES_PASSWORD"),
|
||||
port=os.environ.get("POSTGRES_PORT", 5432),
|
||||
)
|
||||
|
||||
def init_db():
|
||||
conn = get_db_connection()
|
||||
cur = conn.cursor()
|
||||
cur.execute("""
|
||||
CREATE TABLE IF NOT EXISTS students (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
room_number TEXT NOT NULL,
|
||||
faculty TEXT NOT NULL
|
||||
);
|
||||
""")
|
||||
conn.commit()
|
||||
cur.close()
|
||||
conn.close()
|
||||
|
||||
@app.route("/")
|
||||
def index():
|
||||
return "<h1>Welcome!</h1><p>Go to /add to add a student, /students to view all.</p>"
|
||||
|
||||
# HTML Form + POST Submission
|
||||
@app.route("/add", methods=["GET", "POST"])
|
||||
def add_student():
|
||||
if request.method == "POST":
|
||||
name = request.form.get("name")
|
||||
room_number = request.form.get("room_number")
|
||||
faculty = request.form.get("faculty")
|
||||
|
||||
if not name or not room_number or not faculty:
|
||||
return "All fields are required!", 400
|
||||
|
||||
conn = get_db_connection()
|
||||
cur = conn.cursor()
|
||||
cur.execute("INSERT INTO students (name, room_number, faculty) VALUES (%s, %s, %s)", (name, room_number, faculty))
|
||||
conn.commit()
|
||||
cur.close()
|
||||
conn.close()
|
||||
return "<p>Student added successfully!</p><a href='/add'>Add another</a>"
|
||||
|
||||
# HTML form
|
||||
return render_template_string("""
|
||||
<h2>Add Student</h2>
|
||||
<form method="post">
|
||||
Name: <input name="name"><br>
|
||||
Room Number: <input name="room_number"><br>
|
||||
Faculty: <input name="faculty"><br>
|
||||
<input type="submit" value="Add Student">
|
||||
</form>
|
||||
""")
|
||||
|
||||
# View all students
|
||||
@app.route("/students", methods=["GET"])
|
||||
def get_students():
|
||||
conn = get_db_connection()
|
||||
cur = conn.cursor()
|
||||
cur.execute("SELECT id, name, room_number, faculty FROM students")
|
||||
rows = cur.fetchall()
|
||||
cur.close()
|
||||
conn.close()
|
||||
|
||||
return jsonify([
|
||||
{"id": row[0], "name": row[1], "room_number": row[2], "faculty": row[3]} for row in rows
|
||||
])
|
||||
|
||||
if __name__ == "__main__":
|
||||
init_db()
|
||||
app.run(host="0.0.0.0", port=8000)
|
@ -1,5 +0,0 @@
|
||||
Flask==2.0.1
|
||||
Werkzeug==2.0.3
|
||||
psycopg2-binary==2.9.1
|
||||
python-dotenv==0.19.0
|
||||
Jinja2==3.0.3
|
@ -1,32 +0,0 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: flask-app
|
||||
namespace: webapp-namespace
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: flask
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: flask
|
||||
spec:
|
||||
containers:
|
||||
- name: flask
|
||||
image: flask-app:latest
|
||||
imagePullPolicy: Never
|
||||
ports:
|
||||
- containerPort: 8000
|
||||
env:
|
||||
- name: POSTGRES_HOST
|
||||
value: postgres
|
||||
- name: POSTGRES_DB
|
||||
value: mydatabase
|
||||
- name: POSTGRES_USER
|
||||
value: myuser
|
||||
- name: POSTGRES_PASSWORD
|
||||
value: mypassword
|
||||
- name: POSTGRES_PORT
|
||||
value: "5432"
|
@ -1,12 +0,0 @@
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: migrate
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: migrator
|
||||
image: myapp:latest
|
||||
command: ["python", "manage.py", "migrate"]
|
||||
restartPolicy: Never
|
@ -1,4 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: webapp-namespace
|
@ -1,57 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: postgres-pvc
|
||||
namespace: webapp-namespace
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: postgres
|
||||
namespace: webapp-namespace
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: postgres
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: postgres
|
||||
spec:
|
||||
containers:
|
||||
- name: postgres
|
||||
image: postgres:13
|
||||
env:
|
||||
- name: POSTGRES_DB
|
||||
value: mydatabase
|
||||
- name: POSTGRES_USER
|
||||
value: myuser
|
||||
- name: POSTGRES_PASSWORD
|
||||
value: mypassword
|
||||
ports:
|
||||
- containerPort: 5432
|
||||
volumeMounts:
|
||||
- name: postgres-storage
|
||||
mountPath: /var/lib/postgresql/data
|
||||
volumes:
|
||||
- name: postgres-storage
|
||||
persistentVolumeClaim:
|
||||
claimName: postgres-pvc
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: postgres
|
||||
namespace: webapp-namespace
|
||||
spec:
|
||||
selector:
|
||||
app: postgres
|
||||
ports:
|
||||
- port: 5432
|
@ -1,13 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: flask-service
|
||||
namespace: webapp-namespace
|
||||
spec:
|
||||
selector:
|
||||
app: flask
|
||||
type: NodePort
|
||||
ports:
|
||||
- port: 8000
|
||||
targetPort: 8000
|
||||
nodePort: 30080 # <-- Changed this
|
@ -1,10 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "Building Docker image for Flask app..."
|
||||
docker build -t flask-app:latest .
|
||||
|
||||
echo "Creating Minikube image cache (if using Minikube)..."
|
||||
eval $(minikube docker-env)
|
||||
docker build -t flask-app:latest .
|
||||
|
||||
echo "Preparation complete."
|
@ -1,18 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "Creating Namespace..."
|
||||
kubectl apply -f k8s/namespace.yaml
|
||||
|
||||
echo "Creating Persistent Volumes and StatefulSet..."
|
||||
kubectl apply -f k8s/statefulset.yaml -n webapp-namespace
|
||||
|
||||
echo "Deploying PostgreSQL..."
|
||||
kubectl apply -f k8s/postgres-deployment.yaml -n webapp-namespace
|
||||
|
||||
echo "Deploying Flask App..."
|
||||
kubectl apply -f k8s/deployment.yaml -n webapp-namespace
|
||||
|
||||
echo "Creating Service..."
|
||||
kubectl apply -f k8s/service.yaml -n webapp-namespace
|
||||
|
||||
echo "All resources have been applied."
|
@ -1,18 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "Deleting Flask App Deployment..."
|
||||
kubectl delete -f k8s/deployment.yaml -n webapp-namespace
|
||||
|
||||
echo "Deleting Flask Service..."
|
||||
kubectl delete -f k8s/service.yaml -n webapp-namespace
|
||||
|
||||
echo "Deleting PostgreSQL Deployment and PVC..."
|
||||
kubectl delete -f k8s/postgres-deployment.yaml -n webapp-namespace
|
||||
|
||||
echo "Deleting StatefulSet and PVs..."
|
||||
kubectl delete -f k8s/statefulset.yaml -n webapp-namespace
|
||||
|
||||
echo "Deleting Namespace..."
|
||||
kubectl delete -f k8s/namespace.yaml
|
||||
|
||||
echo "All resources have been deleted."
|
Loading…
Reference in New Issue
Block a user