environment-setup
Configure and manage development, staging, and production environments. Use when setting up environment variables, managing configurations, or separating environments. Handles .env files, config management, and environment-specific settings.
What this skill does
# Environment Configuration ## When to use this skill - **New Projects**: Initial environment setup - **Multiple Environments**: Separate dev, staging, production - **Team Collaboration**: Share consistent environments ## Instructions ### Step 1: .env File Structure **.env.example** (template): ```bash # Application NODE_ENV=development PORT=3000 APP_URL=http://localhost:3000 # Database DATABASE_URL=postgresql://user:password@localhost:5432/myapp DATABASE_POOL_MIN=2 DATABASE_POOL_MAX=10 # Redis REDIS_URL=redis://localhost:6379 REDIS_TTL=3600 # Authentication JWT_ACCESS_SECRET=change-me-in-production-min-32-characters JWT_REFRESH_SECRET=change-me-in-production-min-32-characters JWT_ACCESS_EXPIRY=15m JWT_REFRESH_EXPIRY=7d # Email SMTP_HOST=smtp.gmail.com SMTP_PORT=587 [email protected] SMTP_PASSWORD=your-app-password # External APIs STRIPE_SECRET_KEY=sk_test_xxx STRIPE_PUBLISHABLE_KEY=pk_test_xxx AWS_ACCESS_KEY_ID=AKIAXXXXXXXX AWS_SECRET_ACCESS_KEY=xxxxxxxx AWS_REGION=us-east-1 AWS_S3_BUCKET=myapp-uploads # Monitoring SENTRY_DSN=https://[email protected]/xxx LOG_LEVEL=info # Feature Flags ENABLE_2FA=false ENABLE_ANALYTICS=true ``` **.env.local** (per developer): ```bash # Developer personal settings (add to .gitignore) DATABASE_URL=postgresql://localhost:5432/myapp_dev LOG_LEVEL=debug ``` **.env.production**: ```bash NODE_ENV=production PORT=8080 APP_URL=https://myapp.com DATABASE_URL=${DATABASE_URL} # Injected from environment variables REDIS_URL=${REDIS_URL} JWT_ACCESS_SECRET=${JWT_ACCESS_SECRET} JWT_REFRESH_SECRET=${JWT_REFRESH_SECRET} LOG_LEVEL=warn ENABLE_2FA=true ``` ### Step 2: Type-Safe Environment Variables (TypeScript) **config/env.ts**: ```typescript import { z } from 'zod'; import dotenv from 'dotenv'; // Load .env file dotenv.config(); // Define schema const envSchema = z.object({ NODE_ENV: z.enum(['development', 'production', 'test']), PORT: z.coerce.number().default(3000), DATABASE_URL: z.string().url(), JWT_ACCESS_SECRET: z.string().min(32), JWT_REFRESH_SECRET: z.string().min(32), SMTP_HOST: z.string(), SMTP_PORT: z.coerce.number(), SMTP_USER: z.string().email(), SMTP_PASSWORD: z.string(), STRIPE_SECRET_KEY: z.string().startsWith('sk_'), LOG_LEVEL: z.enum(['error', 'warn', 'info', 'debug']).default('info'), }); // Validate and export export const env = envSchema.parse(process.env); // Usage: // import { env } from './config/env'; // console.log(env.DATABASE_URL); // Type-safe! ``` **Error Handling**: ```typescript try { const env = envSchema.parse(process.env); } catch (error) { if (error instanceof z.ZodError) { console.error('❌ Invalid environment variables:'); error.errors.forEach((err) => { console.error(` - ${err.path.join('.')}: ${err.message}`); }); process.exit(1); } } ``` ### Step 3: Per-Environment Config Files **config/index.ts**: ```typescript interface Config { env: string; port: number; database: { url: string; pool: { min: number; max: number }; }; jwt: { accessSecret: string; refreshSecret: string; accessExpiry: string; refreshExpiry: string; }; features: { enable2FA: boolean; enableAnalytics: boolean; }; } const config: Config = { env: process.env.NODE_ENV || 'development', port: parseInt(process.env.PORT || '3000'), database: { url: process.env.DATABASE_URL!, pool: { min: parseInt(process.env.DATABASE_POOL_MIN || '2'), max: parseInt(process.env.DATABASE_POOL_MAX || '10'), }, }, jwt: { accessSecret: process.env.JWT_ACCESS_SECRET!, refreshSecret: process.env.JWT_REFRESH_SECRET!, accessExpiry: process.env.JWT_ACCESS_EXPIRY || '15m', refreshExpiry: process.env.JWT_REFRESH_EXPIRY || '7d', }, features: { enable2FA: process.env.ENABLE_2FA === 'true', enableAnalytics: process.env.ENABLE_ANALYTICS !== 'false', }, }; // Validate required fields const requiredEnvVars = [ 'DATABASE_URL', 'JWT_ACCESS_SECRET', 'JWT_REFRESH_SECRET', ]; for (const envVar of requiredEnvVars) { if (!process.env[envVar]) { throw new Error(`Missing required environment variable: ${envVar}`); } } export default config; ``` ### Step 4: Environment-Specific Configuration Files **config/environments/development.ts**: ```typescript export default { logging: { level: 'debug', prettyPrint: true, }, cors: { origin: '*', credentials: true, }, rateLimit: { enabled: false, }, }; ``` **config/environments/production.ts**: ```typescript export default { logging: { level: 'warn', prettyPrint: false, }, cors: { origin: process.env.ALLOWED_ORIGINS?.split(',') || [], credentials: true, }, rateLimit: { enabled: true, windowMs: 15 * 60 * 1000, max: 100, }, }; ``` **config/index.ts** (unified): ```typescript import development from './environments/development'; import production from './environments/production'; const env = process.env.NODE_ENV || 'development'; const configs = { development, production, test: development, }; export const environmentConfig = configs[env]; ``` ### Step 5: Docker Environment Variables **docker-compose.yml**: ```yaml version: '3.8' services: app: build: . environment: - NODE_ENV=development - DATABASE_URL=postgresql://postgres:password@db:5432/myapp - REDIS_URL=redis://redis:6379 env_file: - .env.local depends_on: - db - redis db: image: postgres:15-alpine environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: password POSTGRES_DB: myapp redis: image: redis:7-alpine ``` ## Output format ``` project/ ├── .env.example # Template (commit) ├── .env # Local (gitignore) ├── .env.local # Per developer (gitignore) ├── .env.production # Production (gitignore or vault) ├── config/ │ ├── index.ts # Main configuration │ ├── env.ts # Environment variable validation │ └── environments/ │ ├── development.ts │ ├── production.ts │ └── test.ts └── .gitignore ``` **.gitignore**: ``` .env .env.local .env.*.local .env.production ``` ## Constraints ### Required Rules (MUST) 1. **Provide .env.example**: List of required environment variables 2. **Validation**: Error when required environment variables are missing 3. **.gitignore**: Never commit .env files ### Prohibited (MUST NOT) 1. **Commit Secrets**: Never commit .env files 2. **Hardcoding**: Do not hardcode environment-specific settings in code ## Best practices 1. **12 Factor App**: Manage configuration via environment variables 2. **Type Safety**: Runtime validation with Zod 3. **Secrets Management**: Use AWS Secrets Manager, Vault ## References - [dotenv](https://github.com/motdotla/dotenv) - [Zod](https://zod.dev/) - [12 Factor App - Config](https://12factor.net/config) ## Metadata ### Version - **Current Version**: 1.0.0 - **Last Updated**: 2025-01-01 - **Compatible Platforms**: Claude, ChatGPT, Gemini ### Tags `#environment` `#configuration` `#env-variables` `#dotenv` `#config-management` `#utilities` ## Examples ### Example 1: Basic usage <!-- Add example content here --> ### Example 2: Advanced usage <!-- Add advanced example content here -->
Related in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.