Upload files to "z2"

This commit is contained in:
Pradeep Dileepkumar 2026-04-29 09:13:25 +00:00
parent b9bb60f17e
commit e029ebbecb
6 changed files with 196 additions and 0 deletions

83
z2/README.md Normal file
View File

@ -0,0 +1,83 @@
# Notes App — Kubernetes Assignment
## What the application does
A simple **Notes** web application where users can create, view, and delete short text notes. Notes are stored persistently in a PostgreSQL database. The app is accessible via a web browser.
## Containers used
| Container | Image | Description |
|---|---|---|
| `frontend` | custom (Nginx 1.27-alpine) | Serves the static HTML/JS frontend and proxies `/api/` requests to the backend |
| `backend` | custom (Python 3.12-slim / Flask) | REST API for CRUD operations on notes |
| `db` | `postgres:16-alpine` | Relational database storing notes persistently |
| `adminer` | `adminer:4` | Web UI for browsing and managing the PostgreSQL database |
## Kubernetes objects
| File | Object | Kind | Description |
|---|---|---|---|
| `k8s/namespace.yaml` | `notes-app` | Namespace | Isolates all app objects in one namespace |
| `k8s/statefulset.yaml` | `db` | StatefulSet | Runs the PostgreSQL pod with stable identity |
| `k8s/statefulset.yaml` | `postgres-pv` | PersistentVolume | Host-path volume providing 1Gi of storage |
| `k8s/statefulset.yaml` | `postgres-pvc` | PersistentVolumeClaim | Claims the PV for use by the StatefulSet |
| `k8s/deployment.yaml` | `backend` | Deployment | Runs the Flask API pod |
| `k8s/deployment.yaml` | `frontend` | Deployment | Runs the Nginx frontend pod |
| `k8s/deployment.yaml` | `adminer` | Deployment | Runs the Adminer pod |
| `k8s/service.yaml` | `db` | Service (ClusterIP/Headless) | Internal DNS for the database (`db:5432`) |
| `k8s/service.yaml` | `backend` | Service (ClusterIP) | Internal DNS for the API (`backend:5000`) |
| `k8s/service.yaml` | `frontend` | Service (NodePort 30080) | Exposes the frontend to the host |
| `k8s/service.yaml` | `adminer` | Service (NodePort 30081) | Exposes Adminer to the host |
| `k8s/configmap.yaml` | `db-init` | ConfigMap | Holds `init.sql` mounted into the DB container |
## Networking and volumes
- All objects live in the `notes-app` namespace.
- Pods communicate via Kubernetes internal DNS (service names).
- The `db` service is headless (`clusterIP: None`) — required for StatefulSets.
- The `frontend` and `adminer` services use `NodePort` to be reachable from the host.
- `postgres-pv` is a `hostPath` PersistentVolume at `/data/notes-postgres` on the node.
- `postgres-pvc` binds to `postgres-pv` and is mounted into the `db` pod.
## Container configuration
- **db**: configured via env vars (`POSTGRES_DB`, `POSTGRES_USER`, `POSTGRES_PASSWORD`). The `db-init` ConfigMap is mounted into `/docker-entrypoint-initdb.d/` and runs once on first startup.
- **backend**: receives `DATABASE_URL` pointing to the `db` service.
- **frontend**: Nginx proxies `/api/` to `http://backend:5000` and serves `index.html` for all other paths.
- **adminer**: no extra configuration, exposed on NodePort 30081.
## Instructions
### Prepare (build and load images)
```bash
chmod +x prepare-app.sh start-app.sh stop-app.sh remove-app.sh
./prepare-app.sh
```
### Start
```bash
./start-app.sh
```
### Stop (data is preserved)
```bash
./stop-app.sh
```
### Remove everything
```bash
./remove-app.sh
```
## Viewing the application
| URL | Description |
|---|---|
| http://localhost:30080 | Notes web application |
| http://localhost:30081 | Adminer — Server: `db`, User: `appuser`, Password: `apppassword`, Database: `appdb` |
> If using minikube, replace `localhost` with the output of `minikube ip`.
## Use of artificial intelligence
This project was created with the assistance of Kiro AI (kiro-cli chat agent). The AI generated the Kubernetes manifests, shell scripts, and documentation. All generated files were reviewed and understood by the author.

55
z2/docker-compose.yaml Normal file
View File

@ -0,0 +1,55 @@
version: "3.9"
networks:
frontend_net:
backend_net:
volumes:
postgres_data:
services:
db:
image: postgres:16-alpine
container_name: app_db
restart: on-failure
environment:
POSTGRES_DB: appdb
POSTGRES_USER: appuser
POSTGRES_PASSWORD: apppassword
volumes:
- postgres_data:/var/lib/postgresql/data
- ./db/init.sql:/docker-entrypoint-initdb.d/init.sql:ro
networks:
- backend_net
backend:
build: ./backend
container_name: app_backend
restart: on-failure
environment:
DATABASE_URL: postgresql://appuser:apppassword@db:5432/appdb
depends_on:
- db
networks:
- backend_net
frontend:
build: ./frontend
container_name: app_frontend
restart: on-failure
ports:
- "8080:80"
depends_on:
- backend
networks:
- frontend_net
- backend_net
adminer:
image: adminer:4
container_name: app_adminer
restart: on-failure
ports:
- "8081:8080"
networks:
- backend_net

21
z2/prepare-app.sh Normal file
View File

@ -0,0 +1,21 @@
#!/usr/bin/env bash
set -e
echo "Building images..."
docker build -t notes-backend:latest ./backend
docker build -t notes-frontend:latest ./frontend
# Load images into the cluster node (minikube or kind)
if command -v minikube &>/dev/null; then
echo "Loading images into minikube..."
minikube image load notes-backend:latest
minikube image load notes-frontend:latest
elif command -v kind &>/dev/null; then
echo "Loading images into kind..."
kind load docker-image notes-backend:latest
kind load docker-image notes-frontend:latest
else
echo "Warning: neither minikube nor kind detected. Make sure the cluster can access local images."
fi
echo "Done. Run ./start-app.sh to deploy."

9
z2/remove-app.sh Normal file
View File

@ -0,0 +1,9 @@
#!/usr/bin/env bash
set -e
echo "Removing Notes App..."
kubectl delete namespace notes-app --ignore-not-found
kubectl delete pv postgres-pv --ignore-not-found
echo "All Kubernetes objects removed."

17
z2/start-app.sh Normal file
View File

@ -0,0 +1,17 @@
#!/usr/bin/env bash
set -e
echo "Deploying Notes App to Kubernetes..."
kubectl apply -f k8s/namespace.yaml
kubectl apply -f k8s/configmap.yaml
kubectl apply -f k8s/statefulset.yaml
kubectl apply -f k8s/service.yaml
kubectl apply -f k8s/deployment.yaml
echo "Waiting for pods to be ready..."
kubectl wait --namespace notes-app --for=condition=ready pod --all --timeout=120s
echo "App is running."
echo "Frontend: http://localhost:30080"
echo "Adminer: http://localhost:30081"

11
z2/stop-app.sh Normal file
View File

@ -0,0 +1,11 @@
.#!/usr/bin/env bash
set -e
echo "Stopping Notes App..."
kubectl delete -f k8s/deployment.yaml --ignore-not-found
kubectl delete -f k8s/service.yaml --ignore-not-found
kubectl delete -f k8s/statefulset.yaml --ignore-not-found
kubectl delete -f k8s/configmap.yaml --ignore-not-found
echo "App stopped. Namespace and volumes are preserved."