docker-compose, can't print environment variable in docker container - docker

I want to print environment variable defined in docker-compose file.
Here is my docker-compose-1.yml:
version: '3.6'
services:
busybox:
image: busybox
command: 'echo $DEBUG'
environment:
- DEBUG='123456'
And, try to print the DEBUG environment variable in docker container:
☁ environment-variables-in-compose [master] ⚡ docker-compose -f docker-compose-1.yml up
WARNING: The DEBUG variable is not set. Defaulting to a blank string.
Creating network "environmentvariablesincompose_default" with the default driver
Creating environmentvariablesincompose_busybox_1 ... done
Attaching to environmentvariablesincompose_busybox_1
busybox_1 |
environmentvariablesincompose_busybox_1 exited with code 0
As you can see, got WARNING: The DEBUG variable is not set. Defaulting to a blank string.
Am I wrong?
update 1:
docker-compose-1.yml:
version: '3.6'
services:
busybox:
image: busybox
command: 'echo $$DEBUG'
environment:
DEBUG: 123456
I change command using double $ sign, but the result is still not what I want.
☁ environment-variables-in-compose [master] ⚡ docker-compose -f docker-compose-1.yml up
Creating network "environmentvariablesincompose_default" with the default driver
Creating environmentvariablesincompose_busybox_1 ... done
Attaching to environmentvariablesincompose_busybox_1
busybox_1 | $DEBUG
environmentvariablesincompose_busybox_1 exited with code 0
As you can see, the environment variable is printed as $DEBUG, not expected value 123456

Compose will expand variables from the environment where you are running compose. To expand the variable inside your container, escape the $ using $$:
command: '/bin/sh -c "echo $$DEBUG"'
For more details, see: https://docs.docker.com/compose/compose-file/#variable-substitution
Edit: I've also added a shell inside the container to expand the variable.

Related

How use a "calculated" variable in a docker-compose.yml or .env file

Question :
Can I use a "result of a bash command" as env variables in docker-compose.yml file ?
Can I "execute a command" and put the result in env variables during the "docker-compose up" ?
The use Case :
I work with docker & VScode in windows WSL2, and I want send "WSL2 internal IP" to my container to use Xdebug (which need a "remote_host").
The problem are the "WSL2 internal IP" can change on each reboot of the PC.
The commande used :
ip addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}'
Where I am
I have tested to put the command in .env file
MY_WSL_IP=$(ip addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}')
and the docker-compose.yml file
version: "3"
services:
lamp_test:
container_name: lamp_test
image: eurelis/aws-ami-php7:php73
volumes:
[...]
ports:
[...]
env_file: ./drupal.env
links:
[...]
environment:
- WSL_HOST_IP=${MY_WSL_IP}
[...]
In this case, I get the whole command in the container.
Notes
When in the terminal il put play the two command in the terminal, that's work
export MY_WSL_IP=$(ip addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}')
docker-compose -f etc/docker/docker-compose.yml up -d
But there is not the "use case" because variable are created "out side" the docker-compose configuration.
When using the VScode's docker plugin, I can't inject this "result"
I don't have found a proper way to inject the value in the container, nor a explicit "that's not possible".
If someone has a tips

I can't input after running command in docker, but I can if I execute it manually

