ETOOBUSY 🚀 minimal blogging for the impatient
Setting environment variables in Dokku
TL;DR
Where we take a look at setting environment variables in Dokku.
Dokku is an amazing, minimalistic system for getting your single, amateur programmer deployment needs out of the way effectively. I already talked extensively about it in Dokku - Your Tiny PaaS.
Setting environment variables can bite you
One thing that hit me recently is how you can set environment variables
(either globally or for a specific application). The sub command is
config
, and in particular config:set
, like this:
ssh $DOKKU config:set KEY='wow, a value here'
Yes, I’m using the low-level interface, i.e. the plain SSH connection.
It so happens that this interface is not exactly robust. By design reasons which are unknown to me, the command above saves the key/value pair in a file that can be sourced easily, but decides to adopt double quotes for saving the thing, like this:
KEY="wow, a value here"
Moreover, it seems to fail spectacularly with newlines.
In-house solution
If you want to be on the safest side, you can encode the whole thing
in a single, long, base64
-encoded string and then set it in the
environment:
VALUE='Hello
every
body'
ssh $DOKKU config:set myapp \
KEY="$(printf %s "$VALUE" | base64 -w 0)"
Note that we are passing -w 0
to base64
, otherwise it will
eventually insert a newline and break the whole thing again.
Then, in your code, you can decode it back:
use MIME::Base64 'decode_base64';
# ...
my $text = decode_base64($ENV{KEY});
This is it, totally under your control.
Assisted solution
Dokku actually assists you with the server-side half of the
solution in the previous section. If you pass parameter --encoded
to
config:set
, you’te telling Dokku that the value is
base64
-encoded and it should treat it as such, decoding before saving
the environment variable:
VALUE='Hello
every
body'
ssh $DOKKU config:set --encoded myapp \
KEY="$(printf %s "$VALUE" | base64 -w 0)"
Now you have to trust that the escaping in saving the variable is done properly, but with this you can just do this in your code:
my $text = $ENV{KEY};
i.e. the same as single-line simple-text stuff. Neat!
The bottom line
If you’re lazy and want to just learn one thing, it’s that you should ALWAYS set variables like this:
VALUE='...' # whatever, with newlines or not
ssh $DOKKU config:set --encoded myapp \
KEY="$(printf %s "$VALUE" | base64 -w 0)"
This will work independently of how complex the $VALUE
is and never
fail you.
Well… never say never, but you get the idea.