Skip to main content

Local and VM Deployment

This page explains how to run WSO2 Integrator projects either directly on your local machine during development using bal run, or as standalone JAR files on virtual machines for self-hosted production deployments.

Prerequisites
  • Ballerina installed on any machine where you want to run the project
  • A WSO2 Integrator project based on Ballerina
  • For production VM deployments: Java Runtime (JDK 21 or later)

Run locally during development

To run the project on your local machine during development:

  1. Open a terminal and navigate to the project directory.

    cd my-integration
  2. Start the project.

    bal run

The Ballerina CLI compiles the project and starts the integration runtime. You will see the program output in the terminal. Integrations with listeners keep running until you terminate it by CTRL + C

Run on a VM from source

To run the project on a remote virtual machine, install the Ballerina distribution on the VM and run the project directly from source using bal run.

Step 1: Push the project to a remote Git repository

From your local machine, push the project to a remote Git repository such as GitHub, GitLab, or Bitbucket.

git add .
git commit -m "Initial integration project"
git push origin main

Step 2: Clone the repository on the VM

SSH into the target VM and clone the repository.

git clone https://github.com/your-org/my-integration.git
cd my-integration

Step 3: Start the integration

Run the project using the Ballerina CLI.

bal run

The runtime starts and the integration begins serving traffic on the configured port.

note

Ballerina must be installed on the VM. Download it from ballerina.io. The version on the VM should match the version used during development.

Deploy with executable JAR

For production VM deployments, WSO2 Integrator projects compile to executable JAR files that run on any JVM. This approach gives you full control over the runtime environment and is ideal for traditional VM-based infrastructure.

Prerequisites for JAR deployment

RequirementDetails
Java RuntimeJDK 21 or later
Operating SystemLinux (recommended), macOS, or Windows
MemoryMinimum 512 MB, recommended 1 GB+ per instance
BallerinaDistribution installed on the build machine

Build the executable JAR

Use the bal build command to produce a standalone executable JAR.

bal build

This generates a fat JAR in the target/bin/ directory:

target/
bin/
my_integration.jar

Run it directly:

java -jar target/bin/my_integration.jar

Build options

FlagDescription
--cloud=dockerAlso generate Docker artifacts
--graalvmBuild a GraalVM native image
--observability-includedBundle observability dependencies
-DskipTestsSkip test execution during build

Transfer the JAR to your VM

scp target/bin/my_integration.jar user@production-vm:/opt/integrations/

Configure the runtime

Create a Config.toml in the same directory as the JAR (or set the BAL_CONFIG_FILES environment variable):

[myIntegration.http]
port = 9090

[myIntegration.db]
host = "db.internal.example.com"
port = 5432
username = "svc_user"
password = "encrypted:xxxxx"

Start the integration

java -jar my_integration.jar

For production deployments with JVM tuning:

java \
-Xms512m \
-Xmx1024m \
-XX:+UseG1GC \
-XX:MaxGCPauseMillis=200 \
-XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=/var/log/integrations/ \
-Dballerina.observability.enabled=true \
-jar my_integration.jar

Verify the deployment

curl http://localhost:9090/health

Consolidated package deployment

For organizations running multiple integrations, a consolidated deployment bundles several integration packages into a single runtime.

Creating a consolidated package

  1. Create a consolidation project:
bal new consolidated_deploy -t lib
  1. Add each integration as a dependency in Ballerina.toml:
[package]
org = "myorg"
name = "consolidated_deploy"
version = "1.0.0"

[[dependency]]
org = "myorg"
name = "order_service"
version = "1.2.0"

[[dependency]]
org = "myorg"
name = "inventory_sync"
version = "1.0.3"

[[dependency]]
org = "myorg"
name = "notification_handler"
version = "2.1.0"
  1. Build the consolidated JAR:
bal build

Running the consolidated package

java -jar target/bin/consolidated_deploy.jar

All services start within the same JVM process, sharing resources.

Consolidated Config.toml

Provide configuration for all included integrations in a single file:

# Order Service configuration
[order_service.http]
port = 9091

[order_service.db]
host = "db.internal.example.com"

# Inventory Sync configuration
[inventory_sync.schedule]
cronExpression = "0 */5 * * * ?"

[inventory_sync.endpoint]
url = "https://erp.example.com/api"

# Notification Handler configuration
[notification_handler.email]
smtpHost = "smtp.example.com"
smtpPort = 587

JVM tuning for production

Recommended JVM flags for production deployments:

java \
-Xms512m \
-Xmx1024m \
-XX:+UseG1GC \
-XX:MaxGCPauseMillis=200 \
-XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=/var/log/integrations/ \
-Dballerina.observability.enabled=true \
-jar my_integration.jar
JVM FlagPurpose
-Xms / -XmxInitial and maximum heap size
-XX:+UseG1GCUse the G1 garbage collector (recommended)
-XX:MaxGCPauseMillisTarget max GC pause time
-XX:+HeapDumpOnOutOfMemoryErrorGenerate heap dump on OOM

Log management

Configure logging in Config.toml:

[ballerina.log]
level = "INFO"

[[ballerina.log.destinations]]
path = "./logs/app.log"

Health checks and monitoring

Expose a health endpoint for load balancers and monitoring systems:

import ballerina/http;

service /health on new http:Listener(9091) {
resource function get .() returns http:Ok {
return http:OK;
}
}

What's next