Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions infrastructure/k8s/monitoring/monitoring.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,6 @@ data:
metrics_path: /metrics
scrape_interval: 10s

- job_name: 'mcp-server'
static_configs:
- targets: ['mcp-server:8000']
metrics_path: /metrics
scrape_interval: 10s

- job_name: 'kubernetes-pods'
kubernetes_sd_configs:
- role: pod
Expand Down
97 changes: 7 additions & 90 deletions infrastructure/k8s/production/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,110 +29,31 @@ spec:
image: enhanced-framework:latest
imagePullPolicy: Always
ports:
- containerPort: 3000
- containerPort: 8000
name: http
env:
- name: NODE_ENV
value: "production"
- name: PORT
value: "3000"
- name: MCP_SERVER_URL
value: "http://mcp-server:8000"
value: "8000"
- name: PYTHONUNBUFFERED
value: "1"
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The enhanced-framework production Deployment's /readyz readiness probe can never pass because the manifest provides no API-cost persistence configuration, so every probe returns HTTP 503 and kubectl rollout status (Step 7 of one-click-deploy.sh) times out.

Fix on Vercel

path: /ready
port: 3000
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3
securityContext:
allowPrivilegeEscalation: false
runAsNonRoot: true
runAsUser: 1001
capabilities:
drop:
- ALL
securityContext:
fsGroup: 1001
restartPolicy: Always
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mcp-server
namespace: production
labels:
app: mcp-server
version: v1.0.0
component: mcp-protocol
spec:
replicas: 2
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
app: mcp-server
template:
metadata:
labels:
app: mcp-server
version: v1.0.0
component: mcp-protocol
spec:
containers:
- name: mcp-server
image: python:3.11-slim
command: ["python3", "/app/mcp_server.py"]
ports:
- containerPort: 8000
name: mcp-http
env:
- name: MCP_HOST
value: "0.0.0.0"
- name: MCP_PORT
value: "8000"
- name: MCP_DEBUG
value: "false"
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
volumeMounts:
- name: app-code
mountPath: /app
livenessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 15
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
path: /readyz
port: 8000
Comment on lines 54 to 57
initialDelaySeconds: 5
periodSeconds: 5
Expand All @@ -145,10 +66,6 @@ spec:
capabilities:
drop:
- ALL
volumes:
- name: app-code
configMap:
name: mcp-server-code
securityContext:
fsGroup: 1001
restartPolicy: Always
restartPolicy: Always
24 changes: 3 additions & 21 deletions infrastructure/k8s/production/service.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,32 +10,14 @@ spec:
type: ClusterIP
ports:
- port: 80
targetPort: 3000
targetPort: 8000
protocol: TCP
name: http
selector:
app: enhanced-framework
---
apiVersion: v1
kind: Service
metadata:
name: mcp-server
namespace: production
labels:
app: mcp-server
component: mcp-protocol
spec:
type: ClusterIP
ports:
- port: 8000
targetPort: 8000
protocol: TCP
name: mcp-http
selector:
app: mcp-server
---
apiVersion: v1
kind: Service
metadata:
name: enhanced-framework-lb
namespace: production
Expand All @@ -46,11 +28,11 @@ spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 3000
targetPort: 8000
protocol: TCP
name: http
- port: 443
targetPort: 3000
targetPort: 8000
protocol: TCP
name: https
selector:
Expand Down
46 changes: 28 additions & 18 deletions scripts/deployment/one-click-deploy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ NAMESPACE="production"
DEPLOYMENT_NAME="enhanced-framework"
TIMEOUT=300

# Every path below is relative to the repository root, so anchor there rather
# than depending on the caller's working directory.
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
DOCKERFILE="infrastructure/docker/Dockerfile.production"
PRODUCTION_MANIFESTS="infrastructure/k8s/production"
MONITORING_MANIFESTS="infrastructure/k8s/monitoring"
cd "$REPO_ROOT"

