Environment variable does not work with docker windows Image - windows

I have the next dockerfile, with build image in two stage
FROM mcr.microsoft.com/dotnet/framework/sdk:4.8 AS build
WORKDIR worker-app
ENV AWS_ACCESS_KEY_ID=AWS_ACCESS_KEY_ID
ENV AWS_SECRET_ACCESS_KEY=AWS_SECRET_ACCESS_KEY
#BUILD PROJECT
RUN mkdir c:\worker-app\out
...
#BUILD IMAGE
FROM mcr.microsoft.com/dotnet/framework/sdk:4.8
WORKDIR /worker-app
COPY --from=build /worker-app/out .
#Install AWS CLI
RUN echo Descargando aws-cli
RUN curl https://s3.amazonaws.com/aws-cli/AWSCLI64PY3.msi -o AWSCLI64PY3.msi
RUN echo Instalando aws-cli
RUN msiexec /i AWSCLI64PY3.msi /qn /norestart
RUN setx Path "%Path%;\"C:\Program Files\Amazon\AWSCLI\bin\""
#Login AWS CLI
CMD ["cmd", "/S", "/C", "aws configure set aws_access_key_id "%AWS_ACCESS_KEY_ID%" && aws configure set aws_secret_access_key "%AWS_SECRET_ACCESS_KEY%" && aws configure set default.region us-east-1 && aws configure set default.output json"]
ENTRYPOINT ["cmd"]
the build command works fine
docker build -t worker-app:1 .
but my issue is when I try to run the image like that
docker run -e AWS_ACCESS_KEY_ID=123456789 -e AWS_SECRET_ACCESS_KEY="abcde123456" -it --entrypoint=cmd worker-app:1
and I type aws configure but all keys are empty, also, I try to do echo %AWS_ACCESS_KEY_ID% && ... in the line CMD but never print it.
Any idea?

Here's the corrected CMD command:
CMD ["cmd", "/S", "/C", "aws configure set aws_access_key_id $env:AWS_ACCESS_KEY_ID && aws configure set aws_secret_access_key $env:AWS_SECRET_ACCESS_KEY && aws configure set default.region us-east-1 && aws configure set default.output json"]
Also, it is worth noting that you are using cmd as the entrypoint, so the CMD command will always run in a new instance of the cmd shell and the environment variables won't persist between runs. To persist the environment variables, you can add the following line to the Dockerfile:
ENV PATH="%PATH%;C:\Program Files\Amazon\AWSCLI\bin"

Related

pass arguments in dockerfile?

