Upload files to "z2"
This commit is contained in:
parent
b9bb60f17e
commit
e029ebbecb
83
z2/README.md
Normal file
83
z2/README.md
Normal 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
55
z2/docker-compose.yaml
Normal 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
21
z2/prepare-app.sh
Normal 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
9
z2/remove-app.sh
Normal 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
17
z2/start-app.sh
Normal 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
11
z2/stop-app.sh
Normal 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."
|
||||||
Loading…
Reference in New Issue
Block a user