Using docker run with a bunch of -e flags or even a .env seems cumbersome.
Is there any simply way to just pass all of the host env variables to a docker container
Using docker run with a bunch of -e flags or even a .env seems cumbersome.
Is there any simply way to just pass all of the host env variables to a docker container
I agree with the commenters who have suggested that you may not actually want to do what you think you want to do. However:
If (a) you're interested in environment variables with a specific prefix and (b) your variables don't contain any whitespace, something like this would work...here, I'm exposing all the XDG_*
variables to a docker container:
$ docker run -it --rm --env-file <(env | grep XDG) alpine sh
/ # env | grep XDG
XDG_SEAT=seat0
XDG_SESSION_TYPE=x11
XDG_SESSION_ID=2
XDG_RUNTIME_DIR=/run/user/21937
XDG_MENU_PREFIX=gnome-
XDG_CURRENT_DESKTOP=GNOME
XDG_SESSION_DESKTOP=gnome
XDG_VTNR=2
If you really want all environment variables, you would probably need to write a smaller wrapper program that would produce properly quoted output (to handle variables that contain whitespace), and that would exclude things that span multiple lines, like the BASH_FUNC_*
variables. Then you would use your wrapper in place of the env | grep ...
in the previous example.
There are two ways to use the -e flag: -e VAR=VALUE and -e VAR; if VAR is already exported then the second format will use the exported value without making it publicly readable, plus you don't need to worry about escaping the VALUE against whitespace, quotes, etc.
So if you really want to pass in all exported variables to your container, try this:
docker run ... $(env | cut -f1 -d= | sed 's/^/-e /') ...
Mixing a bit of both answer for @user3324033 and @larsks, here is what worked best for me to get all exported environment variables and mimic Apptainer/Singularity behaviors:
docker run [...] --env-file <( env| cut -f1 -d= ) [...]
I found @larsks's answer very enlightening, but found I needed to be a little more surgical in how I injected variables into my containers.
If you utilize Makefiles for your container building and/or running, you can combine gnu make's foreach
keyword with env -i
to easily inject environment variables into your container:
SHELL := /bin/bash
FOO := myfooenv
BAR := mybarenv
VARS := FOO BAR
run:
docker run --rm -it \
--env-file <(env -i $(foreach var,$(VARS),$(var)=$($(var)))) \
bash:latest \
bash -c ' \
set -e; \
env; \
'
Which would give the output:
$ make run
docker run --rm -it \
--env-file <(env -i FOO=myfooenv BAR=mybarenv) \
bash:latest \
bash -c ' \
set -e; \
env; \
'
HOSTNAME=9d3b6863b8f2
_BASH_VERSION=4.4
_BASH_LATEST_PATCH=23
PWD=/
HOME=/root
FOO=myfooenv
_BASH_GPG_KEY=7C0135FB088AAF6C66C650B9BB5869F064EA74AB
TERM=xterm
SHLVL=1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
BAR=mybarenv
_BASH_PATCH_LEVEL=18
_=/usr/bin/env
Probably the least ideal answer in terms of security here, but if all else fails, I resorted to something like this that worked for me:
env > env.txt; docker run -it [...] --env-file env.txt [...]; rm env.txt
for above assuming you're running it as an interactive session. Be different to handle cleanup of env.txt if you're running it as a service in the background.
One could set RW permissions on the file within the command chain perhaps to make it more secure. And switch ;
to &&
for better dependent execution of the commands
I myself tried the other solutions with no luck (I'm on Mac OS, using bash 4 via brew if that makes a difference).