Deployment Skill
Guide Claude through building and deploying Kagaribi packages to production environments.
Build Process
npx kagaribi build [--env environment]
Examples:
npx kagaribi build # Default environment npx kagaribi build --env production # Production environment npx kagaribi build --env staging # Staging environment
Output:
dist/
root/
index.js # Bundled application
wrangler.toml # (Cloudflare Workers only)
Dockerfile # (Google Cloud Run only)
users/
index.js
...
Deployment Model
Kagaribi's deployment model enables independent deployment per package.
Independent Package Deployment
Each package can be deployed individually to different FaaS platforms:
- •
users→ Cloudflare Workers (fast edge response) - •
payments→ AWS Lambda (integration with existing AWS infrastructure) - •
analytics→ Google Cloud Run (suitable for batch processing) - •
notifications→ Deno Deploy (lightweight notification processing)
Only Root Package Knows Deployment Locations
Critical design principle:
- •Packages don't know where they are deployed
- •Packages don't know where other packages are deployed
- •Only root package references
urlfield inkagaribi.config.tsand connects to appropriate URLs
Why this design?
- •Package independence: Package code doesn't depend on deployment destination
- •Flexibility: Changing deployment destination doesn't require changing package code
- •Environment switching: Can use different deployment destinations for dev/staging/production
Automatic RPC Communication Switching
getClient<T>() automatically switches communication method based on deployment configuration:
- •
Co-location (same process)
- •Direct function calls
- •No HTTP requests
- •Low latency
- •
Distributed deployment (different FaaS)
- •HTTP RPC communication
- •Uses
urlfromkagaribi.config.ts - •Package code requires no changes
Packages don't need to be aware of communication method.
DB Connection Model
Each package establishes its own DB connection.
Co-location (Same Process)
Root package executes initDb(), and all packages use same DB connection via getDb():
// packages/root/src/index.ts
import { createDbMiddleware } from '@kagaribi/core';
import { initDb } from '../../../db/index.js';
const app = new Hono()
.use('*', createDbMiddleware({ initFn: initDb }));
Other packages simply call getDb():
// packages/users/src/index.ts
import { getDb, schema } from '../../../db/index.js';
app.get('/api/users', async (c) => {
const db = getDb(); // Use connection initialized by root
const users = await db.select().from(schema.users);
return c.json(users);
});
Distributed Deployment (Different FaaS)
Each package independently establishes DB connection using createDbMiddleware():
// packages/users/src/index.ts (deployed to Cloudflare Workers)
import { createDbMiddleware } from '@kagaribi/core';
import { initDb, getDb, schema } from '../../../db/index.js';
const app = new Hono()
// Auto-initialize with middleware
.use('*', createDbMiddleware({ initFn: initDb }))
.get('/api/users', async (c) => {
const db = getDb();
const users = await db.select().from(schema.users);
return c.json(users);
});
Connection string management via environment variables:
- •Set
DATABASE_URLenvironment variable at each deployment destination - •
createDbMiddleware()automatically reads environment variable - •Node.js:
process.env.DATABASE_URL - •Cloudflare Workers:
c.env.DATABASE_URL(via bindings)
Important: All packages connect to the same database, but connections are established individually per package.
Deployment Modes
Dry-Run Mode (Default)
Without explicit target or environment flags, shows deployment instructions:
npx kagaribi deploy npx kagaribi deploy users npx kagaribi deploy --dry-run
Output: Platform-specific commands and setup instructions (does not deploy).
Actual Deployment
Specify target platform or environment to perform actual deployment:
# Deploy specific package to target npx kagaribi deploy users --cloudflare npx kagaribi deploy payments --lambda npx kagaribi deploy api --cloudrun # Deploy all undeployed packages to target npx kagaribi deploy --cloudflare npx kagaribi deploy --lambda # Deploy using environment configuration npx kagaribi deploy --env production npx kagaribi deploy --env staging
After successful deployment, kagaribi.config.ts is automatically updated
with the deployed URL.
Platform-Specific Requirements
Cloudflare Workers
Required tool: wrangler
npm install -g wrangler wrangler login
Deploy command:
kagaribi deploy users --cloudflare
What happens:
- •Generates
dist/users/wrangler.toml - •Runs
wrangler deployfromdist/users/ - •Updates
kagaribi.config.tswith deployed URL
Environment variables:
Configure in wrangler.toml:
[env.production.vars] DATABASE_URL = "postgresql://..."
AWS Lambda
Required tool: aws CLI
Required environment variable: AWS_LAMBDA_ROLE_ARN
# Install AWS CLI brew install awscli # or appropriate package manager aws configure # Set Lambda execution role ARN export AWS_LAMBDA_ROLE_ARN=arn:aws:iam::123456789012:role/lambda-execution-role
Deploy command:
kagaribi deploy payments --lambda
What happens:
- •Creates Lambda function (or updates if exists)
- •Uploads bundled code from
dist/payments/index.js - •Updates
kagaribi.config.tswith function URL - •Configures Node.js 22.x runtime
Environment variables:
aws lambda update-function-configuration \
--function-name payments \
--environment Variables={DATABASE_URL=postgresql://...}
Google Cloud Run
Required tool: gcloud CLI
Required environment variable: CLOUD_RUN_REGION (optional, defaults to us-central1)
# Install gcloud CLI brew install google-cloud-sdk gcloud auth login gcloud config set project YOUR_PROJECT_ID # Set region (optional) export CLOUD_RUN_REGION=asia-northeast1
Deploy command:
kagaribi deploy api --cloudrun
What happens:
- •Generates
dist/api/Dockerfile - •Builds container image with Cloud Build
- •Deploys to Cloud Run in specified region
- •Updates
kagaribi.config.tswith service URL
Environment variables:
gcloud run services update api \ --set-env-vars DATABASE_URL=postgresql://...
Deno Deploy
Required tool: deployctl
npm install -g deployctl
Deploy command:
kagaribi deploy notifications --deno
What happens:
- •Uploads
dist/notifications/index.jsto Deno Deploy - •Creates or updates deployment
- •Updates
kagaribi.config.tswith deployed URL
Node.js (Manual Deployment)
No special tools required - Use your preferred deployment method.
kagaribi build --env production
Deploy to server:
# Copy dist/ directory to server scp -r dist/ user@server:/app/ # On server, run with Node.js cd /app/dist/root node index.js
With PM2:
pm2 start dist/root/index.js --name my-app pm2 save
With systemd:
Create /etc/systemd/system/my-app.service:
[Unit] Description=Kagaribi App [Service] ExecStart=/usr/bin/node /app/dist/root/index.js WorkingDirectory=/app/dist/root Restart=always Environment=DATABASE_URL=postgresql://... [Install] WantedBy=multi-user.target
Co-location Strategy
Co-location bundles multiple packages into a single deployment for simpler infrastructure.
Configuration
// kagaribi.config.ts
export default defineConfig({
packages: {
root: {
target: 'node',
},
auth: {
colocateWith: 'root', // Bundled with root
},
users: {
colocateWith: 'root', // Bundled with root
},
payments: {
target: 'aws-lambda', // Deployed separately
url: 'https://payments.example.com',
},
},
});
Benefits:
- •Fewer deployments to manage
- •Lower infrastructure costs
- •Reduced latency between co-located packages
- •Simpler authentication/authorization
When to use:
- •Development environment (all packages together)
- •Small-to-medium projects
- •Packages with tight coupling
- •Cost optimization
When to deploy separately:
- •Different scaling requirements
- •Different geographic regions needed
- •Security isolation required
- •Team-based ownership boundaries
Automatic URL Management
After deployment, kagaribi.config.ts is automatically updated:
Before deployment:
export default defineConfig({
packages: {
users: {
target: 'cloudflare-workers',
},
},
});
After kagaribi deploy users --cloudflare:
export default defineConfig({
packages: {
users: {
target: 'cloudflare-workers',
url: 'https://users.your-project.workers.dev', // Auto-added
},
},
});
This enables:
- •Automatic service discovery for RPC calls
- •Environment-specific URL management
- •No manual configuration updates needed
Environment-Based Deployment
Define multiple environments in kagaribi.config.ts:
export default defineConfig({
packages: {
root: { target: 'node' },
},
environments: {
development: {
packages: {
'*': { colocateWith: 'root' }, // All local
},
},
staging: {
packages: {
users: {
target: 'cloudflare-workers',
url: '$STAGING_USERS_URL',
},
payments: {
target: 'aws-lambda',
url: '$STAGING_PAYMENTS_URL',
},
},
},
production: {
packages: {
users: {
target: 'cloudflare-workers',
url: '$PROD_USERS_URL',
},
payments: {
target: 'aws-lambda',
url: '$PROD_PAYMENTS_URL',
},
},
},
},
});
Deploy to specific environment:
# Set environment variables export PROD_USERS_URL=https://users.prod.example.com export PROD_PAYMENTS_URL=https://payments.prod.example.com # Deploy kagaribi deploy --env production
Database Deployment
Environment Variables
Set DATABASE_URL for each platform:
Cloudflare Workers (wrangler.toml):
[env.production.vars] DATABASE_URL = "postgresql://user:pass@host/db"
AWS Lambda:
aws lambda update-function-configuration \
--function-name my-function \
--environment Variables={DATABASE_URL=postgresql://...}
Google Cloud Run:
gcloud run services update my-service \ --set-env-vars DATABASE_URL=postgresql://...
Node.js (.env or environment):
export DATABASE_URL=postgresql://user:pass@host:5432/db node dist/root/index.js
Running Migrations
Run migrations before deploying application code:
# Local or CI/CD environment pnpm run db:migrate
In CI/CD:
# Example: GitHub Actions
- name: Run migrations
run: pnpm run db:migrate
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
- name: Deploy
run: kagaribi deploy --env production
Deployment Workflow Example
Scenario: Deploy to Production
- •
Build the project:
bashkagaribi build --env production
- •
Deploy packages:
bash# Deploy users to Cloudflare Workers kagaribi deploy users --cloudflare # Deploy payments to AWS Lambda export AWS_LAMBDA_ROLE_ARN=arn:aws:iam::123456789012:role/lambda-role kagaribi deploy payments --lambda # Deploy API to Google Cloud Run export CLOUD_RUN_REGION=us-central1 kagaribi deploy api --cloudrun
- •
Verify deployments:
bashcurl https://users.your-project.workers.dev/health curl https://payments-xyz.lambda-url.us-east-1.on.aws/health curl https://api-xyz.run.app/health
- •
Check configuration:
bashcat kagaribi.config.ts # Verify URLs are auto-updated
Best Practices
- •Test locally first - Run
npx kagaribi devbefore deploying - •Use environments - Define staging and production configurations
- •Secure secrets - Use environment variables, never commit credentials
- •Deploy incrementally - Deploy to staging before production
- •Monitor health - Include
/healthendpoints in all packages - •Co-locate wisely - Bundle related packages, split when scaling needs differ
- •Run migrations first - Apply database changes before code deployment
Troubleshooting
Issue: Authentication error during deployment
- •Solution: Ensure CLI tool is authenticated (
wrangler login,aws configure,gcloud auth login)
Issue: AWS Lambda deployment fails with missing role
- •Solution: Set
AWS_LAMBDA_ROLE_ARNenvironment variable
Issue: Cloud Run deployment fails
- •Solution: Verify project ID with
gcloud config get-value project
Issue: RPC calls to deployed package fail
- •Solution: Check
urlinkagaribi.config.tsand verify service is running
Issue: Database connection fails in production
- •Solution: Verify
DATABASE_URLis correctly set for the deployment platform
Next Steps
After deployment:
- •Monitor logs and performance
- •Set up alerts for errors
- •Configure autoscaling if needed
- •Implement rollback strategy
- •Refer to USAGE.md for advanced deployment patterns