84 lines
3.6 KiB
Markdown
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.
|