Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set system-wide environment variables in dockerfile from a file inside the docker container?

I am setting up a cross-compile environment as a docker container. During the build process I install a SDK for an embedded device:

ADD sdk.tar /opt
WORKDIR /opt/
RUN sdkinstall.sh

which installs the sdk in a folder /opt/sdk/

Now I have a file /opt/sdk/envsetup that contains some environment variables:

export SDKTARGETSYSROOT=/opt/sdk/sysroots/cortexa9hf-vfp-neon-gad-linux-gnueabi
export PATH=/opt/sdk/sysroots/x86_64-gadsdk-linux/usr/bin:/opt/sdk/sysroots/x86_64-gadsdk-linux/usr/bin/arm-gad-linux-gnueabi:$PATH
export PKG_CONFIG_SYSROOT_DIR=$SDKTARGETSYSROOT

.... and so on

Usually, when I would run a shell in the container I would do source /opt/sdk/envsetup and then compile stuff from the shell.

However, what I am trying to achieve is that all those environment variables are present system wide inside the docker container and are taken into account when I for example do something like docker run -it xyz:latest make <somedir>

I am testing this by calling docker run -it xyz:latest echo $SDKTARGETSYSROOT and I was expecting the container to print /opt/sdk/sysroots/cortexa9hf-vfp-neon-gad-linux-gnueabi`

What I tried to achieve this so far:

  • Adding the vars to /etc/environment: RUN cat /opt/sdk/environment-setup-cortexa9hf-vfp-neon-gad-linux-gnueabi | cut -d" " -f 2 >> /etc/environment
  • Adding the vars to /etc/profile, /root/.profile and /root/.bashrc: RUN echo -e "# Auto source some variables\nsource /opt/sdk/environment-setup-cortexa9hf-vfp-neon-gad-linux-gnueabi" >> [...]
  • Adding one var manually in the dockerfile via ENV SDKTARGETSYSROOT /opt/sdk/sysroots/cortexa9hf-vfp-neon-gad-linux-gnueabi, just to test the behaviour
  • . or /bin/bash -c 'source' the file /opt/sdk/envsetup

neither of those led to my expected result. How can I achieve those variables get setup properly?

As the file that contains the variables is unknown at the beginning of the docker build and gets created during the sdk installation inside of the container, I do not really like the idea of adding its content manually into the dockerfile via ENV, even if that worked, which did not.

like image 702
darkmattercoder Avatar asked Jan 23 '18 13:01

darkmattercoder


1 Answers

When you run this command:

docker run -it xyz:latest echo $SDKTARGETSYSROOT

The $SDKTARGETSYSROOT is expanded by your local shell. In no case were you actually testing environment variables inside of your container. This would work:

docker run -it xyz:latest sh -c 'echo $SDKTARGETSYSROOT'

The single quotes inhibit variable expansion in your local shell, and we need to explicitly call sh -c ... because Docker does not, by default, execute commands using a shell. Compare:

$ docker run -it alpine echo $HOME
/home/lars

With:

$ docker run -it alpine echo '$HOME'
$HOME

With:

$ docker run -it alpine sh -c 'echo $HOME'
/root

Otherwise, several of your approaches look like a reasonable way to do what you want.

like image 54
larsks Avatar answered Nov 15 '22 04:11

larsks