auth.coditect.ai Deployment Plan
Executive Summary
Objective: Deploy complete authentication portal at auth.coditect.ai with:
- User registration and login frontend
- Backend API for authentication, license management
- Secure HTTPS with Google-managed SSL
- Single static IP with Ingress routing
Timeline: 3-5 days Status: Planning → Implementation
Current Infrastructure Status
✅ Existing Resources
GCP Project: coditect-cloud-infra
GKE Cluster: coditect-cluster
Location: us-central1
Nodes: 3 x n1-standard-2
Status: RUNNING
Backend Deployment:
Namespace: coditect-staging
Service: coditect-backend (LoadBalancer)
External IP: 136.114.0.156 (ephemeral)
Ports: 80, 443
Status: DEPLOYED (8 hours ago)
❌ Missing Components
- Global static IP for auth.coditect.ai
- Google-managed SSL certificate
- Ingress controller configuration
- DNS A record: auth.coditect.ai → static IP
- Frontend React application
- Frontend container image
- Frontend Kubernetes deployment
Architecture
Target Architecture
┌──────────────────┐
│ auth.coditect.ai │
│ DNS A Record │
└────────┬─────────┘
│
▼
┌────────────────────────┐
│ Static IP (Global) │
│ 34.x.x.x (new) │
└─────────┬──────────────┘
│
▼
┌────────────────────────────────┐
│ GKE Ingress Controller │
│ (nginx or gce ingress) │
│ + Google-managed SSL Cert │
└─────┬────────────────┬─────────┘
│ │
┌──────────────┴────┐ ┌─────┴───────────────┐
│ Path: /api/v1/* │ │ Path: /* │
▼ ▼ ▼ ▼
┌──────────────┐ ┌──────────────┐
│ Backend │ │ Frontend │
│ Service │ │ Service │
│ (Django API) │ │ (React App) │
└──────────────┘ └──────────────┘
Port 8000 Port 80
Request Flow Examples
User visits: https://auth.coditect.ai/
→ Ingress routes to frontend service (port 80)
→ Returns React app HTML
User calls: https://auth.coditect.ai/api/v1/auth/register/
→ Ingress routes to backend service (port 8000)
→ Returns JSON response
CORS: Not needed (same origin)
Implementation Steps
Phase 1: GCP Infrastructure Setup (Day 1)
Step 1.1: Reserve Global Static IP
# Reserve the IP
gcloud compute addresses create coditect-auth-ip \
--global \
--ip-version IPV4 \
--project coditect-cloud-infra
# Get the IP address
export AUTH_IP=$(gcloud compute addresses describe coditect-auth-ip \
--global \
--format="value(address)")
echo "Reserved IP: $AUTH_IP"
# Output: Reserved IP: 34.120.45.67 (example)
Verification:
gcloud compute addresses list --global | grep coditect-auth-ip
Step 1.2: Create SSL Certificate
# Create Google-managed SSL certificate
gcloud compute ssl-certificates create coditect-auth-cert \
--domains=auth.coditect.ai \
--global \
--project coditect-cloud-infra
# Check provisioning status (takes 10-60 minutes after DNS configured)
gcloud compute ssl-certificates describe coditect-auth-cert \
--global \
--format="value(managed.status)"
Note: Certificate provisioning requires DNS to be configured first (Step 1.3)
Step 1.3: Configure DNS
Action Required: Update DNS at domain registrar
# DNS Configuration (at your domain registrar - e.g., Namecheap, GoDaddy)
Type: A
Host: auth
Domain: coditect.ai
Value: <AUTH_IP from Step 1.1>
TTL: 300 (5 minutes for testing, increase to 3600 after confirmed)
Verification:
# Wait 5-10 minutes for DNS propagation
dig auth.coditect.ai +short
# Should return: <AUTH_IP>
# Alternative check
nslookup auth.coditect.ai
Phase 2: Frontend Development (Day 2-3)
Step 2.1: Initialize React Project
Location: /Users/halcasteel/PROJECTS/coditect-rollout-master/submodules/cloud/coditect-cloud-frontend/
cd submodules/cloud/coditect-cloud-frontend
# Create Vite + React + TypeScript project
npm create vite@latest . -- --template react-ts
# Install dependencies
npm install
# Install additional libraries
npm install \
react-router-dom \
@tanstack/react-query \
axios \
react-hook-form \
zod \
@radix-ui/react-dialog \
@radix-ui/react-dropdown-menu \
tailwindcss postcss autoprefixer
# Initialize Tailwind
npx tailwindcss init -p
Step 2.2: Build Core Pages
Pages to Implement:
-
Landing Page (
/)- Hero section with value proposition
- Pricing table (BASIC, PRO, ENTERPRISE)
- Call-to-action: "Get Started"
- Features overview
- Time: 4-6 hours
-
Registration Page (
/register)- Email, password, full name, company fields
- Email verification notice
- Stripe checkout integration
- Time: 6-8 hours
-
Login Page (
/login)- Email/password form
- JWT token storage
- Redirect to dashboard after login
- "Forgot password" link
- Time: 3-4 hours
-
Dashboard Page (
/dashboard)- Display license key
- Show active sessions
- Organization info
- Download license file
- Time: 6-8 hours
-
Email Verification Page (
/verify-email)- Handle email verification tokens
- Success/failure messaging
- Auto-redirect to login
- Time: 2-3 hours
Total Frontend Time: 21-29 hours (2-3 days with 8-10 hour days)
Step 2.3: API Integration
Create API client:
// src/services/api.ts
import axios from 'axios';
const API_BASE_URL = import.meta.env.VITE_API_URL || '/api/v1';
export const api = axios.create({
baseURL: API_BASE_URL,
timeout: 10000,
headers: {
'Content-Type': 'application/json',
},
});
// Add JWT token to requests
api.interceptors.request.use((config) => {
const token = localStorage.getItem('access_token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});
// Handle token refresh on 401
api.interceptors.response.use(
(response) => response,
async (error) => {
if (error.response?.status === 401) {
const refreshToken = localStorage.getItem('refresh_token');
if (refreshToken) {
// Attempt token refresh
try {
const response = await axios.post(`${API_BASE_URL}/auth/token/refresh/`, {
refresh: refreshToken,
});
localStorage.setItem('access_token', response.data.access);
// Retry original request
error.config.headers.Authorization = `Bearer ${response.data.access}`;
return axios(error.config);
} catch (refreshError) {
// Refresh failed, redirect to login
localStorage.clear();
window.location.href = '/login';
}
}
}
return Promise.reject(error);
}
);
API Services:
// src/services/authService.ts
export const authService = {
register: (data) => api.post('/auth/register/', data),
login: (credentials) => api.post('/auth/login/', credentials),
verifyEmail: (token) => api.post('/auth/verify-email/', { token }),
forgotPassword: (email) => api.post('/auth/forgot-password/', { email }),
resetPassword: (token, password) => api.post('/auth/reset-password/', { token, password }),
};
// src/services/licenseService.ts
export const licenseService = {
getMyLicenses: () => api.get('/licenses/'),
getLicenseDetail: (id) => api.get(`/licenses/${id}/`),
downloadLicense: (id) => api.get(`/licenses/${id}/download/`),
validateLicense: (key) => api.post('/licenses/validate/', { license_key: key }),
};
// src/services/subscriptionService.ts
export const subscriptionService = {
getPlans: () => api.get('/subscriptions/plans/'),
createCheckout: (plan_id) => api.post('/subscriptions/checkout/', { plan_id }),
getCurrentSubscription: () => api.get('/subscriptions/current/'),
};
Step 2.4: Environment Configuration
# .env.example
VITE_API_URL=/api/v1
VITE_STRIPE_PUBLISHABLE_KEY=pk_test_...
# .env.development (local development)
VITE_API_URL=http://localhost:8000/api/v1
VITE_STRIPE_PUBLISHABLE_KEY=pk_test_51K...
# .env.production (production - uses relative path)
VITE_API_URL=/api/v1
VITE_STRIPE_PUBLISHABLE_KEY=pk_live_51K...
Phase 3: Containerization (Day 3)
Step 3.1: Create Dockerfile for Frontend
# Dockerfile
FROM node:18-alpine AS builder
WORKDIR /app
# Install dependencies
COPY package*.json ./
RUN npm ci --only=production
# Copy source code
COPY . .
# Build for production
RUN npm run build
# Production stage with Nginx
FROM nginx:alpine
# Copy built files
COPY --from=builder /app/dist /usr/share/nginx/html
# Custom Nginx config for React Router (SPA)
RUN echo 'server { \
listen 80; \
location / { \
root /usr/share/nginx/html; \
index index.html index.htm; \
try_files $uri $uri/ /index.html; \
} \
}' > /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Step 3.2: Build and Push Image
cd submodules/cloud/coditect-cloud-frontend
# Build image
docker build -t gcr.io/coditect-cloud-infra/coditect-frontend:v1.0.0 .
# Push to Google Container Registry
docker push gcr.io/coditect-cloud-infra/coditect-frontend:v1.0.0
# Tag as latest
docker tag gcr.io/coditect-cloud-infra/coditect-frontend:v1.0.0 \
gcr.io/coditect-cloud-infra/coditect-frontend:latest
docker push gcr.io/coditect-cloud-infra/coditect-frontend:latest
Phase 4: Kubernetes Deployment (Day 4)
Step 4.1: Create Frontend Deployment
# deployment/kubernetes/frontend-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: coditect-frontend
namespace: coditect-staging
spec:
replicas: 2
selector:
matchLabels:
app: coditect-frontend
template:
metadata:
labels:
app: coditect-frontend
spec:
containers:
- name: frontend
image: gcr.io/coditect-cloud-infra/coditect-frontend:latest
ports:
- containerPort: 80
env:
- name: VITE_API_URL
value: "/api/v1"
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 10
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: coditect-frontend
namespace: coditect-staging
spec:
selector:
app: coditect-frontend
ports:
- port: 80
targetPort: 80
type: ClusterIP
Step 4.2: Update Backend Service (Remove LoadBalancer)
# deployment/kubernetes/backend-deployment.yaml (UPDATE)
apiVersion: v1
kind: Service
metadata:
name: coditect-backend
namespace: coditect-staging
spec:
selector:
app: coditect-backend
ports:
- port: 8000
targetPort: 8000
type: ClusterIP # Changed from LoadBalancer to ClusterIP
Step 4.3: Create Ingress Configuration
# deployment/kubernetes/ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: coditect-auth-ingress
namespace: coditect-staging
annotations:
kubernetes.io/ingress.global-static-ip-name: "coditect-auth-ip"
networking.gke.io/managed-certificates: "coditect-auth-cert"
kubernetes.io/ingress.class: "gce"
# Enable HTTPS redirect
networking.gke.io/v1beta1.FrontendConfig: "redirect-http-to-https"
spec:
rules:
- host: auth.coditect.ai
http:
paths:
# Backend API paths (must come first - more specific)
- path: /api/v1/*
pathType: ImplementationSpecific
backend:
service:
name: coditect-backend
port:
number: 8000
# Admin API paths
- path: /admin/*
pathType: ImplementationSpecific
backend:
service:
name: coditect-backend
port:
number: 8000
# Static files (Django admin CSS/JS)
- path: /static/*
pathType: ImplementationSpecific
backend:
service:
name: coditect-backend
port:
number: 8000
# Frontend (catch-all - must come last)
- path: /*
pathType: ImplementationSpecific
backend:
service:
name: coditect-frontend
port:
number: 80
---
# HTTPS redirect configuration
apiVersion: networking.gke.io/v1beta1
kind: FrontendConfig
metadata:
name: redirect-http-to-https
namespace: coditect-staging
spec:
redirectToHttps:
enabled: true
Step 4.4: Deploy to GKE
# Apply configurations
kubectl apply -f deployment/kubernetes/frontend-deployment.yaml
kubectl apply -f deployment/kubernetes/backend-deployment.yaml # Updated ClusterIP
kubectl apply -f deployment/kubernetes/ingress.yaml
# Verify deployments
kubectl get deployments -n coditect-staging
kubectl get services -n coditect-staging
kubectl get ingress -n coditect-staging
# Check Ingress status (wait 5-10 minutes for provisioning)
kubectl describe ingress coditect-auth-ingress -n coditect-staging
# Monitor SSL certificate provisioning (can take 10-60 minutes)
gcloud compute ssl-certificates describe coditect-auth-cert \
--global \
--format="value(managed.status)"
# Expected: ACTIVE (after DNS propagates)
Phase 5: Testing & Validation (Day 4-5)
Step 5.1: Smoke Tests
# Test DNS resolution
dig auth.coditect.ai +short
# Should return: Static IP from Step 1.1
# Test HTTP → HTTPS redirect
curl -I http://auth.coditect.ai
# Should return: 301 Moved Permanently, Location: https://auth.coditect.ai
# Test HTTPS (frontend)
curl -I https://auth.coditect.ai
# Should return: 200 OK, Content-Type: text/html
# Test backend API
curl https://auth.coditect.ai/api/v1/health/
# Should return: {"status": "healthy"}
Step 5.2: End-to-End User Flow
Test Script:
-
Visit Landing Page
- Navigate to: https://auth.coditect.ai
- Verify: React app loads, styling correct
- Click: "Get Started" button
-
Register Account
- Navigate to: https://auth.coditect.ai/register
- Fill: Email, password, full name, company name
- Click: "Create Account"
- Verify: Success message, "Check your email" notice
-
Verify Email
- Check email inbox
- Click: Verification link
- Verify: Redirects to login with success message
-
Complete Stripe Checkout
- Login with verified account
- Select: BASIC plan ($29/month)
- Click: "Subscribe"
- Verify: Redirects to Stripe checkout
- Complete: Test payment (card: 4242 4242 4242 4242)
- Verify: Redirects back to dashboard
-
View License
- Verify: License key displayed (CODITECT-YYYY-XXXX-XXXX)
- Click: "Download License"
- Verify: License file downloads
-
Test License in CODITECT-CORE
- Install: CODITECT-CORE CLI
- Run:
coditect license activate <LICENSE_KEY> - Verify: License accepted, session started
- Check: Dashboard shows 1 active session
Step 5.3: Performance Testing
# Load test with Apache Bench
ab -n 1000 -c 10 https://auth.coditect.ai/
# Check response times
# Target: < 500ms for frontend, < 1000ms for API
Step 5.4: Security Testing
# SSL Labs test
# Visit: https://www.ssllabs.com/ssltest/analyze.html?d=auth.coditect.ai
# Target: A+ rating
# Security headers check
curl -I https://auth.coditect.ai | grep -i 'x-frame-options\|x-content-type-options\|strict-transport-security'
# CORS check
curl -H "Origin: https://evil.com" \
-H "Access-Control-Request-Method: POST" \
-X OPTIONS https://auth.coditect.ai/api/v1/auth/login/
# Should return: CORS headers restricting to auth.coditect.ai only
Cost Estimates
GCP Infrastructure Costs (Monthly)
| Resource | Quantity | Unit Cost | Monthly Cost |
|---|---|---|---|
| GKE Cluster (n1-standard-2) | 3 nodes | $0.095/hr | ~$205 |
| Global Static IP | 1 IP | $0.010/hr | ~$7.20 |
| Ingress Load Balancer | 1 | $18/month | $18 |
| Cloud SQL (PostgreSQL) | db-n1-standard-1 | $0.0825/hr | ~$60 |
| Redis Memorystore | 6 GB | $0.017/GB/hr | ~$73 |
| SSL Certificate | 1 | Free (Google-managed) | $0 |
| Egress (estimate) | 100 GB | $0.12/GB | $12 |
| TOTAL | ~$375/month |
Development Time (Hours)
| Phase | Task | Hours |
|---|---|---|
| 1 | GCP Infrastructure Setup | 2-3 |
| 2 | Frontend Development | 21-29 |
| 3 | Containerization | 3-4 |
| 4 | Kubernetes Deployment | 4-6 |
| 5 | Testing & Validation | 6-8 |
| TOTAL | 36-50 hours |
Timeline: 3-5 days (assuming 8-10 hour workdays)
Rollback Plan
If issues occur during deployment:
Scenario 1: Ingress Not Working
# Quick rollback: Re-enable LoadBalancer on backend
kubectl patch service coditect-backend -n coditect-staging \
-p '{"spec":{"type":"LoadBalancer"}}'
# Update DNS to point to LoadBalancer IP temporarily
# This allows backend API to remain accessible while debugging Ingress
Scenario 2: SSL Certificate Provisioning Stuck
# Check DNS propagation
dig auth.coditect.ai +short
# Check certificate status
gcloud compute ssl-certificates describe coditect-auth-cert --global
# Common issues:
# - DNS not propagated (wait 5-60 minutes)
# - Domain verification failed (check CAA records)
# - Rate limit hit (wait 24 hours, use staging cert temporarily)
Scenario 3: Frontend Not Loading
# Check pod status
kubectl get pods -n coditect-staging | grep frontend
# Check logs
kubectl logs -l app=coditect-frontend -n coditect-staging --tail=100
# Common issues:
# - Image pull error (check GCR permissions)
# - Nginx config error (check Dockerfile)
# - React build error (check build logs)
Success Criteria
- Static IP reserved and DNS configured
- SSL certificate provisioned (ACTIVE status)
- Frontend builds and deploys successfully
- Ingress routes traffic correctly (/ → frontend, /api/v1/* → backend)
- HTTPS working with A+ SSL Labs rating
- User can complete full registration flow end-to-end
- License activation works in CODITECT-CORE
- Performance: Frontend < 500ms, API < 1000ms
- Security: All headers configured, CORS enforced
- Monitoring: GKE metrics showing healthy pods
- Documentation: README updated with deployment instructions
Post-Deployment Tasks
-
Monitor for 24 hours
- Check GKE metrics for CPU/memory usage
- Monitor SSL certificate renewal (automatic)
- Review logs for errors
-
Update Documentation
- Add deployment guide to README
- Document DNS configuration
- Update architecture diagrams
-
Set Up Alerts
- Uptime monitoring (UptimeRobot, Pingdom)
- Error rate alerts (Cloud Monitoring)
- SSL expiration alerts (automatic with Google-managed)
-
Backup & Disaster Recovery
- Document rollback procedures
- Test backup restoration
- Set up automated database backups
Next Steps
Immediate Actions:
- Reserve static IP (5 minutes)
- Configure DNS at domain registrar (10 minutes)
- Create SSL certificate (1 minute - provisioning takes 10-60 min)
- Start frontend development (2-3 days)
- Deploy to GKE (4-6 hours)
- Test end-to-end (4-6 hours)
Decision Needed:
- Proceed with full frontend implementation?
- Simplified MVP first (landing + registration only)?
- Timeline preference (fast MVP vs. complete implementation)?
Created: December 1, 2025 Owner: Hal Casteel Status: Ready for Implementation