Environment Setup Tool
Generate production-ready environment variable files with all configuration extracted from your architecture blueprint.
Perfect for: New project setup, developer onboarding, deployment configuration, secrets management
When to Use This Skill
Use this skill when you need to:
- •Set up environment variables after running
/architect:scaffold - •Onboard new developers with correct configuration
- •Prepare for deployment (staging, production environments)
- •Document all required API keys and secrets
- •Validate environment configuration before running the app
- •Generate Docker/Kubernetes config maps
Input: Architecture blueprint (extracts from Tech Stack, Integrations, Security sections)
Output: .env.example, .env.local, validate-env.sh
Files Generated
1. .env.example
Purpose: Template committed to git, no secrets Content: All required environment variables with placeholder values and comments
# Database Configuration DATABASE_URL="postgresql://user:password@localhost:5432/dbname" DATABASE_POOL_SIZE=10 # Authentication (Clerk) # Get your keys: https://dashboard.clerk.com/ NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY="pk_test_xxx" CLERK_SECRET_KEY="sk_test_xxx" # File Storage (Cloudflare R2) # Get your keys: https://dash.cloudflare.com/ R2_ACCOUNT_ID="your-account-id" R2_ACCESS_KEY_ID="your-access-key" R2_SECRET_ACCESS_KEY="your-secret-key" R2_BUCKET_NAME="your-bucket-name" # Email (Resend) # Get your key: https://resend.com/api-keys RESEND_API_KEY="re_xxx" RESEND_FROM_EMAIL="noreply@yourdomain.com" # Integrations SLACK_WEBHOOK_URL="https://hooks.slack.com/services/xxx" STRIPE_PUBLISHABLE_KEY="pk_test_xxx" STRIPE_SECRET_KEY="sk_test_xxx" STRIPE_WEBHOOK_SECRET="whsec_xxx" # App Configuration NEXT_PUBLIC_APP_URL="http://localhost:3000" NODE_ENV="development" LOG_LEVEL="debug"
2. .env.local
Purpose: Local development secrets, NOT committed to git Content: Same variables with actual values (or instructions to fill in)
# ⚠️ DO NOT COMMIT THIS FILE TO GIT # This file contains your actual secrets for local development # Database Configuration DATABASE_URL="postgresql://postgres:postgres@localhost:5432/myapp_dev" DATABASE_POOL_SIZE=10 # Authentication (Clerk) # TODO: Sign up at https://clerk.com and get your keys NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY="<GET_FROM_CLERK_DASHBOARD>" CLERK_SECRET_KEY="<GET_FROM_CLERK_DASHBOARD>" # File Storage (Cloudflare R2) # TODO: Create R2 bucket at https://dash.cloudflare.com/ R2_ACCOUNT_ID="<GET_FROM_CLOUDFLARE>" R2_ACCESS_KEY_ID="<GET_FROM_CLOUDFLARE>" R2_SECRET_ACCESS_KEY="<GET_FROM_CLOUDFLARE>" R2_BUCKET_NAME="myapp-dev" [... all variables with TODO or default values ...]
3. validate-env.sh
Purpose: Validate all required environment variables are set Content: Shell script that checks each variable and reports missing ones
#!/bin/bash
# Environment Variable Validation Script
# Generated by Architect AI
set -e
MISSING=()
# Function to check if variable is set
check_var() {
VAR_NAME=$1
VAR_VALUE=${!VAR_NAME}
if [ -z "$VAR_VALUE" ] || [[ "$VAR_VALUE" == "<GET_FROM_"* ]]; then
MISSING+=("$VAR_NAME")
fi
}
echo "🔍 Validating environment variables..."
# Database
check_var "DATABASE_URL"
check_var "DATABASE_POOL_SIZE"
# Authentication
check_var "NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY"
check_var "CLERK_SECRET_KEY"
# File Storage
check_var "R2_ACCOUNT_ID"
check_var "R2_ACCESS_KEY_ID"
check_var "R2_SECRET_ACCESS_KEY"
check_var "R2_BUCKET_NAME"
[... check all variables ...]
# Report results
if [ ${#MISSING[@]} -eq 0 ]; then
echo "✅ All environment variables are set!"
exit 0
else
echo "❌ Missing or incomplete environment variables:"
for var in "${MISSING[@]}"; do
echo " - $var"
done
echo ""
echo "See .env.example for details on how to obtain these values."
exit 1
fi
4. .env.production.example (optional)
Purpose: Production environment template Content: Production-specific variables (different URLs, higher limits)
# Production Environment Variables DATABASE_URL="<PRODUCTION_DATABASE_URL>" DATABASE_POOL_SIZE=50 # Higher for production NEXT_PUBLIC_APP_URL="https://yourdomain.com" NODE_ENV="production" LOG_LEVEL="info" # Less verbose than dev # Enable production features ENABLE_ANALYTICS=true ENABLE_ERROR_TRACKING=true SENTRY_DSN="<SENTRY_DSN>"
How It Works
Step 1: Extract Variables from Blueprint
Scan blueprint sections for environment variable requirements:
From Section 3: Tech Stack Decisions
- •Database:
DATABASE_URL,DATABASE_POOL_SIZE - •Caching (if Redis):
REDIS_URL,REDIS_PASSWORD
From Section 6: API Specification
- •
NEXT_PUBLIC_APP_URL - •
API_RATE_LIMIT_PER_MINUTE - •
API_TIMEOUT_MS
From Section 7: Integrations
For each integration detected:
- •Stripe:
STRIPE_PUBLISHABLE_KEY,STRIPE_SECRET_KEY,STRIPE_WEBHOOK_SECRET - •Clerk:
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY,CLERK_SECRET_KEY - •Resend:
RESEND_API_KEY,RESEND_FROM_EMAIL - •Slack:
SLACK_WEBHOOK_URL,SLACK_BOT_TOKEN - •OpenAI:
OPENAI_API_KEY,OPENAI_ORG_ID - •Cloudflare R2:
R2_ACCOUNT_ID,R2_ACCESS_KEY_ID,R2_SECRET_ACCESS_KEY,R2_BUCKET_NAME - •AWS S3:
AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY,AWS_REGION,S3_BUCKET_NAME
From Section 8: Security Architecture
- •
JWT_SECRETorSESSION_SECRET - •
ENCRYPTION_KEY(if encryption used) - •
CORS_ALLOWED_ORIGINS
From Section 9: Deployment & DevOps
- •
NODE_ENV - •
LOG_LEVEL - •
ENABLE_DEBUG - •Monitoring:
SENTRY_DSN,DATADOG_API_KEY
From Product Type Detection
- •Multi-tenant:
DEFAULT_TENANT_ID,TENANT_ISOLATION_MODE - •E-commerce: Payment provider variables
- •AI agents: LLM provider variables
- •Real-time: WebSocket/SSE configuration
Step 2: Categorize Variables
Group variables by category for organization:
# ============================================================================= # DATABASE # ============================================================================= DATABASE_URL="..." DATABASE_POOL_SIZE=10 # ============================================================================= # AUTHENTICATION # ============================================================================= NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY="..." CLERK_SECRET_KEY="..." # ============================================================================= # FILE STORAGE # ============================================================================= [...]
Step 3: Add Comments and Links
For each variable, add:
- •Description: What this variable controls
- •Required: Yes/No
- •Where to get it: Dashboard URL or signup link
- •Example value: Placeholder showing expected format
- •Security level: Public (NEXT_PUBLIC_*), Secret, Internal
Example:
# Clerk Publishable Key (safe to expose in frontend) # Required: Yes # Get it: https://dashboard.clerk.com/ → API Keys # Example: pk_test_Y2xlcmsuZXhhbXBsZS5jb20k NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY="pk_test_xxx" # Clerk Secret Key (NEVER expose in frontend or git) # Required: Yes # Get it: https://dashboard.clerk.com/ → API Keys # Example: sk_test_1234567890abcdef CLERK_SECRET_KEY="sk_test_xxx"
Step 4: Set Default Values
Where applicable, provide sensible defaults:
# Development defaults (can override for production) DATABASE_POOL_SIZE=10 # 10 for dev, 50+ for prod API_RATE_LIMIT_PER_MINUTE=60 # Generous for dev API_TIMEOUT_MS=30000 # 30 seconds LOG_LEVEL="debug" # debug for dev, info for prod NODE_ENV="development" # URLs (update for production) NEXT_PUBLIC_APP_URL="http://localhost:3000"
Step 5: Generate Validation Script
Create validate-env.sh that:
- •Sources
.env.localor current environment - •Checks each required variable is set
- •Checks variables don't have placeholder values (
<GET_FROM_...>) - •Validates format for specific variables (URLs, keys)
- •Reports all missing/invalid variables at once
- •Exits with code 0 (success) or 1 (failure)
Variable format validation:
# Validate DATABASE_URL is a valid PostgreSQL URL if [[ ! "$DATABASE_URL" =~ ^postgresql:// ]]; then echo "⚠️ DATABASE_URL must start with postgresql://" fi # Validate NEXT_PUBLIC_APP_URL is a valid URL if [[ ! "$NEXT_PUBLIC_APP_URL" =~ ^https?:// ]]; then echo "⚠️ NEXT_PUBLIC_APP_URL must start with http:// or https://" fi # Validate Clerk keys have correct prefix if [[ ! "$NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY" =~ ^pk_ ]]; then echo "⚠️ NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY must start with pk_" fi
Step 6: Check .gitignore
Ensure .gitignore includes:
# Environment files with secrets .env.local .env.*.local .env.production # Keep template in git !.env.example
If .gitignore doesn't exist or is missing these entries, add them automatically.
Output Format
When invoked, generate:
🔧 Generating environment configuration... ✅ Extracted 23 environment variables from blueprint - Database: 2 variables - Authentication (Clerk): 2 variables - File Storage (R2): 4 variables - Email (Resend): 2 variables - Integrations (Stripe, Slack): 5 variables - App Configuration: 5 variables - Monitoring (Sentry): 1 variable - Security: 2 variables ✅ Created .env.example (template, safe to commit) ✅ Created .env.local (with TODOs, DO NOT commit) ✅ Created validate-env.sh (validation script) ✅ Updated .gitignore to exclude .env.local 📋 Next steps to configure your environment: 1. Sign up for required services: - Clerk: https://clerk.com (authentication) - Cloudflare: https://cloudflare.com (file storage) - Resend: https://resend.com (email) - Stripe: https://stripe.com (payments) - Sentry: https://sentry.io (error tracking) 2. Get your API keys from each dashboard 3. Fill in .env.local with your actual keys 4. Validate your configuration: chmod +x validate-env.sh ./validate-env.sh 5. Start development: npm run dev 🔒 Security reminders: - NEVER commit .env.local to git - Rotate secrets if accidentally exposed - Use different keys for dev/staging/production
Customization Options
Optional parameters (ask user if they want to customize):
- •Environment type: Development (default), Staging, Production
- •Include optional variables: Yes/No (analytics, monitoring, etc.)
- •Framework-specific: Next.js (default), Remix, Astro, Node.js
- •Output format: Bash (default), Docker Compose, Kubernetes ConfigMap
- •Validation strictness: Basic (default), Strict (validate formats)
Default behavior: Development environment, Next.js format, all variables, basic validation.
Framework-Specific Variables
Next.js
# Next.js specific (NEXT_PUBLIC_* exposed to browser) NEXT_PUBLIC_APP_URL="http://localhost:3000" NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY="pk_test_xxx" # Server-side only (never exposed) CLERK_SECRET_KEY="sk_test_xxx" DATABASE_URL="postgresql://..."
Remix
# Remix specific (loaded via remix.config.js) SESSION_SECRET="your-session-secret-min-32-chars" DATABASE_URL="postgresql://..." # Public variables (explicitly passed to client) APP_URL="http://localhost:3000"
Astro
# Astro specific (PUBLIC_* exposed to browser) PUBLIC_APP_URL="http://localhost:3000" PUBLIC_CLERK_KEY="pk_test_xxx" # Server-side only CLERK_SECRET_KEY="sk_test_xxx"
Node.js / Express
# Standard Node.js PORT=3000 NODE_ENV="development" DATABASE_URL="postgresql://..." JWT_SECRET="your-jwt-secret"
Docker Compose Integration
Generate docker-compose.yml environment section:
version: '3.8'
services:
app:
image: myapp:latest
env_file:
- .env.local
environment:
# Override specific variables
DATABASE_URL: postgresql://db:5432/myapp
REDIS_URL: redis://redis:6379
depends_on:
- db
- redis
db:
image: postgres:15
environment:
POSTGRES_DB: myapp
POSTGRES_USER: postgres
POSTGRES_PASSWORD: ${DB_PASSWORD:-postgres}
redis:
image: redis:7-alpine
Kubernetes ConfigMap/Secret
Generate Kubernetes manifests:
configmap.yaml (non-sensitive values):
apiVersion: v1 kind: ConfigMap metadata: name: myapp-config data: NODE_ENV: "production" LOG_LEVEL: "info" DATABASE_POOL_SIZE: "50" NEXT_PUBLIC_APP_URL: "https://myapp.com"
secret.yaml (sensitive values):
apiVersion: v1 kind: Secret metadata: name: myapp-secrets type: Opaque stringData: DATABASE_URL: "<BASE64_ENCODED>" CLERK_SECRET_KEY: "<BASE64_ENCODED>" STRIPE_SECRET_KEY: "<BASE64_ENCODED>" JWT_SECRET: "<BASE64_ENCODED>"
Validation Features
Basic Validation (Default)
- •Check all required variables are set
- •Check no placeholder values remain (
<GET_FROM_...>) - •Report missing variables
Strict Validation (Optional)
- •Validate URL formats (http://, https://)
- •Validate key prefixes (pk_, sk_, re_, etc.)
- •Validate numeric values (pool size > 0)
- •Validate enum values (NODE_ENV in [development, staging, production])
- •Validate JWT_SECRET length (min 32 characters)
- •Check for common security issues (weak secrets, exposed tokens)
Example strict validation:
# Check JWT_SECRET is strong enough
if [ ${#JWT_SECRET} -lt 32 ]; then
echo "❌ JWT_SECRET must be at least 32 characters long"
echo " Current length: ${#JWT_SECRET}"
echo " Generate a strong secret: openssl rand -base64 48"
fi
# Check CORS_ALLOWED_ORIGINS doesn't allow all
if [[ "$CORS_ALLOWED_ORIGINS" == "*" ]] && [[ "$NODE_ENV" == "production" ]]; then
echo "❌ CORS_ALLOWED_ORIGINS='*' is dangerous in production"
echo " Use specific origins instead"
fi
Security Best Practices
Included in Generated Files
- •Clear secret markings:
# ⚠️ SECRET - Never expose in frontend or commit to git CLERK_SECRET_KEY="sk_test_xxx" # ✅ PUBLIC - Safe to expose in frontend NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY="pk_test_xxx"
- •Rotation reminders:
# Rotate this secret every 90 days # Last rotated: 2026-02-07 JWT_SECRET="..."
- •Environment separation:
# Use different values for dev/staging/production # Development: sk_test_xxx # Production: sk_live_xxx STRIPE_SECRET_KEY="sk_test_xxx"
- •Git commit prevention:
# Add to .gitignore: .env.local .env.*.local .env.production # Pre-commit hook to catch accidental commits: git diff --cached --name-only | grep -E "\.env\.local"
Error Handling
If blueprint section missing:
- •Action: Use defaults for that category
- •Notify user: "ℹ️ No integrations detected, skipping Stripe/Slack variables"
If .gitignore already has .env entries:
- •Action: Skip adding duplicates
- •Notify user: "✅ .gitignore already configured for environment files"
If .env.local already exists:
- •Action: Ask user before overwriting
- •Options: "1) Backup and overwrite, 2) Merge new variables, 3) Cancel"
If validation script fails:
- •Action: Report all missing variables with links to obtain them
- •Example: "Missing CLERK_SECRET_KEY - get it at https://dashboard.clerk.com/"
Integration with Other Skills
Recommended workflow:
# 1. Generate blueprint /architect:blueprint # 2. Scaffold project structure /architect:scaffold # 3. Setup environment variables /architect:setup-env # 4. Validate environment chmod +x validate-env.sh ./validate-env.sh # 5. Start development npm run dev
Success Criteria
A successful environment setup should:
- •✅ Include all variables required by the blueprint
- •✅ Categorize variables logically (Database, Auth, etc.)
- •✅ Provide clear comments and links for each variable
- •✅ Include sensible defaults where applicable
- •✅ Create validation script that catches missing values
- •✅ Update .gitignore to prevent secret leakage
- •✅ Distinguish public vs secret variables clearly
- •✅ Support both development and production environments
- •✅ Be framework-aware (Next.js, Remix, etc.)
- •✅ Pass validation script on first run (with TODOs)
Examples
Example 1: Basic Setup
/architect:setup-env # Output: # ✅ Created .env.example (23 variables) # ✅ Created .env.local (ready to fill in) # ✅ Created validate-env.sh
Example 2: Production Environment
/architect:setup-env --env=production # Output: # ✅ Created .env.production.example # ✅ Higher resource limits (pool size: 50) # ✅ Production-ready defaults (LOG_LEVEL=info)
Example 3: Docker Compose
/architect:setup-env --format=docker # Output: # ✅ Created docker-compose.yml with env_file # ✅ Created .env for Docker Compose
Example 4: Kubernetes
/architect:setup-env --format=kubernetes # Output: # ✅ Created k8s/configmap.yaml # ✅ Created k8s/secret.yaml (with TODOs)