Ctrl-C In VSCode Terminal Does Not Interrupt Docker On Windows - windows

I'm working on a Docker container that, under normal circumstances, does not exit, so has no graceful exit logic. I've installed Docker Desktop on my Windows 11 system so I can build and test the container locally without the overhead of pushing to Git and waiting for CI to build.
If I run docker run --rm -p 80:80 my_container_image within the VSCode terminal, it runs, as expected. When I press Ctrl-C to send a keyboard interrupt to the process afterward so I can rebuild the image, nothing happens. I have to use the kill terminal function. Why can't I interrupt docker run from VSCode?
I'm using Powershell 7.2.6. Docker is configured to use the WSL 2 backend.
What I tried:
Pressing Ctrl-C in the terminal
What I expected:
The program to be exited
Possibly ^C to be printed in terminal
What actually happened:
Nothing.

Add -it to make the session interactive: docker run -it --rm -p 80:80 my_container_image.
As stated here:
The -it instructs Docker to allocate a pseudo-TTY connected to the
container’s stdin; creating an interactive bash shell in the
container.

Related

Is there a way to reintroduce yourself to a docker container running bash?

Let's say I have one docker container that when run it finishes with bash. So after docker run I have a bash terminal and I can put commands.
If for some reason I lost contact to this terminal (it can happen) and then in another terminal, I do docker ps, I can see the container running. However I am not "inside" the bash of this docker
Right now what I do is to delete this and then run docker run again but is there a way I can rejoin the terminal of this running container?
You can "detach" from a container without closing the program by Ctrl-P + Ctrl-Q
docker run -it -d --entrypoint sh busybox
docker attach $container_id
/ # #inside container, use Ctrl-p Ctrl-q to detach

Dockerfile CMD for taking bash commands from host

I've created a dockerfile with various compile and build tools. The goal of the dockerimage is to standardize our development tools, and make it easy and consistent for developing.
Everything is installed.
What I am stuck on, is how to make the docker container keep running, and be able to have a bash shell to that container so that I can run, for example, make etc. ?
If I use ENTRYPOINT /bin/bash my container exits immediately. How to keep the container running?
You should use the command at run time. You run your Docker container in interatice mode (-i) and set the command to "/bin/bash":
docker run -it myDockerImage myCommandToExecuteInteractively
For instance:
docker run -it myDocker /bin/bash
Here is a real life example:
a) Pulling the most basic image
docker pull debian:jessie-slim
b) Let's have a bash there:
docker run -it debian:jessie-slim /bin/bash
c) Enjoy:
A docker container will run as long as the CMD/Entrypoint from your Dockerfile takes.
You can run your Docker container in interactive mode using switch i
sudo docker run -it --entrypoint=/bin/bash <imagename>
Example : docker run -it --entrypoint=/bin/bash ubuntu:14.04
This will start an interactive shell in your container. Your container will exit as soon as you exit that shell.

How do you start a Docker-ubuntu container into bash?

The answers from this question do not work.
The docker container always exits before I can attach or won't accept the -t flag. I could list all of the commands I've tried, but it's a combination of start exec attach with various -it flags and /bin/bash.
How do I start an existing container into bash? Why is this so difficult? Is this an "improper" use of Docker?
EDITS:
I created the container with docker run ubuntu. The information about the container: 60b93bda690f ubuntu "/bin/bash" About an hour ago Exited (0) 50 minutes ago ecstatic_euclid
First of all, a container is not a virtual machine. A container is an isolation environment for running a process. The life-cycle of the container is bound to the process running inside it. When the process exits, the container also exits, and the isolation environment is gone. The meaning of "attach to container" or "enter an container" actually means you go inside the isolation environment of the running process, so if your process has been exited, your container has also been exited, thus there's no container for you to attach or enter. So the command of docker attach, docker exec are target at running container.
Which process will be started when you docker run is configured in a Dockerfile and built into a docker image. Take image ubuntu as an example, if you run docker inspect ubuntu, you'll find the following configs in the output:
"Cmd": ["/bin/bash"]
which means the process got started when you run docker run ubuntu is /bin/bash, but you're not in an interactive mode and does not allocate a tty to it, so the process exited immediately and the container exited. That's why you have no way to enter the container again.
To start a container and enter bash, just try:
docker run -it ubuntu
Then you'll be brought into the container shell. If you open another terminal and docker ps, you'll find the container is running and you can docker attach to it or docker exec -it <container_id> bash to enter it again.
You can also refer to this link for more info.
Here is a very simple Dockerfile with instructions as comments ... launch it to spin up a running container you can exec login to
FROM ubuntu:20.04
ENV TERM linux
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update
RUN apt-get install -y
CMD ["/bin/bash"]
# ... save this file as Dockerfile then in same dir issue following
#
# docker build --tag stens_ubuntu . # creates image stens_ubuntu
#
# docker run -d stens_ubuntu sleep infinity # launches container
#
# docker ps # show running containers
#
#
# ... find CONTAINER ID from above and put into something like this
#
# docker exec -ti $( docker ps | grep stens_ubuntu | cut -d' ' -f1 ) bash # login to running container
# docker exec -ti 3cea1993ed28 bash # login to running container using sample containerId
#
A container will exit normally when it has no work to do ... if you give it no work it will exit immediately upon launch for this reason ... typically the last command of your Dockerfile is the execution of some flavor of a server which stays alive due to an internal event loop and in so doing keeps alive its enclosing container ... short of that you can mention a server executable which has been installed into the container as the final parameter of your call to
docker run -d my-image-name my-server-executable

