From 6409d621dabfd7d82b6b933b9441516ec5768c09 Mon Sep 17 00:00:00 2001 From: Andriy Date: Fri, 18 Apr 2025 08:33:32 +0200 Subject: [PATCH] fixed all the postgreSQL issues --- assignment2/README.md | 100 ++++++++++++++++++++---------- assignment2/deployment-api.yaml | 5 ++ assignment2/inti-db.sql | 0 assignment2/postgres-service.yaml | 13 ++++ assignment2/prepare-app.sh | 2 +- assignment2/server.js | 2 +- assignment2/statefulset.yaml | 19 ------ 7 files changed, 87 insertions(+), 54 deletions(-) create mode 100644 assignment2/inti-db.sql create mode 100644 assignment2/postgres-service.yaml diff --git a/assignment2/README.md b/assignment2/README.md index c976af5..7669725 100644 --- a/assignment2/README.md +++ b/assignment2/README.md @@ -27,29 +27,30 @@ This project deploys a full-stack weather web application to Kubernetes. It incl ## ☸️ Kubernetes Objects -| Object Type | File | Description | -|------------------------|----------------------|----------------------------------------------------------------------| -| `Namespace` | (inside script) | Isolates resources under `webapp-ns` | -| `Deployment` | `deployment.yaml` | Manages frontend app | -| `Deployment` | `deployment-api.yaml` | Manages the Node.js API | -| `StatefulSet` | `statefulset.yaml` | Manages PostgreSQL instance with persistent volume | -| `PersistentVolume` | `statefulset.yaml` | Host-mounted volume for PostgreSQL data | -| `PersistentVolumeClaim`| `statefulset.yaml` | Requests storage for StatefulSet | -| `Service` | `service.yaml` | Exposes frontend via NodePort | -| `Service` | `deployment-api.yaml` | Exposes API via NodePort | -| `ConfigMap` | Created by script | Stores `init-db.sql` used to create the `weather_log` table | +| Object Type | File | Description | +|------------------------|------------------------|----------------------------------------------------------------------| +| `Namespace` | (inside script) | Isolates resources under `webapp-ns` | +| `Deployment` | `deployment.yaml` | Manages frontend app | +| `Deployment` | `deployment-api.yaml` | Manages the Node.js API | +| `StatefulSet` | `statefulset.yaml` | Manages PostgreSQL instance with persistent volume | +| `PersistentVolume` | `statefulset.yaml` | Host-mounted volume for PostgreSQL data | +| `PersistentVolumeClaim`| `statefulset.yaml` | Requests storage for StatefulSet | +| `Service` | `service.yaml` | Exposes frontend via NodePort | +| `Service` | `deployment-api.yaml` | Exposes API via NodePort | +| `Service` | `postgres-service.yaml`| Internal ClusterIP service for PostgreSQL DNS resolution | +| `ConfigMap` | `db-init-script` | Stores the SQL init script for table creation | --- ## Networking & Volumes ### Virtual Networks: -- Kubernetes handles inter-service communication via internal DNS and `ClusterIP` services. -- Frontend and backend are externally reachable using `NodePort` services. +- Kubernetes services provide internal DNS for `postgres` and `weather-api-service`. +- Frontend and API exposed externally using `NodePort` services. ### Volumes: - `PersistentVolume` and `PersistentVolumeClaim` ensure PostgreSQL data is retained. -- `ConfigMap` mounts the SQL init script for PostgreSQL setup. +- `ConfigMap` used to apply `init-db.sql` manually via `psql`. --- @@ -57,18 +58,18 @@ This project deploys a full-stack weather web application to Kubernetes. It incl ### Frontend - Dockerfile uses `nginx:alpine` -- Serves `weather.html` (renamed as `index.html` inside container) +- Serves `weather.html` - Exposed on port `80` ### Node.js API - Built with Node.js 18 - Listens on port `3000` -- Connects to PostgreSQL using service DNS -- Accepts POST requests at `/log` with weather data +- Connects to PostgreSQL using service DNS `postgres` +- Accepts POST requests at `/log` ### PostgreSQL - `postgres:15` with `weatheruser`, `weatherpass`, and `weatherdb` -- Init script creates a `weather_log` table with a sample row +- Table `weather_log` is created manually after StatefulSet starts --- @@ -86,30 +87,62 @@ This project deploys a full-stack weather web application to Kubernetes. It incl ./start-app.sh ``` -### 3. View the App +### 3. Manually Initialize the Database + +```bash +kubectl exec -it -n webapp-ns statefulset/postgres -- psql -U weatheruser -d weatherdb +``` + +Paste this inside the prompt: + +```sql +CREATE TABLE IF NOT EXISTS weather_log ( + id SERIAL PRIMARY KEY, + city VARCHAR(100), + temperature DECIMAL(5,2), + description TEXT, + timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); +``` + +Exit with: +```sql +\q +``` + +### 4. View the App ```bash minikube service weather-service -n webapp-ns ``` -Or get the NodePort manually: +Or manually: ```bash -kubectl get svc -n webapp-ns minikube ip +kubectl get svc -n webapp-ns ``` - Then open: ``` http://: ``` -### 4. Use the App -- Enter a city -- Weather will be shown -- Data is logged in PostgreSQL automatically +### 5. Use the App +- Search for a city +- Weather appears +- Weather data is logged via API to PostgreSQL -### 5. Stop and Clean Up +### 6. View Logged Data + +```bash +kubectl exec -it -n webapp-ns statefulset/postgres -- psql -U weatheruser -d weatherdb +``` + +```sql +SELECT * FROM weather_log ORDER BY timestamp DESC; +``` + +### 7. Stop and Clean Up ```bash ./stop-app.sh @@ -120,8 +153,7 @@ http://: ## API Key Setup - Register at [OpenWeatherMap](https://openweathermap.org/api) -- Get your free API key -- Replace the placeholder in `weather.html`: +- Replace the key in `weather.html`: ```js const apiKey = "YOUR_API_KEY"; @@ -129,8 +161,10 @@ const apiKey = "YOUR_API_KEY"; --- -## Conclusion +## Conclusion + +- Frontend fetches real-time weather from OpenWeatherMap +- Logs are POSTed to backend and stored in PostgreSQL + +--- -- Frontend calls OpenWeatherMap and logs data to your backend -- PostgreSQL is prepped with a table to store queries -- You can expand the API to serve saved data or stats diff --git a/assignment2/deployment-api.yaml b/assignment2/deployment-api.yaml index f8044d6..ef0c51e 100644 --- a/assignment2/deployment-api.yaml +++ b/assignment2/deployment-api.yaml @@ -13,9 +13,14 @@ spec: labels: app: weather-api spec: + initContainers: + - name: wait-for-postgres + image: busybox + command: ['sh', '-c', 'until nslookup postgres; do echo waiting for db; sleep 2; done'] containers: - name: weather-api image: weather-api:latest + imagePullPolicy: IfNotPresent ports: - containerPort: 3000 --- diff --git a/assignment2/inti-db.sql b/assignment2/inti-db.sql new file mode 100644 index 0000000..e69de29 diff --git a/assignment2/postgres-service.yaml b/assignment2/postgres-service.yaml new file mode 100644 index 0000000..0622926 --- /dev/null +++ b/assignment2/postgres-service.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Service +metadata: + name: postgres + namespace: webapp-ns +spec: + selector: + app: postgres + ports: + - protocol: TCP + port: 5432 + targetPort: 5432 + diff --git a/assignment2/prepare-app.sh b/assignment2/prepare-app.sh index 616963a..21d38f9 100755 --- a/assignment2/prepare-app.sh +++ b/assignment2/prepare-app.sh @@ -1,7 +1,7 @@ #!/bin/bash IMAGE_NAME=weather-frontend -IMAGE_TAG=latest +IMAGE_TAG=lates echo "🔧 Building Docker image: $IMAGE_NAME:$IMAGE_TAG" docker build -t $IMAGE_NAME:$IMAGE_TAG . diff --git a/assignment2/server.js b/assignment2/server.js index c8ea8eb..2101596 100644 --- a/assignment2/server.js +++ b/assignment2/server.js @@ -8,7 +8,7 @@ const port = 3000; app.use(bodyParser.json()); const pool = new Pool({ - host: 'postgres-0.postgres.webapp-ns.svc.cluster.local', + host: 'postgres', user: 'weatheruser', password: 'weatherpass', database: 'weatherdb', diff --git a/assignment2/statefulset.yaml b/assignment2/statefulset.yaml index e8c9bcb..081e54b 100644 --- a/assignment2/statefulset.yaml +++ b/assignment2/statefulset.yaml @@ -39,21 +39,6 @@ spec: labels: app: postgres spec: - initContainers: - - name: init-db - image: postgres:15 - env: - - name: POSTGRES_USER - value: "weatheruser" - - name: POSTGRES_PASSWORD - value: "weatherpass" - - name: POSTGRES_DB - value: "weatherdb" - volumeMounts: - - name: init-script - mountPath: /docker-entrypoint-initdb.d - - name: postgres-storage - mountPath: /var/lib/postgresql/data containers: - name: postgres image: postgres:15 @@ -69,10 +54,6 @@ spec: volumeMounts: - name: postgres-storage mountPath: /var/lib/postgresql/data - volumes: - - name: init-script - configMap: - name: db-init-script volumeClaimTemplates: - metadata: name: postgres-storage