352 lines
9.0 KiB
Bash
Executable File
352 lines
9.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# Get project ID
|
|
PROJECT=$(gcloud config get-value project)
|
|
|
|
echo "🔍 Checking current status..."
|
|
kubectl get pods -n sk1
|
|
|
|
echo "🧹 Cleaning up any broken configurations..."
|
|
# Delete the debug pods we created earlier
|
|
kubectl delete pod debug-react -n sk1 --ignore-not-found
|
|
kubectl delete pod test-route -n sk1 --ignore-not-found
|
|
|
|
echo "🔄 Creating a complete backend with all required routes..."
|
|
|
|
# Create a temporary file with our complete backend app
|
|
cat > /tmp/complete-backend.js << 'EOF'
|
|
const express = require('express');
|
|
const cors = require('cors');
|
|
const mongoose = require('mongoose');
|
|
const app = express();
|
|
const port = process.env.PORT || 4000;
|
|
const host = process.env.HOST || '0.0.0.0';
|
|
|
|
// Middleware
|
|
app.use(cors());
|
|
app.use(express.json());
|
|
app.use(express.urlencoded({ extended: true }));
|
|
|
|
// Root route
|
|
app.get('/', (req, res) => {
|
|
res.json({ message: 'Welcome to the API' });
|
|
});
|
|
|
|
// Health check endpoint
|
|
app.get('/api', (req, res) => {
|
|
res.json({ status: 'ok', message: 'API is healthy' });
|
|
});
|
|
|
|
// Health check endpoint
|
|
app.get('/api/health', (req, res) => {
|
|
res.json({ status: 'ok' });
|
|
});
|
|
|
|
// Service routes
|
|
app.get('/api/services/:serviceType', (req, res) => {
|
|
const serviceType = req.params.serviceType;
|
|
const { radius, page, sortBy, order, lat, lon } = req.query;
|
|
|
|
console.log(`Received request for ${serviceType} services`);
|
|
console.log(`Query params: radius=${radius}, page=${page}, sortBy=${sortBy}, order=${order}, lat=${lat}, lon=${lon}`);
|
|
|
|
// Return mock data for any service type
|
|
res.json({
|
|
success: true,
|
|
services: [
|
|
{
|
|
id: 1,
|
|
name: `${serviceType} Service 1`,
|
|
description: `Professional ${serviceType} service`,
|
|
price: Math.floor(Math.random() * 50) + 20,
|
|
distance: parseFloat((Math.random() * 5).toFixed(1)),
|
|
rating: parseFloat((Math.random() * 2 + 3).toFixed(1))
|
|
},
|
|
{
|
|
id: 2,
|
|
name: `${serviceType} Service 2`,
|
|
description: `Expert ${serviceType} provider`,
|
|
price: Math.floor(Math.random() * 50) + 20,
|
|
distance: parseFloat((Math.random() * 5).toFixed(1)),
|
|
rating: parseFloat((Math.random() * 2 + 3).toFixed(1))
|
|
}
|
|
],
|
|
pagination: {
|
|
currentPage: parseInt(page) || 1,
|
|
totalPages: 3,
|
|
totalResults: 6
|
|
}
|
|
});
|
|
});
|
|
|
|
// Authentication endpoints
|
|
app.post('/api/auth/login', (req, res) => {
|
|
console.log('Login attempt:', req.body);
|
|
|
|
res.json({
|
|
success: true,
|
|
token: "mock-jwt-token",
|
|
user: {
|
|
id: 1,
|
|
name: "Test User",
|
|
email: req.body.email || "test@example.com"
|
|
}
|
|
});
|
|
});
|
|
|
|
app.post('/api/auth/register', (req, res) => {
|
|
console.log('Registration attempt:', req.body);
|
|
|
|
res.json({
|
|
success: true,
|
|
message: "User registered successfully",
|
|
user: {
|
|
id: new Date().getTime(),
|
|
name: req.body.name || "New User",
|
|
email: req.body.email || "new@example.com"
|
|
}
|
|
});
|
|
});
|
|
|
|
// MongoDB connection
|
|
const MONGO_URI = process.env.MONGO_URI;
|
|
if (MONGO_URI) {
|
|
mongoose.connect(MONGO_URI)
|
|
.then(() => console.log('✅ MongoDB connected'))
|
|
.catch(err => console.error('MongoDB connection error:', err));
|
|
}
|
|
|
|
// Error handling middleware
|
|
app.use((err, req, res, next) => {
|
|
console.error('Error:', err);
|
|
res.status(500).json({
|
|
success: false,
|
|
message: 'Server error',
|
|
error: process.env.NODE_ENV === 'development' ? err.message : 'Internal server error'
|
|
});
|
|
});
|
|
|
|
// Handle 404s
|
|
app.use((req, res) => {
|
|
console.log(`404: ${req.method} ${req.path}`);
|
|
res.status(404).json({
|
|
success: false,
|
|
message: 'API endpoint not found'
|
|
});
|
|
});
|
|
|
|
// Start server
|
|
app.listen(port, host, () => {
|
|
console.log(`🚀 Server running on http://${host}:${port}`);
|
|
});
|
|
EOF
|
|
|
|
# Create a package.json file
|
|
cat > /tmp/package.json << 'EOF'
|
|
{
|
|
"name": "backend",
|
|
"version": "1.0.0",
|
|
"description": "Backend for Nudges Works application",
|
|
"main": "index.js",
|
|
"scripts": {
|
|
"start": "node index.js"
|
|
},
|
|
"dependencies": {
|
|
"cors": "^2.8.5",
|
|
"express": "^4.18.2",
|
|
"mongoose": "^7.0.3"
|
|
}
|
|
}
|
|
EOF
|
|
|
|
# Create a Dockerfile
|
|
cat > /tmp/Dockerfile << 'EOF'
|
|
FROM node:20-alpine
|
|
|
|
WORKDIR /app
|
|
|
|
COPY package.json .
|
|
RUN npm install
|
|
|
|
COPY index.js .
|
|
|
|
EXPOSE 4000
|
|
|
|
CMD ["node", "index.js"]
|
|
EOF
|
|
|
|
# Create a temporary directory and copy files
|
|
rm -rf /tmp/backend-build || true
|
|
mkdir -p /tmp/backend-build
|
|
cp /tmp/complete-backend.js /tmp/backend-build/index.js
|
|
cp /tmp/package.json /tmp/backend-build/package.json
|
|
cp /tmp/Dockerfile /tmp/backend-build/Dockerfile
|
|
|
|
# Build and push the image
|
|
echo "🏗️ Building and pushing new backend image..."
|
|
cd /tmp/backend-build
|
|
gcloud builds submit --tag gcr.io/${PROJECT}/backend-complete:latest
|
|
|
|
# Create a deployment with the new image
|
|
cat > /tmp/backend-complete.yaml << EOF
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: backend
|
|
namespace: sk1
|
|
spec:
|
|
replicas: 1
|
|
selector:
|
|
matchLabels:
|
|
app: backend
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: backend
|
|
spec:
|
|
containers:
|
|
- name: backend
|
|
image: gcr.io/${PROJECT}/backend-complete:latest
|
|
resources:
|
|
limits:
|
|
cpu: "0.5"
|
|
memory: "512Mi"
|
|
requests:
|
|
cpu: "0.2"
|
|
memory: "256Mi"
|
|
ports:
|
|
- containerPort: 4000
|
|
env:
|
|
- name: PORT
|
|
value: "4000"
|
|
- name: HOST
|
|
value: "0.0.0.0"
|
|
- name: MONGO_URI
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: mongodb-secret
|
|
key: MONGO_URI
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: backend-service
|
|
namespace: sk1
|
|
spec:
|
|
selector:
|
|
app: backend
|
|
ports:
|
|
- port: 4000
|
|
targetPort: 4000
|
|
EOF
|
|
|
|
# Apply the deployment
|
|
echo "📦 Applying new backend deployment..."
|
|
kubectl apply -f /tmp/backend-complete.yaml
|
|
|
|
# Update the frontend nginx config to ensure it's working correctly
|
|
cat > /tmp/fixed-nginx.conf << 'EOF'
|
|
server {
|
|
listen 80;
|
|
server_name localhost;
|
|
root /usr/share/nginx/html;
|
|
index index.html;
|
|
|
|
# Fix for API routing - explicit location block for various endpoints
|
|
location /api/services/ {
|
|
proxy_pass http://backend-service:4000;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection 'upgrade';
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_cache_bypass $http_upgrade;
|
|
}
|
|
|
|
location /api/auth/ {
|
|
proxy_pass http://backend-service:4000;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection 'upgrade';
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_cache_bypass $http_upgrade;
|
|
}
|
|
|
|
# General API requests
|
|
location /api {
|
|
proxy_pass http://backend-service:4000;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection 'upgrade';
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_cache_bypass $http_upgrade;
|
|
}
|
|
|
|
# All other requests go to the React app
|
|
location / {
|
|
try_files $uri $uri/ /index.html;
|
|
}
|
|
}
|
|
EOF
|
|
|
|
# Create a ConfigMap for the new nginx configuration
|
|
kubectl create configmap fixed-nginx-conf -n sk1 --from-file=nginx.conf=/tmp/fixed-nginx.conf -o yaml --dry-run=client | kubectl apply -f -
|
|
|
|
# Update the frontend deployment to use the new ConfigMap
|
|
kubectl patch deployment frontend -n sk1 --type=strategic --patch '
|
|
{
|
|
"spec": {
|
|
"template": {
|
|
"spec": {
|
|
"containers": [
|
|
{
|
|
"name": "frontend",
|
|
"volumeMounts": [
|
|
{
|
|
"name": "nginx-config",
|
|
"mountPath": "/etc/nginx/conf.d/default.conf",
|
|
"subPath": "nginx.conf"
|
|
}
|
|
]
|
|
}
|
|
],
|
|
"volumes": [
|
|
{
|
|
"name": "nginx-config",
|
|
"configMap": {
|
|
"name": "fixed-nginx-conf"
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
'
|
|
|
|
# Restart frontend
|
|
kubectl rollout restart deployment frontend -n sk1
|
|
|
|
echo "⏱️ Waiting for deployments to be ready..."
|
|
kubectl rollout status deployment backend -n sk1
|
|
kubectl rollout status deployment frontend -n sk1
|
|
|
|
echo "✅ Deployment complete!"
|
|
echo "Testing backend API directly..."
|
|
kubectl run api-test --image=curlimages/curl -n sk1 --rm -it -- sh -c '
|
|
echo "Testing /api endpoint:"
|
|
curl -s http://backend-service:4000/api
|
|
echo ""
|
|
echo "Testing /api/services/assembly endpoint:"
|
|
curl -s http://backend-service:4000/api/services/assembly
|
|
echo ""
|
|
echo "Testing /api/auth/login endpoint:"
|
|
curl -s -X POST -H "Content-Type: application/json" -d '\''{"email":"test@example.com","password":"password"}'\'' http://backend-service:4000/api/auth/login
|
|
echo ""
|
|
'
|
|
|
|
echo "🎉 Your application should now be working properly at https://nudges.works"
|
|
echo "If you're still seeing issues, try clearing your browser cache or using a private/incognito window" |