Environment variables with docker run -e - docker

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.

Related

Is it possible to install mysqli extensions via docker run command

I created a docker volume with index.php file.
Now, every time I run a new container I want to mount this file (I know how to do that), but what if I want to add mysqli extension to any new container,
Is it possible????
docker run -d -it -p 80:80 test --name=www1 --mount source=myvol1,destination=/var/www/html php:7.2.2-apache ----
docker-php-ext-install mysqli
See this image's Dockerfile & it's entrypoint:
If you add command to install extension at the end of docker run which will act as CMD of entrypoint, it will make apache2-foreground has no chance to start.
So, the only way in runtime is:
Step1: start the container
docker run -d -it -p 80:80 --name=www1 --mount source=myvol1,destination=/var/www/html php:7.2.2-apache
Step2: install extension with exec
docker exec -it www1 docker-php-ext-install mysqli
Step3: restart the container:
docker stop www1 && docker start www1
And in fact, the typical way to do this is to customize it in your own dockerfile, but it maybe not you want:
Dockerfile:
FROM php:7.2.2-apache
RUN xxx // install things as you like here
I know that it's a bit later, but if someone were facing the same issue and don't want to use a Dockerfile here's how you can do it.
If you look at php-apache's 7.2 Dockerfile where CMD is set you can find the apache2-foreground command.
You can just invoke the mysqli install command on docker run and append the CMD content like:
docker run -d -it -p 80:80 --name=www1 --mount source=myvol1,destination=/var/www/html php:7.2.2-apache sh -c 'docker-php-ext-install mysqli && docker-php-ext-enable mysqli && apache2-foreground'
Doing that way the mysqli extension will be installed, loaded and the container entrypoint properly loaded.

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

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

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

Run docker with dynamic parameter

I'm trying to run a java application on a docker container where the jvm argument of the java program would be dynamic.
Dockerfile:
FROM amazonlinux
ADD http://company.com/artifactory/bins-release-local/com/marc/1.3.1/marc-1.3.1.tar.gz /root/
ADD log4j2.xml /root/
RUN tar xzf /root/marc-1.3.1.tar.gz -C /root && rm -f /root/marc-1.3.1.tar.gz
RUN yum install -y java
ENTRYPOINT ["/bin/bash", "-c", "/usr/bin/java", "${JVM_ARGS}", "-jar", "/root/marc.jar"]
I try to run the container like so:
docker run --rm -it --env-file jvm_args.env -e CLIENT=google moshe/java:latest
And the jvm_args.env is:
JVM_ARGS=-d64
-Dicmq=${CLIENT}
-Dlog4j.configurationFile=/root/log4j2.xml
-server
I couldn't seem to get it to work. I need the client to be dynamic and the JVM_ARGS should contain the client.
Ideas?

Why does docker "--filter ancestor=imageName" find the wrong container?

I have a deployment script that builds new images, stop the existing containers with the same image names, then starts new containers from those images.
I stop the container by image name using the answer here: Stopping docker containers by image name - Ubuntu
But this command stops containers that don't have the specified image name. What am I doing wrong?
See here to watch docker stopping the wrong container:
Here is the dockerfile:
FROM ubuntu:14.04
MAINTAINER j#eka.com
# Settings
ENV NODE_VERSION 5.11.0
ENV NVM_DIR /root/.nvm
ENV NODE_PATH $NVM_DIR/versions/node/v$NODE_VERSION/lib/node_modules
ENV PATH $NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH
# Replace shell with bash so we can source files
RUN rm /bin/sh && ln -s /bin/bash /bin/sh
# Install libs
RUN apt-get update
RUN apt-get install curl -y
RUN curl https://raw.githubusercontent.com/creationix/nvm/v0.31.0/install.sh | bash \
&& chmod +x $NVM_DIR/nvm.sh \
&& source $NVM_DIR/nvm.sh \
&& nvm install $NODE_VERSION \
&& nvm alias default $NODE_VERSION \
&& nvm use default
RUN apt-get clean
# Install app
RUN mkdir /app
COPY ./app /app
#Run the app
CMD ["node", "/app/src/app.js"]
I build like so:
docker build -t "$serverImageName" .
and start like so:
docker run -d -p "3000:"3000" -e db_name="$db_name" -e db_username="$db_username" -e db_password="$db_password" -e db_host="$db_host" "$serverImageName"
Why not use the container name to differentiate you environments?
docker run -d --rm --name nginx-dev nginx
40ca9a6db09afd78e8e76e690898ed6ba2b656f777b84e7462f4af8cb4a0b17d
docker run -d --rm --name nginx-qa nginx
347b32c85547d845032cbfa67bbba64db8629798d862ed692972f999a5ff1b6b
docker run -d --rm --name nginx nginx
3bd84b6057b8d5480082939215fed304e65eeac474b2ca12acedeca525117c36
Then use docker ps
docker ps -f name=nginx$
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3bd84b6057b8 nginx "nginx -g 'daemon ..." 30 seconds ago Up 28 seconds 80/tcp, 443/tcp nginx
According to the docs --filter ancestor could be finding the wrong containers if they are in any way children of other containers.
So to be sure my images are separate right from the start I added this line to the start of my dockerfile, after the FROM and MAINTAINER commands:
RUN echo DEVTESTLIVE: This line ensures that this container will never be confused as an ancestor of another environment
Then in my build scripts after copying the dockerfile to the distribution folder I replace DEVTESTLIVE with the appropriate environment:
sed -i -e "s/DEVTESTLIVE/$env/g" ../dist/server/dockerfile
This seems to have worked; I now have containers for all three environments running simultaneously and can start and stop them automatically through their image names.

Resources