fixed all the postgreSQL issues

This commit is contained in:
Andriy Frolov 2025-04-18 08:33:32 +02:00
parent 2057655061
commit 6409d621da
7 changed files with 87 additions and 54 deletions

View File

@ -27,29 +27,30 @@ This project deploys a full-stack weather web application to Kubernetes. It incl
## ☸️ Kubernetes Objects ## ☸️ Kubernetes Objects
| Object Type | File | Description | | Object Type | File | Description |
|------------------------|----------------------|----------------------------------------------------------------------| |------------------------|------------------------|----------------------------------------------------------------------|
| `Namespace` | (inside script) | Isolates resources under `webapp-ns` | | `Namespace` | (inside script) | Isolates resources under `webapp-ns` |
| `Deployment` | `deployment.yaml` | Manages frontend app | | `Deployment` | `deployment.yaml` | Manages frontend app |
| `Deployment` | `deployment-api.yaml` | Manages the Node.js API | | `Deployment` | `deployment-api.yaml` | Manages the Node.js API |
| `StatefulSet` | `statefulset.yaml` | Manages PostgreSQL instance with persistent volume | | `StatefulSet` | `statefulset.yaml` | Manages PostgreSQL instance with persistent volume |
| `PersistentVolume` | `statefulset.yaml` | Host-mounted volume for PostgreSQL data | | `PersistentVolume` | `statefulset.yaml` | Host-mounted volume for PostgreSQL data |
| `PersistentVolumeClaim`| `statefulset.yaml` | Requests storage for StatefulSet | | `PersistentVolumeClaim`| `statefulset.yaml` | Requests storage for StatefulSet |
| `Service` | `service.yaml` | Exposes frontend via NodePort | | `Service` | `service.yaml` | Exposes frontend via NodePort |
| `Service` | `deployment-api.yaml` | Exposes API 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 | | `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 ## Networking & Volumes
### Virtual Networks: ### Virtual Networks:
- Kubernetes handles inter-service communication via internal DNS and `ClusterIP` services. - Kubernetes services provide internal DNS for `postgres` and `weather-api-service`.
- Frontend and backend are externally reachable using `NodePort` services. - Frontend and API exposed externally using `NodePort` services.
### Volumes: ### Volumes:
- `PersistentVolume` and `PersistentVolumeClaim` ensure PostgreSQL data is retained. - `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 ### Frontend
- Dockerfile uses `nginx:alpine` - Dockerfile uses `nginx:alpine`
- Serves `weather.html` (renamed as `index.html` inside container) - Serves `weather.html`
- Exposed on port `80` - Exposed on port `80`
### Node.js API ### Node.js API
- Built with Node.js 18 - Built with Node.js 18
- Listens on port `3000` - Listens on port `3000`
- Connects to PostgreSQL using service DNS - Connects to PostgreSQL using service DNS `postgres`
- Accepts POST requests at `/log` with weather data - Accepts POST requests at `/log`
### PostgreSQL ### PostgreSQL
- `postgres:15` with `weatheruser`, `weatherpass`, and `weatherdb` - `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 ./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 ```bash
minikube service weather-service -n webapp-ns minikube service weather-service -n webapp-ns
``` ```
Or get the NodePort manually: Or manually:
```bash ```bash
kubectl get svc -n webapp-ns
minikube ip minikube ip
kubectl get svc -n webapp-ns
``` ```
Then open: Then open:
``` ```
http://<minikube-ip>:<frontend-nodeport> http://<minikube-ip>:<frontend-nodeport>
``` ```
### 4. Use the App ### 5. Use the App
- Enter a city - Search for a city
- Weather will be shown - Weather appears
- Data is logged in PostgreSQL automatically - 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 ```bash
./stop-app.sh ./stop-app.sh
@ -120,8 +153,7 @@ http://<minikube-ip>:<frontend-nodeport>
## API Key Setup ## API Key Setup
- Register at [OpenWeatherMap](https://openweathermap.org/api) - Register at [OpenWeatherMap](https://openweathermap.org/api)
- Get your free API key - Replace the key in `weather.html`:
- Replace the placeholder in `weather.html`:
```js ```js
const apiKey = "YOUR_API_KEY"; 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

View File

@ -13,9 +13,14 @@ spec:
labels: labels:
app: weather-api app: weather-api
spec: spec:
initContainers:
- name: wait-for-postgres
image: busybox
command: ['sh', '-c', 'until nslookup postgres; do echo waiting for db; sleep 2; done']
containers: containers:
- name: weather-api - name: weather-api
image: weather-api:latest image: weather-api:latest
imagePullPolicy: IfNotPresent
ports: ports:
- containerPort: 3000 - containerPort: 3000
--- ---

0
assignment2/inti-db.sql Normal file
View File

View File

@ -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

View File

@ -1,7 +1,7 @@
#!/bin/bash #!/bin/bash
IMAGE_NAME=weather-frontend IMAGE_NAME=weather-frontend
IMAGE_TAG=latest IMAGE_TAG=lates
echo "🔧 Building Docker image: $IMAGE_NAME:$IMAGE_TAG" echo "🔧 Building Docker image: $IMAGE_NAME:$IMAGE_TAG"
docker build -t $IMAGE_NAME:$IMAGE_TAG . docker build -t $IMAGE_NAME:$IMAGE_TAG .

View File

@ -8,7 +8,7 @@ const port = 3000;
app.use(bodyParser.json()); app.use(bodyParser.json());
const pool = new Pool({ const pool = new Pool({
host: 'postgres-0.postgres.webapp-ns.svc.cluster.local', host: 'postgres',
user: 'weatheruser', user: 'weatheruser',
password: 'weatherpass', password: 'weatherpass',
database: 'weatherdb', database: 'weatherdb',

View File

@ -39,21 +39,6 @@ spec:
labels: labels:
app: postgres app: postgres
spec: 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: containers:
- name: postgres - name: postgres
image: postgres:15 image: postgres:15
@ -69,10 +54,6 @@ spec:
volumeMounts: volumeMounts:
- name: postgres-storage - name: postgres-storage
mountPath: /var/lib/postgresql/data mountPath: /var/lib/postgresql/data
volumes:
- name: init-script
configMap:
name: db-init-script
volumeClaimTemplates: volumeClaimTemplates:
- metadata: - metadata:
name: postgres-storage name: postgres-storage