From deepgram-pack
Configures Deepgram multi-environment setups for dev, staging, production using TypeScript configs, Docker Compose profiles, and Kubernetes overlays.
npx claudepluginhub jeremylongshore/claude-code-plugins-plus-skills --plugin deepgram-packThis skill is limited to using the following tools:
Configure isolated Deepgram environments for development, staging, and production. Each environment uses a separate Deepgram project, scoped API keys, environment-specific model selection, and validated configuration. Includes typed config, client factory, Docker Compose profiles, and Kubernetes overlays.
Deploys Deepgram transcription services to Docker, Kubernetes, AWS Lambda, and Google Cloud Run using secure Dockerfiles, Compose files, and K8s manifests with health checks.
Executes AssemblyAI production deployment checklist for transcription services, verifying API setup, error handling, performance, and providing TypeScript health checks.
Manages .env files, environment variables, configurations, and secrets across local, staging, production environments. Supports Docker, Kubernetes ConfigMaps/Secrets, AWS Secrets Manager, Vault, validation, and sync.
Share bugs, ideas, or general feedback.
Configure isolated Deepgram environments for development, staging, and production. Each environment uses a separate Deepgram project, scoped API keys, environment-specific model selection, and validated configuration. Includes typed config, client factory, Docker Compose profiles, and Kubernetes overlays.
| Setting | Development | Staging | Production |
|---|---|---|---|
| Model | base (fast, cheap) | nova-3 | nova-3 |
| Concurrency | 5 | 20 | 100 |
| Diarization | Off | On | On |
| PII Redaction | Off | On | On |
| Callback URL | localhost:3000 | staging.example.com | api.example.com |
| Key Rotation | Manual | Monthly | 90-day auto |
interface DeepgramEnvConfig {
apiKey: string;
projectId: string;
model: 'base' | 'nova-2' | 'nova-3';
maxConcurrency: number;
features: {
diarize: boolean;
smart_format: boolean;
redact: string[] | false;
summarize: boolean;
};
callbackBaseUrl?: string;
timeout: number;
}
function loadConfig(env: string): DeepgramEnvConfig {
const configs: Record<string, DeepgramEnvConfig> = {
development: {
apiKey: process.env.DEEPGRAM_API_KEY_DEV!,
projectId: process.env.DEEPGRAM_PROJECT_ID_DEV!,
model: 'base',
maxConcurrency: 5,
features: {
diarize: false,
smart_format: true,
redact: false,
summarize: false,
},
callbackBaseUrl: 'http://localhost:3000',
timeout: 60000,
},
staging: {
apiKey: process.env.DEEPGRAM_API_KEY_STAGING!,
projectId: process.env.DEEPGRAM_PROJECT_ID_STAGING!,
model: 'nova-3',
maxConcurrency: 20,
features: {
diarize: true,
smart_format: true,
redact: ['pci', 'ssn'],
summarize: true,
},
callbackBaseUrl: 'https://staging.example.com',
timeout: 30000,
},
production: {
apiKey: process.env.DEEPGRAM_API_KEY_PRODUCTION!,
projectId: process.env.DEEPGRAM_PROJECT_ID_PRODUCTION!,
model: 'nova-3',
maxConcurrency: 100,
features: {
diarize: true,
smart_format: true,
redact: ['pci', 'ssn'],
summarize: true,
},
callbackBaseUrl: 'https://api.example.com',
timeout: 30000,
},
};
const config = configs[env];
if (!config) throw new Error(`Unknown environment: ${env}. Use: development, staging, production`);
if (!config.apiKey) throw new Error(`DEEPGRAM_API_KEY_${env.toUpperCase()} not set`);
return config;
}
const env = process.env.NODE_ENV ?? 'development';
const config = loadConfig(env);
import { createClient, DeepgramClient } from '@deepgram/sdk';
class DeepgramClientFactory {
private static clients = new Map<string, DeepgramClient>();
static getClient(env?: string): DeepgramClient {
const environment = env ?? process.env.NODE_ENV ?? 'development';
if (!this.clients.has(environment)) {
const config = loadConfig(environment);
this.clients.set(environment, createClient(config.apiKey));
console.log(`Deepgram client created for: ${environment} (model: ${config.model})`);
}
return this.clients.get(environment)!;
}
// Convenience: transcribe with environment defaults
static async transcribe(url: string, overrides: Record<string, any> = {}) {
const environment = process.env.NODE_ENV ?? 'development';
const config = loadConfig(environment);
const client = this.getClient(environment);
const { result, error } = await client.listen.prerecorded.transcribeUrl(
{ url },
{
model: config.model,
smart_format: config.features.smart_format,
diarize: config.features.diarize,
redact: config.features.redact || undefined,
summarize: config.features.summarize ? 'v2' : undefined,
...overrides,
}
);
if (error) throw error;
return result;
}
// Reset for key rotation
static reset(env?: string) {
if (env) {
this.clients.delete(env);
} else {
this.clients.clear();
}
}
}
# .env.development
DEEPGRAM_API_KEY_DEV=dev-key-here
DEEPGRAM_PROJECT_ID_DEV=dev-project-id
# .env.staging
DEEPGRAM_API_KEY_STAGING=staging-key-here
DEEPGRAM_PROJECT_ID_STAGING=staging-project-id
# .env.production (use secret manager, not file)
# DEEPGRAM_API_KEY_PRODUCTION=production-key-here
# DEEPGRAM_PROJECT_ID_PRODUCTION=production-project-id
# docker-compose.yml
x-common: &common
build: .
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "-q", "--spider", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
services:
app-dev:
<<: *common
profiles: ["development"]
ports:
- "3000:3000"
environment:
- NODE_ENV=development
- DEEPGRAM_API_KEY_DEV=${DEEPGRAM_API_KEY_DEV}
- DEEPGRAM_PROJECT_ID_DEV=${DEEPGRAM_PROJECT_ID_DEV}
app-staging:
<<: *common
profiles: ["staging"]
ports:
- "3001:3000"
environment:
- NODE_ENV=staging
- DEEPGRAM_API_KEY_STAGING=${DEEPGRAM_API_KEY_STAGING}
- DEEPGRAM_PROJECT_ID_STAGING=${DEEPGRAM_PROJECT_ID_STAGING}
app-production:
<<: *common
profiles: ["production"]
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- DEEPGRAM_API_KEY_PRODUCTION=${DEEPGRAM_API_KEY_PRODUCTION}
- DEEPGRAM_PROJECT_ID_PRODUCTION=${DEEPGRAM_PROJECT_ID_PRODUCTION}
deploy:
resources:
limits:
memory: 512M
# Usage:
docker compose --profile development up
docker compose --profile staging up
docker compose --profile production up
# k8s/base/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: deepgram-config
data:
DEEPGRAM_MODEL: "nova-3"
DEEPGRAM_SMART_FORMAT: "true"
---
# k8s/overlays/development/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
bases:
- ../../base
patchesStrategicMerge:
- configmap-patch.yaml
secretGenerator:
- name: deepgram-secrets
literals:
- api-key=dev-key-here
---
# k8s/overlays/development/configmap-patch.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: deepgram-config
data:
DEEPGRAM_MODEL: "base"
DEEPGRAM_MAX_CONCURRENCY: "5"
async function validateEnvironments() {
const envs = ['development', 'staging', 'production'];
const results: Record<string, { valid: boolean; error?: string }> = {};
for (const env of envs) {
try {
const config = loadConfig(env);
const client = createClient(config.apiKey);
// Test 1: Key validity
const { error: authError } = await client.manage.getProjects();
if (authError) throw new Error(`Auth failed: ${authError.message}`);
// Test 2: Project access
const { error: projError } = await client.manage.getProject(config.projectId);
if (projError) throw new Error(`Project access failed: ${projError.message}`);
// Test 3: Transcription works
const { error: sttError } = await client.listen.prerecorded.transcribeUrl(
{ url: 'https://static.deepgram.com/examples/Bueller-Life-moves-702702706.wav' },
{ model: config.model, smart_format: true }
);
if (sttError) throw new Error(`STT failed: ${sttError.message}`);
results[env] = { valid: true };
console.log(`[PASS] ${env}`);
} catch (err: any) {
results[env] = { valid: false, error: err.message };
console.log(`[FAIL] ${env}: ${err.message}`);
}
}
const allValid = Object.values(results).every(r => r.valid);
console.log(`\nValidation: ${allValid ? 'ALL PASS' : 'FAILURES DETECTED'}`);
return results;
}
| Issue | Cause | Solution |
|---|---|---|
DEEPGRAM_API_KEY_DEV not set | Missing env var | Set in .env.development |
| Wrong model in staging | Config mismatch | Check loadConfig mapping |
| Cross-env key used | Shared key | Create separate projects per environment |
| Validation fails for one env | Key expired | Rotate key for that environment |