How to get enviroment variables injected via -e key in entrypoint script? - docker

I need to launch my app on the port, set via -e key in docker run command
I run my app in ENTRYPOINT script and try to get $PORT env variable, but there no any env variable, set via -e keys.
Serving the app in Dockerfile
ENTRYPOINT ["sh", "entrypoint.sh"]
entrypoint.sh script:
#!/bin/bash
func start --port $PORT
Docker run command:
docker run -d -p 20937:8081 --name queue_0_middleware -e WEBSITE_CORS_ALLOWED_ORIGINS=https://functions.azure.com,https://functions-staging.azure.com,https://functions-next.azure.com -e PORT=8081

If I run this command locally I add image name like this: sudo docker run -p 15615:8081 30c7bb13d4b4 --name queue_2_middleware -e PORT=8081
That won't do what you expect, the docker command line is order sensitive. Everything after the image name is used to replace the value of CMD inside your image. With the entrypoint defined, those are just args to your entrypoint script. In other words, the docker command looks like:
docker run ${args_to_run} ${image_name} ${cmd_override}
The fix is to reorder your command with the args to run placed before the image name:
sudo docker run -p 15615:8081 --name queue_2_middleware -e PORT=8081 30c7bb13d4b4

Related

What does the "." in "docker run <image> . " do?

I have 2 commands:
docker run -d -p 5000:8080 ${image_name} .
and
docker run -d -p 5000:8080 ${image_name}
The only difference between these two commands is the period at the end. What is the purpose of the period? I understand that it signifies the current directory, but what is its use in a command like this?
Arguments after the image name are passed to the image's entrypoint, so it depends on the default ENTRYPOINT of the image. Often, the entrypoint is bash, so running
docker run -d -p 5000:8080 ${image_name} .
Is like running bash ..
The fact that you are publishing ports in your docker run command makes me think that the image runs a server. Let's say the entrypoint of your image is python server.py. Then the command
docker run -d -p 5000:8080 ${image_name} .
is akin to running python server.py .
and the command
docker run -d -p 5000:8080 ${image_name}
is akin to running python server.py (note the absence of the dot).

Replacing Docker environment variables while running the image locally

Docker Image : test
Following are default value in Dockerfile:
ENV users=2
ENV rampup=10
ENV duration=120
ENV environment=DEV
Following is entrypoint
ENTRYPOINT ["/entrypoint.sh"]
entrypoint.sh :
bash ./bin/jmeter.sh -n -t -Jenvironment=${environment} -Jusers=${users} -Jrampup=${rampup} -Jduration=${duration} -j ${workspace}report.log
Now I want to run it locally by replacing the environment variables:
docker run test -e environment=STG -e users=20 -e rampup=10 -e duration=120
But, somehow the values are not getting replaced. What is that I am doing incorrectly, can someone please help?
Any docker run options (like -e to set environment variables) need to go before the image name in the docker run command. Anything after the image name is interpreted as the command you'd like the container to run, and when you also have an entrypoint, gets passed as parameters to the entrypoint. (If you edit your script to include the line echo "$#" you'll see those -e options.)
docker run \
-e environment=STG -e users=20 -e rampup=10 -e duration=120 \
test
Dockerfile and Docker run command seems fine, I am pretty sure the issue is not with Docker, Here is the simplest example that you can.
FROM alpine
ENV users=2
ENV rampup=10
ENV duration=120
ENV environment=DEV
#COPY entrypoint.sh /entrypoint.sh
RUN echo $'#!/bin/ash \n\
echo \"env is Jenvironment=${environment} -Jusers=${users} -Jrampup=${rampup} -Jduration=${duration} -j ${workspace}report.log"' > /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
Build
Docker build -t testenv .
Run
docker run -e rampup=10 -e users=test -t alpintenv ash
So you can try to change you entrypoint.sh to
#!/bin/bash
./bin/jmeter.sh -n -t -Jenvironment=${environment} -Jusers=${users} -Jrampup=${rampup} -Jduration=${duration} -j ${workspace}report.log

java running inside docker container cannot see environment variables

I am new with Docker. I have a small Java application that I am trying to run inside Docker. I have created a Dockerfile to build the image.
My application is reading Environment Variables to know which database to connect to.
When running the command
docker run -d -p 80:80 occm -e "MYSQL_USER=user" -e "MYSQL_PASSWORD=password" -e "MYSQL_PORT=3306" -e "MYSQL_HOST=somehost"
and then enumerating all the variables using System.getenv, I dont see any of them. So I have added to the Docker file
ENV MYSQL_HOST=localhost
now when I run the container I see this variable, but I see it with the localhost value and not somehost.
What am I doing wrong?
The problem is how you are running your docker image.
$ docker run --help
Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
So, you are passing -e "..." -e "..." as command and arguments
You need to use -e as [OPTIONS].
$ docker run -d -p 80:80 -e "MYSQL_USER=user" -e "MYSQL_PASSWORD=password" -e "MYSQL_PORT=3306" -e "MYSQL_HOST=somehost" occm

Environment variables with docker run -e

Here is my Dockerfile :
FROM ubuntu:16.04
RUN apt-get update
RUN apt-get install -y default-jdk
ADD sample-docker-1.0-SNAPSHOT.jar app.jar
EXPOSE 8080
ENV SITENAME="ASDASD"
ENTRYPOINT ["java", "-jar", "app.jar"]
and here is a bit of Java code that i use:
#Value("${SITENAME:testsite}")
private String siteName;
with this setup everything works good and environment value of SITENAME is indeed "ASDASD". But when i try to set that variable with:
docker run -P -d --name spring spring-app -e SITENAME='DOCKERlocal'
it doesn't work (value is the one from Dockerfile). What am i missing here ?
You want to pass the -e to the docker command. So:
docker run -P -d --name spring -e "SITENAME=DOCKERlocal" spring-app
As you are doing it, you are passing it to the image entrypoint.

How do I append to PATH environment variable when running a Docker container?

I want to mount a volume and add it to the container's PATH environment variable. I've tried the following and none is working.
docker run -it -v $(PWD):/app -e PATH=$PATH:/app/bin debian:jessie bash
docker run -it -v $(PWD):/app -e PATH='$PATH:/app/bin' debian:jessie bash
docker run -it -v $(PWD):/app -e PATH='$$PATH:/app/bin' debian:jessie bash
docker run -it -v $(PWD):/app -e PATH='\$PATH:/app/bin' debian:jessie bash
How do I append the mounted volume to PATH?
If you you use -e option, the $PATH value is the PATH of the host instead of the container.
You can do it like this:
docker run -it -v $(PWD):/app debian:jessie bash -c 'export PATH=$PATH:/app/bin; bash'
Within the docker command line, you can't get "what will be the value of $PATH at runtime". Thus, you cannot append a PATH to the PATH variable, with docker's -e flag. To achieve what you want to do, you will need to do that in a script that will get executed as the cmd / entrypoint of your container.
You can define a fixed Path for your imported Apps and add the new Path to the Apps into the Environment-Variable "Path"
Let's take your Path "/app". In your Dockerfile add the following Line:
ENV PATH=${PATH}:/app/bin
Build your modified Docker
Now you can access all Apps located under < external Directory >/bin that you mount to "/app" via
-v <external Directory>:/app
You can use a shell script (let's call it run.sh):
#/bin/bash
PATH=$PATH:/app/bin
"$#"
and call it from docker:
docker run -it -v $(PWD):/app debian:jessie /app/run.sh bash

Resources