Migrate from Doppler to Envshed
You already decided to leave Doppler. This guide gets you fully moved in under fifteen minutes — with audit-friendly exports, a dry-run, and a one-command importer that mirrors your Doppler project/config layout into Envshed.
- Every Doppler project → an Envshed project (slug is your Doppler project name, lowercased and hyphenated)
- Every Doppler config (
dev,stg,prd,dev_personal, ...) → an Envshed environment inside that project - Every secret value, per config
Doppler-only features that do not migrate: inherited configs (Envshed stores resolved values per env), Doppler personal references (${project.secret}), and Doppler integrations (sync destinations). Resolved values are imported as-is, so your apps keep booting.
Prerequisites
- Envshed CLI installed (
npm i -g @envshed/cliornpx envshedad-hoc). See Installation. - An Envshed account and a target org. See Quickstart.
- A Doppler Service Account token with read access across the projects you want to move. Generate it in Doppler at Dashboard → Workplace settings → Service accounts → New service account. Give it the
readrole on the projects you care about. Service tokens scoped to a single config (dp.st.<config>.<token>) also work, but they only migrate that one config.
Personal tokens have full write access to your workplace. Service account tokens with read scope are the safe choice for a migration.
Option A — One-command migration (recommended)
Log in to Envshed, point the CLI at an org, and run the import:
envshed login
envshed import --from doppler --token dp.sa.xxxxxxxxxxxxxxxxxxxxxxxxxxxx --org my-org
What happens:
- The CLI lists every Doppler project your token can read.
- For each project it fetches every config and every secret.
- It creates a matching Envshed project and environment for each Doppler config (or updates it if it already exists).
- It pushes the secret values into the right environment, encrypted with AES-256-GCM at rest.
- It prints a summary:
X projects, Y environments, Z secrets imported.
Preview before writing
Add --dry-run to see the full plan without creating or modifying anything:
envshed import --from doppler --token dp.sa.xxxx --org my-org --dry-run
Output:
Dopplers projects found: 3
backend → my-org/backend (3 configs: dev, stg, prd)
frontend → my-org/frontend (2 configs: dev, prd)
worker → my-org/worker (1 config: prd)
Total: 3 projects, 6 environments, 214 secrets
No changes written (--dry-run).
Scope the migration to one project
Pass --doppler-project to migrate a single Doppler project. The envshed project slug defaults to the same name — override it with --project:
envshed import --from doppler \
--token dp.sa.xxxx \
--org my-org \
--doppler-project backend \
--project api-backend
Name mapping
- Doppler project
billing-api→ Envshed projectbilling-api - Doppler config
dev→ Envshed environmentdev - Doppler config
dev_personal_alice→ Envshed environmentdev-personal-alice(underscores become hyphens, lowercased)
Pass --config-map 'prd=production,stg=staging' to rename configs during import.
Conflict handling
If the target Envshed project/env already has secrets, the CLI prints the diff and asks before overwriting — same behavior as envshed import <file>. Pass --force to skip the prompt.
Option B — Export then import (works today, before the one-command flow ships)
If your Envshed CLI is older than v0.12 or you prefer to review the dump before pushing, use Doppler's native exporter:
# 1. Authenticate the Doppler CLI (one-time)
doppler login
# 2. Export one config to a .env file
doppler secrets download \
--project backend \
--config prd \
--format env \
--no-file > backend-prd.env
# 3. Import into Envshed
envshed import backend-prd.env \
--org my-org \
--project backend \
--env prd
Repeat step 2 + 3 for every project/config pair you want to migrate. A one-liner for all configs of a single project:
for cfg in $(doppler configs --project backend --json | jq -r '.[].name'); do
doppler secrets download --project backend --config "$cfg" --format env --no-file \
| envshed import /dev/stdin --format env --org my-org --project backend --env "$cfg"
done
Clean up the dump
Never commit exported .env files. If you wrote them to disk:
shred -u backend-*.env # Linux
rm -P backend-*.env # macOS (BSD)
After the migration
- Rotate any Doppler service tokens you created for the move (Doppler dashboard → Service accounts → revoke).
- Update CI: replace
doppler run -- <cmd>withenvshed run -- <cmd>(see envshed run). - Delete Doppler integrations that now duplicate Envshed (Vercel, Netlify, GitHub Actions — see Integrations).
- Let Envshed webhooks take over secret change notifications (see Webhooks).
- Keep Doppler alive for one release cycle as a read-only fallback, then cancel.
Troubleshooting
401 Unauthorized from Doppler
Your token is wrong, expired, or scoped to a single config. Regenerate a Service Account token with read on the projects you need.
Too many requests during import
Doppler's API is rate-limited. The CLI backs off automatically; on repeated failures rerun with --doppler-project to migrate one project at a time.
Config names with characters Envshed rejects
Envshed environment slugs are ^[a-z0-9]+(?:-[a-z0-9]+)*$. The importer lowercases and replaces underscores/spaces with hyphens. If a config still fails validation, pass --config-map 'weird name=clean-name'.
I need to migrate back out
Envshed never locks you in. Run envshed pull --format env to dump a plain .env for any environment — see envshed pull. envshed export dumps the full JSON across projects.
What about Doppler-only features?
| Doppler feature | Envshed equivalent |
|---|---|
Config inheritance (dev inherits dev_base) | Import resolves the effective value per config. Re-create shared values in a parent Envshed env if you want the same pattern (on the roadmap). |
Secret references ${project.secret} | Resolved at export time; Envshed stores the concrete value. |
| Doppler integrations (sync → Vercel / AWS / etc.) | Replace with Envshed's native integrations — see Vercel, GitHub Actions, Kubernetes. |
| Personal configs per engineer | Envshed supports per-env overrides. Give each engineer their own env (e.g. dev-alice) and scope access with project roles. |
| Audit log | Envshed audit log on the Team plan. Every secret read/write is recorded with actor, IP, and timestamp. |
Questions the guide did not cover? Email support@envshed.com and we'll unblock you — migrations are our highest-priority thread.