AuthServiceApplication - Started AuthServiceApplication in 36.106 seconds
...
Error from server (BadRequest): previous terminated container "app-auth" in pod "app-auth-xxxxx-xxxxx" not found
Error: Process completed with exit code 1.
AuthServiceApplication - Started AuthServiceApplication in 36.106 seconds
...
Error from server (BadRequest): previous terminated container "app-auth" in pod "app-auth-xxxxx-xxxxx" not found
Error: Process completed with exit code 1.
AuthServiceApplication - Started AuthServiceApplication in 36.106 seconds
...
Error from server (BadRequest): previous terminated container "app-auth" in pod "app-auth-xxxxx-xxxxx" not found
Error: Process completed with exit code 1.
Readiness probe failed: Get "http://10.x.x.x:8080/actuator/health": connection refused
Readiness probe failed: Get "http://10.x.x.x:8080/actuator/health": connection refused
Readiness probe failed: Get "http://10.x.x.x:8080/actuator/health": connection refused
replicasets.apps is forbidden: exceeded quota
replicasets.apps is forbidden: exceeded quota
replicasets.apps is forbidden: exceeded quota
apiVersion: apps/v1
kind: Deployment
metadata: name: my-service
spec: revisionHistoryLimit: 1 # Only keep 1 old ReplicaSet replicas: 1 selector: matchLabels: app: my-service # ... rest of your spec
apiVersion: apps/v1
kind: Deployment
metadata: name: my-service
spec: revisionHistoryLimit: 1 # Only keep 1 old ReplicaSet replicas: 1 selector: matchLabels: app: my-service # ... rest of your spec
apiVersion: apps/v1
kind: Deployment
metadata: name: my-service
spec: revisionHistoryLimit: 1 # Only keep 1 old ReplicaSet replicas: 1 selector: matchLabels: app: my-service # ... rest of your spec
# Clean up old ReplicaSets to avoid quota issues on free-tier clusters
echo "Cleaning up old ReplicaSets..."
for dep in app-auth app-user app-core app-gateway; do # Get all ReplicaSets for this deployment, sorted oldest first # Delete all except the most recent one OLD_RS=$(oc get rs -l "app=$dep" \ --sort-by=.metadata.creationTimestamp \ -o name 2>/dev/null | head -n -1) if [ -n "$OLD_RS" ]; then echo "$OLD_RS" | xargs oc delete echo " Cleaned old ReplicaSets for $dep" fi
done
# Clean up old ReplicaSets to avoid quota issues on free-tier clusters
echo "Cleaning up old ReplicaSets..."
for dep in app-auth app-user app-core app-gateway; do # Get all ReplicaSets for this deployment, sorted oldest first # Delete all except the most recent one OLD_RS=$(oc get rs -l "app=$dep" \ --sort-by=.metadata.creationTimestamp \ -o name 2>/dev/null | head -n -1) if [ -n "$OLD_RS" ]; then echo "$OLD_RS" | xargs oc delete echo " Cleaned old ReplicaSets for $dep" fi
done
# Clean up old ReplicaSets to avoid quota issues on free-tier clusters
echo "Cleaning up old ReplicaSets..."
for dep in app-auth app-user app-core app-gateway; do # Get all ReplicaSets for this deployment, sorted oldest first # Delete all except the most recent one OLD_RS=$(oc get rs -l "app=$dep" \ --sort-by=.metadata.creationTimestamp \ -o name 2>/dev/null | head -n -1) if [ -n "$OLD_RS" ]; then echo "$OLD_RS" | xargs oc delete echo " Cleaned old ReplicaSets for $dep" fi
done
curl https://my-gateway-route.apps.openshiftapps.com/actuator/health
# → 200 OK ✅
curl https://my-gateway-route.apps.openshiftapps.com/actuator/health
# → 200 OK ✅
curl https://my-gateway-route.apps.openshiftapps.com/actuator/health
# → 200 OK ✅
curl https://my-gateway-route.apps.openshiftapps.com/api/auth/signup
# → 502 Bad Gateway ❌
curl https://my-gateway-route.apps.openshiftapps.com/api/auth/signup
# → 502 Bad Gateway ❌
curl https://my-gateway-route.apps.openshiftapps.com/api/auth/signup
# → 502 Bad Gateway ❌
spring: cloud: gateway: routes: - id: auth-service uri: http://localhost:7071 # Works on my laptop predicates: - Path=/api/auth/** - id: user-service uri: http://localhost:7072 # Works on my laptop predicates: - Path=/api/users/** - id: core-service uri: http://localhost:7073 # Works on my laptop predicates: - Path=/api/core/**
spring: cloud: gateway: routes: - id: auth-service uri: http://localhost:7071 # Works on my laptop predicates: - Path=/api/auth/** - id: user-service uri: http://localhost:7072 # Works on my laptop predicates: - Path=/api/users/** - id: core-service uri: http://localhost:7073 # Works on my laptop predicates: - Path=/api/core/**
spring: cloud: gateway: routes: - id: auth-service uri: http://localhost:7071 # Works on my laptop predicates: - Path=/api/auth/** - id: user-service uri: http://localhost:7072 # Works on my laptop predicates: - Path=/api/users/** - id: core-service uri: http://localhost:7073 # Works on my laptop predicates: - Path=/api/core/**
oc create secret generic app-secrets \ --from-literal=AUTH_SERVICE_URL="http://app-auth-svc:8080" \ --from-literal=USER_SERVICE_URL="http://app-user-svc:8080" \ --from-literal=CORE_SERVICE_URL="http://app-core-svc:8080"
oc create secret generic app-secrets \ --from-literal=AUTH_SERVICE_URL="http://app-auth-svc:8080" \ --from-literal=USER_SERVICE_URL="http://app-user-svc:8080" \ --from-literal=CORE_SERVICE_URL="http://app-core-svc:8080"
oc create secret generic app-secrets \ --from-literal=AUTH_SERVICE_URL="http://app-auth-svc:8080" \ --from-literal=USER_SERVICE_URL="http://app-user-svc:8080" \ --from-literal=CORE_SERVICE_URL="http://app-core-svc:8080"
# core-service application.yml — Correct
app: user-service: base-url: ${USER_SERVICE_URL:http://localhost:7072}
# core-service application.yml — Correct
app: user-service: base-url: ${USER_SERVICE_URL:http://localhost:7072}
# core-service application.yml — Correct
app: user-service: base-url: ${USER_SERVICE_URL:http://localhost:7072}
spring: cloud: gateway: routes: - id: auth-service uri: ${AUTH_SERVICE_URL:http://localhost:7071} predicates: - Path=/api/auth/** - id: user-service uri: ${USER_SERVICE_URL:http://localhost:7072} predicates: - Path=/api/users/** - id: core-service uri: ${CORE_SERVICE_URL:http://localhost:7073} predicates: - Path=/api/core/**
spring: cloud: gateway: routes: - id: auth-service uri: ${AUTH_SERVICE_URL:http://localhost:7071} predicates: - Path=/api/auth/** - id: user-service uri: ${USER_SERVICE_URL:http://localhost:7072} predicates: - Path=/api/users/** - id: core-service uri: ${CORE_SERVICE_URL:http://localhost:7073} predicates: - Path=/api/core/**
spring: cloud: gateway: routes: - id: auth-service uri: ${AUTH_SERVICE_URL:http://localhost:7071} predicates: - Path=/api/auth/** - id: user-service uri: ${USER_SERVICE_URL:http://localhost:7072} predicates: - Path=/api/users/** - id: core-service uri: ${CORE_SERVICE_URL:http://localhost:7073} predicates: - Path=/api/core/** - Flutter mobile frontend (automated APK releases)
- API Gateway (Spring Cloud Gateway) — single entry point for all client requests
- Auth Service — handles registration, login, OTP verification, JWT tokens
- User Service — user profiles, preferences, settings
- Core Service — main business logic, AI features, data processing
- MongoDB Atlas — separate databases per service
- GitHub Container Registry (GHCR) — Docker image hosting
- OpenShift Developer Sandbox — free-tier Kubernetes hosting - Builds all 4 services with Maven
- Creates Docker images and pushes to GHCR
- Logs into OpenShift via CLI (oc login)
- Creates/updates Kubernetes secrets (MongoDB URIs, JWT secret, API keys)
- Applies all deployment manifests
- Runs oc rollout restart on each deployment
- Waits for health checks to pass - 4 services × 10 ReplicaSets = 40 ReplicaSets - Kubernetes cannot create new ReplicaSets for the rollout
- No new ReplicaSet = no new pods get scheduled
- No pods = readiness probe has nothing to connect to → connection refused
- Rollout waits... and eventually times out → context deadline exceeded
- Pipeline fails with exit code 1 - 4 services × (1 current + 1 old) = 8 ReplicaSets — well within any quota. - On Kubernetes: uses the injected secret value → http://app-auth-svc:8080
- On localhost: falls back to the default → http://localhost:7071