In my .env file I have setup the USERNAME:
USERNAME=myuser
When I do a docker compose build, it is unable to resolve the placeholders $USERNAME in the Dockerfile.
My Dockerfile:
FROM busybox:latest as build
ENV USERNAME=$USERNAME
.
.
.
How can I achieve this
Try this:
docker-compose.yml
version: '3.5'
services:
container:
build:
context: .
args:
USERNAME: ${USERNAME} # from .env file
env_file:
- .env
Dockerfile
# docker-compose args
ARG USERNAME
...
.env
USERNAME=value
If you not use .env file, just remove env_file properties and set env in args.
I figured out the reason - the .env file must reside in the same folder as docker-compose.yml
Related
Is it possible to RUN a command within docker-compose.yml file? So instead of having a dockerfile where I have something like this RUN mkdir foo, to have the same command withing the docker-compose.yml file
services:
server:
container_name: nginx
image: nginx:stable-alpine
volumes:
- ./public:/var/www/html/public
ports:
- "${PORT:-80}:80"
???: 'mkdir foo' // <--- sudo code
I am trying to use wget inside my DockerFile to download a file that requires a password to do so, so in docker-compose.yml I tried to add to args a variable that reads a variable from host and passes it to DockerFile but i cannot figure out what i am doing wrong in here.
The whole thing is run inside visual code studio
Inside devcontainer.json
...
"containerEnv": {
"${localEnv:PRIVATE_TOKEN}"
},
"remoteEnv": {
"${localEnv:PRIVATE_TOKEN}"
},
...
inside .bashrc:
...
MY_PASSWORD='123'
inside Docker-Compose
version: '3.8'
services:
my_service:
image: ...
build:
...
args:
MY_PASSWORD: ${MY_PASSWORD}
...
inside Dockerfile:
ARG MY_PASSWORD
RUN wget --progress=dot:giga -O my_file.tgz remot_link_to_my_file --header "MY_PASSWORD: $MY_PASSWORD"
when inside Docker-compose i change ${MY_PASSWORD} to real value it does work.
Your args configuration is wrong or old. This works as expected:
docker-compose.yml
version: '3.8'
services:
web:
build:
context: .
args:
MY_PASSWORD: ${MY_PASSWORD}
Dockerfile
from ubuntu
ARG MY_PASSWORD
RUN mkdir /tmp/$MY_PASSWORD
RUN ls -la /tmp
Arg is passed and used to create folder:
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
If I have Dockerfile:
FROM ubuntu:18.04
ENV NAME=Dockerfile-wins
CMD echo $NAME
and a docker-compose.yml with:
version: '3'
services:
myservice:
build: .
container_name: myservice
environment:
- NAME=docker-compose-wins
when I run docker-compose up myservice which one will win out and why?
docker-compose wins out as it overrides whats in the Dockerfile. What is specified in the Dockerfile is a default. and can be overridden by using the docker command which is what docker-compose does.
This is documented in the docs here
under the covers essentially docker-compose is running something like
docker run -e VARIABLE=VALUE
I have part of a docker-compose file as so
docker-compose.yml
pitchjob-fpm01:
container_name: pitchjob-fpm01
env_file:
- env/base.env
build:
context: ./pitch
dockerfile: PitchjobDockerfile
volumes:
- "/Sites/pitch/pitchjob/:/Sites"
restart: always
depends_on:
- memcached01
- memcached02
links:
- memcached01
- memcached02
extends:
file: "shared/common.yml"
service: pitch-common-env
my extended yml file is
compose.yml
version: '2.0'
services:
pitch-common-env:
environment:
APP_VOL_DIR: Sites
WEB_ROOT_FOLDER: web
CONFIG_FOLDER: app/config
APP_NAME: sony_pitch
in the docker file for pitchjob-fpm01 i have a command like so
PitchjobDockerfile
# Set folder groups
RUN chown -Rf www-data:www-data /$APP_VOL_DIR
But when I run the command to bring up the stack
docker-compose -f docker-compose-base.yml up --build --force-recreate --remove-orphans
I get the following error
failed to build: The command '/bin/sh -c chown -Rf www-data:www-data
/$APP_VOL_DIR' returned a non-zero code: 1
I'm guessing this is because it doesn't have the $APP_VOL_DIR, but why is that so if the docker compose is extending another compose file that defines
environment: variables
You can use build-time arguments for that.
In Dockerfile define:
ARG APP_VOL_DIR=app_vol_dir
# Set folder groups
RUN chown -Rf www-data:www-data /$APP_VOL_DIR
Then in docker-compose.yml set app_vol_dir as build argument:
pitchjob-fpm01:
container_name: pitchjob-fpm01
env_file:
- env/base.env
build:
context: ./pitch
dockerfile: PitchjobDockerfile
args:
- app_vol_dir=Sites
I think your problem is not with the overrides, but with the way you are trying to do environment variable substitution. From the docs:
Note: Unlike the shell form, the exec form does not invoke a command
shell. This means that normal shell processing does not happen. For
example, RUN [ "echo", "$HOME" ]will not do variable substitution
on $HOME. If you want shell processing then either use theshell form
or execute a shell directly, for example:RUN [ "sh", "-c", "echo
$HOME" ].