{"id":50492555,"url":"https://github.com/mjunaidca/ramadan-cloud-nights-ai-400","last_synced_at":"2026-06-02T04:02:13.155Z","repository":{"id":340009404,"uuid":"1163525015","full_name":"mjunaidca/ramadan-cloud-nights-ai-400","owner":"mjunaidca","description":null,"archived":false,"fork":false,"pushed_at":"2026-03-07T18:58:54.000Z","size":65,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-03-08T00:37:37.158Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mjunaidca.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-21T19:04:57.000Z","updated_at":"2026-03-07T18:58:57.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/mjunaidca/ramadan-cloud-nights-ai-400","commit_stats":null,"previous_names":["mjunaidca/ramadan-cloud-nights-ai-400"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mjunaidca/ramadan-cloud-nights-ai-400","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mjunaidca%2Framadan-cloud-nights-ai-400","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mjunaidca%2Framadan-cloud-nights-ai-400/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mjunaidca%2Framadan-cloud-nights-ai-400/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mjunaidca%2Framadan-cloud-nights-ai-400/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mjunaidca","download_url":"https://codeload.github.com/mjunaidca/ramadan-cloud-nights-ai-400/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mjunaidca%2Framadan-cloud-nights-ai-400/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33805341,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-02T02:00:07.132Z","response_time":109,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-02T04:02:12.366Z","updated_at":"2026-06-02T04:02:13.147Z","avatar_url":"https://github.com/mjunaidca.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AI-400 Cloud Classes - Ramadan Coding Nights\n\n## Table of Contents\n\n- [Class 1: Kubernetes Communication Between Services](#class-1-kubernetes-communication-between-services)\n  - [Project Structure](#project-structure)\n  - [Running Locally](#running-locally)\n  - [API Endpoints](#api-endpoints)\n- [Challenge 1: Deploy Both Services in Kubernetes](#challenge-1-deploy-both-services-in-kubernetes)\n  - [What You Need To Do](#what-you-need-to-do)\n  - [Hints](#hints)\n  - [Questions To Explore](#questions-to-explore)\n  - [Bonus](#bonus)\n\n---\n\n## Class 1: Kubernetes Communication Between Services\n\nIn this class we built a simple **Task Manager** application with two services:\n\n- **Backend** — FastAPI REST API that stores tasks in memory\n- **Frontend** — A lightweight web UI that talks to the backend API\n\n### Project Structure\n\n```\nlive-code/\n├── backend/\n│   ├── main.py            # Task CRUD API\n│   ├── Dockerfile\n│   ├── pyproject.toml\n│   └── uv.lock\n├── frontend/\n│   ├── main.py            # Serves the web UI\n│   ├── templates/\n│   │   └── index.html     # Task manager page\n│   ├── pyproject.toml\n│   └── uv.lock\n├── k8s.yaml\n└── README.md\n```\n\n### Running Locally\n\n```bash\n# Terminal 1 - Backend\ncd backend \u0026\u0026 uv run uvicorn main:app --port 8000\n\n# Terminal 2 - Frontend\ncd frontend \u0026\u0026 uv run uvicorn main:app --port 3000\n```\n\nOpen `http://localhost:3000` to use the app.\n\n### API Endpoints\n\n| Method   | Endpoint        | Description       |\n|----------|-----------------|-------------------|\n| GET      | /tasks          | List all tasks    |\n| GET      | /tasks/{id}     | Get a task        |\n| POST     | /tasks          | Create a task     |\n| PATCH    | /tasks/{id}     | Update a task     |\n| DELETE   | /tasks/{id}     | Delete a task     |\n| GET      | /docs           | Swagger UI        |\n| GET      | /redoc          | ReDoc             |\n\n---\n\n## Challenge 1: Deploy Both Services in Kubernetes\n\nYour goal is to deploy **both the frontend and backend** in Kubernetes and make them communicate with each other.\n\n### What You Need To Do\n\n1. **Build Docker images** for both frontend and backend\n2. **Create Kubernetes manifests** (Deployment + Service) for each\n3. **Make the frontend talk to the backend** inside the cluster\n\n### Hints\n\n- The frontend uses the `API_URL` environment variable to know where the backend is\n- In Kubernetes, services can talk to each other using internal DNS\n- The DNS format is: `http://\u003cservice-name\u003e.\u003cnamespace\u003e.svc.cluster.local:\u003cport\u003e`\n- For services in the same namespace, just `http://\u003cservice-name\u003e:\u003cport\u003e` works\n- You will need a **ClusterIP** service for the backend (internal only)\n- You will need a **NodePort** service for the frontend (external access)\n- Pass `API_URL` to the frontend deployment using `env` in the container spec\n\n### Questions To Explore\n\n- What is the difference between ClusterIP, NodePort, and LoadBalancer?\n- Why does the frontend need a NodePort but the backend only needs ClusterIP?\n- What happens if the backend service name changes? How does the frontend know?\n- How does Kubernetes DNS resolution work inside a pod?\n\n### Bonus\n\n- Add a `/health` endpoint to both services and configure readiness/liveness probes\n- Try scaling the backend to 2 replicas — does the frontend still work? Why?\n- What happens to tasks when a backend pod restarts?\n\nGood luck and happy coding!\n\n---\n\n## Challenge 2: Debug Frontend-Backend Communication\n\nThe frontend pod is running and accessible via port-forward, but it's not making successful calls to the backend. Your goal is to figure out **why** and understand the root cause.\n\n### Debugging Steps\n\n1. **Check backend pod logs** — verify if the backend is receiving any requests from the frontend\n   ```bash\n   kubectl logs pod/backend\n   ```\n\n2. **Check browser Network tab** — open the frontend in your browser, open DevTools (F12) → Network tab, and observe:\n   - Are API calls being made?\n   - What URL are they hitting?\n   - What error do you see? (e.g., `net::ERR_CONNECTION_REFUSED`, CORS, timeout)\n\n### Questions To Explore\n\n- Where do the `fetch()` calls in `index.html` actually execute — on the server or in the browser?\n- Can your browser reach a Kubernetes pod IP like `10.42.0.52`?\n- What is the difference between server-side rendering and client-side API calls?\n- If the frontend server renders `API_URL` into the HTML template, who actually makes the HTTP request to that URL?\n\n### Debug Tip: Use BusyBox to Test from Inside the Cluster\n\nSpin up a temporary pod inside the cluster to test if the backend is reachable internally:\n\n```bash\n# Launch a debug pod and get a shell\nkubectl run debug --rm -it --image=busybox -- sh\n\n# From inside the pod, test backend connectivity\nwget -qO- http://10.42.0.56:8000/tasks\n\n# If you have a Service, test DNS resolution\nnslookup backend\nwget -qO- http://backend:8000/tasks\n```\n\nIf the backend responds from inside the cluster but not from your browser, the problem is **not** cluster networking — it's the browser trying to reach a cluster-internal IP.\n\n### Port Forward Commands\n\n```bash\n# Frontend\nkubectl port-forward pod/frontend 3010:3000 --address 0.0.0.0\n\n# Backend\nkubectl port-forward pod/backend 8010:8000 --address 0.0.0.0\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmjunaidca%2Framadan-cloud-nights-ai-400","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmjunaidca%2Framadan-cloud-nights-ai-400","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmjunaidca%2Framadan-cloud-nights-ai-400/lists"}