I have a docker-compose file for starting a Terraria server, but after starting the server, I can't input any commands. If I start the server directly in my shell, I am able to input commands. How can I get the same result in docker as if I had run the command myself in a shell?
This is the desired behavior, which is what happens when I run it from my shell:
$ TerrariaServerVolume/TerrariaServer -pass xxx -port 7777 -world ~/absolute/path/TerrariaWorldsVolume/testWorldName.wld
Terraria Server v1.4.2.2
Listening on port 7777
Type 'help' for a list of commands.
: Server started
help // my input
Available commands:
... //list of commands
: % //I pressed Ctrl+c
$
This is what actually happens in my docker container:
$ sudo docker-compose up
Terraria Server v1.4.2.2
TerrariaServer_1 |
TerrariaServer_1 | Listening on port 7777
TerrariaServer_1 | Type 'help' for a list of commands.
TerrariaServer_1 |
TerrariaServer_1 | : Server started
^[[6;23
I don't know what ^[[6;23 is, but then here's me trying to input commands:
...
TerrariaServer_1 | : Server started
^[[6;23Rhelp
help
exit
stop
ljadgkljasdgl
^CGracefully stopping... (press Ctrl+C again to force)
Stopping terraria_TerrariaServer_1 ... done
$
This is my setup:
docker-compose.yml
version: "3"
services:
TerrariaServer:
image: "mono:6.8.0.96-slim"
ports:
- 7777:7777
expose:
- 7777
volumes:
- "./TerrariaServerVolume:/Terraria/Server"
- "./TerrariaWorldsVolume:/Terraria/Worlds"
environment:
- WorldName=testWorldName.wld
command: bash -c "/Terraria/Server/TerrariaServer -pass <password> -port 7777 -world /Terraria/Worlds/$WorldName"
stdin_open: true
tty: true
To type other commands after running docker-compose You need to use -d parameter.
Example:
docker-compose up -d
From docs:
-d, --detach Detached mode: Run containers in the background, print new container names.

setting a variable from a file

Is there a way to set a variable from a file in the docker compose?
The following does not work in compose (however it does if you attach to the container):
version: '2'
services:
foo:
image: busybox
command:
- /bin/sh
- -c
- |
echo "hello" > id #this file will be supplied by a volume-from
ls
cat id
TEST=$(cat id) #This line does not work
echo TEST
The error which is produced is:
ERROR: Invalid interpolation format for "command" option in service "foo":
you have to change a bit your config file.
version: '2'
services:
foo:
image: busybox
command:
- /bin/sh
- -c
- |
echo "hello" > id
ls
cat id
TEST=$$(cat id)
echo TEST
I checked against Docker Version Docker version 18.06.0-ce and Docker compose version docker-compose version 1.20.0-rc2,
https://github.com/docker/docker.github.io/blob/master/compose/compose-file/index.md#variable-substitution
You can use a $$ (double-dollar sign) when your configuration needs a
literal dollar sign. This also prevents Compose from interpolating a
value, so a $$ allows you to refer to environment variables that you
don’t want processed by Compose.

Declare env variable which value include space for docker/docker-compose

I have an environment variable defined in a file passed in via --env-file like this:
TEST_VAR=The value
Does anybody know whether this is legal? should I place " around the value for this to be interpreted as needed in docker?
Thanks
EDIT: Quotation marks will not be a good solution as it is will be part of the val see reference here.
Lets see the result running the following compose file:
version: "3"
services:
service:
image: alpine
command: env
env_file: env.conf
env.conf:
TEST_VAR1=The value
TEST_VAR2="The value2"
docker-compose up Result:
service_1 | PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
service_1 | TEST_VAR2="The value2"
service_1 | TEST_VAR1=The value
service_1 | HOME=/root
Therefore, it is legal to have spaces in the env value.
You can escape the space with a \:
TEST_VAR=The\ value
Edit: This is how I pass them when starting the container (i.e. docker run -e TEST_VAR=The\ value hello-world). If you're using docker-compose or an env file, see the answer by #yamenk.
In Dockerfile use doublequotes, do not use singlequotes because they do not expand variables inside, excerp from passing buildargs/envs to dockerfile and into a python script below:
ARG HOST="welfare-dev testapi"
ENV HOST "${HOST}"
ARG SITENAME="Institusjon"
ENV SITENAME "${SITENAME}"
RUN cd ${TESTDIR}/sensiotools/sensiotools && cd test && \
./testapi-events.py --activate --sitename="${SITENAME}" --host="${HOST}" --dbcheck --debug --wait=0.5 && \
./testapi-events.py --deactivate --sitename="${SITENAME}" --host="${HOST}" --dbcheck --debug
My case with docker-compose, if that can help. I couldn't make use of the suggestions in the other answers.
For a variable in volumes, I could use the .env file:
# .env
LOCAL_DIR=/local/path
while for a variable with spaces (for https://github.com/wolfcw/libfaketime in my case) I had to use command line: FAKETIME_ARG="#2021-02-11 13:23:02" docker-compose up.
The resulting docker-compose file (note the ${} just for LOCAL_DIR) :
# docker-compose.yml
services:
myservice:
build:
context: ./path/to/dir/of/Dockerfile
args:
- FAKETIME_ARG
volumes:
- ${LOCAL_DIR}:/path/in/container

Docker-compose does not start containers

I'm new with docker-compose. I have a problem when I use the command "docker-compose up -d" to start a multi-container application what should start the containers with the status "up" but all the time a execute the command the status is "Exit", I'm not sure if I'm doing something wrong, this is my docker-compose.yml file
version: '3'
services: catalog:
image: ciscatalog
hostname: catalogHost
command: hostname
volumes:
- /home/docker:/opt/host
container:
image: dis/ciscontainer
hostname: containerHost
command: hostname
volumes:
- /home/docker:/opt/host
inbound:
image: dsi/cisinbound
hostname: inboundHost
depends_on:
- catalog
links:
- catalog
command: hostname
volumes:
- /home/docker:/opt/host
outbound:
image: dsi/cisoutbound
hostname: outboundHost
depends_on:
- catalog
links:
- catalog
command: hostname
volumes:
- /home/docker:/opt/host
example run:
root#docker1:/home/docker/DSI# docker-compose scale catalog=3 container=4 inbound=1 outbound=1
Creating and starting dsi_catalog_1 ... done
Creating and starting dsi_catalog_2 ... done
Creating and starting dsi_catalog_3 ... done
Creating and starting dsi_container_1 ... done
Creating and starting dsi_container_2 ... done
Creating and starting dsi_container_3 ... done
Creating and starting dsi_container_4 ... done
Creating and starting dsi_inbound_1 ... done
Creating and starting dsi_outbound_1 ... done
root#docker1:/home/docker/DSI# docker-compose up -d
Starting dsi_container_4
Starting dsi_catalog_3
Starting dsi_catalog_1
Starting dsi_container_3
Starting dsi_catalog_2
Starting dsi_container_1
Starting dsi_outbound_1
Starting dsi_inbound_1
Starting dsi_container_2
root#docker1:/home/docker/DSI# docker-compose ps
Name Command State Ports
-------------------------------------------
dsi_catalog_1 hostname Exit 0
dsi_catalog_2 hostname Exit 0
dsi_catalog_3 hostname Exit 0
dsi_container_1 hostname Exit 0
dsi_container_2 hostname Exit 0
dsi_container_3 hostname Exit 0
dsi_container_4 hostname Exit 0
dsi_inbound_1 hostname Exit 0
dsi_outbound_1 hostname Exit 0
Please, can anybody help me? docker-compose version 1.13.
I think I got it: you are overriding the command you give in the dockerfile because you have this line in each of the services
command: hostname
so the only command you give is "hostname", which is actually what is run.
If you run an image with docker, you are probably running a completely different command!
If this is a linux based image, 'hostname' will just print the hostname and then exit. So then the command is stopped which logically will result in a stopped container (exit 0)
Remove the command-override so the containers actually run their respective commands.

Resources