# Adopt-a-Street Makefile # Provides convenient commands for building and running the application .PHONY: help install build run dev test clean lint format docker-multiarch docker-multiarch-verify \ k8s-test-connection k8s-test-manifests k8s-test-deploy-dev k8s-namespace-create k8s-secret-create \ k8s-deploy k8s-deploy-dev k8s-deploy-staging k8s-deploy-prod k8s-status k8s-logs-backend \ k8s-logs-frontend k8s-health k8s-port-forward k8s-exec-backend k8s-rollback k8s-delete # Kubernetes Configuration K8S_NAMESPACE ?= adopt-a-street-dev K8S_CONTEXT ?= k0s-cluster REGISTRY ?= gitea-http.taildb3494.ts.net GITEA_USERNAME ?= will # Default target help: @echo "Adopt-a-Street Development Commands" @echo "" @echo "Setup & Installation:" @echo " install Install dependencies for both frontend and backend" @echo " clean Clean node_modules and build artifacts" @echo "" @echo "Development:" @echo " dev Start both frontend and backend in development mode" @echo " dev-frontend Start frontend development server only" @echo " dev-backend Start backend development server only" @echo "" @echo "Building:" @echo " build Build both frontend and backend for production" @echo " build-frontend Build frontend for production" @echo " build-backend Build backend for production" @echo "" @echo "Testing:" @echo " test Run tests for both frontend and backend" @echo " test-frontend Run frontend tests" @echo " test-backend Run backend tests" @echo " test-coverage Run tests with coverage reports" @echo "" @echo "Code Quality:" @echo " lint Run linting for both frontend and backend" @echo " lint-frontend Run frontend linting" @echo " lint-backend Run backend linting" @echo "" @echo "Production:" @echo " run Run production build" @echo " start Start production servers" @echo "" @echo "Kubernetes Testing:" @echo " k8s-test-connection Verify kubectl connectivity to cluster" @echo " k8s-test-manifests Validate manifest syntax (dry-run)" @echo " k8s-test-deploy-dev Deploy to dev namespace and verify" @echo "" @echo "Kubernetes Deployment:" @echo " k8s-namespace-create Create namespace (K8S_NAMESPACE=name)" @echo " k8s-deploy Deploy all manifests to namespace (includes registry secret)" @echo " k8s-deploy-dev Deploy to adopt-a-street-dev" @echo " k8s-deploy-staging Deploy to adopt-a-street-staging" @echo " k8s-deploy-prod Deploy to adopt-a-street-prod" @echo "" @echo "Kubernetes Verification:" @echo " k8s-status Show pods/services status" @echo " k8s-logs-backend Tail backend logs" @echo " k8s-logs-frontend Tail frontend logs" @echo " k8s-health Check health endpoints" @echo "" @echo "Kubernetes Utilities:" @echo " k8s-port-forward Port forward for local testing" @echo " k8s-exec-backend Shell into backend pod" @echo " k8s-rollback Rollback deployment" @echo " k8s-delete Delete all resources from namespace" # Installation install: @echo "Installing dependencies..." cd backend && bun install cd frontend && bun install @echo "Dependencies installed successfully!" clean: @echo "Cleaning up..." rm -rf backend/node_modules rm -rf frontend/node_modules rm -rf frontend/build rm -rf backend/dist @echo "Cleanup complete!" # Development dev: @echo "Starting development servers..." @echo "Backend will start on http://localhost:5000" @echo "Frontend will start on http://localhost:3000" @echo "Press Ctrl+C to stop both servers" @make -j2 dev-frontend dev-backend dev-frontend: @echo "Starting frontend development server..." cd frontend && bun start dev-backend: @echo "Starting backend development server..." cd backend && node server.js # Building build: build-frontend build-backend @echo "Build complete!" build-frontend: @echo "Building frontend for production..." cd frontend && bun run build @echo "Frontend build complete!" build-backend: @echo "Backend is ready for production (no build step required for Node.js)" @echo "Backend production files are in backend/" # Testing test: test-frontend test-backend @echo "All tests completed!" test-frontend: @echo "Running frontend tests..." cd frontend && bun test -- --watchAll=false --coverage test-backend: @echo "Running backend tests..." cd backend && bun test test-coverage: @echo "Running tests with coverage..." @echo "Backend coverage:" cd backend && bun run test:coverage @echo "" @echo "Frontend coverage:" cd frontend && bun run test:coverage # Code Quality lint: lint-frontend lint-backend @echo "Linting complete!" lint-frontend: @echo "Linting frontend..." cd frontend && bun run lint 2>/dev/null || echo "Frontend linting not configured" lint-backend: @echo "Linting backend..." cd backend && bunx eslint . # Production run: build @echo "Starting production servers..." @echo "Note: In production, you would typically use process managers like PM2" @echo "or container orchestration like Kubernetes" @echo "See deploy/ directory for Kubernetes deployment files" start: @echo "Starting production backend server..." cd backend && NODE_ENV=production node server.js # Docker (if needed) docker-build: @echo "Building Docker images..." docker build -t adopt-a-street-frontend ./frontend docker build -t adopt-a-street-backend ./backend @echo "Docker images built!" docker-run: @echo "Running Docker containers..." docker run -d -p 3000:3000 --name frontend adopt-a-street-frontend docker run -d -p 5000:5000 --name backend adopt-a-street-backend @echo "Docker containers running!" # Multi-Architecture Docker docker-multiarch-setup: @echo "Setting up multi-architecture Docker builder..." ./scripts/setup-multiarch-builder.sh docker-multiarch-build: @echo "Building and pushing multi-architecture Docker images..." ./scripts/build-multiarch.sh docker-multiarch-verify: @echo "Verifying multi-architecture Docker images..." ./scripts/verify-multiarch.sh docker-multiarch: docker-multiarch-setup docker-multiarch-build docker-multiarch-verify @echo "Multi-architecture Docker workflow complete!" # Database (for development) db-setup: @echo "Setting up MongoDB..." @echo "Make sure MongoDB is installed and running on your system" @echo "Or use Docker: docker run -d -p 27017:27017 --name mongodb mongo" @echo "Create .env file in backend/ with MONGO_URI and JWT_SECRET" # Environment setup env-setup: @echo "Setting up environment files..." @if [ ! -f backend/.env ]; then \ echo "Creating backend/.env file..."; \ cp backend/.env.example backend/.env 2>/dev/null || echo "MONGO_URI=mongodb://localhost:27017/adopt-a-street\nJWT_SECRET=your-secret-key-here\nPORT=5000" > backend/.env; \ echo "Please edit backend/.env with your actual values"; \ else \ echo "backend/.env already exists"; \ fi # Quick start for new developers quick-start: install env-setup db-setup @echo "" @echo "Quick start complete!" @echo "" @echo "Next steps:" @echo "1. Edit backend/.env with your MongoDB URI and JWT secret" @echo "2. Run 'make dev' to start development servers" @echo "3. Visit http://localhost:3000 to see the application" @echo "" @echo "For more commands, run 'make help'" @echo "" @echo "Docker Commands:" @echo " docker-build Build single-architecture Docker images" @echo " docker-run Run Docker containers" @echo " docker-multiarch-setup Setup multi-architecture builder" @echo " docker-multiarch-build Build and push multi-arch images" @echo " docker-multiarch-verify Verify multi-arch images" @echo " docker-multiarch Complete multi-arch workflow" # ==================== Kubernetes Testing ==================== k8s-test-connection: @echo "Testing kubectl connectivity to $(K8S_CONTEXT)..." @kubectl cluster-info --context=$(K8S_CONTEXT) @echo "" @echo "Cluster nodes:" @kubectl get nodes @echo "" @echo "Connection test successful!" k8s-test-manifests: @echo "Validating Kubernetes manifests (dry-run)..." @kubectl apply -f deploy/k8s/ --dry-run=client -n $(K8S_NAMESPACE) @echo "" @echo "Manifest validation successful!" k8s-test-deploy-dev: @echo "Testing deployment to $(K8S_NAMESPACE)..." @$(MAKE) K8S_NAMESPACE=adopt-a-street-dev k8s-namespace-create || true @echo "Running manifest validation..." @$(MAKE) K8S_NAMESPACE=adopt-a-street-dev k8s-test-manifests @echo "" @echo "Note: Run 'make k8s-deploy-dev' to deploy (includes registry secret)" # ==================== Kubernetes Deployment ==================== k8s-namespace-create: @echo "Creating namespace: $(K8S_NAMESPACE)..." @kubectl create namespace $(K8S_NAMESPACE) --dry-run=client -o yaml | kubectl apply -f - @echo "Namespace $(K8S_NAMESPACE) ready!" k8s-secret-create: ifndef GITEA_PASSWORD @echo "Error: GITEA_PASSWORD environment variable not set" @echo "Usage: make k8s-secret-create GITEA_PASSWORD=your-password K8S_NAMESPACE=namespace" @exit 1 endif @echo "Creating image pull secret in $(K8S_NAMESPACE)..." @kubectl create secret docker-registry regcred \ --docker-server=$(REGISTRY) \ --docker-username=$(GITEA_USERNAME) \ --docker-password=$(GITEA_PASSWORD) \ --namespace=$(K8S_NAMESPACE) \ --dry-run=client -o yaml | kubectl apply -f - @echo "Image pull secret created successfully!" k8s-deploy: k8s-namespace-create @echo "Deploying to namespace: $(K8S_NAMESPACE)..." @kubectl apply -f deploy/k8s/registry-secret.yaml -n $(K8S_NAMESPACE) @kubectl apply -f deploy/k8s/configmap.yaml -n $(K8S_NAMESPACE) @kubectl apply -f deploy/k8s/secrets.yaml -n $(K8S_NAMESPACE) 2>/dev/null || echo "Warning: secrets.yaml not found or already exists" @kubectl apply -f deploy/k8s/couchdb-statefulset.yaml -n $(K8S_NAMESPACE) @kubectl apply -f deploy/k8s/backend-deployment.yaml -n $(K8S_NAMESPACE) @kubectl apply -f deploy/k8s/frontend-deployment.yaml -n $(K8S_NAMESPACE) @echo "" @echo "Deployment initiated! Waiting for pods to be ready..." @sleep 5 @kubectl get pods -n $(K8S_NAMESPACE) @echo "" @echo "Deployment complete! Run 'make k8s-status K8S_NAMESPACE=$(K8S_NAMESPACE)' to check status" k8s-deploy-dev: @$(MAKE) K8S_NAMESPACE=adopt-a-street-dev k8s-deploy k8s-deploy-staging: @$(MAKE) K8S_NAMESPACE=adopt-a-street-staging k8s-deploy k8s-deploy-prod: @$(MAKE) K8S_NAMESPACE=adopt-a-street-prod k8s-deploy @echo "" @echo "WARNING: Deployed to PRODUCTION namespace!" # ==================== Kubernetes Verification ==================== k8s-status: @echo "Status for namespace: $(K8S_NAMESPACE)" @echo "" @echo "=== Pods ===" @kubectl get pods -n $(K8S_NAMESPACE) -o wide @echo "" @echo "=== Services ===" @kubectl get services -n $(K8S_NAMESPACE) @echo "" @echo "=== Deployments ===" @kubectl get deployments -n $(K8S_NAMESPACE) @echo "" @echo "=== StatefulSets ===" @kubectl get statefulsets -n $(K8S_NAMESPACE) k8s-logs-backend: @echo "Tailing backend logs in $(K8S_NAMESPACE)..." @kubectl logs -f -n $(K8S_NAMESPACE) -l app=adopt-a-street-backend --tail=100 k8s-logs-frontend: @echo "Tailing frontend logs in $(K8S_NAMESPACE)..." @kubectl logs -f -n $(K8S_NAMESPACE) -l app=adopt-a-street-frontend --tail=100 k8s-health: @echo "Checking health endpoints in $(K8S_NAMESPACE)..." @echo "" @echo "Backend health:" @kubectl exec -n $(K8S_NAMESPACE) deployment/adopt-a-street-backend -- curl -s http://localhost:5000/api/health || echo "Backend health check failed" @echo "" @echo "" @echo "Frontend health:" @kubectl exec -n $(K8S_NAMESPACE) deployment/adopt-a-street-frontend -- curl -s http://localhost:80/health || echo "Frontend health check failed" @echo "" @echo "" @echo "CouchDB health:" @kubectl exec -n $(K8S_NAMESPACE) deployment/adopt-a-street-backend -- curl -s http://adopt-a-street-couchdb:5984/_up || echo "CouchDB connection failed" # ==================== Kubernetes Utilities ==================== k8s-port-forward: @echo "Port forwarding services in $(K8S_NAMESPACE)..." @echo "Backend: http://localhost:5000" @echo "Frontend: http://localhost:3000" @echo "" @echo "Press Ctrl+C to stop port forwarding" @kubectl port-forward -n $(K8S_NAMESPACE) service/adopt-a-street-backend 5000:5000 & \ kubectl port-forward -n $(K8S_NAMESPACE) service/adopt-a-street-frontend 3000:80 k8s-exec-backend: @echo "Opening shell in backend pod..." @kubectl exec -it -n $(K8S_NAMESPACE) deployment/adopt-a-street-backend -- /bin/bash k8s-rollback: @echo "Rolling back deployments in $(K8S_NAMESPACE)..." @kubectl rollout undo deployment/adopt-a-street-backend -n $(K8S_NAMESPACE) @kubectl rollout undo deployment/adopt-a-street-frontend -n $(K8S_NAMESPACE) @echo "Rollback initiated! Checking status..." @kubectl rollout status deployment/adopt-a-street-backend -n $(K8S_NAMESPACE) @kubectl rollout status deployment/adopt-a-street-frontend -n $(K8S_NAMESPACE) k8s-delete: @echo "WARNING: This will delete all resources in $(K8S_NAMESPACE)" @echo "Press Ctrl+C within 5 seconds to cancel..." @sleep 5 @echo "Deleting resources in $(K8S_NAMESPACE)..." @kubectl delete -f deploy/k8s/ -n $(K8S_NAMESPACE) --ignore-not-found=true @echo "" @echo "Resources deleted from $(K8S_NAMESPACE)" @echo "Note: The namespace itself still exists. Use 'kubectl delete namespace $(K8S_NAMESPACE)' to remove it."