Concatenate variables in Dockerfile at runtime - docker

I want to concatenate JSON environment variable out of multiple parameters provided during runtime.
Simplified Dockerfile:
FROM ubuntu:18.04
ENV VSS_NUGET_EXTERNAL_FEED_ENDPOINTS='{"endpointCredentials": [{"endpoint":"'${AZP_ENDPOINT}'", "username":"someuser", "password":"'${AZP_TOKEN}'"}]}'
Then i build image like this:
docker build -t myubuntu .
and run it
docker run -it -e AZP_ENDPOINT="https://pkgs.dev.azure.com/myorg/nuget/v3/index.json" -e AZP_TOKEN="some token" myubuntu
However when i run env command inside the container i see the following picture. Variable provided during container run are there, but VSS_NUGET_EXTERNAL_FEED_ENDPOINTS has not been updated:
AZP_ENDPOINT=https://pkgs.dev.azure.com/myorg/nuget/v3/index.json
AZP_TOKEN=some token
VSS_NUGET_EXTERNAL_FEED_ENDPOINTS={"endpointCredentials": [{"endpoint":"", "username":"someuser", "password":""}]}
Just wondering what i'm doing wrong here?

Related

Why is ASPNETCORE_ prefix ignored when passing environment variables to docker run?

When I call...
docker run myImage -e ASPNETCORE_ENVIRONMENT=Development
... the environment in the app is Production.
This however results in the environment set to Development.
docker run myImage -e ENVIRONMENT=Development
Why is this? It's the same with the Compose file that Visual Studio generates. Even when you run it from Visual Studio, the app ignores the value of ASPNETCORE_ENVIRONMENT.
There's an option within ASP.net to remove the prefix when loading env variables but it defaults to true and I can't find anywhere where it's set.
https://github.com/dotnet/aspnetcore/blob/a450cb69b5e4549f5515cdb057a68771f56cefd7/src/Hosting/Hosting/src/WebHostBuilderOptions.cs
if (!options.SuppressEnvironmentConfiguration)
{
configBuilder.AddEnvironmentVariables(prefix: "ASPNETCORE_");
}
https://github.com/dotnet/aspnetcore/blob/259ff381eb80b197eb9d9d2421251e3e1edd40ae/src/Hosting/Hosting/src/GenericHost/GenericWebHostBuilder.cs
Discussed here...
https://github.com/dotnet/aspnetcore/pull/25136
I am not sure what is wrong with your sample - you did not attach your Dockerfile.
Dockerfile itself should declare its environment variables via ENV directive.
Let's see empty dotnet6-based image:
FROM mcr.microsoft.com/dotnet/sdk:6.0
#dev as default value
ENV ASPNETCORE_ENVIRONMENT=Development
ENTRYPOINT ["bash", "-c", "tail -f /dev/null"]
Build image:
docker build --no-cache -t aspnet_env_test:1.0 .
Run container with default environment:
docker run -d aspnet_env_test:1.0
Check environment variable using command:
docker exec <containerId> env
Personally i see this output:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=0af57424ed63
ASPNETCORE_URLS=
DOTNET_RUNNING_IN_CONTAINER=true
DOTNET_VERSION=6.0.1
ASPNET_VERSION=6.0.1
Logging__Console__FormatterName=
DOTNET_GENERATE_ASPNET_CERTIFICATE=false
DOTNET_NOLOGO=true
DOTNET_SDK_VERSION=6.0.101
DOTNET_USE_POLLING_FILE_WATCHER=true
NUGET_XMLDOC_MODE=skip
POWERSHELL_DISTRIBUTION_CHANNEL=PSDocker-DotnetSDK-Debian-11
ASPNETCORE_ENVIRONMENT=Development
HOME=/root
Now stop, remove container and run new one based on the same image, but with the Production environment:
docker rm -f <containerId> && docker run --rm -d -e ASPNETCORE_ENVIRONMENT=Production aspnet_env_test:1.0
Check again the environment of newly created container:
docker exec <containerId> env
Mine output is this one:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=ebdaeb19795a
ASPNETCORE_ENVIRONMENT=Production
ASPNETCORE_URLS=
DOTNET_RUNNING_IN_CONTAINER=true
DOTNET_VERSION=6.0.1
ASPNET_VERSION=6.0.1
Logging__Console__FormatterName=
DOTNET_GENERATE_ASPNET_CERTIFICATE=false
DOTNET_NOLOGO=true
DOTNET_SDK_VERSION=6.0.101
DOTNET_USE_POLLING_FILE_WATCHER=true
NUGET_XMLDOC_MODE=skip
POWERSHELL_DISTRIBUTION_CHANNEL=PSDocker-DotnetSDK-Debian-11
HOME=/root
So, we see here that environment is successfully passed to container file system.
The only thing to be done in your app - just call aforementioned command for your env variables to be caught (with or without prefix parameter overload):
builder.Configuration.AddEnvironmentVariables();
BTW: afaik you might or might not use prefix in environment variables. But prefix itself is removed from env variable names, so you get access to them from your app without prefix if you use it (did not check it).
Guess your error was in using ENV directives without prefix in Dockerfile.
Names in Dockerfile should match exactly.
That works fine.

How use ENV variables in Dockerfile ENTRYPOINT command

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?

how to set an environment variable with pwd in a docker container

I would like to set the LD_LIBRARY_PATH variable based on my working directory using my Dockerfile. I have tried using ENV $PWD/some/subpath but when I inspect the container later using docker exec mycontainer bash -c "env" it shows up as /some/subpath rather than /my/working/dir/some/subpath however I also see that PWD is defined as /my/working/dir/ as I would expect it to be. so why is using $PWD in my Dockerfile not substituting the way I am expecting it to?
From this answer, $PWD is a special environment variable set when running a shell. Unlike RUN commands, ENV commands do not create a shell so PWD is never set.
To get the value of PWD at build time, you could instead use a build-arg and pass in $PWD in the build command.
You'd do this in your Dockerfile like this:
# dockerfile
ARG working_directory
ENV $working_directory/some/subpath
and build like this:
docker build --build-arg "working_directory=$PWD" .

DockerFile and environment variable

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.

Dockerfile and environnement variables

I have a strange behavior with my Dockerfile. I try to make it write file with text coming from environment varibales :
FROM ubuntu:14.04
ENV KEY ''
ENV VAL ''
RUN echo "${KEY}:${VAL}" > /etc/test
CMD []
I built this image and run it like this :
docker run -it --rm -e KEY=aaa -e VAL=bbb mytest
If I display the /etc/test file, it is empty (it is present, but empty). It seems that when it creates the file, environment variables are not set.
Any idea?
Thank you
The command in the docker file RUN echo "${KEY}:${VAL}" > /etc/test is executed when you build the image using docker build ...
Thus this is logical, since at that point the env variables are empty.
You need to move the commad to the CMD command which will run when the image is started.
You can define KEY and VALUE as arguments and set their values when you're building the docker image.
FROM ubuntu:14.04
ARG KEY
ARG VAL
RUN echo "${KEY}:${VAL}" > /etc/test
CMD []
Then you can build the image using like this:
docker build --build-arg KEY=<value> --build-arg VAL=<value> .
https://docs.docker.com/engine/reference/builder/#using-arg-variables

Resources