DockerFile and environment variable - docker

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.

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?

Passing env variables at runtime without quotes

When passing environment during docker runtime, my environment variables are getting wrapped with quotes. How am I able to set an environment variable without having it quoted?
I set the environment like such; docker run server -e NODE_ENV=dev
Output from the command above:
node dist/server.js "NODE_ENV=dev"
Heres a snippet from my Dockerfile
FROM base AS release
# copy production node_modules
COPY --from=dependencies /root/app/prod_node_modules ./node_modules
# copy app sources
COPY . .
# expose port and define CMD
EXPOSE 3000
ENTRYPOINT ["npm", "run", "start:prod"]
First of all I think the sequence of your docker run command has a problem.
-e option should be before your docker image name, like this
docker run -e NODE_ENV=dev server
If its still not helping, then try --env-file option of docker run.
docker run --env-file /path/to/server.env server
In server.env
NODE_ENV=dev

User-provided environment variable within docker CMD

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

Can we pass ENV variables through cmd line while building a docker image through dockerfile?

I am working on a task that involves building a docker image with centOs as its base using a Dockerfile . One of the steps inside the dockerfile needs http_proxy and https_proxy ENV variables to be set in order to work behind the proxy.
As this Dockerfile will be used by multiple teams having different proxies, I want to avoid having to edit the Dockerfile for each team. Instead I am looking for a solution which allows me to pass ENV variables at build time, e.g.,
sudo docker build -e http_proxy=somevalue .
I'm not sure if there is already an option that provides this. Am I missing something?
Containers can be built using build arguments (in Docker 1.9+) which work like environment variables.
Here is the method:
FROM php:7.0-fpm
ARG APP_ENV=local
ENV APP_ENV=${APP_ENV}
RUN cd /usr/local/etc/php && ln -sf php.ini-${APP_ENV} php.ini
and then build a production container:
docker build --build-arg APP_ENV=prod .
For your particular problem:
FROM debian
ENV http_proxy=${http_proxy}
and then run:
docker build --build-arg http_proxy=10.11.24.31 .
Note that if you build your containers with docker-compose, you can specify these build-args in the docker-compose.yml file, but not on the command-line. However, you can use variable substitution in the docker-compose.yml file, which uses environment variables.
So I had to hunt this down by trial and error as many people explain that you can pass ARG -> ENV but it doesn't always work as it highly matters whether the ARG is defined before or after the FROM tag.
The below example should explain this clearly. My main problem originally was that all of my ARGS were defined prior to FROM which resulted all the ENV to be undefined always.
# ARGS PRIOR TO FROM TAG ARE AVAIL ONLY TO FROM for dynamic a FROM tag
ARG NODE_VERSION
FROM node:${NODE_VERSION}-alpine
# ARGS POST FROM can bond/link args to env to make the containers environment dynamic
ARG NPM_AUTH_TOKEN
ARG EMAIL
ARG NPM_REPO
ENV NPM_AUTH_TOKEN=${NPM_AUTH_TOKEN}
ENV EMAIL=${EMAIL}
ENV NPM_REPO=${NPM_REPO}
# for good measure, what do we really have
RUN echo NPM_AUTH_TOKEN: $NPM_AUTH_TOKEN && \
echo EMAIL: $EMAIL && \
echo NPM_REPO: $NPM_REPO && \
echo $HI_5
# remember to change HI_5 every build to break `docker build`'s cache if you want to debug the stdout
..... # rest of whatever you want RUN, CMD, ENTRYPOINT etc..
I faced the same situation.
According to Sin30's answer pretty solution is using shell,
CMD ["sh", "-c", "cd /usr/local/etc/php && ln -sf php.ini-$APP_ENV php.ini"]

Resources