I have a Dockerfile that sets environment variables that are common to all environments, whether dev, test, or production ones, but I have to set another environment variable that is only applicable to my development environment, so I can't set it in the Dockerfile because such file is managed by the version control, so the change would be deployed to all environments.
How can add an environment variable to a docker container only in my local development environment?
In case that the env variable can be specified when the image is being used, then just supplying the variable then makes more sense. For instance, if you are locally testing the image, by using the docker cli, you can set the variable with:
docker run -e KEY=VALUE $image
If you are using other tools to test the image, there are always other methods to set env keys.
If it's required for you to have set the variable at build time, you can specify built args inside the Dockerfile.
An example for that would be:
FROM someimage:v1
ARG DEV_ONLY_VAR
ENV KEY=$DEV_ONLY_VAR
Using this, you can specify the build arg DEV_ONLY_VAR in the build command by writing:
docker build --build-arg DEV_ONLY_VAR=VALUE .
Note, even without the ENV KEY=$DEV_ONLY_VAR line the build arg will be available like a env variable during build time, on other run steps.
More on build args here
Related
I have a CI variable that I would like to use within my docker file. I have tried to include it such as
ENV TESTING_UNIT=$TESTING_ID
It seems like that you need to specify to Dockerfile that it expects an argument variable
With the following approach it will be available in the container
Change:
ENV TESTING_UNIT=$TESTING_ID
To:
ARG TESTING_UNIT_ARG
ENV TESTING_UNIT=$TESTING_UNIT_ARG
and build the image: docker build --build-arg TESTING_UNIT_ARG=$TESTING_ID
Is there any way to create local variables in Dockerfile that only available during the build process? What I can see is if I define a variable with the ENV keyword, then it will be available later in the image as an exported environment variable. But I would like to have a "technical" variable with build scope only.
I would like to avoid repetition in my Doclerfile so I would like to have a variable available only from the Dockerfile:
ENV MY_JAR=myJar.jar
COPY bin/$MY_JAR $ORACLE_HOME/user_projects/domains/$DOMAIN_NAME/lib/
COPY bin/$MY_JAR $ORACLE_HOME/wlserver/server/lib/mbeantypes/
But the MY_JAR variable appears in the container. I do not need it there. It just confuses users. Can I do this somehow?
Use ARG instead of ENV
ARG MY_JAR=myJar.jar # ARG is only available during the build of a Docker image
COPY bin/$MY_JAR $ORACLE_HOME/user_projects/domains/$DOMAIN_NAME/lib/
COPY bin/$MY_JAR $ORACLE_HOME/wlserver/server/lib/mbeantypes/
see also ARG or ENV, which one to use in this case?
You can use the --build-arg parameter to pass environment variables that lives just during docker building process.
So your docker build command will look something like this
docker build --build-arg HTTP_PROXY=http://10.20.30.2:1234 -t sample:v1 .
Where HTTP_PROXY is just available during the build process.
Both ARGs an ENVs are available to a Dockerfile at build time, but apparently Docker Compose allows only to specify ARGs in service.build.args. ENVs specified in service.environment apparently are not visible at build time (which also makes sense given this path).
So if my build depends on ENVs (as well as ARGs) and if I build with docker-compose build, how can I provide the build-time ENVs inside my docker-compose.yaml?
There's no way to externally pass environment variables into a Dockerfile, whether via docker build or the Compose build: block. You can only specify arguments.
If you really need to specify an environment variable at build time, you can pass it as an argument and then set the environment variable in the Dockerfile
ARG FOO
ENV FOO ${FOO}
You must rebuild the image if you ever change one of these things. That makes this technique not work well for deployment-specific settings like user IDs, host names, etc. It's also okay for container-side port numbers and filesystem paths to be fixed properties of the image.
I am using Docker composé ver 1.5 or 6 and nginx image. I want to parameterize the nginx.config. To do that I want to create a var from $(basename some path). But the problem is Docker does not accept dynamic vars like that in env part of the Dockerfile. Another problem is that I also cannot map those variables on build run as Docker compose does not accept dynamic, scripted vars. How to overcome that issue?
From nginx
ENV myvar=$(basename /)
This is impossible to build the image.
The other way was
ARG myvar
ENV myvar2=myvar
But my version of Docker compose allows only to set
Environment: myvar=$(basename mypathinthevolume/)
That also does not seem to work
After reading the config point of the 12 factor app I decided to override my config file containing default value with environment variable.
I have 3 Dockerfiles, one for an API, one for a front-end and one for a worker. I have one docker-compose.yml to run those 3 services plus a database.
Now I'm wondering if I should define the environment variables in Dockerfiles or docker-compose.yml ? What's the difference between using one rather than another ?
See this:
You can set environment variables in a service’s containers with the 'environment' key, just like with docker run -e VARIABLE=VALUE ...
Also, you can use ENV in dockerfile to define a environment variable.
The difference is:
Environment variable define in Dockerfile will not only used in docker build, it will also persist into container. This means if you did not set -e when docker run, it will still have environment variable same as defined in Dockerfile.
While environment variable define in docker-compose.yaml just used for docker run.
Maybe next example could make you understand more clear:
Dockerfile:
FROM alpine
ENV http_proxy http://123
docker-compose.yaml:
app:
environment:
- http_proxy=http://123
If you define environment variable in Dockerfile, all containers used this image will also has the http_proxy as http://123. But the real situation maybe when you build the image, you need this proxy. But, the container maybe run by other people maybe not need this proxy or just have another http_proxy, so they had to remove the http_proxy in entrypoint or just change to another value in docker-compose.yaml.
If you define environment variable in docker-compose.yaml, then user could just choose his own http_proxy when do docker-compose up, http_proxy will not be set if user did not configure it docker-compose.yaml.