Skip to content

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

    1. Create a new directory for your GoRules application:

      Terminal window
      mkdir my-gorules-app
      cd my-gorules-app
    2. Initialize a Git repository:

      Terminal window
      git init
    3. Create a basic directory structure:

      Terminal window
      mkdir -p rules
      mkdir -p config

2. Create Sample Rule Files

    1. 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]
      }
      ]
      }
    2. Create a test input file test-input.json:

      {
      "customer_type": "premium",
      "order_amount": 150
      }

3. Create Environment Configuration

    1. Create a .env.example file for reference (never commit actual .env with secrets):

      # Server Configuration
      PORT=8080
      HOST=0.0.0.0
      # Rules Configuration
      RULES_DIR=/app/rules
      RULES_CACHE_ENABLED=true
      # Database (optional - for persistent storage)
      # DATABASE_URL=postgresql://user:password@host:5432/gorules
      # API Configuration
      API_KEY=your-secret-api-key-here
      # Logging
      LOG_LEVEL=info
      LOG_FORMAT=json
      # CORS Configuration
      CORS_ENABLED=true
      CORS_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:

    1. Create a Dockerfile in your project root:

      # Use Node.js LTS as the base image for GoRules
      FROM node:18-alpine AS base
      # Install system dependencies
      RUN apk add --no-cache \
      python3 \
      make \
      g++ \
      curl \
      git
      WORKDIR /app
      # Copy package files
      COPY package*.json ./
      # Install production dependencies
      RUN npm ci --only=production && \
      npm cache clean --force
      # Copy application code
      COPY . .
      # Create rules directory with proper permissions
      RUN mkdir -p /app/rules && \
      chown -R node:node /app
      # Switch to non-root user
      USER node
      # Expose the application port
      EXPOSE 8080
      # Health check
      HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
      CMD curl -f http://localhost:8080/health || exit 1
      # Start the application
      CMD ["node", "server.js"]
    2. For GoRules Business Rules Engine (Go-based implementation), use this alternative Dockerfile:

      # Build stage
      FROM golang:1.21-alpine AS builder
      # Install build dependencies
      RUN apk add --no-cache git make
      WORKDIR /build
      # Copy go mod files
      COPY go.mod go.sum ./
      RUN go mod download
      # Copy source code
      COPY . .
      # Build the application
      RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o gorules-server .
      # Runtime stage
      FROM alpine:latest
      # Install runtime dependencies
      RUN apk --no-cache add ca-certificates curl
      WORKDIR /app
      # Copy binary from builder
      COPY --from=builder /build/gorules-server .
      # Copy rules directory
      COPY --from=builder /build/rules ./rules
      # Create non-root user
      RUN addgroup -g 1000 gorules && \
      adduser -D -u 1000 -G gorules gorules && \
      chown -R gorules:gorules /app
      USER gorules
      # Expose the application port
      EXPOSE 8080
      # Health check
      HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
      CMD curl -f http://localhost:8080/health || exit 1
      # Start the application
      CMD ["./gorules-server"]
    3. Create a .dockerignore file to exclude unnecessary files:

      node_modules
      npm-debug.log
      .git
      .gitignore
      .env
      .env.local
      .DS_Store
      *.md
      docker-compose.yml
      .vscode
      .idea
      coverage
      dist
      test

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

    1. Push your code to GitHub:

      Terminal window
      git add .
      git commit -m "Add GoRules application with Dockerfile"
      git branch -M main
      git remote add origin https://github.com/yourusername/gorules-app.git
      git push -u origin main
    2. Log in to Klutch.sh:

      Navigate to klutch.sh/app and sign in with your GitHub account.

    3. Create a new project:

      • Go to Create Project
      • Give your project a meaningful name (e.g., “gorules-production”)
      • Click “Create Project”
    4. 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
    5. Configure environment variables:

      Add the following environment variables in the Klutch.sh dashboard:

      PORT=8080
      HOST=0.0.0.0
      RULES_DIR=/app/rules
      API_KEY=your-secure-api-key-here
      LOG_LEVEL=info
      CORS_ENABLED=true
      CORS_ORIGINS=https://example-app.klutch.sh
    6. 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:

    1. Access your app settings in the Klutch.sh dashboard

    2. Navigate to the Volumes section

    3. 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
    4. 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)

# Server
PORT=8080
HOST=0.0.0.0
# Rules
RULES_DIR=/app/rules
RULES_RELOAD_ENABLED=true
# API
API_KEY=dev-api-key-12345
# Logging
LOG_LEVEL=debug

Production Configuration

# Server
PORT=8080
HOST=0.0.0.0
# Rules
RULES_DIR=/app/rules
RULES_CACHE_ENABLED=true
RULES_CACHE_TTL=3600
RULES_RELOAD_ENABLED=false
# Database (PostgreSQL for production)
DATABASE_URL=postgresql://gorules:YOUR_SECURE_PASSWORD@postgres-host:5432/gorules_prod?sslmode=require
# API Security
API_KEY=prod-secure-api-key-xyz789
API_RATE_LIMIT=1000
API_RATE_LIMIT_WINDOW=60
# Logging
LOG_LEVEL=info
LOG_FORMAT=json
# CORS
CORS_ENABLED=true
CORS_ORIGINS=https://your-domain.com,https://app.your-domain.com
# Performance
MAX_CONCURRENT_EXECUTIONS=100
EXECUTION_TIMEOUT=30000
# Monitoring
METRICS_ENABLED=true
METRICS_PORT=9090

High Availability Configuration

# All production settings above, plus:
# Clustering
CLUSTER_ENABLED=true
CLUSTER_NODES=3
# Cache
REDIS_URL=redis://redis-host:6379
CACHE_STRATEGY=distributed
# Health Checks
HEALTH_CHECK_INTERVAL=10
READINESS_TIMEOUT=5

