Deploying GoRules
Introduction
GoRules is a powerful open-source business rules engine designed to help you manage complex decision logic through visual decision tables, rule flows, and expressions. Built with performance and developer experience in mind, GoRules enables you to externalize business logic from your application code, making it easier to maintain, test, and update business rules without redeploying your entire application.
This comprehensive guide walks you through deploying GoRules on Klutch.sh using a Dockerfile. You’ll learn how to set up the application, configure environment variables, manage persistent storage for rules and configurations, and follow production best practices for running a reliable business rules engine in the cloud.
Prerequisites
- A Klutch.sh account
- A GitHub repository for your GoRules project
- Basic familiarity with Docker and business rules engines
- (Optional) PostgreSQL database for persistent rule storage in production
Quick Overview
- Inputs: GitHub repository with GoRules application and Dockerfile
- Outputs: Running GoRules instance accessible over HTTPS with persistent storage
- Success criteria: Web UI loads, you can create and execute decision tables, rules persist across restarts
Edge cases to consider:
- Large rule sets consuming memory — monitor resource usage and scale compute accordingly
- Rule versioning and rollback — implement version control for your rules directory
- Concurrent rule execution — ensure proper resource allocation for your workload
- Secrets and credentials — store all sensitive data in environment variables, not in the repository
Getting Started: Setting Up GoRules Locally
Before deploying to Klutch.sh, let’s set up GoRules locally to understand its structure and create the necessary configuration files.
1. Create Your Project Directory
-
Create a new directory for your GoRules application:
Terminal window mkdir my-gorules-appcd my-gorules-app -
Initialize a Git repository:
Terminal window git init -
Create a basic directory structure:
Terminal window mkdir -p rulesmkdir -p config
2. Create Sample Rule Files
-
Create a sample decision table in
rules/pricing-rules.json:{"name": "Pricing Decision Table","type": "decision-table","hitPolicy": "first","inputs": [{"id": "customer_type","name": "Customer Type","type": "string"},{"id": "order_amount","name": "Order Amount","type": "number"}],"outputs": [{"id": "discount","name": "Discount Percentage","type": "number"}],"rules": [{"id": "rule1","description": "Premium customers get 20% discount","input": ["premium", ">=100"],"output": [20]},{"id": "rule2","description": "Standard customers get 10% discount on large orders","input": ["standard", ">=500"],"output": [10]},{"id": "rule3","description": "No discount for small orders","input": ["*", "*"],"output": [0]}]} -
Create a test input file
test-input.json:{"customer_type": "premium","order_amount": 150}
3. Create Environment Configuration
-
Create a
.env.examplefile for reference (never commit actual.envwith secrets):# Server ConfigurationPORT=8080HOST=0.0.0.0# Rules ConfigurationRULES_DIR=/app/rulesRULES_CACHE_ENABLED=true# Database (optional - for persistent storage)# DATABASE_URL=postgresql://user:password@host:5432/gorules# API ConfigurationAPI_KEY=your-secret-api-key-here# LoggingLOG_LEVEL=infoLOG_FORMAT=json# CORS ConfigurationCORS_ENABLED=trueCORS_ORIGINS=*
Creating the Dockerfile
GoRules requires a properly configured Docker container. Here’s a production-ready Dockerfile that sets up GoRules with all necessary dependencies:
-
Create a
Dockerfilein your project root:# Use Node.js LTS as the base image for GoRulesFROM node:18-alpine AS base# Install system dependenciesRUN apk add --no-cache \python3 \make \g++ \curl \gitWORKDIR /app# Copy package filesCOPY package*.json ./# Install production dependenciesRUN npm ci --only=production && \npm cache clean --force# Copy application codeCOPY . .# Create rules directory with proper permissionsRUN mkdir -p /app/rules && \chown -R node:node /app# Switch to non-root userUSER node# Expose the application portEXPOSE 8080# Health checkHEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \CMD curl -f http://localhost:8080/health || exit 1# Start the applicationCMD ["node", "server.js"] -
For GoRules Business Rules Engine (Go-based implementation), use this alternative Dockerfile:
# Build stageFROM golang:1.21-alpine AS builder# Install build dependenciesRUN apk add --no-cache git makeWORKDIR /build# Copy go mod filesCOPY go.mod go.sum ./RUN go mod download# Copy source codeCOPY . .# Build the applicationRUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o gorules-server .# Runtime stageFROM alpine:latest# Install runtime dependenciesRUN apk --no-cache add ca-certificates curlWORKDIR /app# Copy binary from builderCOPY --from=builder /build/gorules-server .# Copy rules directoryCOPY --from=builder /build/rules ./rules# Create non-root userRUN addgroup -g 1000 gorules && \adduser -D -u 1000 -G gorules gorules && \chown -R gorules:gorules /appUSER gorules# Expose the application portEXPOSE 8080# Health checkHEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \CMD curl -f http://localhost:8080/health || exit 1# Start the applicationCMD ["./gorules-server"] -
Create a
.dockerignorefile to exclude unnecessary files:node_modulesnpm-debug.log.git.gitignore.env.env.local.DS_Store*.mddocker-compose.yml.vscode.ideacoveragedisttest
Deploying GoRules on Klutch.sh
Now that we have our Dockerfile ready, let’s deploy GoRules to Klutch.sh. Klutch.sh will automatically detect the Dockerfile in your repository’s root directory and use it to build your application.
Step-by-Step Deployment Process
-
Push your code to GitHub:
Terminal window git add .git commit -m "Add GoRules application with Dockerfile"git branch -M maingit remote add origin https://github.com/yourusername/gorules-app.gitgit push -u origin main -
Log in to Klutch.sh:
Navigate to klutch.sh/app and sign in with your GitHub account.
-
Create a new project:
- Go to Create Project
- Give your project a meaningful name (e.g., “gorules-production”)
- Click “Create Project”
-
Create a new app:
- Go to Create App
- Configure the following settings:
- Repository: Select your GoRules GitHub repository
- Branch: Choose the branch to deploy (e.g.,
main) - Traffic Type: Select HTTP (GoRules serves web traffic)
- Internal Port: Set to
8080(the port GoRules listens on inside the container) - Region: Choose your preferred region
- Compute: Select appropriate resources based on your rule complexity and traffic
- Small rules engine: 0.5 CPU, 512 MB RAM
- Medium workload: 1 CPU, 1 GB RAM
- High traffic: 2+ CPU, 2+ GB RAM
- Instances: Start with 1, scale up based on load
-
Configure environment variables:
Add the following environment variables in the Klutch.sh dashboard:
PORT=8080HOST=0.0.0.0RULES_DIR=/app/rulesAPI_KEY=your-secure-api-key-hereLOG_LEVEL=infoCORS_ENABLED=trueCORS_ORIGINS=https://example-app.klutch.sh -
Click “Create” to deploy:
Klutch.sh will:
- Clone your repository
- Detect the Dockerfile automatically
- Build your Docker image
- Deploy the container
- Make your app available at a URL like
example-app.klutch.sh
Persistent Storage Configuration
GoRules needs persistent storage to save rule definitions, configurations, and execution history across container restarts. Here’s how to set up volumes on Klutch.sh:
Recommended Volume Mounts
-
Access your app settings in the Klutch.sh dashboard
-
Navigate to the Volumes section
-
Add persistent volumes with the following configurations:
For Rules Storage:
- Mount Path:
/app/rules - Size: 1 GB (adjust based on rule set size)
- Purpose: Stores rule definitions and decision tables
For Logs and Cache (optional):
- Mount Path:
/app/logs - Size: 2 GB
- Purpose: Stores application logs and execution history
For Database Files (if using SQLite):
- Mount Path:
/app/data - Size: 5 GB
- Purpose: Stores SQLite database file
- Mount Path:
-
Save the volume configuration and restart your app
Important Volume Considerations
- Ensure proper file permissions within your container
- Back up volumes regularly for disaster recovery
- Monitor volume usage to prevent running out of space
- Use separate volumes for different types of data for better organization
Environment Variables Configuration
GoRules can be extensively configured through environment variables. Here are the recommended settings for different scenarios:
Basic Configuration (Development/Testing)
# ServerPORT=8080HOST=0.0.0.0
# RulesRULES_DIR=/app/rulesRULES_RELOAD_ENABLED=true
# APIAPI_KEY=dev-api-key-12345
# LoggingLOG_LEVEL=debugProduction Configuration
# ServerPORT=8080HOST=0.0.0.0
# RulesRULES_DIR=/app/rulesRULES_CACHE_ENABLED=trueRULES_CACHE_TTL=3600RULES_RELOAD_ENABLED=false
# Database (PostgreSQL for production)DATABASE_URL=postgresql://gorules:YOUR_SECURE_PASSWORD@postgres-host:5432/gorules_prod?sslmode=require
# API SecurityAPI_KEY=prod-secure-api-key-xyz789API_RATE_LIMIT=1000API_RATE_LIMIT_WINDOW=60
# LoggingLOG_LEVEL=infoLOG_FORMAT=json
# CORSCORS_ENABLED=trueCORS_ORIGINS=https://your-domain.com,https://app.your-domain.com
# PerformanceMAX_CONCURRENT_EXECUTIONS=100EXECUTION_TIMEOUT=30000
# MonitoringMETRICS_ENABLED=trueMETRICS_PORT=9090High Availability Configuration
# All production settings above, plus:
# ClusteringCLUSTER_ENABLED=trueCLUSTER_NODES=3
# CacheREDIS_URL=redis://redis-host:6379CACHE_STRATEGY=distributed
# Health ChecksHEALTH_CHECK_INTERVAL=10READINESS_TIMEOUT=5Verifying Your Deployment
After deployment, verify that GoRules is running correctly:
1. Check Application Health
-
Navigate to your app URL (e.g.,
https://example-app.klutch.sh) -
You should see the GoRules dashboard or API documentation
-
Test the health endpoint:
Terminal window curl https://example-app.klutch.sh/healthExpected response:
{"status": "healthy","version": "1.0.0","uptime": 3600}
2. Test Rule Execution
-
Create a simple test rule through the API:
Terminal window curl -X POST https://example-app.klutch.sh/api/rules/execute \-H "Content-Type: application/json" \-H "X-API-Key: your-api-key" \-d '{"rule": "pricing-rules","input": {"customer_type": "premium","order_amount": 150}}' -
Expected response:
{"output": {"discount": 20},"executionTime": 5,"ruleId": "rule1"}
3. Verify Persistent Storage
-
Create a new rule through the UI or API
-
Restart your app in the Klutch.sh dashboard
-
Verify the rule still exists after restart
Working with Rules
Creating a Decision Table
-
Access the GoRules web interface at your app URL
-
Click “New Rule” and select “Decision Table”
-
Define your inputs and outputs:
Inputs:- age (number)- income (number)- credit_score (number)Outputs:- loan_approved (boolean)- interest_rate (number) -
Add your business rules:
Age Income Credit Score Loan Approved Interest Rate >=18 >=50000 >=700 true 3.5 >=18 >=30000 >=650 true 5.5 >=18 * <650 false 0 <18 * * false 0 -
Save and test your decision table
Using the API
-
Execute a rule via REST API:
Terminal window curl -X POST https://example-app.klutch.sh/api/v1/execute \-H "Content-Type: application/json" \-H "X-API-Key: your-api-key" \-d '{"ruleId": "loan-approval","context": {"age": 25,"income": 60000,"credit_score": 720}}' -
Batch execution for multiple inputs:
Terminal window curl -X POST https://example-app.klutch.sh/api/v1/batch-execute \-H "Content-Type: application/json" \-H "X-API-Key: your-api-key" \-d '{"ruleId": "loan-approval","contexts": [{"age": 25, "income": 60000, "credit_score": 720},{"age": 30, "income": 45000, "credit_score": 680},{"age": 22, "income": 35000, "credit_score": 640}]}'
Production Best Practices
Security
-
Use strong API keys: Generate cryptographically secure API keys
Terminal window openssl rand -hex 32 -
Enable HTTPS only: Klutch.sh provides HTTPS by default
-
Implement authentication: Use OAuth2 or JWT tokens for production
-
Rate limiting: Configure rate limits to prevent abuse
API_RATE_LIMIT=1000API_RATE_LIMIT_WINDOW=60 -
Input validation: Always validate rule inputs before execution
Performance Optimization
-
Enable caching: Cache frequently used rules
RULES_CACHE_ENABLED=trueRULES_CACHE_TTL=3600 -
Use a database: For production, use PostgreSQL instead of file-based storage
DATABASE_URL=postgresql://user:password@host:5432/gorules -
Monitor resource usage:
- Track CPU and memory usage in Klutch.sh dashboard
- Scale vertically (more resources) or horizontally (more instances) as needed
-
Optimize rules: Keep decision tables simple and well-organized
-
Connection pooling: Configure database connection pooling
DB_POOL_MIN=2DB_POOL_MAX=10
Monitoring and Logging
-
Enable structured logging:
LOG_LEVEL=infoLOG_FORMAT=json -
Set up health checks: Use the
/healthendpoint -
Track metrics: Enable Prometheus metrics if available
METRICS_ENABLED=trueMETRICS_PORT=9090 -
Monitor execution times: Track rule execution performance
-
Set up alerts: Configure alerts for:
- High error rates
- Slow rule execution
- Memory/CPU spikes
- Failed health checks
Backup and Disaster Recovery
-
Regular backups:
- Back up your rules directory daily
- Back up your database if using PostgreSQL
- Store backups in a secure, separate location
-
Version control: Keep rules in Git for version history
-
Testing: Test disaster recovery procedures regularly
-
Documentation: Document your rule logic and dependencies
Scaling GoRules
Vertical Scaling (Single Instance)
-
In Klutch.sh dashboard, go to your app settings
-
Increase compute resources:
- CPU: 2-4 cores for high-traffic applications
- RAM: 2-4 GB for large rule sets
-
Restart the app to apply changes
Horizontal Scaling (Multiple Instances)
-
Increase the number of instances in Klutch.sh:
- Start with 2-3 instances
- Add more based on load
-
Use a distributed cache (Redis) for rule caching:
REDIS_URL=redis://redis-host:6379CACHE_STRATEGY=distributed -
Use PostgreSQL for shared state across instances
-
Ensure your rules are stateless for best scalability
Troubleshooting
Common Issues and Solutions
Issue: Application fails to start
- Solution: Check environment variables are correctly set
- Verify the PORT variable matches the internal port in Klutch.sh
- Review application logs in Klutch.sh dashboard
Issue: Rules not persisting after restart
- Solution: Ensure persistent volume is correctly mounted
- Verify volume mount path matches RULES_DIR environment variable
- Check file permissions in the container
Issue: Slow rule execution
- Solution: Enable caching with RULES_CACHE_ENABLED=true
- Optimize decision tables (reduce complexity)
- Increase compute resources
- Consider using a database instead of file-based storage
Issue: Out of memory errors
- Solution: Increase RAM allocation in Klutch.sh
- Optimize rules to use less memory
- Enable rule caching with TTL
- Clear execution history periodically
Issue: API authentication failures
- Solution: Verify API_KEY matches in requests
- Check CORS settings if calling from a browser
- Ensure API key is set as a secret environment variable
Advanced Configuration
Using PostgreSQL for Production
-
Create a PostgreSQL database on Klutch.sh or use an external provider
-
Add database environment variables:
DATABASE_URL=postgresql://user:YOUR_SECURE_PASSWORD@host:5432/gorulesDB_POOL_MIN=2DB_POOL_MAX=10DB_SSL_MODE=require -
Run database migrations (if required by your GoRules version):
Terminal window # This depends on your GoRules implementationnode migrate.js# or./gorules-server migrate -
Verify the connection through the health endpoint
Custom Domain Configuration
-
In Klutch.sh dashboard, navigate to your app settings
-
Go to the “Domains” section
-
Add your custom domain (e.g.,
rules.yourdomain.com) -
Configure your DNS:
- Add a CNAME record pointing to your Klutch.sh app URL
-
Update CORS settings to include your custom domain:
CORS_ORIGINS=https://rules.yourdomain.com
Integrating with External Services
-
Webhooks: Configure GoRules to send webhooks on rule execution
WEBHOOK_URL=https://your-service.com/webhookWEBHOOK_ENABLED=true -
External APIs: Call external services from rules
- Ensure network policies allow outbound connections
- Set appropriate timeouts
- Handle errors gracefully
-
Message queues: Integrate with RabbitMQ or Kafka for async processing
RABBITMQ_URL=amqp://user:YOUR_SECURE_PASSWORD@host:5672QUEUE_ENABLED=true
Sample Application: Complete Example
Here’s a complete example repository structure for a GoRules application:
my-gorules-app/├── Dockerfile├── .dockerignore├── .gitignore├── .env.example├── README.md├── package.json (for Node.js version)├── go.mod (for Go version)├── go.sum├── server.js (or main.go)├── rules/│ ├── pricing-rules.json│ ├── approval-rules.json│ └── validation-rules.json├── config/│ ├── production.json│ └── development.json└── tests/ ├── pricing-rules.test.js └── approval-rules.test.jsSample package.json (Node.js implementation)
{ "name": "gorules-app", "version": "1.0.0", "description": "GoRules Business Rules Engine", "main": "server.js", "scripts": { "start": "node server.js", "dev": "nodemon server.js", "test": "jest" }, "dependencies": { "express": "^4.18.2", "gorules-engine": "^1.0.0", "pg": "^8.11.0", "dotenv": "^16.0.3", "cors": "^2.8.5" }, "devDependencies": { "nodemon": "^2.0.22", "jest": "^29.5.0" }}Resources
- GoRules Official Documentation
- GoRules GitHub Repository
- Klutch.sh Quick Start Guide
- Klutch.sh Volumes Documentation
- Klutch.sh Networking Guide
- DMN (Decision Model and Notation) Specification
Conclusion
Deploying GoRules on Klutch.sh provides a robust, scalable platform for running your business rules engine. With automatic Docker detection, built-in HTTPS, and easy scaling options, you can focus on building powerful decision logic while Klutch.sh handles the infrastructure.
Remember to:
- Use persistent volumes for rules and data
- Configure proper environment variables for security
- Monitor your application’s performance
- Back up your rules regularly
- Scale resources based on your workload
Your GoRules application will be available at example-app.klutch.sh and ready to handle business rules at any scale.