windows docker-compose args not working - docker

I'm trying to use args in a docker compose file.
The docker-compose file:
version: '3'
services:
service1:
image: test
restart: always
build:
context: C:/ProgramData/
dockerfile: Dockerfile
args:
entry: 1
volumes:
- C:/ProgramData/test
The Dockerfile:
FROM microsoft/dotnet-framework:3.5
ARG entry
WORKDIR C:\\test
ADD ["/bin/x86/Release/","C:/test/"]
ENTRYPOINT ["C:\\test\\file.exe", ${entry}]
I don't know how exactly works the syntax in the docker file. How I have to put the arg in the ENTRYPOINT?

You cannot use ARG in ENTRYPOINT (at least not directly). See How to pass ARG value to ENTRYPOINT?:
Both ARG and ENV are not expanded in ENTRYPOINT or CMD. (https://docs.docker.com/engine/reference/builder/#environment-replacement) However, because ENVs are passed in as part of the environment, they are available at run time, so the shell can expand them. (This means you can't use the array form of ENTRYPOINT or CMD.)

I solved this issue by changing the Dockerfile as follows:
FROM microsoft/dotnet-framework:3.5
ARG ENTRY
ENV my_env=$ENTRY
#RUN echo %ENTRY%
#RUN echo %my_env%
WORKDIR C:\\test
ADD ["/bin/x86/Release/","C:/test/"]
ENTRYPOINT C:/test/file.exe %my_env%

Related

Passing env variables to RUN in Dockerfile

How to pass environment variables to RUN command in Dockerfile? In my scenario, I want to pass env variables to RUN command which runs a script & uses these variables?
.env
NAME=John
script.sh
#!/bin/sh
echo $NAME
Dockerfile
FROM alpine:3.14
COPY . .
RUN chmod +x script.sh
RUN ./script.sh
docker-compose.yml
version: "3.1"
services:
foo:
container_name: foo
build:
context: .
dockerfile: Dockerfile
restart: unless-stopped
How can I pass the NAME env variable to the last RUN command in Dockerfile (to be used by the script executable)?
I am aware of --build-arg but it is inconvenient when there are 100s of env variables. Even then how can I format the docker compose command to read all arguments from an env file & pass them as build arguments?

How do I add ability for child image to overwrite arg from base docker image?

So I want to have an arg, but also a way to overwrite this arg via onbuild. Something like this in the base dockerfile:
ARG randvar
ONBUILD ARG randvar
ENV randvar=$randvar
In my child dockerfile I have
FROM baseimage
ARG randvar
RUN echo $randvar
But I can't seem to overwrite the ARG for some reason.
This is my docker-compose file.
version: "3.9"
services:
basec:
build:
context: ./dir
dockerfile: base.Dockerfile
args:
randvar: "this is orig arg"
childc:
build:
context: ./dir
dockerfile: child.Dockerfile
args:
randvar: "this is new arg"
First I run docker-compose run basec then docker-compose run childc
My echo statement is showing "this is orig arg" instead of "this is new arg". Thx

How to pass ENV arguments in my Dockerfile when using docker-compose

I have a docker-compose.yml that has a section:
myservice:
env_file:
- myvars.env
My env variable file has:
myvars.env:
SOME_VAL=123
And then in my Dockerfile I have this:
..
RUN echo "some_val ${SOME_VAL}"
ENTRYPOINT bash ${APP_BASE}/run.sh SOME_VAL=${SOME_VAL}
When I run docker-compose up, the value of some_val is empty.
Why is SOME_VAL not accessible in my dockerfile?
How do I pass the env variable SOME_VAL to my run.sh script?
You need to declare the variable with ENV in the Dockerfile before using it:
ENV variables are also available during the build, as soon as you introduce them with an ENV instruction.
Dockerfile
ENV SOME_VAL
RUN echo "some_val ${SOME_VAL}"
ENTRYPOINT bash ${APP_BASE}/run.sh SOME_VAL=${SOME_VAL}
When you docker-compose build an image, it only considers the build: sections of the docker-compose.yml file. Nothing else from any other part of the file is considered. environment: and env_file: settings aren't available, nor are volumes: nor networks:. The only way to pass settings in is through the Dockerfile ARG and the corresponding Compose args: settings, and even then, you only want to use this for things you'd "compile in" to the image.
Conveniently, shell scripts can directly access environment variables already, so you don't need to do anything at all; just use the variable.
#!/bin/sh
# run.sh
echo "SOME_VAL is $SOME_VAL"
# Dockerfile
FROM busybox
WORKDIR /app
COPY run.sh .
# RUN chmod +x run.sh
CMD ["./run.sh"]
# docker-compose.yml
version: '3.8'
services:
echoer:
build: .
env_file:
- my_vars.env
# environment:
# SOME_VAL: foo

Setting container PATH with an ENV parameter

I have a docker-compose file which includes the following:
environment:
DOCUMENT_ROOT: /var/some/dir
I would like to add that path to my container.
In my DockerFile I add:
RUN echo "export PATH=$PATH:${DOCUMENT_ROOT}" >> /root/.bashrc
But it doesn't work. It seems the ENV parameter isn't available.
What's the problem ?
Yaron
ARG some_variable_name
RUN echo "export PATH=$PATH:${some_variable_name}" >> /root/.bashrc
You should use ARG in Dockerfile and set arguments in build command:
docker build --build-arg some_variable_name=a_value
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, CMD). You can use ARG values to set ENV values to work
around that.
or in docker-compose:
version: '3'
services:
somename:
build:
context: ./app
dockerfile: Dockerfile
args:
some_variable_name: a_value
Understanding Docker Build Args, Environment Variables and Docker Compose Variables

Pass host environment variables to dockerfile

How can I pass a host environment variable (like user and hostname) to a dockerfile?
For example, if my username is taha:
echo $USER
taha
How do I write my Docker file to get the same output?
FROM centos:centos7
ARG myuser=$USER
CMD echo $myuser
I was experiencing the same issue. My solution was to provide the variable inside of a docker-compose.yml because yml supports the use of environment variables.
In my opinion this is the most efficient way for me because I didn't like typing it over and over again in the command line using something like docker run -e myuser=$USER . . .
Declaring ENV myuser=$USER will NOT work, in the container, $myuser will be set to null.
So your docker-compose.yml could look something like this:
version: '3'
services:
app:
build:
context: .
dockerfile: Dockerfile
environment:
- "myuser=${USER}"
and can be run with the short command docker-compose up
To check that the variable has been applied, run docker exec -it container-name printenv to list all variables in the container.
When you start your docker container you can pass environment variables using the -e option like so:
docker run -it <image> -e USER=$USER /bin/bash
I had a similar use-case where I wanted to be able to specify a version for the image. This has a slight extra requirement that you must specify the ARG before the FROM.
First we specify IMAGE_VERSION in the Dockerfile, as per the question I'm also including a USER arg that we can pass in too:
# give it a default of latest
# declare the ARG before FROM
ARG IMAGE_VERSION=latest
FROM centos:${IMAGE_VERSION}
ARG myuser
CMD echo $myuser
Then, as from the Docker compose docs on args:
Add build arguments, which are environment variables accessible only during the build process.
You can add these in your docker-compose.yml for example:
version: '3'
services:
app:
build:
context: .
dockerfile: Dockerfile
args:
"myuser=${USER}"
IMAGE_VERSION
Then as long as you have IMAGE_VERSION set in your environment it will be passed through.
you need to use the ENV setting in your dockerfile
ENV myuser=$USER
https://docs.docker.com/engine/reference/builder/#env

Resources