Overwriting of environment variables in Dockerfile with passed by `--build-arg` - docker

I am building two docker images, one is a base docker image, and another is a custom image.
The custom image is build from base image, but I want to assign different environment variables in the image.
For example, I prepare following Dockerfiles for these two images.
For base image:
# base.Dockerfile
FROM ubuntu
ARG MY_ENV
ENV MY_ENV=${MY_ENV}
# RUNs to install basic tools
# ...
For custom image
# base.Dockerfile
FROM my_base_image
ARG MY_ENV
ENV MY_ENV=${MY_ENV}
ENV IMAGE='This container is from a custom image'
# RUNs to setup custom images
# ...
Then build and run like follows.
# build a base image
docker build --file 'base.Dockerfile' \
--build-arg MY_ENV='my_value_in_base' \
--tag 'my_base_image' .
# build a custom image
docker build --file 'custom.Dockerfile' \
--build-arg MY_ENV='my_value_in_custom' \
--tag 'my_custom_image' .
I expected that in
I expected that 'my_value_in_custom' is stored in MY_ENV in my_custom_image, but 'my_value_in_base' is stored.
$ docker run my_custom_image env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=9fd195c99739
MY_ENV=my_value_in_base
IMAGE=This container is from custom image
HOME=/root
How can I overwrite MY_ENV when I build the custom image?
docker run -e MY_ENV='my_value_in_custom' changes the environment variables in the container, but this is not what I am looking for as I want to change the environment variables in the custom image.

I suspect it's not possible to replace environment variables in the specific way you suggest.
The documentation on Dockerfile ARG notes:
Environment variables defined using the ENV instruction always override an ARG instruction of the same name.
You're probably in this case. In the second Dockerfile, an environment variable $MY_ENV is defined (from the base image), and so even though there's an ARG without an ENV before it in this Dockerfile, the extant environment variable still takes precedence.
In practice you may not need to set this variables in a Dockerfile at all. You can also specify environment variable values when you run a container, and this is a more appropriate way to specify many values (related host names, credentials). The `docker run -e' invocation at the end of your question does this, and for a user-provided setting, I'd frequently expect that to be correct.
If you really need to override the environment variable in the derived image, and the value really needs to be build-time configurable, then you need to give the ARG a different name.
FROM my_base_image
ARG CUSTOM_MY_ENV
ENV MY_ENV=${CUSTOM_MY_ENV}
docker build --file 'custom.Dockerfile' \
--build-arg CUSTOM_MY_ENV='my_value_in_custom' \
--tag 'my_custom_image' .

Related

Pass Linux enviromental varibles into a dockerfile

I have a docker image that needs some credentials passed from the host-environment. How do I pass Linux environmental variables into dockerfile. No flags attachment only dockerfile.
When I build the Docker Image it fetches packages from a local repo that needs authentication. This is all automated and the credentials depend on the host machine that is running.
I have tried to google it and only found how to pass hard-coded varibles. But I need e.g.
export VAR=[PASSWORD]
to be passed into the dockerfile.
ENV PASSWORD = $VAR
You should use ARG with the ENV in your Dockerfile:
ARG name
ENV env_name $name
When you build your image, pass the arg from your local environment
docker build -t my_image --build-arg name=$MY_LOCAL_ENV_VAR .

Docker file set arguments from environment variables

I want to just print HOMEPATH variable from my machine:
This is my Dockerfile:
FROM python:3.8-slim
ARG some_path=$HOMEPATH
RUN echo "this is some_path: $some_path"
but receiving empty string, during image creation - docker build -t test_image . :
What I am doing wrong ?
Docker doesn't expose the builder to this sort of security risk. The build environment could have sensitive data in environment variables that they do not want exposed when the build arbitrary docker images. To inject a variables during build, you must explicitly pass it on the build command line with:
docker build --build-arg "some_path=$HOMEPATH" -t test_image .
Note that the path on the build server is typically not something you would want to inject in a build. The same build should work regardless of where you perform the build.

How to use environment variable from parent Docker file?

I have two Dockerfiles Dockerfile.A & Dockerfile.B where Dockerfile.B inherits using the FROM keyword from Dockerfile.A. In Dockerfile.A I set an environment variable that I would like to use in Dockerfile.B (PATH). Is this possible, and how would I go about doing it?
So far I have tried the following in Dockerfile.A:
RUN export PATH=/my/new/dir:$PATH
ENV PATH=/my/new/dir:$PATH
RUN echo "PATH=/my/new/dir:$PATH" >/etc/profile
And in Dockerfile.B, respectively:
Just use tools in the path to see if they were available (they were not)
ENV PATH
RUN source /etc/profile
I realized that every RUN command is executed in it's own environment, and that is probably why the ENV keyword exists, to make it possible to treat environments independently of the RUN commands. But I am not sure what that means for my case.
So how can I do this?
Works as expected for me.
Dockerfile.A
FROM alpine:3.6
ENV TEST=VALUE
Build it.
docker build -t imageA .
Dockerfile.B
FROM imageA
CMD echo $TEST
Build it.
$ docker build -t imageB .
Run it
$ docker run -it imageB
VALUE

Build the docker image with environment variables

so the objective is to have a different image for prod and testing so there are certain variables change accordingly so I need to set env variables during the build.
# Dockerfile
ENV Somename: $value
...
docker build --build-arg Somename=value -t test .
docker run -d -p port:port test
this work flow is not taking the env variables
First you need to consume the build-arg inside you dockerfile using the ARG command.
FROM alpine
# consume the build arg
ARG somename
# persist the env variable in the built image
ENV somename=$somename
# somename will appear as an env variable
RUN echo $somename
RUN env
And running the build command docker build --build-arg somename=hello . will show you an env variable somename=hello
your syntax is not correct, do not put
:
it is either
ENV somename somevalue
or
ENV somename=somevalue
Check the doc
https://docs.docker.com/engine/reference/builder/#env

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