How to fix ctrl+c inside a docker container

If I connect to a docker container
$> docker exec -it my_container zsh
and inside it I want to kill something I started with ctrl+c I noticed that it takes forever to complete. I've googled around and it seems that ctrl+c works a bit different than you would expect. My question, how can I fix ctrl+c inside a container ?
The problem is that Ctrl-C sends a signal to the top-level process inside the container, but that process doesn't necessarily react as you would expect. The top-level process has ID 1 inside the container, which means that it doesn't get the default signal handlers that processes usually have. If the top-level process is a shell, then it can receive the signal through its own handler, but doesn't forward it to the command that is executed within the shell. Details are explained here. In both cases, the docker container acts as if it simply ignores Ctrl-C.
Starting with docker 0.6.5, you can add -t to the docker run command, which will attach a pseudo-TTY. Then you can type Control-C to detach from the container without terminating it.
If you use -t and -i then Control-C will terminate the container. When using -i with -t then you have to use Control-P Control-Q to detach without terminating.
Test 1:
$ ID=$(sudo docker run -t -d ubuntu /usr/bin/top -b)
$ sudo docker attach $ID
Control-P Control-Q
$ sudo docker ps
The container is still listed.
Test 2:
$ ID=$(sudo docker run -t -i -d ubuntu /usr/bin/top -b)
$ sudo docker attach $ID
Control-C
$ sudo docker ps
the container is not there (it has been terminated). If you type Control-P Control-Q instead of Control-C in the 2nd example, the container would still be running.
Wrap the program with a docker-entrypoint.sh bash script that blocks
the container process and is able to catch ctrl-c. This bash example
might help:
https://rimuhosting.com/knowledgebase/linux/misc/trapping-ctrl-c-in-bash
#!/bin/bash
# trap ctrl-c and call ctrl_c()
trap ctrl_c INT
function ctrl_c() {
echo "** Trapped CTRL-C"
}
for i in `seq 1 5`; do
sleep 1
echo -n "."
done
Use Ctrl+\ instead of Ctrl+C
it kills the process instead of politely asking it to shut down.(read more here.)
In some cases, when I used ctrl-C to terminate a process inside a container, the container terminates.
Additionally, I've seen cases where processes running inside containers leave zombie processes.
I have found that when starting a container with the --init switch, both of these problems are addressed. This appears to make my containers operate in a more "normal, expected UNIX-like manner".
Note: --init is different from -i, which is short for --interactive
If you want more information on what the --init switch does, please read up on it on the Docker web pages that include information on docker run. The information on that web page says "Run an init inside the container that forwards signals and reaps processes".
I had the similar problem when I was trying to run mdbook (the Rust executable) in the docker container. The mdbook starts simple webserver and I want to stop it via Ctrl+C which did not work.
$ docker -ti --rm -p 4321:4321 my-docker-image mdbook serve --hostname 0.0.0.0 --port 4321
2019-08-16 14:00:11 [INFO] (mdbook::book): Book building has started
2019-08-16 14:00:11 [INFO] (mdbook::book): Running the html backend
2019-08-16 14:00:11 [INFO] (mdbook::cmd::serve): Serving on: http://0.0.0.0:4321
2019-08-16 14:00:11 [INFO] (ws): Listening for new connections on 0.0.0.0:3001.
2019-08-16 14:00:11 [INFO] (mdbook::cmd::watch): Listening for changes...
^C^C
Be inspired by #NID's answer I encapsulated the mdbook executable by universal bash script docker-entrypoint.sh which did the trick (without the need to explicitly catch the INT signal).
$ docker -ti --rm -p 4321:4321 my-docker-image docker-entrypoint.sh mdbook serve --hostname 0.0.0.0 --port 4321
2019-08-16 14:00:11 [INFO] (mdbook::book): Book building has started
2019-08-16 14:00:11 [INFO] (mdbook::book): Running the html backend
2019-08-16 14:00:11 [INFO] (mdbook::cmd::serve): Serving on: http://0.0.0.0:4321
2019-08-16 14:00:11 [INFO] (ws): Listening for new connections on 0.0.0.0:3001.
2019-08-16 14:00:11 [INFO] (mdbook::cmd::watch): Listening for changes...
^C $
The content of the docker-entrypoint.sh is very simple:
#!/bin/bash
$#
I tried the --init solution by #Remy Orange and it worked for me. After some searching, including i)How to use --init parameter in docker run, ii) What is advantage of Tini? and iii) init, I wrote the detailed solution below:
Install tini on Ubuntu:
via launching:
$ sudo apt update && sudo apt install tini
Or, if tini is not available in your distribution or is too old, please check a Dockerfile to add tini at here.
Run your Docker container with --init:
docker run -ti --init --rm YOUR_DOCKER_CONTAINER_EXMAPLE bash
Then you come into your docker container and you can run some processes or experiments. E.g., run a Python code, then you can launch Ctrl + C to cancel this Python code, just as what you can do on Ubuntu (i.e., the regular terminal which is outside the docker container).
See the screenshot in my case:
launching Ctrl + C (i.e., ^C) to cancel the python process:
It stops, showing KeyboardInterrupt as expected:
when your docker terminal is not responding to Ctrl+C/Ctrl+D/Ctrl+/, try these steps:
#1>> Open another terminal session and enter the command:
**`docker container ls`**
or
**`docker container list`**
#2>> locate the container id from the above list and issue the docker container stop command:
**`docker stop <<containerId>>`**
#3>> next time when you launch the docker container, use the flag "**-it**" to respond to the Ctrl+C event
docker run -it <>
Now you can stop ,with control+C
If you use Docker Compose, you can add the init parameter to forward signals to the container:
version: "2.4"
services:
web:
image: alpine:latest
init: true
To make it work you need to have the option -ti in your docker exec command.
Wasted about 2 hours.
New commands -- (Working fine)
sudo docker stop
sudo docker rm
sudo docker run -t
Old commands -- (Not working anymore)
sudo docker stop
sudo docker rm
sudo docker run
Ctrl + C
sudo docker start
Hope that helps someone.
For me Ctrl+C works only after running a container with docker run -it <container id/name>
For whom still have this issue, worked for me the Ctrl+d. Neither Ctrl+c or Ctrl+z worked.

docker run ubuntu on mac and nothing happens

i'm on mac running:
docker is configured to use the default machine with IP 192.168.99.100
For help getting started, check out the docs at https://docs.docker.com
my-mac:mydir$ docker run ubuntu /bin/bash
my-mac:mydir$
am i doing something wrong? shouldn't I get into the ubuntu shell?
By running docker run ubuntu /bin/bash, docker create a randomly-named container from the image ubuntu and runs a bash without stdin, stdout nor stderr then bash exits (right after being started).
Try at least to set a tty and interactive mode (aka foreground mode):
docker ps -a
# if not exited, stop it first
docker stop <container_id>
# remove the container which cannot be used
docker rm <container_id>
# let's try again
docker run -it --rm --name=test ubuntu bash
As commented by physincubus:
'-it' is the bit that makes it interactive,
'--rm' removes the container when you exit (so if you want to be able to exit for detach and reattach later, do not do this), and
'--name' allows you to name the container more explicitly in case you want to run multiple instances of the same container
Run it with following command
docker run -it ubuntu /bin/bash
Then you will get bash prompt of ubuntu container

Resources