Skip to main content

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.

What gets migrated
  • 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/cli or npx envshed ad-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 read role 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.
Do not use a personal Doppler CLI token

Personal tokens have full write access to your workplace. Service account tokens with read scope are the safe choice for a migration.

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:

  1. The CLI lists every Doppler project your token can read.
  2. For each project it fetches every config and every secret.
  3. It creates a matching Envshed project and environment for each Doppler config (or updates it if it already exists).
  4. It pushes the secret values into the right environment, encrypted with AES-256-GCM at rest.
  5. 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 project billing-api
  • Doppler config dev → Envshed environment dev
  • Doppler config dev_personal_alice → Envshed environment dev-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

  1. Rotate any Doppler service tokens you created for the move (Doppler dashboard → Service accounts → revoke).
  2. Update CI: replace doppler run -- <cmd> with envshed run -- <cmd> (see envshed run).
  3. Delete Doppler integrations that now duplicate Envshed (Vercel, Netlify, GitHub Actions — see Integrations).
  4. Let Envshed webhooks take over secret change notifications (see Webhooks).
  5. 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 featureEnvshed 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 engineerEnvshed supports per-env overrides. Give each engineer their own env (e.g. dev-alice) and scope access with project roles.
Audit logEnvshed 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.