apiVersion: v1 kind: Service metadata: name: postgres-service namespace: z2app spec: selector: app: postgres ports: - port: 5432 targetPort: 5432 --- apiVersion: v1 kind: Service metadata: name: backend-service namespace: z2app spec: selector: app: backend ports: - port: 5000 targetPort: 5000 --- apiVersion: v1 kind: Service metadata: name: frontend-service namespace: z2app spec: type: NodePort selector: app: frontend ports: - port: 80 targetPort: 80 nodePort: 30080 --- apiVersion: v1 kind: ConfigMap metadata: name: frontend-html-config namespace: z2app data: index.html: | Task Notes App

Task Notes App

Simple notes/tasks app running on Kubernetes.

--- apiVersion: v1 kind: ConfigMap metadata: name: frontend-nginx-config namespace: z2app data: default.conf: | server { listen 80; server_name localhost; location / { root /usr/share/nginx/html; index index.html; try_files $uri $uri/ /index.html; } location /api/ { proxy_pass http://backend-service:5000/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } --- apiVersion: v1 kind: ConfigMap metadata: name: backend-code-config namespace: z2app data: app.py: | import os import psycopg2 from flask import Flask, request, jsonify app = Flask(__name__) DB_HOST = os.getenv("DB_HOST", "postgres-service") DB_PORT = os.getenv("DB_PORT", "5432") DB_NAME = os.getenv("DB_NAME", "appdb") DB_USER = os.getenv("DB_USER", "appuser") DB_PASSWORD = os.getenv("DB_PASSWORD", "apppass") def get_conn(): return psycopg2.connect( host=DB_HOST, port=DB_PORT, dbname=DB_NAME, user=DB_USER, password=DB_PASSWORD ) def init_db(): conn = get_conn() cur = conn.cursor() cur.execute(""" CREATE TABLE IF NOT EXISTS tasks ( id SERIAL PRIMARY KEY, text TEXT NOT NULL ) """) conn.commit() cur.close() conn.close() @app.after_request def add_cors_headers(response): response.headers["Access-Control-Allow-Origin"] = "*" response.headers["Access-Control-Allow-Headers"] = "Content-Type" response.headers["Access-Control-Allow-Methods"] = "GET,POST,DELETE,OPTIONS" return response @app.route("/") def home(): return "Backend is running" @app.route("/health") def health(): return {"status": "ok"} @app.route("/tasks", methods=["GET"]) def get_tasks(): conn = get_conn() cur = conn.cursor() cur.execute("SELECT id, text FROM tasks ORDER BY id DESC") rows = cur.fetchall() cur.close() conn.close() return jsonify([{"id": r[0], "text": r[1]} for r in rows]) @app.route("/tasks", methods=["POST"]) def create_task(): data = request.get_json() text = data.get("text", "").strip() if not text: return jsonify({"error": "Text is required"}), 400 conn = get_conn() cur = conn.cursor() cur.execute("INSERT INTO tasks (text) VALUES (%s) RETURNING id", (text,)) new_id = cur.fetchone()[0] conn.commit() cur.close() conn.close() return jsonify({"id": new_id, "text": text}), 201 @app.route("/tasks/", methods=["DELETE"]) def delete_task(task_id): conn = get_conn() cur = conn.cursor() cur.execute("DELETE FROM tasks WHERE id = %s", (task_id,)) conn.commit() cur.close() conn.close() return jsonify({"deleted": task_id}) if __name__ == "__main__": init_db() app.run(host="0.0.0.0", port=5000)