Quick Start
This guide will help you understand Kasho’s architecture and get it running in your environment. While we use Docker Compose as an example, the concepts apply to any production orchestration system like Kubernetes.
Production Deployment Overview
Kasho consists of four required containers that work together:
- Redis - Used for distributed state management and caching
- licensing - Validates and manages Kasho licenses
- pg-change-stream - Captures changes from your source PostgreSQL database
- pg-translicator - Applies transformations and writes to your target database
Production Environments
Most production deployments use Kubernetes, ECS, or similar orchestration systems. The Docker Compose example below illustrates how the containers interact and can be adapted to your specific environment.
Container Images
All Kasho components are packaged in a single Docker image available from Docker Hub:
- Image:
kashoio/kasho:latest(or specific version likev0.3.0) - Commands:
./pg-change-streamand./pg-translicator
Prerequisites
Important: Single Translicator Only
Currently, only a single pg-translicator instance is supported. Multiple translicators would process the same changes multiple times.
License Required
Kasho requires a valid license file to operate. See the Licensing guide for details. If you’re interested in becoming a design partner, contact oi.ohsak@olleh.
Before you begin, ensure you have:
- PostgreSQL 15+ databases (source and target)
- Databases configured with
wal_level = logical(see below) - A Redis instance (or Redis-compatible service)
- Container orchestration system (Kubernetes, ECS, Docker, etc.)
- Valid Kasho license file
PostgreSQL WAL Level Configuration
Check your current WAL level:
SHOW wal_level;If it’s not logical, update your postgresql.conf:
wal_level = logicalImportant: After changing this setting, you must restart PostgreSQL for it to take effect.
Docker Compose Example
Example Configuration
The following Docker Compose configuration demonstrates how Kasho’s containers interact. Adapt this to your production orchestration system (Kubernetes manifests, ECS task definitions, etc.).
Step 1: Example Directory Structure
For this example, create a directory structure:
mkdir kasho-example
cd kasho-exampleStep 2: Example Docker Compose Configuration
Create a docker-compose.yml file:
Port Conflicts
If you have other services running locally, you may need to change the exposed ports. For example, change "6379:6379" to "6380:6379" if Redis is already running. The second number is the container’s internal port and should not be changed.
services:
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
- redis-data:/data
licensing:
image: kashoio/kasho:latest
command: /app/bin/licensing
ports:
- "50052:50052"
environment:
GRPC_PORT: 50052
volumes:
- ./config:/app/config:ro # Contains license.jwt
pg-change-stream:
image: kashoio/kasho:latest
command: /app/bin/pg-change-stream
environment:
KV_URL: redis://redis:6379
PRIMARY_DATABASE_URL: ${PRIMARY_DATABASE_URL}
LICENSING_SERVICE_ADDR: ${LICENSING_SERVICE_ADDR}
volumes:
- ./config:/app/config:ro # Contains license.jwt
ports:
- "50051:50051"
depends_on:
- redis
- licensing
pg-translicator:
image: kashoio/kasho:latest
command: /app/bin/pg-translicator
environment:
CHANGE_STREAM_SERVICE_ADDR: pg-change-stream:50051
REPLICA_DATABASE_URL: ${REPLICA_DATABASE_URL}
LICENSING_SERVICE_ADDR: ${LICENSING_SERVICE_ADDR}
volumes:
- ./config:/app/config:ro # Contains transforms.yml and license.jwt
depends_on:
- pg-change-stream
- licensing
volumes:
redis-data:Step 3: Configuration Files
Create a config directory for your transforms and license:
mkdir configPlace your license.jwt file in the config directory:
cp /path/to/your/license.jwt config/Create config/transforms.yml with your transformation rules:
version: v1
tables:
# Example: Transform user emails in the public.users table
public.users:
email: FakeEmail
phone: FakePhoneSee the Transform Configuration guide for all available transforms.
Step 4: Environment Variables
Create a .env file with your database connections and service configuration.
Important: Replace the example database URLs below with your actual PostgreSQL connection strings. The services will not start successfully without valid database connections.
# Source database (read-only access needed)
# Replace with your actual source database connection string
PRIMARY_DATABASE_URL=postgresql://kasho:password@source-host:5432/source_db?sslmode=disable
# Target database (write access needed)
# Replace with your actual target database connection string
REPLICA_DATABASE_URL=postgresql://kasho:password@target-host:5432/target_db?sslmode=disable
# Redis connection for pg-change-stream
KV_URL=redis://redis:6379
# Change stream service for pg-translicator
CHANGE_STREAM_SERVICE_ADDR=pg-change-stream:50051
# License service address
LICENSING_SERVICE_ADDR=licensing:50052Production Note
In production, these service URLs will depend on your infrastructure. For example, in Kubernetes you might use service names like redis.default.svc.cluster.local:6379.
Step 5: Run the Example
docker-compose up -dVerify all services are running:
docker-compose psYou should see:
redis- Runninglicensing- Running on port 50052pg-change-stream- Running on port 50051pg-translicator- Running
Production Considerations
When deploying to production:
-
Container Orchestration: Translate the Docker Compose configuration to your platform:
- Kubernetes: Create Deployments, Services, and ConfigMaps
- ECS: Define Task Definitions and Services
- Other platforms: Follow your standard container deployment practices
-
Redis: Use a managed Redis service or ensure high availability
-
Networking: Ensure containers can communicate:
pg-translicatormust reachpg-change-streamservice- Both services need access to their respective databases
- Consider service discovery mechanisms in your environment
-
Configuration Management: Mount transform configurations using your platform’s methods:
- Kubernetes: ConfigMaps or Secrets
- ECS: Parameter Store or S3
- Docker: Volume mounts or config management tools
Bootstrap Existing Data
If you have existing data in your source database, you’ll need to run the bootstrap process:
The bootstrap process ensures zero data loss by capturing changes during the initial data load
- Execute the bootstrap process in the pg-change-stream container:
# Run bootstrap process (will prompt for confirmation)
docker exec -it kasho-example-pg-change-stream-1 /app/scripts/bootstrap-kasho.shContainer Name
The container name may vary based on your setup. Use docker ps to find the exact name of your pg-change-stream container.
- The bootstrap process will:
- Create a consistent snapshot of your source database
- Start capturing changes from that point
- Load the snapshot data
- Transition to streaming mode
If you prefer, you can manually bootstrap things with a bit more effort. See the Bootstrap Process guide for detailed information.
Verify Installation
Check that replication is working:
-
Check
pg-change-streamstatus (using gRPC):# Using grpcurl (install with: brew install grpcurl) grpcurl -plaintext localhost:50051 kasho.ChangeStreamService/GetStatus -
View logs:
docker-compose logs -f pg-change-stream docker-compose logs -f pg-translicator -
Make a test change in your source database:
-- In your source database UPDATE users SET updated_at = NOW() WHERE id = 1; -
Verify the change appears in your target database
Next Steps
- Configure your databases for production use
- Understand configuration options
- Learn about transforms
Troubleshooting
Services won’t start:
- Ensure your environment variables are set correctly, especially the database URLs.
- Verify
transforms.ymlexists in the config directory - Check logs:
docker-compose logs [service-name]
Connection errors:
- Ensure databases are accessible from Docker containers
- Verify PostgreSQL has
wal_level = logical - Check firewall rules allow connections