How to overwrite doppler envs?

(I’m using react/node with nextjs for my projects)

Let’s say I have an env variable called base_url which points to an API hosted at mycompany.com/api

This works for most people but let’s say a backend developer needs to debug some specific quirks and they want to run the site locally while connecting to an API also running locally.

So they just need to change the base_url to http://localhost:3000/api or something.

So I’d like to know if it’s possible to overrule doppler envs locally? I tried using .env files but this doens’t seem to work.

Hey @bothrs-dev and welcome to the Doppler community!

Branch configs would be my recommended approach for developer-specific overrides, but it sounds like what you’re after is the ----preserve-env option for doppler run which will favor a locally defined environment variable over a secret in Doppler.

Let me know how you go in any case!

I can’t find anything about the preserve-env option in the docs. How do I used it?

doppler run -- yarn dev ----preserve-env or how

1 Like

Yeah, we need to add more comprehensive docs for our CLI, sorry about that.

Usage is doppler run --preserve-env -- your-command here.

You can get a bit more info from the CLI if you add in the --help flag. It’ll print all available options and what each does.

$ doppler run --help
Run a command with secrets injected into the environment

To view the CLI's active configuration, run `doppler configure debug`

Usage:
  doppler run [command] [flags]
  doppler run [command]

Examples:
doppler run -- YOUR_COMMAND --YOUR-FLAG
doppler run --command "YOUR_COMMAND && YOUR_OTHER_COMMAND"

Available Commands:
  clean       Delete old fallback files

Flags:
      --command string             command to execute (e.g. "echo hi")
  -c, --config string              config (e.g. dev)
      --fallback string            path to the fallback file. encrypted secrets are written to this file after each successful fetch. secrets will be read from this file if subsequent connections are unsuccessful.
      --fallback-only              read all secrets directly from the fallback file, without contacting Doppler. secrets will not be updated. (implies --fallback-readonly)
      --fallback-readonly          disable modifying the fallback file. secrets can still be read from the file.
      --forward-signals            forward signals to the child process (defaults to false when STDOUT is a TTY)
  -h, --help                       help for run
      --no-cache                   disable using the fallback file to speed up fetches. the fallback file is only used when the API indicates that it's still current.
      --no-exit-on-write-failure   do not exit if unable to write the fallback file
      --no-fallback                disable reading and writing the fallback file (implies --no-cache)
      --passphrase string          passphrase to use for encrypting the fallback file. the default passphrase is computed using your current configuration.
      --preserve-env               ignore any Doppler secrets that are already defined in the environment. this has potential security implications, use at your own risk.
  -p, --project string             project (e.g. backend)

Global Flags:
      --api-host string         The host address for the Doppler API (default "https://api.doppler.com")
      --configuration string    config file (default "/Users/user/.doppler/.doppler.yaml")
      --dashboard-host string   The host address for the Doppler Dashboard (default "https://dashboard.doppler.com")
      --debug                   output additional information
      --json                    output json
      --no-check-version        disable checking for Doppler CLI updates
      --no-read-env             do not read config from the environment
      --no-timeout              disable http timeout
      --no-verify-tls           do not verify the validity of TLS certificates on HTTP requests (not recommended)
      --print-config            output active configuration
      --scope string            the directory to scope your config to (default ".")
      --silent                  disable output of info messages
      --timeout duration        max http request duration (default 10s)
  -t, --token string            doppler token

Use "doppler run [command] --help" for more information about a command.

Hey there, I used preserve-env and it logs a message stating that it would work… however.

If you are using something like dotenv to load env files… it won’t work.

Because I’m loading the env variables after starting the command, doppler will still inject everything.

Do you have some workaround for this problem?

Hey @bothrs-dev you can work around this issue by overriding the variables Doppler injects with this code:

const fs = require('fs')
const dotenv = require('dotenv')
const envConfig = dotenv.parse(fs.readFileSync('.env.override'))
for (const k in envConfig) {
  process.env[k] = envConfig[k]
}

Reference: GitHub - motdotla/dotenv: Loads environment variables from .env for nodejs projects.

Hey, just in case anyone is reading this now and needs to find a way for this to work with dotenv. I solved the above issue with dotenv without having to do any additional configuration and allows you to keep a standard .env file or whatever you want to name it.

    "dev:local": "run-s doppler:setup:local doppler:local",
    "doppler:local": "dotenv -e .env -- doppler run next dev --preserve-env",
    "doppler:setup:local": "doppler setup -p series-app -c dev_local",

The order of operations is to:

  1. Setup the doppler environment first
  2. Inject your local .env after
  3. Run doppler with the --preserve-env flag
  • Just to note we’re using next here but the above should work for any framework/raw react
  • packages needed: npm-run-all dotenv dotenv-cli
1 Like