# Logging function
log() {
echo -e "${BLUE}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1"
Expand Down Expand Up @@ -65,13 +73,11 @@ success "Kubernetes cluster is accessible"

# Check if required files exist
REQUIRED_FILES=(
"Dockerfile.production"
"$DOCKERFILE"
"package.json"
"k8s/production/deployment.yaml"
"k8s/production/service.yaml"
"k8s/monitoring/monitoring.yaml"
"mcp_server.py"
"learning_app_processor.py"
"$PRODUCTION_MANIFESTS/deployment.yaml"
"$PRODUCTION_MANIFESTS/service.yaml"
"$MONITORING_MANIFESTS/monitoring.yaml"
)

for file in "${REQUIRED_FILES[@]}"; do
Expand All @@ -85,14 +91,18 @@ success "All required files are present"
log "Step 2: Running Integration Tests"

if [[ -d "venv" ]]; then
# shellcheck disable=SC1091
source venv/bin/activate
if python3 tests/integration/test_runner.py; then
success "Integration tests passed"
else
error "Integration tests failed. Please fix issues before deployment."
fi
fi

if ! command -v python3 &> /dev/null; then
warning "python3 is not available. Skipping integration tests."
elif ! python3 -c "import pytest" &> /dev/null; then
warning "pytest is not installed. Skipping integration tests."
elif PYTHONPATH="src" python3 -m pytest tests/integration -q; then
success "Integration tests passed"
else
warning "Virtual environment not found. Skipping integration tests."
error "Integration tests failed. Please fix issues before deployment."
fi

# Step 3: Build Docker Image
Expand All @@ -101,7 +111,7 @@ log "Step 3: Building Docker Image"
DOCKER_TAG="enhanced-framework:$(date +%Y%m%d-%H%M%S)"
LATEST_TAG="enhanced-framework:latest"

if docker build -f Dockerfile.production -t "$DOCKER_TAG" -t "$LATEST_TAG" .; then
if docker build -f "$DOCKERFILE" -t "$DOCKER_TAG" -t "$LATEST_TAG" .; then
success "Docker image built successfully: $DOCKER_TAG"
else
error "Docker image build failed"
Expand All @@ -111,21 +121,21 @@ fi
log "Step 4: Validating Kubernetes Manifests"

# Validate deployment manifest
if kubectl apply --dry-run=client -f k8s/production/deployment.yaml; then
if kubectl apply --dry-run=client -f "$PRODUCTION_MANIFESTS/deployment.yaml"; then
success "Deployment manifest is valid"
else
error "Deployment manifest validation failed"
fi

# Validate service manifest
if kubectl apply --dry-run=client -f k8s/production/service.yaml; then
if kubectl apply --dry-run=client -f "$PRODUCTION_MANIFESTS/service.yaml"; then
success "Service manifest is valid"
else
error "Service manifest validation failed"
fi

# Validate monitoring manifest
if kubectl apply --dry-run=client -f k8s/monitoring/monitoring.yaml; then
if kubectl apply --dry-run=client -f "$MONITORING_MANIFESTS/monitoring.yaml"; then
success "Monitoring manifest is valid"
else
error "Monitoring manifest validation failed"
Expand All @@ -144,14 +154,14 @@ fi
log "Step 6: Deploying to Kubernetes"

# Deploy application
if kubectl apply -f k8s/production/ -n "$NAMESPACE"; then
if kubectl apply -f "$PRODUCTION_MANIFESTS/" -n "$NAMESPACE"; then
success "Application deployed successfully"
else
error "Application deployment failed"
fi

# Deploy monitoring
if kubectl apply -f k8s/monitoring/ -n "$NAMESPACE"; then
if kubectl apply -f "$MONITORING_MANIFESTS/" -n "$NAMESPACE"; then
success "Monitoring stack deployed successfully"
else
error "Monitoring deployment failed"
Expand Down
Loading
Loading