Dot Your Environment
Env::Dot
In the category of “scratching my itch”.
Background
An app’s config is everything that is likely to vary between deploys (staging, production, developer environments, etc). The Twelve-Factor App
Storing the often changing parts of configuration in environment variables is one of the principles of The Twelve-Factor App.
From this principle follows the need to store those environment variables and their values
in an easily accessible way. Hence, every developer maintains his or her own
project specific .env
files next to the project files in the same directory
where they are used, for instance, when running locally or testing locally.
Yet Another Dotenv Solution
As if we didn’t have these enough already…
What is different with this one, except the name Env::Dot?
Flexibility in input
.env
files come in two formats: Shell compatible and Docker combatible.Env::Dot
supports both.- If no
.env
file is present, then do nothing. - If your
.env
file is located in another path, not the current working directory, you can use the environment variableDOTENV_FILEPATHS
to tell where your dotenv file is located. You can specify several file paths; just separate them by:
.Dot::Env
will load all the files in the order you specify them.
Flexibility in output
- Just use
Env::Dot
in your program and your%ENV
will grow with the variables defined in.env
file. - There is also a command line executable,
envdot
, to read the.env
file and write out commands to create the environment variables. - Command
envdot
can write the env vars insh
(sh/Bash/Zsh),csh
(C shell/tcsh) andfish
(Fish) shell formats. - Command
envdot
will by default also export variables but you can prevent this if you don’t want the variables to be present in subshells and programs. This would make the variables only local to your current shell.
Existing Environment Takes Precedence
Existing environment variables always take precedence to dotenv variables!
A dotenv variable (variable from a file) does not overwrite an existing environment variable. This is by design because a dotenv file is to augment the environment, not to replace it.
This means that you can override a variable in .env
file by creating
its counterpart in the environment. For instance:
unset VAR
echo "VAR='Good value'" >> .env
perl -e 'use Env::Dot; print "VAR:$ENV{VAR}\n";'
# VAR:Good value
VAR='Better value'; export VAR
perl -e 'use Env::Dot; print "VAR:$ENV{VAR}\n";'
# VAR:Better value
DotEnv File Meta Commands
The file:
commands affect all rows following its use.
The var:
commands affect only the subsequent variable definition.
If there is another envdot command, the second overwrites the first
and default values are applied again.
file:type
Changes how Env::Dot
reads lines below from this commands. Default is:
# envdot (file:type=shell)
VAR="value"
Other possible value of file:type
is plain
.
Docker is using these kinds of .env
files.
Variable name is followed by =
and value is the rest
of the row before linefeed.
# envdot (file:type=plain)
VAR=My var value
var:allow_interpolate
By default, when writing variable definitions for the shell,
every variable is treated as static and surrounded with
single quotation marks (‘) in Unix shell which means
shell will read the variable content as is.
By setting this to 1
or true
, you allow shell
to interpolate.
This meta command is only useful when running envdot
command
to create variable definitions for eval
command to read.
# envdot (var:allow_interpolate)
DYNAMIC_VAR="$(pwd)/${ANOTHER_VAR}"
Usage
use Env::Dot;
print $ENV{'VAR_DEFINED_IN_DOTENV_FILE'};
envdot
envdot
is a shell command which translates the dotenv files into shell commands. The file .env
is of course the default input.
envdot
# VAR='Good value'; export VAR
It has the following parameters:
—export, —no-export
Write commands to set variables for local shell or for exporting them. You usually want to export the variables to all subsequent programs and subshells, i.e. make them into environment variables.
Default: export
-s, —shell
Which shell (family) are you using? Supported: sh, csh, fish.
-e, —dotenv
Path to .env file.
Default: current directory .env
Installation
If you need to use the envdot
command in a restricted environment,
such as a docker image build,
there is a FatPacked executable ready.
Usable when using CPAN is overkill.
curl -LSs -o envdot https://raw.githubusercontent.com/mikkoi/env-dot/master/envdot.self-contained
chmod +x ./envdot
Or you can do this in a Dockerfile
:
RUN curl -LSs -o /usr/local/bin/envdot \
https://raw.githubusercontent.com/mikkoi/env-dot/master/envdot.self-contained
RUN chmod +x /usr/local/bin/envdot
There is no extra dependencies outside Perl’s standard distribution, so envdot
is as lean as it can be. And Perl, of course, is present in every more or less standard
Linux distribution.
Leave a comment