Initial commit
This commit is contained in:
390
references/deployment-guide.md
Normal file
390
references/deployment-guide.md
Normal file
@@ -0,0 +1,390 @@
|
||||
# Deployment Guide for TypeScript MCP Servers
|
||||
|
||||
Complete guide to deploying MCP servers on Cloudflare Workers.
|
||||
|
||||
---
|
||||
|
||||
## Quick Deployment
|
||||
|
||||
```bash
|
||||
# Build
|
||||
npm run build
|
||||
|
||||
# Deploy
|
||||
wrangler deploy
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Environment Setup
|
||||
|
||||
### Development (.dev.vars)
|
||||
|
||||
Create `.dev.vars` for local secrets:
|
||||
```bash
|
||||
WEATHER_API_KEY=abc123
|
||||
DATABASE_URL=http://localhost:3306
|
||||
```
|
||||
|
||||
**Never commit `.dev.vars` to git!**
|
||||
|
||||
### Production Secrets
|
||||
|
||||
```bash
|
||||
# Set secrets
|
||||
wrangler secret put WEATHER_API_KEY
|
||||
wrangler secret put DATABASE_URL
|
||||
|
||||
# List secrets
|
||||
wrangler secret list
|
||||
|
||||
# Delete secret
|
||||
wrangler secret delete OLD_KEY
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Multiple Environments
|
||||
|
||||
**wrangler.jsonc:**
|
||||
```jsonc
|
||||
{
|
||||
"name": "mcp-server",
|
||||
"main": "src/index.ts",
|
||||
|
||||
"env": {
|
||||
"staging": {
|
||||
"name": "mcp-server-staging",
|
||||
"vars": {
|
||||
"ENVIRONMENT": "staging"
|
||||
},
|
||||
"d1_databases": [
|
||||
{ "binding": "DB", "database_id": "staging-db-id" }
|
||||
]
|
||||
},
|
||||
"production": {
|
||||
"name": "mcp-server-production",
|
||||
"vars": {
|
||||
"ENVIRONMENT": "production"
|
||||
},
|
||||
"d1_databases": [
|
||||
{ "binding": "DB", "database_id": "prod-db-id" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Deploy to specific environment:**
|
||||
```bash
|
||||
wrangler deploy --env staging
|
||||
wrangler deploy --env production
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Custom Domains
|
||||
|
||||
### Setup
|
||||
|
||||
1. **Add domain in Cloudflare dashboard:**
|
||||
- Workers & Pages → your worker → Settings → Domains & Routes
|
||||
- Add custom domain: `mcp.example.com`
|
||||
|
||||
2. **Or via wrangler.jsonc:**
|
||||
```jsonc
|
||||
{
|
||||
"routes": [
|
||||
{
|
||||
"pattern": "mcp.example.com/*",
|
||||
"custom_domain": true
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### SSL/TLS
|
||||
|
||||
Cloudflare provides automatic SSL certificates for custom domains.
|
||||
|
||||
---
|
||||
|
||||
## CI/CD with GitHub Actions
|
||||
|
||||
**.github/workflows/deploy.yml:**
|
||||
```yaml
|
||||
name: Deploy MCP Server
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Run tests
|
||||
run: npm test
|
||||
|
||||
- name: Build
|
||||
run: npm run build
|
||||
|
||||
- name: Deploy to Cloudflare Workers
|
||||
uses: cloudflare/wrangler-action@v3
|
||||
with:
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
command: deploy --env production
|
||||
```
|
||||
|
||||
### Setup Secrets
|
||||
|
||||
1. **Get Cloudflare API token:**
|
||||
- Dashboard → My Profile → API Tokens
|
||||
- Create token with "Edit Cloudflare Workers" permissions
|
||||
|
||||
2. **Add to GitHub:**
|
||||
- Repository → Settings → Secrets → Actions
|
||||
- Add `CLOUDFLARE_API_TOKEN`
|
||||
- Add `CLOUDFLARE_ACCOUNT_ID`
|
||||
|
||||
---
|
||||
|
||||
## Database Migrations
|
||||
|
||||
### D1 Migrations
|
||||
|
||||
**Create migration:**
|
||||
```bash
|
||||
wrangler d1 migrations create my-db add-users-table
|
||||
```
|
||||
|
||||
**migrations/0001_add_users_table.sql:**
|
||||
```sql
|
||||
CREATE TABLE users (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL,
|
||||
email TEXT UNIQUE NOT NULL,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
```
|
||||
|
||||
**Apply migrations:**
|
||||
```bash
|
||||
# Local
|
||||
wrangler d1 migrations apply my-db --local
|
||||
|
||||
# Production
|
||||
wrangler d1 migrations apply my-db --remote
|
||||
```
|
||||
|
||||
**In CI/CD:**
|
||||
```yaml
|
||||
- name: Run D1 migrations
|
||||
run: wrangler d1 migrations apply my-db --remote
|
||||
env:
|
||||
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Monitoring & Logs
|
||||
|
||||
### Real-time Logs
|
||||
|
||||
```bash
|
||||
# Tail logs
|
||||
wrangler tail
|
||||
|
||||
# Filter by status
|
||||
wrangler tail --status error
|
||||
|
||||
# Filter by method
|
||||
wrangler tail --method POST
|
||||
```
|
||||
|
||||
### Workers Analytics
|
||||
|
||||
View in dashboard:
|
||||
- Requests per second
|
||||
- Error rate
|
||||
- CPU time
|
||||
- Bandwidth
|
||||
|
||||
### Custom Logging
|
||||
|
||||
```typescript
|
||||
app.post('/mcp', async (c) => {
|
||||
console.log('MCP request:', {
|
||||
method: c.req.method,
|
||||
path: c.req.path,
|
||||
timestamp: new Date().toISOString()
|
||||
});
|
||||
|
||||
// ... handle request
|
||||
|
||||
console.log('MCP response:', { status: 200, duration: '15ms' });
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Rollback Strategy
|
||||
|
||||
### Quick Rollback
|
||||
|
||||
```bash
|
||||
# List deployments
|
||||
wrangler deployments list
|
||||
|
||||
# Rollback to specific deployment
|
||||
wrangler rollback --deployment-id abc123
|
||||
```
|
||||
|
||||
### Git-based Rollback
|
||||
|
||||
```bash
|
||||
# Revert to previous commit
|
||||
git revert HEAD
|
||||
git push
|
||||
|
||||
# CI/CD will auto-deploy reverted version
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Performance Optimization
|
||||
|
||||
### 1. Enable Compression
|
||||
|
||||
Cloudflare automatically compresses responses. No configuration needed.
|
||||
|
||||
### 2. Caching
|
||||
|
||||
```typescript
|
||||
app.get('/mcp-schema', async (c) => {
|
||||
const schema = { ... };
|
||||
|
||||
return c.json(schema, 200, {
|
||||
'Cache-Control': 'public, max-age=3600',
|
||||
'CDN-Cache-Control': 'max-age=86400'
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### 3. Edge Caching with KV
|
||||
|
||||
```typescript
|
||||
async function getCachedOrFetch(key: string, fetcher: () => Promise<string>, env: Env) {
|
||||
const cached = await env.CACHE.get(key);
|
||||
if (cached) return cached;
|
||||
|
||||
const fresh = await fetcher();
|
||||
await env.CACHE.put(key, fresh, { expirationTtl: 3600 });
|
||||
return fresh;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Health Checks
|
||||
|
||||
```typescript
|
||||
app.get('/health', (c) => {
|
||||
return c.json({
|
||||
status: 'healthy',
|
||||
timestamp: new Date().toISOString(),
|
||||
version: '1.0.0'
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
**Monitor with UptimeRobot, Pingdom, etc.**
|
||||
|
||||
---
|
||||
|
||||
## Cost Optimization
|
||||
|
||||
### Workers Pricing
|
||||
|
||||
- Free: 100,000 requests/day
|
||||
- Paid: $5/month + $0.50/million requests
|
||||
|
||||
### Tips
|
||||
|
||||
1. **Use KV for caching** (reduces computation)
|
||||
2. **Optimize D1 queries** (use indexes)
|
||||
3. **Batch operations** where possible
|
||||
4. **Set reasonable rate limits**
|
||||
5. **Monitor usage** in dashboard
|
||||
|
||||
---
|
||||
|
||||
## Security Checklist
|
||||
|
||||
Before production:
|
||||
|
||||
- [ ] Authentication implemented
|
||||
- [ ] Rate limiting enabled
|
||||
- [ ] CORS configured correctly
|
||||
- [ ] Secrets in Wrangler secrets (not code)
|
||||
- [ ] Error messages don't leak data
|
||||
- [ ] HTTPS only (enforced by CF)
|
||||
- [ ] Input validation on all tools
|
||||
- [ ] SQL injection protection
|
||||
- [ ] API keys rotated regularly
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting Deployments
|
||||
|
||||
### Deployment Fails
|
||||
|
||||
```bash
|
||||
# Check syntax
|
||||
npm run build
|
||||
|
||||
# Validate wrangler.jsonc
|
||||
wrangler deploy --dry-run
|
||||
|
||||
# View detailed logs
|
||||
wrangler deploy --verbose
|
||||
```
|
||||
|
||||
### Worker Not Responding
|
||||
|
||||
```bash
|
||||
# Check logs
|
||||
wrangler tail
|
||||
|
||||
# Test locally first
|
||||
wrangler dev
|
||||
|
||||
# Verify bindings
|
||||
wrangler d1 list
|
||||
wrangler kv namespace list
|
||||
```
|
||||
|
||||
### Performance Issues
|
||||
|
||||
```bash
|
||||
# Check CPU time
|
||||
wrangler tail --status ok | grep "CPU time"
|
||||
|
||||
# Profile with Analytics
|
||||
# Dashboard → Workers → Analytics
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Last Updated:** 2025-10-28
|
||||
Reference in New Issue
Block a user