From 24280897ed997d8cad51c0f7af0b078300c7ba90 Mon Sep 17 00:00:00 2001 From: dilhasha Date: Mon, 8 Jun 2026 17:27:31 +0530 Subject: [PATCH 1/4] Improve GraalVM native images guide --- .../deploy/graalvm-native-images.md | 51 +++++++++++++++++-- 1 file changed, 48 insertions(+), 3 deletions(-) diff --git a/en/docs/deploy-operate/deploy/graalvm-native-images.md b/en/docs/deploy-operate/deploy/graalvm-native-images.md index e59979c05c..268f4cbc4f 100644 --- a/en/docs/deploy-operate/deploy/graalvm-native-images.md +++ b/en/docs/deploy-operate/deploy/graalvm-native-images.md @@ -8,7 +8,7 @@ description: Compile Ballerina integrations to GraalVM native binaries for insta GraalVM native image compilation transforms your Ballerina integration into a platform-specific binary that starts in milliseconds and uses significantly less memory than JVM-based deployments. This is ideal for serverless, CLI tools, and resource-constrained environments. -## Benefits +## JVM vs Native Image | Metric | JVM (JAR) | GraalVM Native | |--------|-----------|----------------| @@ -22,22 +22,55 @@ GraalVM native image compilation transforms your Ballerina integration into a pl | Requirement | Details | |-------------|---------| -| GraalVM JDK | GraalVM for JDK 17 or later (Community or Enterprise) | +| GraalVM JDK | GraalVM for JDK 21 (Community or Enterprise Edition) | | Native Image | `gu install native-image` (included in newer distributions) | | OS Tools | `gcc`, `zlib` headers (Linux), Xcode Command Line Tools (macOS) | | Memory | 8 GB+ RAM recommended for compilation | +| Docker | 8 GB+ memory allocated to Docker (for container builds) | ### Install GraalVM ```bash # Using SDKMAN (recommended) -sdk install java 17.0.9-graal +sdk install java 21.0.2-graalce # Verify installation java -version native-image --version ``` +Set the `GRAALVM_HOME` environment variable: + +**Linux/macOS:** +```bash +export GRAALVM_HOME=$HOME/.sdkman/candidates/java/current +``` + +**Windows:** +```cmd +set GRAALVM_HOME=C:\path\to\graalvm +``` + +If using SDKMAN, you can alternatively use `JAVA_HOME` instead of `GRAALVM_HOME`. + +### Platform-specific requirements + +**Windows:** +- Install Visual Studio with Microsoft Visual C++ (MSVC) +- Initialize the **x64 Native Tools Command Prompt** before running `bal build --graalvm` + +For more details, see [Prerequisites for Native Image on Windows](https://www.graalvm.org/latest/getting-started/windows/#prerequisites-for-native-image-on-windows). + +**macOS (Apple Silicon):** +- GraalVM native-image support for Apple M1/M2 (darwin-aarch64) is experimental +- Most features work, but some edge cases may have compatibility issues + +For more details, see [GraalVM on macOS](https://www.graalvm.org/latest/getting-started/macos/). + +**Linux:** + +For distribution-specific requirements, see [GraalVM on Linux](https://www.graalvm.org/latest/getting-started/linux/). + ## Building a native image ### Basic build @@ -60,6 +93,18 @@ target/ ./target/bin/my_integration ``` +### Test native compatibility + +Test your integration with GraalVM to verify runtime compatibility of dependencies: + +```bash +bal test --graalvm +``` + +:::note +Code coverage and runtime debugging features are not supported with GraalVM native image testing. +::: + ### Build with Docker isolation Build inside a Docker container for consistent, reproducible builds: From 6666c20cdff5db6f73ab75e290b84856868973de Mon Sep 17 00:00:00 2001 From: dilhasha Date: Tue, 9 Jun 2026 09:35:47 +0530 Subject: [PATCH 2/4] Remove deployment-specific content from GraalVM guide --- .../deploy/graalvm-native-images.md | 58 ------------------- 1 file changed, 58 deletions(-) diff --git a/en/docs/deploy-operate/deploy/graalvm-native-images.md b/en/docs/deploy-operate/deploy/graalvm-native-images.md index 268f4cbc4f..5c531e01a8 100644 --- a/en/docs/deploy-operate/deploy/graalvm-native-images.md +++ b/en/docs/deploy-operate/deploy/graalvm-native-images.md @@ -160,64 +160,6 @@ Set additional options in `Ballerina.toml`: graalvmBuildOptions = "--no-fallback --initialize-at-build-time -march=native" ``` -## Deploying native images - -### Standalone binary on VM - -Copy the binary directly -- no JVM installation needed: - -```bash -scp target/bin/my_integration user@production-vm:/opt/integrations/ -ssh user@production-vm "chmod +x /opt/integrations/my_integration" -``` - -Create a systemd service: - -```ini -[Unit] -Description=WSO2 Integration (Native) -After=network.target - -[Service] -Type=simple -User=ballerina -ExecStart=/opt/integrations/my_integration -Restart=on-failure -RestartSec=5 -Environment=BAL_CONFIG_FILES=/opt/integrations/Config.toml - -[Install] -WantedBy=multi-user.target -``` - -### Minimal Docker image - -Use a `distroless` or `scratch` base image for the smallest possible container: - -```dockerfile -FROM gcr.io/distroless/base-debian12 -COPY target/bin/my_integration /app/my_integration -COPY Config.toml /app/Config.toml -WORKDIR /app -EXPOSE 9090 -ENTRYPOINT ["./my_integration"] -``` - -Build and run: - -```bash -docker build -t my-integration:native . -docker run -p 9090:9090 my-integration:native -``` - -### AWS lambda with native image - -```bash -bal build --graalvm --cloud=aws_lambda -``` - -Deploy the generated ZIP -- cold start drops from seconds to under 100ms. - ## Troubleshooting | Issue | Solution | From 1b0894af21a09dc2d4fde352ce2757df4682640e Mon Sep 17 00:00:00 2001 From: dilhasha Date: Tue, 9 Jun 2026 10:02:01 +0530 Subject: [PATCH 3/4] Remove specific Kubernetes YAML content from scaling and high availability guide --- .../deploy/scaling-high-availability.md | 242 ++---------------- 1 file changed, 20 insertions(+), 222 deletions(-) diff --git a/en/docs/deploy-operate/deploy/scaling-high-availability.md b/en/docs/deploy-operate/deploy/scaling-high-availability.md index 1ede14ce60..53cc37e28f 100644 --- a/en/docs/deploy-operate/deploy/scaling-high-availability.md +++ b/en/docs/deploy-operate/deploy/scaling-high-availability.md @@ -36,88 +36,7 @@ service /orders on new http:Listener(9090) { ## Horizontal scaling configuration -### Kubernetes replica scaling - -Set the number of replicas in your Kubernetes deployment: - -```yaml -# k8s/deployment.yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: wso2-integrator-app - namespace: production -spec: - replicas: 3 - selector: - matchLabels: - app: wso2-integrator-app - template: - metadata: - labels: - app: wso2-integrator-app - spec: - containers: - - name: app - image: registry.example.com/wso2-integrator-app:latest - ports: - - containerPort: 9090 - resources: - requests: - cpu: "250m" - memory: "256Mi" - limits: - cpu: "500m" - memory: "512Mi" -``` - -### Horizontal pod autoscaler (HPA) - -Automatically scale based on CPU or memory utilization: - -```yaml -# k8s/hpa.yaml -apiVersion: autoscaling/v2 -kind: HorizontalPodAutoscaler -metadata: - name: wso2-integrator-app-hpa - namespace: production -spec: - scaleTargetRef: - apiVersion: apps/v1 - kind: Deployment - name: wso2-integrator-app - minReplicas: 2 - maxReplicas: 10 - metrics: - - type: Resource - resource: - name: cpu - target: - type: Utilization - averageUtilization: 70 - - type: Resource - resource: - name: memory - target: - type: Utilization - averageUtilization: 80 - behavior: - scaleDown: - stabilizationWindowSeconds: 300 - policies: - - type: Pods - value: 1 - periodSeconds: 60 - scaleUp: - stabilizationWindowSeconds: 30 - policies: - - type: Pods - value: 2 - periodSeconds: 60 -``` - -### Cloud.toml Auto-Scaling +### Cloud.toml auto-scaling Configure auto-scaling directly in your project's `Cloud.toml`: @@ -130,81 +49,19 @@ cpu_threshold = 70 memory_threshold = 80 ``` -## Load balancing considerations - -### Kubernetes service - -Expose your deployment through a Kubernetes Service for internal load balancing: - -```yaml -# k8s/service.yaml -apiVersion: v1 -kind: Service -metadata: - name: wso2-integrator-service - namespace: production -spec: - type: ClusterIP - selector: - app: wso2-integrator-app - ports: - - port: 80 - targetPort: 9090 - protocol: TCP -``` - -### Ingress configuration - -For external traffic, configure an Ingress resource: - -```yaml -# k8s/ingress.yaml -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: wso2-integrator-ingress - namespace: production - annotations: - nginx.ingress.kubernetes.io/ssl-redirect: "true" - nginx.ingress.kubernetes.io/proxy-body-size: "10m" - nginx.ingress.kubernetes.io/proxy-read-timeout: "60" -spec: - tls: - - hosts: - - api.example.com - secretName: tls-secret - rules: - - host: api.example.com - http: - paths: - - path: / - pathType: Prefix - backend: - service: - name: wso2-integrator-service - port: - number: 80 -``` +When deploying to Kubernetes, the `bal build --cloud=k8s` command uses these settings to generate HorizontalPodAutoscaler resources automatically. For manual scaling configuration, refer to the [Kubernetes HorizontalPodAutoscaler documentation](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/). -### Session affinity +## Load balancing -If your integration requires sticky sessions (not recommended for stateless services), configure session affinity on the Service: +When multiple instances of your integration run behind a load balancer, ensure your services are stateless and idempotent. Ballerina HTTP services work seamlessly with standard load balancers (Kubernetes Service, NGINX, HAProxy, cloud load balancers). -```yaml -spec: - sessionAffinity: ClientIP - sessionAffinityConfig: - clientIP: - timeoutSeconds: 600 -``` +For Kubernetes deployments, use a Service resource for internal load balancing and an Ingress for external traffic. Refer to the [Kubernetes Service documentation](https://kubernetes.io/docs/concepts/services-networking/service/) and [Ingress documentation](https://kubernetes.io/docs/concepts/services-networking/ingress/) for configuration details. ## Health checks -Configure health probes so Kubernetes can detect unhealthy instances and route traffic away from them. +Expose health check endpoints in your Ballerina services to enable load balancers and orchestrators to monitor instance health. -### Ballerina health endpoint - -Ballerina HTTP services support health check endpoints. Add a health resource to your service: +### Health endpoints ```ballerina import ballerina/http; @@ -227,88 +84,29 @@ service /orders on new http:Listener(9090) { } ``` -### Kubernetes probe configuration - -```yaml -spec: - containers: - - name: app - livenessProbe: - httpGet: - path: /orders/healthz - port: 9090 - initialDelaySeconds: 15 - periodSeconds: 10 - failureThreshold: 3 - readinessProbe: - httpGet: - path: /orders/readyz - port: 9090 - initialDelaySeconds: 10 - periodSeconds: 5 - failureThreshold: 3 - startupProbe: - httpGet: - path: /orders/healthz - port: 9090 - initialDelaySeconds: 5 - periodSeconds: 5 - failureThreshold: 30 -``` +Configure your orchestrator to call these endpoints for health monitoring. For Kubernetes, use liveness, readiness, and startup probes. Refer to the [Kubernetes Probes documentation](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) for configuration details. -## Failover and resilience +## High availability strategies -### Multi-Zone deployment +### Multi-zone deployment -Distribute pods across availability zones using topology spread constraints: +Deploy integration instances across multiple availability zones or data centers to survive zone failures. In Kubernetes, use topology spread constraints to distribute pods across zones. In cloud environments, use availability zone configuration in your load balancer or auto-scaling groups. -```yaml -spec: - topologySpreadConstraints: - - maxSkew: 1 - topologyKey: topology.kubernetes.io/zone - whenUnsatisfiable: DoNotSchedule - labelSelector: - matchLabels: - app: wso2-integrator-app -``` +### Minimum instance count -### Pod disruption budget - -Ensure a minimum number of pods remain available during voluntary disruptions (node upgrades, scaling events): - -```yaml -# k8s/pdb.yaml -apiVersion: policy/v1 -kind: PodDisruptionBudget -metadata: - name: wso2-integrator-pdb - namespace: production -spec: - minAvailable: 2 - selector: - matchLabels: - app: wso2-integrator-app -``` +Maintain at least 2 replicas in production to ensure availability during deployments and instance failures. For critical integrations, consider running 3+ replicas across multiple zones. -## Graceful shutdown +When using Kubernetes, configure PodDisruptionBudgets to prevent voluntary disruptions from taking down too many instances simultaneously during maintenance operations. Refer to the [Kubernetes PodDisruptionBudget documentation](https://kubernetes.io/docs/tasks/run-application/configure-pdb/) for details. -Ballerina services handle graceful shutdown automatically. When a `SIGTERM` signal is received, the runtime stops accepting new requests and waits for in-flight requests to complete before shutting down. +## Graceful shutdown -Configure the Kubernetes termination grace period to allow enough time for in-flight requests: +Ballerina services handle graceful shutdown automatically. When a `SIGTERM` signal is received, the runtime: -```yaml -spec: - terminationGracePeriodSeconds: 60 - containers: - - name: app - lifecycle: - preStop: - exec: - command: ["sleep", "5"] # Allow load balancer to deregister -``` +1. Stops accepting new requests +2. Waits for in-flight requests to complete +3. Shuts down cleanly -The `preStop` sleep ensures the pod is removed from the Service endpoints before the application begins shutting down, preventing requests from being routed to a terminating pod. +Ensure your orchestrator allows sufficient time for graceful shutdown. In Kubernetes, set `terminationGracePeriodSeconds` to at least 60 seconds and use a `preStop` hook with a short delay to allow load balancers to deregister the instance before shutdown begins. Refer to the [Kubernetes Pod Lifecycle documentation](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-termination) for configuration details. ## What's next From c2833e7702498e73c8c527659acf0f73d93753fc Mon Sep 17 00:00:00 2001 From: dilhasha Date: Tue, 9 Jun 2026 10:49:25 +0530 Subject: [PATCH 4/4] Address PR suggestions --- en/docs/deploy-operate/deploy/graalvm-native-images.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/en/docs/deploy-operate/deploy/graalvm-native-images.md b/en/docs/deploy-operate/deploy/graalvm-native-images.md index 5c531e01a8..ebff7fe68c 100644 --- a/en/docs/deploy-operate/deploy/graalvm-native-images.md +++ b/en/docs/deploy-operate/deploy/graalvm-native-images.md @@ -8,7 +8,7 @@ description: Compile Ballerina integrations to GraalVM native binaries for insta GraalVM native image compilation transforms your Ballerina integration into a platform-specific binary that starts in milliseconds and uses significantly less memory than JVM-based deployments. This is ideal for serverless, CLI tools, and resource-constrained environments. -## JVM vs Native Image +## JVM vs native image | Metric | JVM (JAR) | GraalVM Native | |--------|-----------|----------------|