Skip to content

LastAirbender07/Docker-K8s-Helm

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

41 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Building the image

docker build -t jayaraj0781/tasktracker-frontend:latest .

docker push jayaraj0781/tasktracker-frontend:latest

docker pull jayaraj0781/tasktracker-frontend:latest

docker build -t jayaraj0781/tasktracker-backend:latest .

docker push jayaraj0781/tasktracker-backend:latest

docker pull jayaraj0781/tasktracker-backend:latest

helm upgrade --install tasktracker ./tasktracker -n tasktracker

web page is available at: http://task.local/


Frontend Runtime Configuration with Docker and Nginx

Problem

Vite's import.meta.env.* values are baked into the build and are not available at container runtime. This prevents using a single frontend image across environments with different backend URLs.

Solution

Serve a small runtime JS file (config.js) from Nginx that is generated from a template at container start. The React app reads window.BACKEND_API_URL instead of import.meta.env.

Files & Steps

  1. config.template.js (in frontend root)
// config.template.js
window.__BACKEND_API_URL__ = "${BACKEND_API_URL}";
  1. Dockerfile (multi-stage)
# Stage 1: build
FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

# Stage 2: serve with nginx
FROM nginx:1.28-alpine
# envsubst (gettext) for runtime replacement
RUN apk add --no-cache gettext
COPY --from=build /app/dist /usr/share/nginx/html
COPY config.template.js /usr/share/nginx/html/config.js
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
EXPOSE 80
ENTRYPOINT ["/entrypoint.sh"]
  1. entrypoint.sh
#!/bin/sh
# Replace ${BACKEND_API_URL} with the runtime env value
envsubst '${BACKEND_API_URL}' < /usr/share/nginx/html/config.js > /usr/share/nginx/html/config.tmp.js
mv /usr/share/nginx/html/config.tmp.js /usr/share/nginx/html/config.js

# Start nginx in foreground
nginx -g 'daemon off;'
  1. Load config before app in index.html
<!-- ensure this appears before your main bundle -->
<script src="/config.js"></script>
<script type="module" src="/src/main.jsx"></script>
  1. Read value in React
// example: src/config.js
export const BACKEND_BASE_URL = window.__BACKEND_API_URL__ || "http://localhost:5001";
  1. docker-compose service snippet
frontend:
    image: jayaraj0781/tasktracker-frontend:latest
    ports:
        - "5173:80"
    environment:
        - BACKEND_API_URL=http://backend:5001
    depends_on:
        - backend
    networks:
        - app-network

Notes

  • config.template.js contains a placeholder ${BACKEND_API_URL}.
  • Docker entrypoint replaces the placeholder with the actual environment variable.
  • Nginx serves config.js as /config.js.
  • React app loads /config.js and reads window.BACKEND_API_URL.
  • API calls use the correct backend URL at runtime.

Backend Connectivity Issue after deploying in k8s using helm

The frontend was initially unable to reach the backend because it was trying to call an internal Kubernetes service URL like http://tasktracker-backend:5001/auth/signup or tasktracker.svc.cluster.local.

These internal service names are resolvable only inside the Kubernetes cluster, not from the browser. Since the browser runs outside the cluster (on the user’s machine), it couldn’t resolve that hostname, causing the frontend API calls to fail.

To resolve this, the Ingress was configured to act as a reverse proxy for both the frontend and backend.

The host task.local (exposed via Ingress) now routes:

/auth and /api → backend service (inside cluster)

/ → frontend service

This allows the frontend to make API calls to http://task.local/auth/..., which the Ingress correctly forwards to the backend service.

Ingress Annotation Issue

Originally, the Ingress included the annotation:

nginx.ingress.kubernetes.io/rewrite-target: /

This caused incoming requests like /auth/signup to be rewritten to /signup before reaching the backend. Since the backend expected the full /auth/... path, the routes no longer matched, resulting in 404 or failed API calls.

By removing this annotation, the Ingress now forwards requests exactly as received — ensuring /auth/signup remains intact and correctly reaches the backend.

FastAPI Backend — API Documentation

Version: 0.1.0 OpenAPI: 3.1

Overview

This backend provides user authentication and per-user task management. Use the authentication endpoints to create and sign in users. Authenticated users can list, create, update, and delete their own tasks.

Base URL

Assume the API is served at the server root (e.g., https://api.example.com/). All example paths are relative to the base URL.

Authentication

  • Sign up: POST /auth/signup
  • Log in: POST /auth/login — returns credentials (token or session cookie) used to authenticate subsequent requests.
  • Log out: POST /auth/logout — invalidates the current session/token.

All task endpoints are protected. Include the returned authentication token (e.g., Bearer token in Authorization header or session cookie) when calling /api/users/{username}/tasks endpoints.

Endpoints

Authentication

  • POST /auth/signup

    • Summary: Register a new user.
    • Request body (application/json):
      • username: string (required)
      • email: string (required, email)
      • password: string (required)
    • Responses:
      • 201 Created: User created. Returns a message indicating success.
      • 400 Bad Request: Validation error.
      • 409 Conflict: Username or email already exists.
  • POST /auth/login

    • Summary: Authenticate a user.
    • Request body (application/json):
      • username: string (required)
      • password: string (required)
    • Responses:
      • 200 OK: Authentication succeeded. Returns a token or sets session cookie and a success message.
      • 400 Bad Request: Validation error.
      • 401 Unauthorized: Invalid credentials.
  • POST /auth/logout

    • Summary: Log out the current user.
    • Request body: none
    • Responses:
      • 200 OK: Successfully logged out (or 204 No Content). Session or token invalidated.

Tasks

  • GET /api/users/{username}/tasks

    • Summary: List tasks for the specified user.
    • Path parameters:
      • username: string (required)
    • Query parameters: (optional filtering, sorting or pagination can be added)
    • Responses:
      • 200 OK: Returns an array of Task objects.
      • 401 Unauthorized: Missing/invalid authentication.
      • 403 Forbidden: Authenticated user not allowed to access another user's tasks.
  • POST /api/users/{username}/tasks

    • Summary: Create a new task for the specified user.
    • Path parameters:
      • username: string (required)
    • Request body (application/json):
      • title: string (required)
      • description: string | null (optional)
      • tags: array of tag values (optional)
      • completed: boolean | null (optional, default false)
    • Responses:
      • 201 Created: Returns the created Task object.
      • 400 Bad Request: Validation error.
      • 401 / 403: Authentication/authorization errors.
  • PATCH /api/users/{username}/tasks/{task_id}

    • Summary: Partially update a task.
    • Path parameters:
      • username: string (required)
      • task_id: integer (required)
    • Request body (application/json): Partial Task fields to update (e.g., title, description, tags, completed).
    • Responses:
      • 200 OK: Returns the updated Task object.
      • 400 Bad Request: Validation error.
      • 401 / 403: Authentication/authorization errors.
      • 404 Not Found: Task not found.
  • DELETE /api/users/{username}/tasks/{task_id}

    • Summary: Delete a task.
    • Path parameters:
      • username: string (required)
      • task_id: integer (required)
    • Responses:
      • 204 No Content: Task deleted successfully.
      • 401 / 403: Authentication/authorization errors.
      • 404 Not Found: Task not found.

Default / Health

  • GET /

    • Summary: Index endpoint — basic welcome/info response.
    • Responses: 200 OK
  • GET /health

    • Summary: Health check endpoint for monitoring.
    • Responses:
      • 200 OK: Service healthy (may return a simple JSON status).

Schemas

  • UserSignup

    • username: string
    • email: string (email)
    • password: string
  • UserLogin

    • username: string
    • password: string
  • Task

    • id: integer
    • title: string
    • description: string | null
    • tags: array of string (allowed values: "personal", "work", "study", "hobby", "other")
    • completed: boolean
    • created_at: string (date-time)
    • updated_at: string (date-time)
  • GenericResponse

    • msg: string
    • type: string (e.g., "success", "error", "info")
    • data: object | array | null (optional payload)

Examples

Create user (request) { "username": "jdoe", "email": "[email protected]", "password": "StrongPassword123!" }

Login (response) { "msg": "Login successful", "type": "success" // token or cookie will be provided for subsequent requests }

Create task (request) { "title": "Write documentation", "description": "Draft API docs for the backend", "tags": ["work", "personal"], "completed": false }

Create task (response) { "id": 42, "title": "Write documentation", "description": "Draft API docs for the backend", "tags": ["work","personal"], "completed": false, "created_at": "2024-01-01T12:00:00Z", "updated_at": "2024-01-01T12:00:00Z" }

Error response example { "msg": "Invalid credentials", "type": "error" }

Notes & Recommendations

  • Use HTTPS for all requests to protect credentials.
  • Prefer short-lived access tokens with refresh tokens or secure, httpOnly session cookies.
  • Validate and sanitize all user-provided input on the server.
  • Implement rate limiting and brute-force protection on authentication endpoints.
  • Consider pagination, filtering, and sorting for task listings when scaling.

About

Built a working system with: Containerized microservices (frontend + backend + DB + cache) Orchestrated via Kubernetes Deployed with Helm (a production-standard approach) Exposed via Ingress

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors