How to Set docker container ip to environment variable dynamically on startup? - bash

I want to export docker container hostname as an environment variable which I can later use in my app. In my docker file I call my script "run" as last command
CMD run
The run file is executable and works fine with rest of commands I perform but before them I want to export container hostname to an env. variable as follows
"run" File Try 1
#!/bin/bash
export DOCKER_MACHINE_IP=`hostname -i`
my_other_commands
exec tail -f /dev/null
But when I enter docker container and check, the variable is not set. If I use
echo $DOCKER_MACHINE_IP
in run file after exporting, it shows ip on console when I try
docker logs
I also tried sourcing another script from "run" file as follows
"run" File Try 2
#!/bin/bash
source ./bin/script
my_other_commands
exec tail -f /dev/null
and the script again contains the export command. But this also does not set the environment variable. What I am doing wrong?

When you execute a script, any environment variable set by that script will be lost when the script exits.
But for both the cases you've posted above the environment variable should be accessible for the commands in your scripts, but when you enter the docker container via docker run you will get a new shell, which does not contain your variable.
tl;dr Your exported environment variable will only be available to sub shells of the shell which set the variable. And if you need it when logging in you should source the ./bin/script file.

Related

Setting enviroment variable of the container through bash script is not working

I'm trying to set a enviroment variable of a docker container through bash script.
CMD ["/bin/bash", "-c","source runservice.sh"]
runservice.sh
#!/usr/bin/env bash
export "foo"="bar"
Now after pushing it when I go inside the container and do printenv, it is not setting up enviroment variable.
But if I run the same command inside the container, env variable is getting set up.
What's the correct way I can export using bash script?
it is not setting up enviroment variable
It's setting the environment for the duration of CMD build stage. Sure, it has no effect on anything else - the shell run at CMD stage is then exiting. See dockerfile documentation.
What's the correct way I can export using bash script?
There is no correct way. The correct way to affect the environment, is to use ENV.
There is a workaround in contexts that use entrypoint - you can set entrypoint to a shell (or a custom process) that will first source the variables.
ENTRYPOINT ["bash", "-c", "source runservice.sh && \"$#\"", "--"]

Execute environment file in ansible

I am trying to setup a playbook which will execute the env file of a service before running the command to stop the service.
Note that stop or start service command will only work after execute that env file.
The command to execute the env file is . ./.env_file_name or ksh .env_file_name
I am not able to execute the file using the above command in command module and shell module.
How to execute the above env file in ansible ?
How to run the stop command after executing the env file ?
If env file contains some environment variables that you need to set before running stop, then you can read the file, store results in a variable, then use environment keyword to provide them to the task, that actually stops the service.
Alternatively, you can add multiple commands in shell module at once, like so:
- name: Example for a shell module
shell:
cmd: |
./.env_file_name
./stop.sh (insert command to stop the service here)

Access a bash script variable outside the docker container in which the script is running

I have a bash script running inside a docker container. In this script, I set the value of some variable.
Can I somehow access the value of this variable outside the container?
I tried to make the variable "global" but could not figure out how to do it. Is it a good idea to make the required variable an environment variable inside the container?
How to reproduce
Create a bash script called temp.sh with the following contents:
a=$RANDOM
Now, run this file in a docker container as follows:
docker run -it --rm -v $(pwd):/opt alpine sh -c "sh /opt/temp.sh"
Desired behaviour: To be able to access the variable a outside the docker container
Credit: This comment by Mark
I mounted a directory on the docker filesystem using
docker run -v <host-file-system-directory>:<docker-file-system-directory>
In the bash script, I added
echo "$variable" >docker-file-system-directory/variable.txt
As I had mounted a host filesystem directory on the docker filesystem, I can still access variable.txt simply using cat <host-file-system-directory>/variable.txt
Note that docker-file-system-directory must be an absolute path, and not a relative path.
One way of achieving that is using docker exec, if your container is running and has access to bash.
#!/usr/bin/env bash
set -x
yourContainerName="testContainerName"
test=$(docker exec -i "${yourContainerName}" bash <<EOF
# do some work here e.g. execute your script
testVar="thisIsTest" # the value we want to access outside of container
echo \$testVar
EOF
)
echo $test
We pass a multiline script to docker container, which in the end echo's the value we need. This value is then accessible from shell that executed docker exec.
Output looks like this:
++ docker exec -i testContainerName bash
+ test=thisIsTest
+ echo thisIsTest
thisIsTest

Set environment variables in Docker

I'm having trouble with Docker creating a container that does not have environment variables set that I know I set in the image definition.
I have created a Dockerfile that generates an image of OpenSuse 42.3. I need to have some environment variables set up in the image so that anyone that starts a container from the image can use a code that I've compiled and placed in the image.
I have created a shell file called "image_env_setup.sh" that contains the necessary environment variable definitions. I also manually added those environment variable definitions to the Dockerfile.
USER codeUser
COPY ./docker/image_env_setup.sh /opt/MyCode
ENV PATH="$PATH":"/opt/MyCode/bin:/usr/lib64/mpi/gcc/openmpi/bin"
ENV LD_LIBRARY_PATH="/usr/lib64:/opt/MyCode/lib:"
ENV PS1="[\u#docker: \w]\$ "
ENV TERM="xterm-256color"
ENV GREP_OPTIONS="--color=auto"
ENV EDITOR=/usr/bin/vim
USER root
RUN chmod +x /opt/MyCode/image_env_setup.sh
USER codeUser
RUN /opt/MyCode/image_env_setup.sh
RUN /bin/bash -c "source /opt/MyCode/image_env_setup.sh"
The command that I use to create the container is:
docker run -it -d --name ${containerName} -u $userID:$groupID \
-e USER=$USER --workdir="/home/codeUser" \
--volume="${home}:/home/codeUser" ${imageName} /bin/bash \
The only thing that works is to pass the shell file to be run again when the container starts up.
docker start $MyImageTag
docker exec -it $MyImageTag /bin/bash --rcfile /opt/MyCode/image_env_setup.sh
I didn't think it would be that difficult to just have the shell variables setup within the container so that any entry into it would provide a user with them already defined.
RUN entries cannot modify environment variables (I assume you want to set more variables in image_env_setup.sh). Only ENV entries in the Dockerfile (and docker options like --rcfile can change the environment).
You can also decide to source image_env_setup.sh from the .bashrc, of course.
For example, you could either pre-fabricate a .bashrc and pull it in with COPY, or do
RUN echo '. /opt/MyCode/image_env_setup.sh' >> ~/.bashrc
you can put /opt/MyCode/image_env_setup.sh in ~/.bash_profile or ~/.bashrc of the container so that everytime you get into the container you have the env's set

Docker Ubuntu environment variables

During the build stage of my docker images, i would like to set some environment variables automatically for every subsequent "RUN" command.
However, I would like to set these variables from within the docker conatiner, because setting them depends on some internal logic.
Using the dockerfile "ENV" command is not good, because that cannot rely on internal logic. (It cannot rely on a command run inside the docker container)
Normally (if this were not docker) I would set my ~/.profile file. However, docker does not load this file in non-interactive shells.
So at them moment I have to run each docker RUN command with:
RUN bash -c "source ~/.profile && do_something_here"
However, this is very tedious (and unclean) when I have to repeat this every time I want to run a bash command. Is there some other "profile" file I can use instead.
you can try setting the arg as env like this
ARG my_env
ENV my_env=${my_env}
in Dockerfile,
and pass the 'my_env=prod' in build-args so that you can use the set env for subsequent RUN commands
you can also use env_file: option in docker compose yml file in case of a stack deploy
I had a similar problem and couldn't find a satisfactory solution. What I did was creating a script that would source the variables, then do the operation. I would then rewrite the RUN commands in the Dockerfile to use that script instead.
In your case, if you need to run multiple commands, you could create a wrapper that loads the variables, runs the command given as argument, and include that script in the docker image.

Resources