Doppler: The Docker of Environment Variables
By Manthan Mallikarjun, Published almost 4 years ago
Since this article was written, the pricing has changed. We have switched to Infisical, a very similar open-source drop-in replacement for Doppler
We have been working on a few projects and the one tool that we always set up first is Doppler. Doppler makes it easy to load your environment variables seamlessly into any context, which means you don't need to redefine the same environment variables on your local machines, Github Actions, CircleCI, Heroku, Netlify, etc., over and over again!
We specifically use Doppler in our local development environment, in all of our Github Actions, in Vercel, and in our Docker containers (which are pushed to render). It is quite refreshing to not have to define and manage the environment variables in 4+ different contexts.
Normally we only talk about open source projects, but Doppler has been such an amazing tool to work with that we felt the need to share it. They have a pretty good free plan if you would like to give it a shot!
Setup
To get started, go ahead and create an account on Doppler. They have a very generous free plan which should cover most of your use cases. After creating an account, set up the cli, and create a project.
By default you should have three environments, dev
, stg
, and prd
. You can easily delete the environments you don't want and add new custom environments. We currently do not have a staging environment but do have a custom "CI" environment, so our setup usually looks something like this:
dev
contains values that allow us to work on our laptops such as sandboxed tokens and dummy data.ci
contains a subset of the production variables that are needed in the CI. For example, we need theDATABASE_URL
to run migrations, but we don't needJOBS_REDIS_URL
orSTRIPE_TOKEN
since those are more runtime related variables.prd
contains all of our production variables
Using in a Docker Container
Using Doppler in a Docker container is super easy. Setting the ENTRYPOINT
to Doppler will make sure any commands you run afterward will use the environment variables.
EXPOSE 5000
ENTRYPOINT ["doppler", "run", "--"]
CMD ["npm", "start"]
When you run your container, make sure to pass in a DOPPLER_TOKEN
as an environment variable so Doppler can load your variables. Check out their Docker docs for more information.
An additional bonus is that when you set ENTRYPOINT
, it prefixes every command. That means that if you SSH into your container at a later date and run a command, they will automatically contain the correct environment variables.
Deploying Via Github Actions
We extensively use Doppler in our Github Actions. The first thing we do in every action is define the Doppler token at the top as a global env (don't forget to set up Github in the Doppler Integrations settings):
name: main
on: [push]
env:
DOPPLER_TOKEN: ${{ secrets.DOPPLER_TOKEN }}
This allows any of the underlying jobs to use the variables stored in Doppler when they need it.
Then when we need to use the environment variables, we can simply run it with the Doppler command like so:
- run: doppler run -- prisma migrate up --experimental
In cases where we need to use an environment variable in the command itself, you'll need to use a tiny hack to substitute your values in like this:
- run: ssh-keyscan $(doppler run -- printenv PRODUCTION_HOST) >> ~/.ssh/known_hosts
In this case, Doppler is run in a sub-command and has its value substituted in the main command.
Conclusion
You should now have a very portable way to move your environment variables around. Check Doppler out at doppler.com