Doppler: The Docker of Environment Variables

Subscribe to my newsletter and never miss my upcoming articles

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 Netlify, and in our Docker containers (which are pushed to multiple different places). You can find out more about our deployments in the Indie DevOps series. 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.

We currently have three main environments: dev, prd, and prd_ci in each project which looks something like this:

image.png

  • dev contains values that allow us to work on our laptops as well as sandboxed tokens and dummy data.
  • prd contains all of our production variables
  • prd_ci contains a subset of the production variables that are needed in the CI. For example, we need the DATABASE_URL to run migrations, but we don't need JOBS_REDIS_URL or STRIPE_TOKEN since those are more runtime related variables.
  • stg is currently unused for us

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 put set Doppler token in the Github Action secrets 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. In Github Actions, we make sure to use a token associated with the prd_ci environment.

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 the case that we need to use an environment variable in the command itself, you'll need to use a tiny hack to substitute your value 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

No Comments Yet