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 コミュニティが作成したAIスキルを発見・探索
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
直接コマンドでは確認用 Prompt が省略されます。実行前にソースを確認してください。
npx skills add https://github.com/ComeOnOliver/skillshub --skill customerio-multi-env-setupコマンドは1行のまま表示されます。コピー前に横へスクロールして全体を確認してください。
ローカルで確認しますか?SkillsMP が現在取得できるファイルをダウンロードできます。
Zipをダウンロード ダウンロード中... このリポジトリの他の Skills Review product and feature risk before an AI coding agent starts implementation.
Use Xquik for X data and confirmation-gated X actions: tweet search, user lookup, follower export, media download, monitors, webhooks, MCP, and SDK workflows.
Canton Network open-source ecosystem guide covering DAML SDK, Canton runtime, and Splice applications. Use when working with Canton Network, DAML smart contracts, or building decentralized applications.
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.