I know you can set Fabric's env items using --set flag:
fab --set A=1,B=2 my_task
And those variables will be available into fabfile.py:
print(env.A) # will print 1
The question is, is it possible to get those variables straight from a .env file? Eg:
A=1
B=2
...
Executing something like fab --env-file .env my_task (much alike docker run's env-file flag)
Yes, the --config option. It allows you to:
Sets env.rcfile to the given file path, which Fabric will try to load on startup and use to update environment variables.
The command:
fab --config .env my_task
Related
Assuming the host machine has the TESTVARIABLE set
user#hostmachine> echo $TESTVARIABLE
test_value
How can you pass this variable to a container with docker-compose, using an .envfile or the docker-compose.yml file?
Most answers I find, involve explicitly defining that value in an .envfile, or directly in the docker-compose.yml, or in the command line when executing the up command`. However, I am looking to pass an existing variable on the host machine to the container.
First, make sure that TESTVARIABLE is actually exported to your environment and isn't just a shell variable:
export TESTVARIABLE
Then you can simply refer to it in your docker-compose.yaml like this:
version: "3"
services:
example:
image: docker.io/alpine:latest
command:
- sleep
- inf
environment:
- "TESTVARIABLE=${TESTVARIABLE}"
If I run:
$ export TESTVARIABLE=foo
$ docker-compose up -d
$ docker-compose exec example env
I will get output like this:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=68705fc07b09
TERM=xterm
TESTVARIABLE=foo
HOME=/root
There you can see the value of TESTVARIABLE from the local environment.
Note that if TESTVARIABLE is not defined in your environment, docker-compose will warn you:
$ docker-compose up
WARNING: The TESTVARIABLE variable is not set. Defaulting to a blank string.
...
For example, I can quote ABC as part of BCD.
ABC='value_abc'
BCD=${ABC}:9876
The .env file is not parsed by a shell, it's simply a key=value mapping defined in the compose-go spec. It will not handle any nested variables, quotes, escape characters, etc., they are simply passed directly through as the value of the variable.
To do anything more complex, you'll need to set your environment variables yourself before calling compose. This could be with a script that sources your env file, e.g. you could make a docker-compose-expanded script that contains:
set -a
[ -f ./.env-expanded ] && . ./.env-expanded
set +a
docker-compose "$#"
Let suppose I have an env file with
DB_PW=123
And a docker command that expects
-env MYSQL_ROOT_PASSWORD=123
Is there a way to take that DB_PW from the env file and assign it to MYSL_ROOT_PASSWORD in the command line? (obviously not having to add a line to the env file with the explicit assignment)
I have been reading here and there, but I am not sure if it's possible or where this would be documented.
if you're using "--env-file <ENV_FILE>" flag or .env file exists in compose directory then, you can directly call values from .env file by using "${ENV_VAR}"
ex:
-env MYSQL_ROOT_PASSWORD=${DB_PW}
https://docs.docker.com/compose/environment-variables/
I am involved in a Docker Compose project and we take advantage of the .env file possibility. However, I discovered that I can not reuse one environment variable while constructing another one, or reuse existing OS-level environment variables.
For example, this doesn't work:
VIRTUAL_HOST=domain.com
LETSENCRYPT_HOST=${VIRTUAL_HOST}
LETSENCRYPT_EMAIL=contact#${VIRTUAL_HOST}
Any ways around it?
Create a entry script similar to this:
#!/usr/bin/env bash
set -e
# Run a substitution because docker don't support nesting variables
export LETSENCRYPT_HOST=$(echo ${LETSENCRYPT_HOST} | envsubst)
export LETSENCRYPT_EMAIL=$(echo ${LETSENCRYPT_EMAIL} | envsubst)
exec "$#"
It seems that I am not understanding something about variable substitution in the following page (my variable NUM is not registering): https://github.com/compose-spec/compose-spec/blob/master/spec.md#Interpolation
See screenshot below. Running this on mac OSX.
Regarding docker-compose variable substitution, it can depend on how NUM has been set.
set NUM=5 would only set it in the current shell, not for another process.
Make sure to type:
export NUM=5
It is mentioned in the docs:
You can use a $$ (double-dollar sign) when your configuration needs a
literal dollar sign. This also prevents Compose from interpolating a
value, so a $$ allows you to refer to environment variables that you
don’t want processed by Compose.
web:
build: .
command: "$$VAR_NOT_INTERPOLATED_BY_COMPOSE"
If you forget and use a single dollar sign ($), Compose interprets the
value as an environment variable and will warn you:
The VAR_NOT_INTERPOLATED_BY_COMPOSE is not set. Substituting an empty
string.
According to that, line 03 of your compose file should be:
command: echo $$NUM
In addition to $$ solution provided by #ayman-nedjmeddine above you also need to do following, to make shell variables available in compose you have two options
Option 1
log in as root , set your variable and execute docker-compose
root>export NUM=5
root>docker-compose up
Option 2
use sudo -E from user shell, -E will propagate user shell env to sudo,
provide sudo access to docker/docker-compose
add :SETENV: to the command in sudoer file to use -E option in sudo
eg:
sudo visudo -f /etc/sudoers.d/docker-compose
ALL ALL=(ALL:ALL) NOPASSWD:SETENV: /usr/local/bin/docker-compose
sudo visudo -f /etc/sudoers.d/docker
ALL ALL=(ALL:ALL) NOPASSWD:SETENV: /usr/bin/docker
finally use
user1>export NUM=5
user1>sudo -E docker-compose up