Every so often you get your ass kicked by something and you just need to write down all of the quirks. Dotenv was today’s culprit.
At AMA we start up our blessing of unicorns using foreman (which loads in our .env files). When we do a 0 downtime (USR2) restart we
Dotenv.load to reload in the environmental vars(.env). Here’s the code in our
1 2 3
Through time we’ve learned a few valuable lessons when upgrading:
- < 0.7 you can’t have comments in your .env’s
- < 0.8 you can’t have blank variables (which was a bummer for .env.development)
- 0.9 and above you’ll need to escape all of your dollar signs as variable expansion is now enabled (or use single quotes – not double)
Recently we noticed our unicorns weren’t properly reloading their environment which led to us having to do a hard restart (TERM) on the unicorns. Luckily we weren’t taking on a huge load and our caching offloaded most of the hits, but this can mean that some users could get an error if the unicorns don’t come up fast enough.
We dug in a bit deeper and we noticed that calling
Dotenv.load just loads in any new variables (it won’t override any variables).
This led to the inevitable “How did that even work in the first place?”.
At this point, we’re not sure if it ever did (seriously, it did :( ), but
what we did find was that we should have been using
Dotenv.overload. This will override all of the variables that were
in your .env file.
Hopefully this will save you a few ‘wtfs’ when your app is acting up when you upgrade dotenv. I think we’ve burned enough universal ‘wtfs’ on our own.