Skip to main content 首页 创作者 comeonoliver skillshub customerio-multi-env-setup
customerio-multi-env-setup Configure Customer.io multi-environment setup with workspace isolation.
Use when setting up dev/staging/prod workspaces, environment-aware
clients, or Kubernetes config overlays.
Trigger: "customer.io environments", "customer.io staging",
"customer.io dev prod", "customer.io workspace isolation".
跳到安装 Skills Marketplace 发现并探索由社区构建的 Agent Skills
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/ComeOnOliver/skillshub --skill customerio-multi-env-setup命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
下载 Zip 下载中... name customerio-multi-env-setup description Configure Customer.io multi-environment setup with workspace isolation.
Use when setting up dev/staging/prod workspaces, environment-aware
clients, or Kubernetes config overlays.
Trigger: "customer.io environments", "customer.io staging",
"customer.io dev prod", "customer.io workspace isolation".
allowed-tools Read, Write, Edit, Bash(npm:*), Bash(kubectl:*), Glob, Grep version 1.0.0 license MIT author Jeremy Longshore <jeremy@intentsolutions.io> compatible-with claude-code, codex, openclaw tags ["saas","customer-io","multi-environment","kubernetes"]
Customer.io Multi-Environment Setup
Overview
Configure isolated Customer.io environments for dev, staging, and production: separate workspaces per environment, typed configuration with validation, environment-aware client wrappers, Kubernetes ConfigMap overlays, and data isolation verification.
Prerequisites
Customer.io account with multiple workspaces (create at fly.customer.io)
Environment variable management (dotenv, secrets manager)
CI/CD pipeline for per-environment deployment
Workspace Strategy
Environment Workspace Name Purpose Dry Run Data Local dev myapp-devIndividual developer testing Optional Fake/test data CI myapp-ciAutomated test runs No Auto-cleaned test data Staging myapp-stagingPre-production validation No Subset of real data Production myapp-prodLive users No Real user data
Each workspace has its own Site ID, Track API Key, and App API Key. Create workspaces at Settings > Workspace Settings.
Instructions
Step 1: Typed Environment Configuration
import { RegionUS , RegionEU } from "customerio-node" ;
type CioEnvironment = "development" | "ci" | "staging" | "production" ;
interface CioEnvConfig {
siteId : string ;
trackApiKey : string ;
appApiKey : ;
: | ;
: ;
: | | | ;
: ;
}
( ): {
(!config. ) ( );
(!config. ) ( );
(env === && config. ) {
( );
}
(env === && config. ) {
( );
}
}
( ): {
env = (process. . ?? ) ;
region = process. . === ? : ;
: = {
: process. . ?? ,
: process. . ?? ,
: process. . ?? ,
region,
: process. . === ,
: (process. . ) ?? (env === ? : ),
: process. . ?? (env === ? : ),
};
(config, env);
config;
}
string
region
typeof
RegionUS
typeof
RegionEU
dryRun
boolean
logLevel
"debug"
"info"
"warn"
"error"
eventPrefix
string
function
validateConfig
config : CioEnvConfig , env : CioEnvironment
void
if
siteId
throw
new
Error
`Missing CUSTOMERIO_SITE_ID for ${env} `
if
trackApiKey
throw
new
Error
`Missing CUSTOMERIO_TRACK_API_KEY for ${env} `
if
"production"
dryRun
throw
new
Error
"Production cannot be in dry-run mode"
if
"production"
eventPrefix
throw
new
Error
"Production must not use event prefix"
export
function
loadCioConfig
CioEnvConfig
const
env
NODE_ENV
"development"
as
CioEnvironment
const
env
CUSTOMERIO_REGION
"eu"
RegionEU
RegionUS
const
config
CioEnvConfig
siteId
env
CUSTOMERIO_SITE_ID
""
trackApiKey
env
CUSTOMERIO_TRACK_API_KEY
""
appApiKey
env
CUSTOMERIO_APP_API_KEY
""
dryRun
env
CUSTOMERIO_DRY_RUN
"true"
logLevel
env
CUSTOMERIO_LOG_LEVEL
as
any
"production"
"warn"
"debug"
eventPrefix
env
CUSTOMERIO_EVENT_PREFIX
"production"
""
`${env} _`
validateConfig
return
Step 2: Environment-Aware Client
import { TrackClient , APIClient } from "customerio-node" ;
import { loadCioConfig } from "../config/customerio" ;
const config = loadCioConfig ();
export class EnvAwareCioClient {
private track : TrackClient | null ;
private app : APIClient | null ;
constructor ( ) {
if (config.dryRun ) {
this .track = null ;
this .app = null ;
} else {
this .track = new TrackClient (config.siteId , config.trackApiKey , {
region : config.region ,
});
this .app = config.appApiKey
? new APIClient (config.appApiKey , { region : config.region })
: null ;
}
}
async identify (userId : string , attrs : Record <string , any >): Promise <void > {
const prefixedId = config.eventPrefix
? `${config.eventPrefix} ${userId} `
: userId;
const envAttrs = {
...attrs,
_cio_env : process.env .NODE_ENV ,
};
if (config.dryRun ) {
if (config.logLevel === "debug" ) {
console .log (`[CIO DRY RUN] identify: ${prefixedId} ` , envAttrs);
}
return ;
}
await this .track !.identify (prefixedId, envAttrs);
}
async track (userId : string , name : string , data ?: Record <string , any >): Promise <void > {
const prefixedId = config.eventPrefix
? `${config.eventPrefix} ${userId} `
: userId;
const prefixedName = config.eventPrefix
? `${config.eventPrefix} ${name} `
: name;
if (config.dryRun ) {
if (config.logLevel === "debug" ) {
console .log (`[CIO DRY RUN] track: ${prefixedId} ${prefixedName} ` , data);
}
return ;
}
await this .track !.track (prefixedId, { name : prefixedName, data });
}
getAppClient (): APIClient {
if (!this .app ) {
throw new Error ("App API not available (dry-run or missing key)" );
}
return this .app ;
}
}
Step 3: Environment Files
NODE_ENV=development
CUSTOMERIO_SITE_ID=dev-workspace-site-id
CUSTOMERIO_TRACK_API_KEY=dev-track-key
CUSTOMERIO_APP_API_KEY=dev-app-key
CUSTOMERIO_REGION=us
CUSTOMERIO_DRY_RUN=false
CUSTOMERIO_EVENT_PREFIX=dev_
CUSTOMERIO_LOG_LEVEL=debug
NODE_ENV=staging
CUSTOMERIO_SITE_ID=staging-workspace-site-id
CUSTOMERIO_TRACK_API_KEY=staging-track-key
CUSTOMERIO_APP_API_KEY=staging-app-key
CUSTOMERIO_REGION=us
CUSTOMERIO_DRY_RUN=false
CUSTOMERIO_EVENT_PREFIX=staging_
CUSTOMERIO_LOG_LEVEL=info
NODE_ENV=production
CUSTOMERIO_SITE_ID=prod-workspace-site-id
CUSTOMERIO_TRACK_API_KEY=prod-track-key
CUSTOMERIO_APP_API_KEY=prod-app-key
CUSTOMERIO_REGION=us
CUSTOMERIO_DRY_RUN=false
CUSTOMERIO_EVENT_PREFIX=
CUSTOMERIO_LOG_LEVEL=warn
Step 4: Kubernetes ConfigMap Overlays
apiVersion: v1
kind: ConfigMap
metadata:
name: customerio-config
data:
CUSTOMERIO_REGION: "us"
CUSTOMERIO_LOG_LEVEL: "info"
---
apiVersion: v1
kind: ConfigMap
metadata:
name: customerio-config
data:
CUSTOMERIO_DRY_RUN: "true"
CUSTOMERIO_EVENT_PREFIX: "dev_"
CUSTOMERIO_LOG_LEVEL: "debug"
---
apiVersion: v1
kind: ConfigMap
metadata:
name: customerio-config
data:
CUSTOMERIO_DRY_RUN: "false"
CUSTOMERIO_EVENT_PREFIX: "staging_"
CUSTOMERIO_LOG_LEVEL: "info"
---
apiVersion: v1
kind: ConfigMap
metadata:
name: customerio-config
data:
CUSTOMERIO_DRY_RUN: "false"
CUSTOMERIO_EVENT_PREFIX: ""
CUSTOMERIO_LOG_LEVEL: "warn"
Step 5: Data Isolation Verification
import { TrackClient , RegionUS } from "customerio-node" ;
async function verifyIsolation ( ) {
const envs = ["development" , "staging" , "production" ];
const testId = `isolation-test-${Date .now()} ` ;
for (const env of envs) {
const siteId = process.env [`CIO_${env.toUpperCase()} _SITE_ID` ];
const apiKey = process.env [`CIO_${env.toUpperCase()} _TRACK_KEY` ];
if (!siteId || !apiKey) {
console .log (`[SKIP] ${env} : credentials not configured` );
continue ;
}
const client = new TrackClient (siteId, apiKey, { region : RegionUS });
try {
await client.identify (testId, {
email : `${testId} @isolation-test.example.com` ,
_test_env : env,
});
console .log (`[OK] ${env} : identify succeeded (separate workspace)` );
await client.suppress (testId);
await client.destroy (testId);
} catch (err : any ) {
console .log (`[FAIL] ${env} : ${err.statusCode} ${err.message} ` );
}
}
}
verifyIsolation ();
Step 6: CI/CD Environment Promotion
name: Promote to Environment
on:
workflow_dispatch:
inputs:
target_env:
description: "Target environment"
required: true
type: choice
options: [staging , production ]
jobs:
promote:
runs-on: ubuntu-latest
environment: ${{ inputs.target_env }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 20 }
- run: npm ci
- name: Smoke test target environment
env:
CUSTOMERIO_SITE_ID: ${{ secrets.CIO_SITE_ID }}
CUSTOMERIO_TRACK_API_KEY: ${{ secrets.CIO_TRACK_API_KEY }}
run: npx tsx scripts/verify-customerio.ts
- name: Deploy
run: echo "Deploy to ${{ inputs.target_env }} "
Error Handling Issue Solution Wrong workspace credentials Config validation throws on startup — check error message Cross-env data leak Event prefix prevents accidental production triggers Production in dry-run Config validator explicitly blocks this combination Missing env-specific secret Kubernetes ExternalSecrets or CI secret scoping
Resources
Next Steps After multi-env setup, proceed to customerio-observability for monitoring.