| name | kagaribi-deployment |
| description | Build and deploy Kagaribi packages to cloud platforms with automatic URL tracking |
Deployment Skill
Guide Claude through building and deploying Kagaribi packages to production
environments.
Build Process
npx kagaribi build [--env environment]
Examples:
npx kagaribi build
npx kagaribi build --env production
npx kagaribi build --env staging
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
url field in kagaribi.config.ts and 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
url from kagaribi.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():
import { createDbMiddleware } from '@kagaribi/core';
import { initDb } from '../../../db/index.js';
const app = new Hono()
.use('*', createDbMiddleware({ initFn: initDb }));
Other packages simply call getDb():
import { getDb, schema } from '../../../db/index.js';
app.get('/api/users', async (c) => {
const db = getDb();
const users = await db.select().from(schema.users);
return c.json(users);
});
Distributed Deployment (Different FaaS)
Each package independently establishes DB connection using createDbMiddleware():
import { createDbMiddleware } from '@kagaribi/core';
import { initDb, getDb, schema } from '../../../db/index.js';
const app = new Hono()
.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_URL environment 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:
npx kagaribi deploy users --cloudflare
npx kagaribi deploy payments --lambda
npx kagaribi deploy api --cloudrun
npx kagaribi deploy --cloudflare
npx kagaribi deploy --lambda
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 deploy from dist/users/
- Updates
kagaribi.config.ts with deployed URL
Environment variables:
Configure in wrangler.toml:
[env.production.vars]
DATABASE_URL = "postgresql://..."
Using Cloudflare D1:
D1 is configured as a binding (not an environment variable). Add the binding to wrangler.toml:
[[d1_databases]]
binding = "DB"
database_name = "my-database"
database_id = "xxxx-xxxx-xxxx-xxxx"
Migrations must be applied using wrangler d1 migrations apply (not drizzle-kit migrate):
npx wrangler d1 migrations apply my-database --local
npx wrangler d1 migrations apply my-database
AWS Lambda
Required tool: aws CLI
Required environment variable: AWS_LAMBDA_ROLE_ARN
brew install awscli
aws configure
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.ts with 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)
brew install google-cloud-sdk
gcloud auth login
gcloud config set project YOUR_PROJECT_ID
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.ts with 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.js to Deno Deploy
- Creates or updates deployment
- Updates
kagaribi.config.ts with deployed URL
Node.js (Manual Deployment)
No special tools required - Use your preferred deployment method.
kagaribi build --env production
Deploy to server:
scp -r dist/ user@server:/app/
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
export default defineConfig({
packages: {
root: {
target: 'node',
},
auth: {
colocateWith: 'root',
},
users: {
colocateWith: 'root',
},
payments: {
target: 'aws-lambda',
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',
},
},
});
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' },
},
},
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:
export PROD_USERS_URL=https://users.prod.example.com
export PROD_PAYMENTS_URL=https://payments.prod.example.com
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:
pnpm run db:migrate
In CI/CD:
- 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:
kagaribi build --env production
-
Deploy packages:
kagaribi deploy users --cloudflare
export AWS_LAMBDA_ROLE_ARN=arn:aws:iam::123456789012:role/lambda-role
kagaribi deploy payments --lambda
export CLOUD_RUN_REGION=us-central1
kagaribi deploy api --cloudrun
-
Verify deployments:
curl 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:
cat kagaribi.config.ts
Best Practices
- Test locally first - Run
npx kagaribi dev before 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
/health endpoints 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_ARN environment 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
url in kagaribi.config.ts and verify service is running
Issue: Database connection fails in production
- Solution: Verify
DATABASE_URL is 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