This project uses dotenvx for secure environment variable management with encryption support.
- Development:
.env(unencrypted, local only) - Staging:
.env.staging(encrypted) - Production:
.env.production(encrypted) - Keys:
.env.keys(private decryption keys - NEVER commit)
npm install -D dotenvx
# or globally
npm install -g dotenvxdotenvx keygenThis generates a base64-encoded private key. Save it somewhere secure.
cp .env.example .env
# Edit .env with your local development values
nano .env# Create .env.staging with your staging values
dotenvx set TELEGRAM_BOT_TOKEN "your_staging_token" -f .env.staging
dotenvx set PLAID_CLIENT_ID "your_staging_plaid_id" -f .env.staging
dotenvx set PLAID_SECRET "your_staging_plaid_secret" -f .env.staging
dotenvx set DATABASE_URL "postgresql://staging_user:pass@staging-host:5432/db" -f .env.staging
# ... add other variablesdotenvx set TELEGRAM_BOT_TOKEN "your_production_token" -f .env.production
dotenvx set PLAID_CLIENT_ID "your_production_plaid_id" -f .env.production
dotenvx set PLAID_SECRET "your_production_plaid_secret" -f .env.production
dotenvx set DATABASE_URL "postgresql://prod_user:pass@prod-host:5432/db" -f .env.production
# ... add other variablesCreate .env.keys locally (NEVER commit):
# .env.keys
DOTENV_PRIVATE_KEY_STAGING="your_staging_key_from_keygen"
DOTENV_PRIVATE_KEY_PRODUCTION="your_production_key_from_keygen"Add to .gitignore ✓ (already configured)
# Load and display variables (redacted)
dotenvx ls
# Test with Node.js
dotenvx run -- node -e "console.log(process.env.TELEGRAM_BOT_TOKEN)"npm run dev
# or with dotenvx explicitly
dotenvx run -- npm run devDOTENV_PRIVATE_KEY_STAGING="your_key" dotenvx run -f .env.staging -- npm startDOTENV_PRIVATE_KEY_PRODUCTION="your_key" dotenvx run -f .env.production -- npm start-
Store Private Keys as GitHub Secrets:
- Go to: Settings → Secrets and variables → Actions
- Add:
DOTENV_PRIVATE_KEY_PRODUCTION - Add:
DOTENV_PRIVATE_KEY_STAGING
-
Use in Workflows:
name: Deploy to Production
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
- name: Install dependencies
run: npm ci
- name: Build
env:
DOTENV_PRIVATE_KEY_PRODUCTION: ${{ secrets.DOTENV_PRIVATE_KEY_PRODUCTION }}
run: dotenvx run -f .env.production -- npm run build
- name: Deploy
env:
DOTENV_PRIVATE_KEY_PRODUCTION: ${{ secrets.DOTENV_PRIVATE_KEY_PRODUCTION }}
run: dotenvx run -f .env.production -- npm start✅ DO:
- Store
.env.keyssecurely (password manager, vault, etc.) - Rotate encryption keys regularly
- Use different keys for each environment
- Restrict access to
.env.keysin your local environment - Document which team members have access to which environments
- Review
.env.*files before committing (they're encrypted)
❌ DON'T:
- Commit
.env.keysto version control - Share private keys via email or chat
- Use the same key for multiple environments
- Store keys in code comments
- Commit unencrypted
.envfiles with real secrets
- Ensure the private key is set in environment or
.env.keys - Verify the key format (base64)
- Check environment variable name matches file name (PRODUCTION, STAGING, etc.)
# Debug: Check which file is being loaded
dotenvx ls -f .env.production
# Verbose output
dotenvx run -f .env.production --debug -- node index.js# Generate new key (old encrypted values become unreadable)
dotenvx keygen
# Re-encrypt .env files with new key
dotenvx set VAR_NAME "value" -f .env.production