Deployment
Deploy your Shuttl agents to production. Choose between managed hosting with Shuttl Cloud or self-hosting on your own infrastructure.
Shuttl Cloud (Recommended)
The easiest way to deploy agents is with Shuttl Cloud—no infrastructure to manage.
Step 1: Create an Account
shuttl login
This opens your browser to authenticate with GitHub or Google.
Step 2: Link Your Project
shuttl link
Follow the prompts to connect your project to Shuttl Cloud.
Step 3: Deploy
shuttl deploy
That's it! Your agents are now live with:
- Automatic scaling based on demand
- Built-in monitoring and logging
- Managed triggers (cron, webhooks, etc.)
- SSL/TLS out of the box
Environment Variables
Set secrets and configuration in the Shuttl Cloud dashboard or via CLI:
shuttl env set OPENAI_API_KEY=sk-...
shuttl env set SLACK_BOT_TOKEN=xoxb-...
Self-Hosting
Prefer to run on your own infrastructure? Shuttl provides everything you need.
Build Your Project
The shuttl build command generates a complete deployment manifest:
shuttl build --output ./dist
This creates:
dist/
├── manifest.json # Full deployment manifest
├── agents.json # Agent definitions
├── triggers.json # Trigger configurations
├── outcomes.json # Outcome configurations
└── bundle.js # Compiled application (if applicable)
Understanding the Manifest
The manifest.json contains everything needed to deploy:
{
"agents": [
{
"name": "SupportBot",
"triggers": [
{ "type": "api", "config": {} },
{ "type": "rate", "config": { "cron": "0 9 * * *", "timezone": "UTC" } }
],
"outcomes": [
{ "type": "streaming" },
{ "type": "slack", "config": { "channel": "#support" } }
]
}
]
}
Use this to determine your infrastructure needs:
| Trigger Type | Infrastructure Needed |
|---|---|
api |
HTTP server, load balancer |
rate (cron) |
Cron scheduler or Lambda/Cloud Functions |
email |
Email server integration (SES, SendGrid) |
file |
File system watcher or S3 triggers |
The Serve Command
The shuttl serve command runs your agents in production mode with an HTTP server.
Mode 1: Serve All Agents
Run all agents with all their triggers:
shuttl serve
With SSL:
shuttl serve --ssl-cert ./cert.pem --ssl-key ./key.pem
Options
| Flag | Short | Default | Description |
|---|---|---|---|
--port |
-p |
8080 |
HTTP server port |
--ssl-cert |
Path to SSL certificate | ||
--ssl-key |
Path to SSL private key | ||
--config |
-c |
./shuttl.json |
Config file path |
Endpoints
| Endpoint | Method | Description |
|---|---|---|
/chat |
POST | Send message to an agent |
/chat/:threadId |
POST | Continue a conversation |
/agents |
GET | List available agents |
/agents/:name |
GET | Get agent details |
/health |
GET | Health check |
Mode 2: Serve Specific Agent or Trigger
Run only specific agents or triggers:
# Serve only the SupportBot agent
shuttl serve --agent SupportBot
# Serve only the API trigger for SupportBot
shuttl serve --agent SupportBot --trigger api
# Serve only rate-based triggers (for cron workers)
shuttl serve --trigger rate
Use Cases
| Command | Use Case |
|---|---|
--agent SupportBot |
Dedicated instance for one agent |
--trigger api |
API-only server (no scheduled tasks) |
--trigger rate |
Worker for scheduled/cron triggers |
This allows you to scale different parts of your system independently:
# docker-compose.yml example
services:
api:
command: shuttl serve --trigger api
ports:
- "8080:8080"
deploy:
replicas: 3
workers:
command: shuttl serve --trigger rate
deploy:
replicas: 1
Mode 3: Invoke a Specific Trigger
For event-based deployments (Lambda, Cloud Functions, Kubernetes CronJobs), invoke a specific agent and trigger directly:
shuttl serve --invoke --agent DailyReporter --trigger rate
This:
- Loads the agent
- Fires the specified trigger once
- Processes the outcome
- Exits
Perfect For
- AWS Lambda: Invoke on CloudWatch Events schedule
- Google Cloud Functions: Trigger from Cloud Scheduler
- Kubernetes CronJobs: Run as a one-shot container
- GitHub Actions: Scheduled workflows
Example: AWS Lambda
# serverless.yml
functions:
dailyReport:
handler: handler.run
events:
- schedule: cron(0 9 * * ? *)
environment:
OPENAI_API_KEY: ${ssm:/shuttl/openai-key}
// handler.js
const { execSync } = require('child_process');
exports.run = async (event) => {
execSync('shuttl serve --invoke --agent DailyReporter --trigger rate');
return { statusCode: 200 };
};
Example: Kubernetes CronJob
apiVersion: batch/v1
kind: CronJob
metadata:
name: daily-reporter
spec:
schedule: "0 9 * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: shuttl
image: your-registry/shuttl-app:latest
command: ["shuttl", "serve", "--invoke", "--agent", "DailyReporter", "--trigger", "rate"]
env:
- name: OPENAI_API_KEY
valueFrom:
secretKeyRef:
name: shuttl-secrets
key: openai-key
restartPolicy: OnFailure
Deployment Patterns
Pattern 1: Simple HTTP Server
For small deployments, run everything on one server:
shuttl serve --port 80 --ssl-cert /etc/ssl/cert.pem --ssl-key /etc/ssl/key.pem
Pattern 2: Separate API and Workers
Scale API and background workers independently:
┌─────────────────┐ ┌─────────────────┐
│ Load Balancer │ │ Cron Scheduler│
└────────┬────────┘ └────────┬────────┘
│ │
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ API Servers │ │ Worker Nodes │
│ (--trigger api) │ │ (--trigger rate)│
│ x3 replicas │ │ x1 replica │
└─────────────────┘ └─────────────────┘
Pattern 3: Serverless
Use the invoke mode with cloud functions:
┌─────────────────┐
│ API Gateway │──────▶ Lambda (--invoke --trigger api)
└─────────────────┘
┌─────────────────┐
│ CloudWatch/Cron │──────▶ Lambda (--invoke --trigger rate)
└─────────────────┘
Docker Deployment
Dockerfile
FROM node:20-slim
WORKDIR /app
# Copy built application
COPY dist/ ./dist/
COPY shuttl.json ./
# Install Shuttl CLI
RUN curl -fsSL https://shuttl.io/install.sh | bash
EXPOSE 8080
CMD ["shuttl", "serve"]
Docker Compose
version: '3.8'
services:
shuttl:
build: .
ports:
- "8080:8080"
environment:
- OPENAI_API_KEY=${OPENAI_API_KEY}
- SLACK_BOT_TOKEN=${SLACK_BOT_TOKEN}
restart: unless-stopped
Health Checks
All serve modes expose a /health endpoint:
curl http://localhost:8080/health
Response:
{
"status": "healthy",
"agents": 3,
"uptime": 3600
}
Use this for:
- Load balancer health checks
- Kubernetes liveness probes
- Monitoring systems
Next Steps
- 📖 CLI Commands - Full command reference
- ⚡ Triggers - Configure triggers for deployment
- 📤 Outcomes - Route outputs in production