I have successfully pushed my docker image to the swisscom app cloud (similar to this example: https://ict.swisscom.ch/2016/05/docker-and-cloudfoundry/).
Now I would like to use a user-provided environment variable within my docker CMD. Something like this:
ADD target/app.jar app.jar
CMD java -jar app.jar -S $USER_PROVIDED_ENV_VARIABLE
I also tried system-provided environment variables:
ADD target/app.jar app.jar
CMD java -jar app.jar -S $VCAP_APPLICATION
What am I doing wrong here?
If your Dockerfile is built like that, you'll simply need to pass the -e flag when running the image.
Example Dockerfile:
FROM ubuntu:16.10
ENV MY_VAR "default value" # Optional - set a default value.
CMD echo $MY_VAR
Build the image:
docker build -t my_image .
Run a container from the image:
docker run -e MY_VAR="my value here" my_image
Related
I'm brand new user of Docker...
I'm tring use Enviroments variables on my Dockerfile...
It's like that:
FROM openjdk:11-jdk-slim-buster
ENV JAVA_APP my-app
EXPOSE 8080
COPY target/$JAVA_APP-*.jar /app/$JAVA_APP.jar
CMD java -jar /app/$JAVA_APP.jar
The result is that: the COPY command gets the value of JAVA_APP variable. But the CMD command doesn't.
Is there some another way to use ENV variables?
If I make this super simple Dockerfile
FROM ubuntu
ENV JAVA_APP my-app
CMD echo $JAVA_APP
and build and run it with
docker build -t test .
docker run --rm test
docker run --rm -e JAVA_APP=Hello test
It prints 'my-app' and 'Hello'. So it does work. If it still doesn't work for you, can you expand your post with the command you use to run the container?
I'm trying to start an app based on arg passed at build time
cmd:
docker build --build-arg profile=live . -t app
Dockerfile:
FROM openjdk:11.0.7-jre-slim-buster
WORKDIR /app
ARG JAR_FILE=target/*.jar
ARG profile
ENV profile ${profile:-dev}
EXPOSE 8080
COPY ${JAR_FILE} /app/app.jar
# ENTRYPOINT ["java", "-jar", "app.jar", "--spring.profiles.active=${profile}"] --- not working
RUN echo $profile <--- here I got the value
#CMD java -jar app.jar --spring.profiles.active=${profile} --- not working
#CMD java -jar app.jar --spring.profiles.active=$profile --- not working
CMD ["sh", "-c", "node server.js ${profile}"] --- not working
when I inspect the docker image I got
"Cmd": [
"sh",
"-c",
"node server.js ${profile}"
],
What i'm missing?
Thanks
update:
works with CMD java -jar app.jar --spring.profiles.active=$profile and the $profile will have the desired value at runtime
Environment replacement doesn't happen in CMD. Instead it happens in the shell running inside the container (in your case sh, though it's not clear why you've used the json/exec syntax to call a sh command).
Documentation on environment replacement is available from: https://docs.docker.com/engine/reference/builder/#environment-replacement
Try this Dockerfile: docker build --build-arg PROFILE=uat -t app .
FROM alpine
ARG PROFILE
ENV PROFILE ${PROFILE:-dev}
CMD ["ash", "-c", "while :; do echo $PROFILE; sleep 1; done"]
Run it and it prints uat every second: docker run -it --rm app
You didn't mention what exactly is the outcome when you said "not working". Presumed you got empty string or other unexpected value, the environment variable could be in used by the base image. Try another name for your environment variable, or use non-slim version of openjdk image.
FROM alpine:3.11
COPY out/ /bin/
CMD ["command", "--flag1", "${HOST}", "--flag2", "${PORT}", "--flag3", "${AUTH_TOKEN}"]
This is the docker file used. I am loading the env variables during run through an env file.
But the variables are not substituted when running the command. If I override the CMD and exec into the container I am able to see the envs though.
What am I missing here?
You are running CMD in exec mode. Switch to shell mode and it will work out. As for the environment variables to be present you need a shell. more reading
your example:
CMD command --flag1 ${HOST} --flag2 ${PORT} --flag3 ${AUTH_TOKEN}
Full generic example:
Dockerfile:
FROM debian:stretch-slim
CMD echo ${env}
Run:
docker build .
docker run --rm -e env=hi <image id from build step>
hi
According to this:
https://hub.docker.com/_/mysql/
I can set the MySQL root password with:
docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
I assumed that MYSQL_ROOT_PASSWORD would be an environment variable that's set using ARG (e.g. Get environment variable value in Dockerfile ) however, looking at the DockerFile (https://github.com/docker-library/mysql/blob/696fc899126ae00771b5d87bdadae836e704ae7d/8.0/Dockerfile ) I don't see this ARG.
So, how is this root password being set?
It's actually used in the entrypoint script -
Ref - https://github.com/docker-library/mysql/blob/696fc899126ae00771b5d87bdadae836e704ae7d/8.0/docker-entrypoint.sh
Entrypoint config in Dockerfile -
COPY docker-entrypoint.sh /usr/local/bin/
RUN ln -s usr/local/bin/docker-entrypoint.sh /entrypoint.sh # backwards compat
ENTRYPOINT ["docker-entrypoint.sh"]
Let me clarify a bit about parameters in Dockerfile.
ARG - is only available during docker image build.
Let’s say, you want to store in docker image a hash commit of you source code.
ARG Commit
than you build a docker image:
docker build -t someimage —build-arg Commit=<somehash>
ENV - values that are available for docker containers and can be used as a part of RUN command.
On actual runtime, you can change ENV variable or add new env variables by adding it to run string:
docker run -e SOME_VAR=somevar someimage.
Hope this will help you.
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}