From c807ceab51fc5c914715ebb6f42dad3a13ca4bd9 Mon Sep 17 00:00:00 2001 From: openhands Date: Tue, 25 Feb 2025 19:39:00 +0000 Subject: [PATCH] feat(k8s): Update Kubernetes configurations with proper port and CORS settings --- k8s/README.md | 74 ------------------------------------ k8s/backend-deployment.yaml | 16 +++++--- k8s/frontend-deployment.yaml | 26 +++++++------ k8s/ingress.yaml | 12 +++--- 4 files changed, 33 insertions(+), 95 deletions(-) delete mode 100644 k8s/README.md diff --git a/k8s/README.md b/k8s/README.md deleted file mode 100644 index 282927fce2fd..000000000000 --- a/k8s/README.md +++ /dev/null @@ -1,74 +0,0 @@ -# OpenHands Kubernetes Deployment - -This directory contains Kubernetes configurations for deploying OpenHands in a production environment. - -## Overview - -OpenHands uses a single Docker image `ghcr.io/all-hands-ai/openhands:main` that contains both the frontend and backend code. The image is built and published automatically via GitHub Actions when changes are merged to the main branch. - -## Deployment Configuration - -The deployment is configured to work with two runtime environments: - -1. **work-1** environment: - - Host: work-1-abdcoxuzwicybucg.prod-runtime.all-hands.dev - - Port: 12000 - -2. **work-2** environment: - - Host: work-2-abdcoxuzwicybucg.prod-runtime.all-hands.dev - - Port: 12001 - -## Components - -### Frontend Service -- React/Vite application serving the web UI -- Runs on ports 12000/12001 (work-1/work-2) -- Environment variables configured for backend communication -- CORS and iframe access enabled -- Resource limits: - - Memory: 512Mi (limit), 256Mi (request) - - CPU: 200m (limit), 100m (request) - -### Backend Service -- FastAPI server providing API endpoints -- Runs on ports 12000/12001 (work-1/work-2) -- Handles API requests at /api endpoint -- CORS enabled for frontend access -- Resource limits: - - Memory: 1Gi (limit), 512Mi (request) - - CPU: 500m (limit), 250m (request) - -### Ingress Configuration -- Routes /api/* to the backend service -- Routes /* to the frontend service -- Enables CORS headers -- Supports both work-1 and work-2 environments - -## Deployment Instructions - -1. Apply the Kubernetes configurations: -```bash -kubectl apply -f backend-deployment.yaml -kubectl apply -f frontend-deployment.yaml -kubectl apply -f ingress.yaml -``` - -2. Verify the deployment: -```bash -# Check pod status -kubectl get pods -l app=openhands - -# Check services -kubectl get services -l app=openhands - -# Check ingress rules -kubectl get ingress openhands-ingress - -# View pod logs -kubectl logs -l app=openhands -l component=frontend -kubectl logs -l app=openhands -l component=backend -``` - -3. Access the application: -- Frontend: https://work-1-abdcoxuzwicybucg.prod-runtime.all-hands.dev or https://work-2-abdcoxuzwicybucg.prod-runtime.all-hands.dev -- Backend API: https://work-1-abdcoxuzwicybucg.prod-runtime.all-hands.dev/api or https://work-2-abdcoxuzwicybucg.prod-runtime.all-hands.dev/api \ No newline at end of file diff --git a/k8s/backend-deployment.yaml b/k8s/backend-deployment.yaml index 373a60195fb9..e07506d660e7 100644 --- a/k8s/backend-deployment.yaml +++ b/k8s/backend-deployment.yaml @@ -6,7 +6,7 @@ metadata: app: openhands component: backend spec: - replicas: 1 + replicas: 2 # One for each work environment selector: matchLabels: app: openhands @@ -16,20 +16,26 @@ spec: labels: app: openhands component: backend + annotations: + openhands.dev/port: "12000" # Default to work-1 port spec: containers: - name: backend image: ghcr.io/all-hands-ai/openhands:main - command: ["poetry", "run", "uvicorn", "openhands.server.listen:app", "--host", "0.0.0.0", "--port", "12000"] + command: ["poetry", "run", "uvicorn", "openhands.server.listen:app", "--host", "0.0.0.0", "--port", "$(PORT)"] workingDir: /app ports: - containerPort: 12000 + name: work1-port - containerPort: 12001 + name: work2-port env: - name: HOST value: "0.0.0.0" - name: PORT - value: "12000" # Will be 12000 for work-1 and 12001 for work-2 + valueFrom: + fieldRef: + fieldPath: metadata.annotations['openhands.dev/port'] resources: requests: memory: "512Mi" @@ -49,11 +55,11 @@ spec: type: ClusterIP ports: - port: 12000 - targetPort: 12000 + targetPort: work1-port protocol: TCP name: http-work1 - port: 12001 - targetPort: 12001 + targetPort: work2-port protocol: TCP name: http-work2 selector: diff --git a/k8s/frontend-deployment.yaml b/k8s/frontend-deployment.yaml index f24b75bc6960..2517148d5e86 100644 --- a/k8s/frontend-deployment.yaml +++ b/k8s/frontend-deployment.yaml @@ -6,7 +6,7 @@ metadata: app: openhands component: frontend spec: - replicas: 1 + replicas: 2 # One for each work environment selector: matchLabels: app: openhands @@ -16,26 +16,30 @@ spec: labels: app: openhands component: frontend + annotations: + openhands.dev/port: "12000" # Default to work-1 port spec: containers: - name: frontend image: ghcr.io/all-hands-ai/openhands:main - command: ["npm", "run", "dev", "--", "--port", "12000", "--host", "0.0.0.0"] + command: ["npm", "run", "dev", "--", "--port", "$(PORT)", "--host", "0.0.0.0"] workingDir: /app/frontend ports: - containerPort: 12000 + name: work1-port - containerPort: 12001 + name: work2-port env: - - name: VITE_BACKEND_HOST + - name: PORT valueFrom: fieldRef: - fieldPath: metadata.namespace + fieldPath: metadata.annotations['openhands.dev/port'] + - name: VITE_BACKEND_HOST + value: "openhands-backend-service" - name: VITE_BACKEND_PORT - value: "12000" # Will be 12000 for work-1 and 12001 for work-2 - - name: VITE_FRONTEND_PORT - value: "12000" # Will be 12000 for work-1 and 12001 for work-2 - - name: HOST - value: "0.0.0.0" + valueFrom: + fieldRef: + fieldPath: metadata.annotations['openhands.dev/port'] resources: requests: memory: "256Mi" @@ -55,11 +59,11 @@ spec: type: ClusterIP ports: - port: 12000 - targetPort: 12000 + targetPort: work1-port protocol: TCP name: http-work1 - port: 12001 - targetPort: 12001 + targetPort: work2-port protocol: TCP name: http-work2 selector: diff --git a/k8s/ingress.yaml b/k8s/ingress.yaml index 0a55c71fce2f..1702c5c6c407 100644 --- a/k8s/ingress.yaml +++ b/k8s/ingress.yaml @@ -3,23 +3,25 @@ kind: Ingress metadata: name: openhands-ingress annotations: - nginx.ingress.kubernetes.io/rewrite-target: / + nginx.ingress.kubernetes.io/rewrite-target: /$1 nginx.ingress.kubernetes.io/cors-allow-origin: "*" nginx.ingress.kubernetes.io/cors-allow-methods: "GET, PUT, POST, DELETE, PATCH, OPTIONS" nginx.ingress.kubernetes.io/cors-allow-headers: "DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization" + nginx.ingress.kubernetes.io/enable-cors: "true" + nginx.ingress.kubernetes.io/use-regex: "true" spec: rules: - host: work-1-abdcoxuzwicybucg.prod-runtime.all-hands.dev http: paths: - - path: /api + - path: /api/(.*) pathType: Prefix backend: service: name: openhands-backend-service port: number: 12000 - - path: / + - path: /(.*) pathType: Prefix backend: service: @@ -29,14 +31,14 @@ spec: - host: work-2-abdcoxuzwicybucg.prod-runtime.all-hands.dev http: paths: - - path: /api + - path: /api/(.*) pathType: Prefix backend: service: name: openhands-backend-service port: number: 12001 - - path: / + - path: /(.*) pathType: Prefix backend: service: