beginner12 minutesevnx v0.2.1+

Migrate to Platform Secret Stores

Migrate .env secrets to Doppler, Infisical, Azure Key Vault, Vercel, Heroku, or Railway using evnx migrate.

Migrate to Platform Secret Stores

For six destinations — Doppler, Infisical, Azure Key Vault, Vercel, Heroku, and Railway — evnx generates CLI commands you review and run. None of these destinations need evnx to hold platform credentials; evnx only knows your .env file.


Doppler

Doppler stores secrets in projects and configs. evnx generates one doppler secrets set command per variable.

What evnx generates

Bash
doppler secrets set DATABASE_URL='postgres://user:pass@host:5432/db'
doppler secrets set STRIPE_SECRET_KEY='sk_live_…'

If --project and --doppler-config are supplied, a --config flag is added:

Bash
doppler secrets set --project myapp --config prd DATABASE_URL='postgres://…'

Requirements

  • Doppler CLI installed: docs.doppler.com/docs/cli
  • Logged in (doppler login) and a project already created in the Doppler dashboard

Usage

Bash
# Interactive — evnx asks for project and config
evnx migrate --to doppler

# Non-interactive
evnx migrate \
  --to doppler \
  --project myapp \
  --doppler-config prd \
  --exclude "*_LOCAL"
Bash
# Pipe and run
evnx migrate \
  --to doppler \
  --project myapp \
  --doppler-config prd \
  > doppler-upload.sh && bash doppler-upload.sh

After migration

Replace your .env-based start command with doppler run:

Bash
# Before
node server.js

# After
doppler run -- node server.js

Infisical

Infisical works identically to Doppler from evnx's perspective — one infisical secrets set command per variable.

What evnx generates

Bash
infisical secrets set DATABASE_URL='postgres://user:pass@host:5432/db'
infisical secrets set STRIPE_SECRET_KEY='sk_live_…'

If project and environment are supplied:

Bash
infisical secrets set \
  --projectId abc123 \
  --env prod \
  DATABASE_URL='postgres://…'

Requirements

Usage

Bash
evnx migrate \
  --to infisical \
  --project abc123 \
  --infisical-env prod \
  --exclude "*_LOCAL,*_TEST"

After migration

Bash
infisical run -- node server.js

Azure Key Vault

Azure Key Vault stores secrets individually, and does not allow underscores in secret names.

What evnx generates

evnx converts every _ to - in key names and prints one az keyvault secret set per variable:

Bash
az keyvault secret set --vault-name my-vault --name DATABASE-URL --value 'postgres://…'
az keyvault secret set --vault-name my-vault --name STRIPE-SECRET-KEY --value 'sk_live_…'

It also prints a rename log so you can see which keys were changed:

Key renames applied:
  DATABASE_URL → DATABASE-URL
  STRIPE_SECRET_KEY → STRIPE-SECRET-KEY

Key names are transformed. Any code that reads DATABASE_URL from your .env must be updated to read DATABASE-URL from Key Vault, or use an alias/mapping layer in your application.

Requirements

Usage

Bash
# Interactive — evnx asks for vault name
evnx migrate --to azure-keyvault

# Non-interactive
evnx migrate \
  --to azure-keyvault \
  --vault-name my-vault \
  --exclude "*_LOCAL"
Bash
evnx migrate \
  --to azure \
  --vault-name my-vault \
  > azure-upload.sh && bash azure-upload.sh

Minimum permissions

The user or service principal running the commands needs:

  • Key Vault Secrets Officer role on the vault — for creating and updating secrets
  • Or Key Vault Contributor at the resource group level

Vercel

Vercel stores environment variables per project and environment. evnx generates one vercel env add command per variable using a heredoc so the value is passed through stdin rather than appearing in shell history.

What evnx generates

Bash
vercel env add DATABASE_URL production <<'EOF'
postgres://user:pass@host:5432/db
EOF

vercel env add STRIPE_SECRET_KEY production <<'EOF'
sk_live_…
EOF

All secrets are added to the production environment by default.

Requirements

  • Vercel CLI installed: npm install -g vercel
  • Logged in (vercel login)
  • Project linked (vercel link) or --vercel-project supplied

Usage

Bash
evnx migrate \
  --to vercel \
  --vercel-project my-project-id \
  --exclude "*_LOCAL,*_TEST"

After migration

Bash
# Verify secrets were set
vercel env pull .env.local

# Redeploy
vercel --prod

Heroku

Heroku uses config vars (environment variables) set per app. evnx generates a single bulk heroku config:set command — one command triggers one dyno restart, rather than one restart per variable.

What evnx generates

Bash
heroku config:set \
  --app my-app \
  DATABASE_URL='postgres://user:pass@host:5432/db' \
  STRIPE_SECRET_KEY='sk_live_…' \
  REDIS_URL='redis://localhost:6379/0'

Requirements

Usage

Bash
# Interactive — evnx asks for app name
evnx migrate --to heroku

# Non-interactive
evnx migrate \
  --to heroku \
  --heroku-app my-app \
  --exclude "*_LOCAL,*_TEST"
Bash
evnx migrate --to heroku --heroku-app my-app | bash

After migration

Bash
# Verify
heroku config --app my-app

# The dyno restarts automatically after config:set

Railway

Railway stores environment variables per project and service. evnx generates a single railway variables set command.

What evnx generates

Bash
railway variables set \
  DATABASE_URL='postgres://user:pass@host:5432/db' \
  STRIPE_SECRET_KEY='sk_live_…'

If --railway-project is supplied, a --projectId flag is added.

Requirements

  • Railway CLI installed: npm install -g @railway/cli
  • Logged in (railway login)
  • Project linked (railway link) or --railway-project supplied

Usage

Bash
# Interactive
evnx migrate --to railway

# Non-interactive
evnx migrate \
  --to railway \
  --railway-project my-project-id \
  --exclude "*_LOCAL"

After migration

Bash
# 1. Verify
railway variables

# 2. Deploy
railway up

Choosing the right platform

If you want…Use
A dedicated secret manager with audit logs and role-based accessDoppler or Infisical
Azure infrastructure already in useAzure Key Vault
Frontend / serverless deployments on VercelVercel
Existing Heroku applicationHeroku
Railway-hosted servicesRailway
Full cloud provider integration (IAM, KMS)AWS or GCP (see separate guides)

See also