I would like to run /bin/bash in the case that the CMD or ENTRYPOINT programs fails.
So: CMD top && /bin/bash
I want that when I close top with cntrl-C I get a shell in the container.
Thank you
This is the way to do it:
CMD bash -c 'top; bash'
Related
My cmd instruction in dockerfile is:
CMD /etc/init.d/ssh start && su - gpadmin bash -c /home/gpadmin/entrypoint.sh && tail -f /dev/null
I want to convert it to ENTRYPOINT instruction. My entrypoint script file is entrypoint.sh
I want to enter the entrypoint script with gpadmin user and also i want the container to stay alive with docker run command that is why i am using tail -f /dev/null command
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-alpine
ENV CORECLR_ENABLE_PROFILING=1 \
CORECLR_PROFILER={846F5F1C-F9AE-4B07-969E-05C26BC060D8} \
CORECLR_PROFILER_PATH=/opt/datadog/Datadog.Trace.ClrProfiler.Native.so \
DD_INTEGRATIONS=/opt/datadog/integrations.json \
DD_DOTNET_TRACER_HOME=/opt/datadog
WORKDIR /app
RUN apk --no-cache update \
&& apk add bash make curl
ARG TRACER_VERSION=1.19.1
RUN mkdir -p /opt/datadog
RUN curl -L https://github.com/DataDog/dd-trace-dotnet/releases/download/v${TRACER_VERSION}/datadog-dotnet-apm-${TRACER_VERSION}.tar.gz \
| tar xzf - -C /opt/datadog
WORKDIR /app
COPY --from=buildcontainer /app/build .
COPY ./Entrypoint.sh /
RUN chmod +x /Entrypoint.sh && /Entrypoint.sh
ENTRYPOINT ["dotnet","testdatadog.dll"]
Entrypoint.sh
#!/bin/bash
set -e
curl http://169.254.169.254/latest/meta-data/local-ipv4 > temp_var
export DD_AGENT_HOST=$(cat temp_var)
exec "$#"
When I ssh in to my ec2 and see for environment variables I don't see the DD_AGENT_HOST set. When I am manually trying to set the env it works. Am I missing something? appreciate the inputs.
The gist of the problem is that your directive RUN chmod +x /Entrypoint.sh && /Entrypoint.sh got executed at BUILD time, and had no impact on your RUNTIME environment.
Konrad's correct in changing your ENTRYPOINT to have Entrypoint.sh change your environment.
The issue with Konrad's solution is that the run command he used to start the container had no impact on the bash shell that docker ran when he issued the exec command.
Expanding on Konrad's answer a little, you can actually get entrypoint.sh to set your environment for you.
I copied Konrad's Dockerfile, but changed the ENTRYPOINT as follows:
FROM alpine:latest AS build
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
FROM alpine:latest
RUN apk add --no-cache bash
COPY --from=build /entrypoint.sh /entrypoint.sh
ENTRYPOINT [ "/entrypoint.sh", "bash" ]
Now, the entrypoint.sh will set the environment, and execute bash.
I used Konrad's command to run the container:
docker run -itd --rm --name entrypoint entrypoint-test:latest
24a7f3d740c37bb345374a835a465482e3bf49a04361e55205b6d63af48d5c3d
This results in the container being launched. Entrypoint.sh will run bash for us, but it's in daemon mode, so we will have to attach to it:
$ docker attach 24a7f3d740c37bb345374a835a465482e3bf49a04361e55205b6d63af48d5c3d
bash-5.0# echo $DD_AGENT_HOST
127.0.0.1
Alternatively, you can just run the docker image without the -d option, avoiding the daemon mode:
$ docker run -it --rm --name entrypoint entrypoint-test:latest
bash-5.0# echo $DD_AGENT_HOST
127.0.0.1
bash-5.0# echo Hit Ctrl-P Ctrl-Q to leave this container running
All that said, will this work for your dotnet invocation?
ENTRYPOINT [ "/entrypoint.sh", "dotnet" , "testdatadog.dll" ]
This:
RUN chmod +x /Entrypoint.sh && /Entrypoint.sh
actually runs the following command:
bash -c "chmod +x /Entrypoint.sh && /Entrypoint.sh"
Your script sets the environment variable for the Bash instance that runs it, which itself exits as soon as the script is finished, discarding its environment.
You need to move the execution of Entrypoint.sh to the ENTRYPOINT line.
Edit:
So this is my test Dockerfile (note that copying and changing permissions on the script is done in a separate stage to reduce the size of the final image):
FROM alpine:latest AS build
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
FROM alpine:latest
RUN apk add --no-cache bash
COPY --from=build /entrypoint.sh /entrypoint.sh
ENTRYPOINT [ "/entrypoint.sh", "sleep", "10m" ]
and entrypoint.sh:
#!/bin/bash
set -e
echo "127.0.0.1" > temp_var
export DD_AGENT_HOST=$(cat temp_var)
exec "$#"
I ran the following commands:
docker build -t entrypoint-test .
docker run -itd --rm --name entrypoint entrypoint-test:latest
docker exec -it entrypoint bash
and inside the newly opened Bash shell:
export
Result:
declare -x HOME="/root"
declare -x HOSTNAME="c951e699bf7b"
declare -x OLDPWD
declare -x PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
declare -x PWD="/"
declare -x SHLVL="1"
declare -x TERM="xterm"
No DD_AGENT_HOST!
So the I searched for the container's main process (in my case sleep)
ps -a | grep sleep
and got
1 root 0:00 sleep 10m
32 root 0:00 grep sleep
Finally I ran
strings /proc/1/environ
to see the environment of that proces.
Result:
HOSTNAME=3f9760ceb473
PWD=/
HOME=/root
TERM=xterm
SHLVL=0
DD_AGENT_HOST=127.0.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
DD_AGENT_HOST found!
So what's happening?
It's simple. entrypoint.sh sets the variable only for the process it executes - in my case sleep. docker exec creates a new, unrelated process running Bash. Since a new process (both in Linux and Windows) inherits environment from the parent process and the new Bash process, spawned by docker exec, is not a child (but rather a sibling) of the container's main process, it has no knowledge of DD_AGENT_HOST variable.
I hope this helps.
Edit 2:
I believe that what David Maze meant is that you can replace
ENTRYPOINT [ "/entrypoint.sh", "sleep", "10m" ]
with
ENTRYPOINT [ "/entrypoint.sh" ]
CMD [ "sleep", "10m" ]
and then you can run
docker run -it --rm --name entrypoint entrypoint-test:latest bash
so that entrypoint.sh executes bash rather than sleep 10m, allowing you to inspect the environment directly rather than through /proc/$pid/environ.
The equivalent in your Dockerfile would be:
ENTRYPOINT [ "/Entrypoint.sh" ]
CMD [ "dotnet" , "testdatadog.dll" ]
I cannot get a bash shell into an alpine container.
I'm starting with this Alpine container:
gitlab/gitlab-runner:alpine
I'm adding a bash shell and other configs in this dockerfile:
from gitlab/gitlab-runner:alpine
ENV http_proxy=<corporate_proxy>
ENV https_proxy=<corporate_proxy>
RUN apk add vim wget curl nmap lsof bash bash-completion which
CMD ["/bin/bash"]
RUN ls -l /bin # THIS WORKS, I CAN SEE 'BASH' SHOW UP WITH 755 OWNED BY ROOT
RUN which bash # THIS ALSO WORKS
RUN /bin/bash -c "echo hi" # YES, THIS WORKS TOO
However when spawning the container to use a bash shell via:
docker run -idt <image_name> /bin/bash, the container fails to start with FATAL: Command /bin/bash not found.
Note that these other options also fail for me when spawning a container: ash, sh, /bin/ash, /bin/sh, etc
running the container with --user root also does not work.
The entrypoint is a GitLab Runner script. Change it to bash to get shell access:
$ docker run -it --entrypoint /bin/bash <image_name>
It turns out something funky was being set in the container's entrypoint. I need to remember to override the entrypoint when spawning a new container via docker run.
Adding this line in the Dockerfile fixed the problem:
ENTRYPOINT: []
1- verify if you container in fully loaded by :
docker ps
so after to enter in bash shell like:
docker exec -it <<container_name>> bash
Alpine doesn't have bash, use sh instead:
docker exec -it 64103333b32 /bin/sh
I have to run my .sh script in Dockerfile based on "grafana/grafana" but I'm not sure how to do it.
FROM grafana/grafana
COPY setup.sh /setup.sh
CMD ["/bin/bash", "/setup.sh"]
after docker run my script is not running. I guess it due to in grafana Dockerfile runs another sh script.
Can you please try if that works:
RUN ./setup.sh
There are two ways to do it inside Dockerfile
RUN <command> (shell form, the command is run in a shell, which by default is /bin/sh -c on Linux or cmd /S /C on Windows)
RUN ["executable", "param1", "param2"] (exec form)
On a simple dockerfile:
FROM python:3
ENV PYTHONUNBUFFERED 1
WORKDIR /code/
If I run:
docker build -t my_image .
docker run -v ~/Downloads/data/:/home -it -d my_image # mount data folder inside home
docker exec -it container_id sh -c "python script.py -i /home/db.sqlite"
Everything runs ok. But I would like to run the script.py on run so that there is no need for an exec command.
So I added to the dockerfile:
ENTRYPOINT ["python script.py -i /home/db.sqlite"]
But when I run my container now it fails with a file or folder not found error at python script.py
I think the problem is how the ENTRYPOINT syntax works. Your using the exec-form and it does not find the binary (it uses the whole command line as path to the binary).
From https://docs.docker.com/engine/reference/builder/#entrypoint:
ENTRYPOINT has two forms:
ENTRYPOINT ["executable", "param1",
"param2"] (exec form, preferred)
ENTRYPOINT command param1 param2
(shell form)
So try either:
ENTRYPOINT ["/path/to/python", "script.py", "-i", "/home/db.sqlite"]
Or
ENTRYPOINT python script.py -i /home/db.sqlite