zkt26/z2/README.md

84 lines
3.6 KiB
Markdown

# 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.