How to specify in Dockerfile that the image is interactive? - docker

I have created a docker container that runs a command line tool. The container is supposed to be interactive. Am I somehow able to specify in the Dockerfile that the container is always started in interactive mode?
For reference this is the dockerfile:
FROM ubuntu:latest
RUN apt-get update && apt-get -y install curl
RUN mkdir adr-tools && \
cd adr-tools && \
curl -L https://github.com/npryce/adr-tools/archive/2.2.0.tar.gz --output adr-tools.tar.gz && \
tar -xvzf adr-tools.tar.gz && \
cp */src/* /usr/bin && \
rm -rf adr-tools
CMD ["/bin/bash"]
EDIT:
I know of the -it options for the run command. I'm explicitly asking for a way to do this in the docker file.
EDIT2:
This is not a duplicate of Interactive command in Dockerfile since my question addresses an issue with how arguments specified to docker run can be avoided in favor of specifying them in the Dockerfile whereas the supposed duplicate addresses an issue of interactive input during the build of the image by docker itself.

Many of the docker run options can only be specified at the command line or via higher-level wrappers (shell scripts, Docker Compose, Kubernetes, &c.). Along with port mappings and network settings, the “interactive” and “tty” options can only be set at run time, and you can’t force these in the Dockerfile.

You can use the docker run command.
docker build -t curly .
docker run -it curly curl https://stackoverflow.com
The convention is:
docker run -it IMAGE_NAME [COMMAND] [ARG...]
Where [COMMAND] is curl and [ARG...] are the curl arguments, which is https://stackoverflow.com in my example.
-i enables interactive process mode. You can't specify this in the Dockerfile.
-t allocates a pseudo-TTY for the container.

Are you looking for the -it option?
From the Docker documentation:
For interactive processes (like a shell), you must use -i -t together
in order to allocate a tty for the container process.
So, for example you can run it like:
docker run -it IMAGE_NAME [COMMAND] [ARG...]

Actually, in Ubuntu, I am running Apache Server in the background.
But for you, Try with below command and you should be able to go inside docker container.
docker exec -i -t your_container_name bash

Related

Trying to copy a script into a detached Docker container, and execute it with docker exec

Right now I am setting my Docker instance running with:
sudo docker run --name docker_verify --rm \
-t -d daoplays/rust_v1.63
so that it runs in detached mode in the background. I then copy a script to that instance:
sudo docker cp verify_run_script.sh docker_verify:/.
and I want to be able to execute that script with what I expected to be:
sudo docker exec -d docker_verify bash \
-c "./verify_run_script.sh"
However, this doesn't seem to do anything. If from another terminal I run
sudo docker container logs -f docker_verify
nothing is shown. If I attach myself to the Docker instance then I can run the script myself but that sort of defeats the point of running in detached mode.
I assume I am just not passing the right arguments here, but I am really not clear what I should be doing!
When you run a command in a container you need to also allocate a pseudo-TTY if you want to see the results.
Your command should be:
sudo docker exec -t docker_verify bash \
-c "./verify_run_script.sh"
(note the -t flag)
Steps to reproduce it:
# create a dummy script
cat > script.sh <<EOF
echo This is running!
EOF
# run a container to work with
docker run --rm --name docker_verify -d alpine:latest sleep 3000
# copy the script
docker cp script.sh docker_verify:/
# run the script
docker exec -t docker_verify sh -c "chmod a+x /script.sh && /script.sh"
# clean up
docker container rm -f docker_verify
You should see This is running! in the output.

How to navigate to different folder in prebuilt Docker container?

I'm using a prebuilt container from Dockerhub. When I run the container it acts like it's in a folder called workspace, since my run command sudo docker run -it shubhamgoel/birds:bigbang bash returns root#eg2e775g0a1b:/workspace#
I don't know how to navigate to the correct folder. I need to run this container in a folder /home/s/ucmr.
If I do
sudo docker run -it shubhamgoel/birds:bigbang bash -c "cd:/home/s/ucmr"
I get
bash: cd:/home/s/ucmr: No such file or directory
How do I navigate to the correct folder with this prebuilt container? Thank you.
__
Edit: I've tried
sudo docker run -v /kitty:/dog --name kittycat -it shubhamgoel/birds:bigbang
and when I search for 'dog' on my disk there's no such folder. Also when I type in mkdir frog and search for 'frog' on my disk there's no such folder...
docker run -it shubhamgoel/birds:bigbang bash -c "cd:/home/s/ucmr" is wrong for 2 reasons. The first one has already been covered by the other answer (wrong syntax with cd command). The other is that using the -it docker option with a non-interactive bash is kind of meaningless. The -c bash option just means "execute whatever there is between the double quotes and return to the caller", this last part makes the interactivity vanish.
A first naive solution, but still working, could be creating another shell like this:
docker run -it shubhamgoel/birds:bigbang bash -c "cd /home/s/ucmr && bash"
However, docker is far smarter and flexible and lets you override some Dockerfile directive, for instance the WORKDIR:
docker run -it -w="/home/s/ucmr" shubhamgoel/birds:bigbang bash

Run a repository in Docker

I am super new to Docker. I have a repository (https://github.com/hect1995/UBIMET_Challenge.git) I have developed in Mac that want to test it in a Ubuntu environment using Docker.
I have created a Dockerfile as:
FROM ubuntu:18.04
# Update aptitude with new repo
RUN apt-get update \
&& apt-get install -y git
RUN git clone https://github.com/hect1995/UBIMET_Challenge.git
WORKDIR /UBIMET_Challenge
RUN mkdir build
WORKDIR build
RUN cmake ..
RUN make
Now, following some examples I am running:
docker run --publish 8000:8080 --detach --name trial
But I do not see the output of the terminal from the docker to see what is going on. How could I create this docker and check what things I need to add and so on and so forth while inside the docker
TLDR
add '-it' and remove '--detach'
or add ENTRYPOINT in Dockerfile and use docker exec -it to access your container
Longer explanation:
With this command
docker run --publish 8000:8080 --detach --name trial image_name
you tell docker to run image image_name as container named trial, expose port 8080 to host and detach (run in background).
Your Dockerfile does not mention which command should be executed (CMD, ENTRYPOINT), however your image extends 'ubuntu:18.04' image, so docker will run command defined in that image. It's bash.
Your container by default is in non interactive mode so bash has nothing to do and simply exits. Check this with docker ps -a command.
Also you have specified --detach command which tells docker to run container in background.
To avoid this situation you need to remove --detach and add -it (interactive, allocate pseudo-tty). Now you can execute commands in your container.
Next step
Better idea is to set ENTRYPOINT to your application or just hang container with 'sleep infinity' command.
try (sleep forever or run /opt/my_app):
docker run --publish 8000:8080 --detach --name trial image_name sleep infinity
or
docker run --publish 8000:8080 --detach --name trial image_name /opt/my_app
You can also define ENTRYPOINT in your Dockerfile
ENTRYPOINT=sleep infinity
or
ENTRYPOINT=/opt/my_app
then use
docker exec -it trial bash #to run bash on container
docker exec trial cat /opt/app_logs #to see logs
docker logs trial # to see console output of your app
You want to provide and ENTRYPOINT or CMD layer to your docker file I believe.
Right now, it configures itself nicely when you build it - but I'm not seeing any component that points to an executable for the container to do something with.
You're probably not seeing any output because the container 'doesn't do anything' currently.
Checkout this breakdown of CMD: Difference between RUN and CMD in a Dockerfile

Practically, what is the difference between docker run -dit(-itd) vs docker run -d?

I've used docker run -it to launch containers interactively and docker run -d to start them in background. These two options seemed exclusive. However, now I've noticed that docker run -dit (or docker run -itd) is quite common. So what is the difference? When -it is really needed together with -d?
Yes, sometimes, it's necessary to include -it even you -d
When the ENTRYPOINT is bash or sh
docker run -d ubuntu:14.04 will immediately stop, cause bash can't find any pseudo terminal to be allocated. You have to specify -it so that bash or sh can be allocated to a pseudo terminal.
docker run -dit ubuntu:14.04
If you want to use nano or vim with any container in the future, you have to specify -it when the image starts. Otherwise you'll get error. For example,
docker run --name mongodb -d mongo
docker exec -it mongodb bash
apt-get update
apt-get install nano
nano somefile
It will throw an error
Error opening terminal: unknown.

Start and attach a docker container with X11 forwarding

There are various articles like this, this and this and many more, that explains how to use X11 forwarding to run GUI apps on Docker. I am using a Centos Docker container.
However, all of these approaches use
docker run
with all appropriate options in order to visualize the result. Any use of docker run creates a new image and performs the operation on top of that.
A way to work in the same container is to use docker start followed by docker attach and then executing the commands on the prompt of the container. Additionally, the script (let's say xyz.sh) that I intend to run on Docker container resides inside a folder MyFiles in the root directory of the container and accepts a parameter as well
So is there a way to run the script using docker start and/or docker attach while also X11-forwarding it?
This is what I have tried, although would like to avoid docker run and instead use docker start and docker attach
sudo docker run -it \
--env="DISPLAY" \
--volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \
centos \
cd MyFiles \
./xyz.sh param1
export containerId='docker ps -l -q'
This in turn throws up an error as below -
/usr/bin/cd: line 2: cd: MyFiles/: No such file or directory
How can I run the script xyz.sh under MyFiles on the Docker container using docker start and docker attach?
Also since the location and the name of the script may vary, I would like to know if it is mandatory to include each of these path in the system path variable on the Docker container or can it be done at runtime also?
It looks to me your problem is not with X11 forwarding but with general Docker syntax.
You could do it rather simply:
sudo docker run -it \
--env="DISPLAY" \
--volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \
-w MyFiles \
--rm \
centos \
bash -c xyz.sh param1
I added:
--rm to avoid stacking old dead containers.
-w workdir, obvious meaning
/bin/bash -c to get sure your script is interpreted by bash.
How to do without docker run:
run is actually like create then start. You can split it in two steps if you prefer.
If you want to attach to a container, it must be running first. And for it to be running, there must be a process currently running inside.

Resources