I want to pass an argument to my dockerfile such that I should be able to use that argument in my run command but it seems I am not able to do so
I am using a simple bash file that will trigger the docker build and docker run
FROM openjdk:8 AS SCRATCH
WORKDIR /
ADD . .
RUN apt install unzip
RUN unzip target/universal/rule_engine-1.0.zip -d target/universal/rule_engine-1.0
COPY target/universal/rule_engine-1.0 .
ENV MONGO_DB_HOST="host.docker.internal"
ENV MONGO_DB_PORT="27017"
EXPOSE 9000
ARG path
CMD target/universal/rule_engine-1.0/bin/rule_engine -Dconfig.file=$path
above is my dockerfile
and below is my bash file which will access this dockerfile
#!/bin/bash
# change the current path to rule engine path
cd /Users/zomato/Documents/Intern_Project/rule_engine
sbt dist
ENVIR=$1
config=""
if [ $ENVIR == "local" ]
then
config=conf/application.conf
elif [ $ENVIR == "staging" ]
then
config=conf/staging.conf
else
config=conf/production.conf
fi
echo $config
docker build --build-arg path=$config -t rule_engine_zip .
docker run -i -t -p 9000:9000 rule_engine_zip
but when i access the dockerfile through bash script which will set config variable I am not able to set path variable in last line of dockerfile to the value of config.
ARG values won't be available after the image is built, so
a running container won’t have access to those values. To dynamically set an env variable, you can combine both ARG and ENV (since ENV can't be overridden):
ARG PATH
ENV P=${PATH}
CMD target/universal/rule_engine-1.0/bin/rule_engine -Dconfig.file=$P
For further explanation, I recommend this article, which explains the difference between ARG and ENV in a clear way:
As you can see from the above image, the ARG values are available only during the image build.

Not able to pass the command line arguments using docker run to a Shell Script file

Command Used:
sudo docker run -it -p 80:9000 c822030cc576 sh /app/test/play/docker-entrypoint.sh /app/test/play/servers/server01/play/conf/override.conf /app/log/nflott/play true dev
My Parameters:
$2:/app/test/play/servers/server01/play/conf/override.conf
$3:/app/log/nflott/play
$4:true
$5:dev Which needs to be passed to the docker-entrypoint.sh Script
My entrypoint.sh Script Code:
echo "CONFIG:$2
echo "LOG_HOME:$3"
echo "SKIP_LOGFILE:$4"
echo "LOG_ENV:$5
/app/test/play/servers/server01/play/bin/apiserver \
-Dconfig.file=/app/test/play/servers/server01/play/conf/override.conf \
-Dpidfile.path=/app/test/play/servers/server01/RUNNING_PID \
-DLOG_HOME=$3 \
-DSKIP_LOGFILE=$4 \
-DLOG_ENV=$5 \
Error:
CONFIG:/app/test/play/servers/server01/play/conf/override.conf
LOG_HOME:/app/log/nflott/play
SKIP_LOGFILE:true
LOG_ENV:dev
Bad root server path: /app/nflott/play/docker-entrypoint.sh
Seems after the echo statement my parameters are not getting passed to the logic block and its failing with Bad Root server Path issue. How to resolve the Bad root serer path error and run my script?
IMHO they might be getting passed as args of the docker command. You can instead try -e docker option to pass them as some named env variables to the docker container and then access inside your script.
You may use special --entrypoint flag and pass params in cmd:
sudo docker run -it -p 80:9000 --entrypoint /app/test/play/docker-entrypoint.sh c822030cc576 /app/test/play/servers/server01/play/conf/override.conf /app/log/nflott/play true dev

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

How to substitute a command output into a string and append that to a file (in Alpine Linux running in Docker)

I'm trying to build the following Dockerfile:
FROM alpine:latest
EXPOSE 9050 9051
RUN apk --update add tor
RUN echo "ControlPort 9051" >> /etc/tor/torrc
RUN password_hash=$(tor --hash-password "foo")
RUN echo "HashedControlPassword $password_hash" >> /etc/tor/torrc
CMD ["tor"]
I'm trying to add the line HashedControllPassword [pw] to /etc/tor/torrc, where [pw] is generated by the command tor --hash-password "foo". (I'm using "foo" as password in this example).
If I build the image using docker build --tag my_tor . and enter the command line using
docker run -it my_tor /bin/ash
and run cat /etc/tor/torrc, I see
ControlPort 9051
HashedControlPassword
In other words, in the end the torrc doesn't seem to contain the hashed password. However, similar commands in my Ubuntu terminal do work. Can anyone spot what the problem is?
You can use ARG
FROM alpine:latest
EXPOSE 9050 9051
ARG password
RUN apk --update add tor
RUN echo "ControlPort 9051" >> /etc/tor/torrc
RUN echo "HashedControlPassword $(tor --hash-password $password)" >> /etc/tor/torrc
CMD ["tor"]
And then build using:
docker build --build-arg password=foo Dockerfile
In general I would not bake password in an image. It would be better to provide those things when you run the container using -e.

Difference between "docker build" and "docker run" if we running dockerfile having .sh files

This is my Dockerfile
# This Dockerfile describes the standard way to build
FROM centos:latest
MAINTAINER praveen
# Run a root to allow "rpm"
USER root
WORKDIR /root/
# Get the ACE-TAO rpm from seachange repo
COPY TAO-1.7.7-0.x86_64.rpm /root/TAO-1.7.7-0.x86_64.rpm
# Insatall the rpm
RUN rpm -ivh /root/TAO-1.7.7-0.x86_64.rpm
#Start the TAO service
#CMD /etc/init.d/tao start
COPY namingServiceConfig.sh /
RUN /namingServiceConfig.sh
EXPOSE 13021
EXPOSE 13022
EXPOSE 13023
ENV NS_PORTS=13021,13022,13023
#ENTRYPOINT /etc/init.d/tao start && bash
While doing the docker build
Whether it'll execute the shell script and reflect the changes as part images or while running the images using docker run its will reflect the changes to container level
In my case ,I'm suspecting that, it is executing while docker build and docker run both time
I'm using below commands as part of building and running via vagrant file
d.build_image "/vagrant/tao", args: " -t tao/basic"
d.run "tao/basic:latest",
args: " -t -d"\
" --name tao-basic"\
" -p 13021:13021"\
" -e NS_PORT=13025,13026,13027"
let me know, need any more information
The Dockerfile instructions (such as RUN etc...) are actioned at build time (docker build -t something . etc...). Only the CMD and ENTRYPOINT instructions happen at run time (when the container is started).
In your example the shell script will get run as part of the build and whatever changes occur will be committed as a new layer in the image.

Resources