Verifying Your Deployment

After deployment, verify that GoRules is running correctly:

1. Check Application Health

    1. Navigate to your app URL (e.g., https://example-app.klutch.sh)

    2. You should see the GoRules dashboard or API documentation

    3. Test the health endpoint:

      Terminal window
      curl https://example-app.klutch.sh/health

      Expected response:

      {
      "status": "healthy",
      "version": "1.0.0",
      "uptime": 3600
      }

2. Test Rule Execution

    1. 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
      }
      }'
    2. Expected response:

      {
      "output": {
      "discount": 20
      },
      "executionTime": 5,
      "ruleId": "rule1"
      }

3. Verify Persistent Storage

    1. Create a new rule through the UI or API

    2. Restart your app in the Klutch.sh dashboard

    3. Verify the rule still exists after restart


Working with Rules

Creating a Decision Table

    1. Access the GoRules web interface at your app URL

    2. Click “New Rule” and select “Decision Table”

    3. Define your inputs and outputs:

      Inputs:
      - age (number)
      - income (number)
      - credit_score (number)
      Outputs:
      - loan_approved (boolean)
      - interest_rate (number)
    4. Add your business rules:

      AgeIncomeCredit ScoreLoan ApprovedInterest Rate
      >=18>=50000>=700true3.5
      >=18>=30000>=650true5.5
      >=18*<650false0
      <18**false0
    5. Save and test your decision table

Using the API

    1. 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
      }
      }'
    2. 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

    1. Use strong API keys: Generate cryptographically secure API keys

      Terminal window
      openssl rand -hex 32
    2. Enable HTTPS only: Klutch.sh provides HTTPS by default

    3. Implement authentication: Use OAuth2 or JWT tokens for production

    4. Rate limiting: Configure rate limits to prevent abuse

      API_RATE_LIMIT=1000
      API_RATE_LIMIT_WINDOW=60
    5. Input validation: Always validate rule inputs before execution

Performance Optimization

    1. Enable caching: Cache frequently used rules

      RULES_CACHE_ENABLED=true
      RULES_CACHE_TTL=3600
    2. Use a database: For production, use PostgreSQL instead of file-based storage

      DATABASE_URL=postgresql://user:password@host:5432/gorules
    3. Monitor resource usage:

      • Track CPU and memory usage in Klutch.sh dashboard
      • Scale vertically (more resources) or horizontally (more instances) as needed
    4. Optimize rules: Keep decision tables simple and well-organized

    5. Connection pooling: Configure database connection pooling

      DB_POOL_MIN=2
      DB_POOL_MAX=10

Monitoring and Logging

    1. Enable structured logging:

      LOG_LEVEL=info
      LOG_FORMAT=json
    2. Set up health checks: Use the /health endpoint

    3. Track metrics: Enable Prometheus metrics if available

      METRICS_ENABLED=true
      METRICS_PORT=9090
    4. Monitor execution times: Track rule execution performance

    5. Set up alerts: Configure alerts for:

      • High error rates
      • Slow rule execution
      • Memory/CPU spikes
      • Failed health checks

Backup and Disaster Recovery

    1. Regular backups:

      • Back up your rules directory daily
      • Back up your database if using PostgreSQL
      • Store backups in a secure, separate location
    2. Version control: Keep rules in Git for version history

    3. Testing: Test disaster recovery procedures regularly

    4. Documentation: Document your rule logic and dependencies


Scaling GoRules

Vertical Scaling (Single Instance)

    1. In Klutch.sh dashboard, go to your app settings

    2. Increase compute resources:

      • CPU: 2-4 cores for high-traffic applications
      • RAM: 2-4 GB for large rule sets
    3. Restart the app to apply changes

Horizontal Scaling (Multiple Instances)

    1. Increase the number of instances in Klutch.sh:

      • Start with 2-3 instances
      • Add more based on load
    2. Use a distributed cache (Redis) for rule caching:

      REDIS_URL=redis://redis-host:6379
      CACHE_STRATEGY=distributed
    3. Use PostgreSQL for shared state across instances

    4. 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

    1. Create a PostgreSQL database on Klutch.sh or use an external provider

    2. Add database environment variables:

      DATABASE_URL=postgresql://user:YOUR_SECURE_PASSWORD@host:5432/gorules
      DB_POOL_MIN=2
      DB_POOL_MAX=10
      DB_SSL_MODE=require
    3. Run database migrations (if required by your GoRules version):

      Terminal window
      # This depends on your GoRules implementation
      node migrate.js
      # or
      ./gorules-server migrate
    4. Verify the connection through the health endpoint

Custom Domain Configuration

    1. In Klutch.sh dashboard, navigate to your app settings

    2. Go to the “Domains” section

    3. Add your custom domain (e.g., rules.yourdomain.com)

    4. Configure your DNS:

      • Add a CNAME record pointing to your Klutch.sh app URL
    5. Update CORS settings to include your custom domain:

      CORS_ORIGINS=https://rules.yourdomain.com

Integrating with External Services

    1. Webhooks: Configure GoRules to send webhooks on rule execution

      WEBHOOK_URL=https://your-service.com/webhook
      WEBHOOK_ENABLED=true
    2. External APIs: Call external services from rules

      • Ensure network policies allow outbound connections
      • Set appropriate timeouts
      • Handle errors gracefully
    3. Message queues: Integrate with RabbitMQ or Kafka for async processing

      RABBITMQ_URL=amqp://user:YOUR_SECURE_PASSWORD@host:5672
      QUEUE_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.js

Sample 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


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.