I have been trying to run timeout command on my shellscript with time being passed as variabe through Dockerfile
This is my DokcerFile(sample)
FROM locustio/locust:1.2.3
ARG TIME_CHECK=15
COPY --chown=locust:locust ping.sh .
RUN echo "Hello $TIME_CHECK"
RUN chown locust:locust /home/locust && chmod +x ./ping.sh
ENTRYPOINT ["/bin/bash","-c", "timeout $TIME_CHECK ./ping.sh"]
Docker build happens successfully with below command and I can the value being passed correctly
docker build -t pingit --build-arg TIME_CHECK=10
When I do docker run it fails with following error
Try 'timeout --help' for more information.
I do understand this is because ENTRYPOINT is not recogninsing variable as such.
What am I doing wrong can you anyone help me here.
From docker reference, you can only access ARG values at build-time.
To pass a value to the runtime environment variable, you can use ENV instruction:
FROM locustio/locust:1.2.3
ARG TIME_CHECK=15
# assign ENV from ARG
ENV TIME_CHECK=${TIME_CHECK}
COPY --chown=locust:locust ping.sh .
RUN echo "Hello $TIME_CHECK"
RUN chown locust:locust /home/locust && chmod +x ./ping.sh
ENTRYPOINT ["/bin/bash","-c", "timeout $TIME_CHECK ./ping.sh"]
Just add a ENV TIME_CHECK=$TIME_CHECK to your dockerfile after the ARG statement.
The issue is that ARG is at build time. If you need to use it as environment variable then you need to set the variable yourself
Related
I have a project that uses Docker. When the image is being built, we have a need to pass in a full, multi-line bash script as a dynamic argument, and for the Dockerfile to execute that script as part of the image build. So for example, we'd have a variable named S_VAR whose contents are:
#!/bin/sh
mkdir -p /home/new_dir
chmod 700 /home/new_dir
Then our build command is:
docker build --build-arg S_VAR="$S_VAR" .
In our Dockerfile currently, that gets saved to a local script and executed (and it works correctly), using the lines below:
ARG S_VAR
ENV S_VAR=$S_VAR
RUN mkdir /src
RUN echo "$S_VAR" > /src/temp_script.sh
RUN chmod +x /src/temp_script.sh
RUN if [ "$S_VAR" != "" ] ; then /src/temp_script.sh; fi
That feels really silly though - we have no need to actually keep the script around in a persisted file. Is there a more efficient way to tell the Dockerfile to just run that variable as a script if it exists?
Did you try the eval command?
ARG S_VAR
ENV S_VAR=$S_VAR
RUN mkdir /src
RUN eval $S_VAR
It will execute the variable, but won't do anything if it doesn't exist.
I have a dockerfile with these lines:
ARG ENVIRONMENT
ENV ENVIRONMENT $ENVIRONMENT
RUN npm run ng build --configuration=${ENVIRONMENT}
I cant get the "RUN npm run ng build --configuration= to pass the value of $ENVIRONMENT to the npm command.
What is the syntax for this?
Per the Dockerfile ARG docs,
The ARG instruction defines a variable that users can pass at build-time to the builder with the docker build command using the --build-arg = flag.
in order to accept an argument as part of the build, we use --build-arg.
Dockerfile ENV docs:
The ENV instruction sets the environment variable to the value .
We also need to include an ENV statement because the CMD will be executed after the build is complete, and the ARG will not be available.
FROM busybox
ARG ENVIRONMENT
ENV ENVIRONMENT $ENVIRONMENT
CMD echo $ENVIRONMENT
will cause an environment variable to be set in the image, so that it is available during a docker run command.
docker build -t test --build-arg ENVIRONMENT=awesome_environment .
docker run -it test
This will echo awesome_environment.
Try changing your RUN command do this:
RUN npm run ng build --configuration=$ENVIRONMENT
This should work. Check here
Thanks.
I've got the following line in Dockerfile:
ARG COOL_ID
...
ENTRYPOINT ["java", "-jar", "/usr/share/java/${COOL_ID}/app.jar"]
but when I run it there's an error:
Error: Unable to access jarfile /usr/share/java//app.jar
and I can see that my ${COOL_ID} argument was not formatted correctly.
How can I fix it?
It will not substitute the variable, as Docker treat ENTRYPOINT and CMD as a command so processing variables like shell will not work. Try to change the CMD to run it as a shell and then you will able to process variable the same as the shell.
Also, you can not use ARG in CMD to treat them as an environment variable, you just use them inside Dockerfile, to use them as an environment variable you must assign them to some ENV.
ARG COOL_ID
ENV COOL_ID=$COOL_ID
I will also suggest to verify and check COOL_ID in Docker build time, if not set then it should print the warning or error to the user, see below example if ARG not passed to builds params then it will print an error message to the user.
ARG COOL_ID
#see ARG is for build time
RUN if [ -z $COOL_ID ];then \
>&2 echo "\n****************Warning!!!!*************\n"; \
>&2 echo "COOL_ID seems empty!" ;\
fi
ENV COOL_ID=$COOL_ID
# ENV is for run time
CMD ["sh", "-c", "java -jar /usr/share/java/${COOL_ID}/app.jar"]
Now build the docker with --build-arg
docker build --build-arg COOL_ID=myid -t myjava .
If you missed passing COOL_ID you will be notified.
I use Docker Toolbox for windows (for compatibility issues) and in the Dockerfile I specify an ARG so that I can use it when building the image with --build-arg command. Inside the dockerfile I also have some COPY commands and there I would like to use my variable but when I run docker build --build-arg VERSION_APP=something . it does not translate the variable . I have already used $VERSION_APP or ${VERSION_APP} or %VERSION_APP%.
FROM alpine
MAINTAINER Marinos
ARG VERSION_APP
RUN apk update && apk add dos2unix
COPY script.sh /home/script.sh
RUN chmod a+x /home/script.sh
RUN dos2unix /home/script.sh
RUN sh /home/script.sh
COPY installation.txt /home/Desktop/${VERSION_APP}
UPDATE
It seems that you should pass the whole path to the variable you use that is how I got it working.
If you actually use the command below then it is expected not to work because the argument called VERSION_APP
docker build --build-arg myVar=something
So the command should be
docker build --build-arg VERSION_APP=something
And in Dockerfile it should be %VERSION_APP% also you may need to use ENV like below:
ARG VERSION_APP
ENV VERSION_APP ${VERSION_APP}
Using Docker for Windows, Community version 17.06.0-ce-win19 (12801), Windows 10
Dockerfile
FROM frolvlad/alpine-oraclejdk8:slim
ARG APP_NAME=client-default
RUN mkdir -p /client/
ADD build/libs/$APP_NAME.jar /client/$APP_NAME.jar
ENTRYPOINT ["java", "-jar", "/client/$APP_NAME.jar"]
Running
docker build --build-arg APP_NAME=client-1 -t test/client-1 .
Placeholders not replaced after build (tried ${APP_NAME}, %APP_NAME%)
ARG and ENV are not replaced by Docker in an ENTRYPOINT or a CMD when you use the EXEC form inside []. If the ENTRYPOINT or CMD use the shell form (string, not an array) the shell will be able to do the variable substitution for you.
ARG and ENV variables will be available in RUN commands in the container as environment variables.
Docker will also replace $VARIABLES in the Dockerfile in the following instructions:
ADD
COPY
ENV
EXPOSE
FROM
LABEL
STOPSIGNAL
USER
VOLUME
WORKDIR
Only ENV variables will become available in a CMD or ENTRYPOINT, only in the environment of the running container:
Using ARG
FROM frolvlad/alpine-oraclejdk8:slim
ARG APP_NAME=client-default
ENV APP_NAME=$APP_NAME
RUN mkdir -p /client/
ADD build/libs/$APP_NAME.jar /client/$APP_NAME.jar
ENTRYPOINT ["sh", "-c", "java -jar /client/$APP_NAME.jar"]
or with only ENV
FROM frolvlad/alpine-oraclejdk8:slim
ENV APP_NAME=client-default
RUN mkdir -p /client/
ADD build/libs/$APP_NAME.jar /client/$APP_NAME.jar
ENTRYPOINT ["sh", "-c", "java -jar /client/$APP_NAME.jar"]
Environment variables in Dockerfile are declared with the ENV statement.
In your case:
FROM frolvlad/alpine-oraclejdk8:slim
ENV APP_NAME client-default
RUN mkdir -p /client/
ADD build/libs/${APP_NAME}.jar /client/${APP_NAME}.jar
ENTRYPOINT ["java", "-jar", "/client/${APP_NAME}.jar"]
ARG is only available during the build of a Docker image (RUN etc), not after the image is created and containers are started from it (ENTRYPOINT OR CMD)
ARG variable doesn't get substituted in Dockerfile. ARG IS really an environment variable. During the build, docker "runs" the container using ARG variables as environment variables. Easy to prove (you can test it): Try RUN printenv on your Dockerfile and you'll see the ARG as environment variable
So, you've got two problems:
First:
The Steps in console DOESN'T substitute the ARG variable. So, your jar is really in the container, your line:
ADD build/libs/$APP_NAME.jar /client/$APP_NAME.jar
it's working. Try it.
Second:
Entrypoint is for the running container, not for the image, so you need to put your ARG into an ENV variable, and not to use the exec form. If your use the exec form of ENTRYPOINT does not invoke a command shell. This means that normal shell processing does not happen. If you want shell processing then either use the shell form or execute a shell directly, for example:
ENTRYPOINT cat ${APP_NAME_RUN}
So, try this working example:
FROM ubuntu
ARG APP_NAME=client
RUN mkdir -p /client/
ADD ./$APP_NAME.txt /client/$APP_NAME.txt
ENV APP_NAME_RUN="/client/${APP_NAME}.txt"
RUN echo $APP_NAME_RUN
ENTRYPOINT cat ${APP_NAME_RUN}