New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add timeout option to docker run #1905
Comments
@benbro Thanks for the idea. What other use cases for docker would this be needed for? I am trying to decide if this should be in the scope of docker itself or if this should be handled by an external tool. |
I think it is useful in any case you use a container as executable. A user can wrap the call to docker run with a timeout in bash: When the -rm option will be added, the container might be left if docker run is stopped or exited. A timeout could also be useful with the remote API. |
I've given this issue quite a bit of thought over the past several days, and here's the solution I've come up with that does the equivalent of a container timeout today, including cleanup, with no changes to the docker core: (I've got this script saved as #!/bin/bash
set -e
to=$1
shift
cont=$(docker run -d "$@")
code=$(timeout "$to" docker wait "$cont" || true)
docker kill $cont &> /dev/null
echo -n 'status: '
if [ -z "$code" ]; then
echo timeout
else
echo exited: $code
fi
echo output:
# pipe to sed simply for pretty nice indentation
docker logs $cont | sed 's/^/\t/'
docker rm $cont &> /dev/null Here's some example output from the script:
Now, we don't get real-time output from the process as it runs this way, but if this were implemented somewhere outside the shell (such as in a Go library consuming the docker API proper), that should be easier to implement than it is here. |
I still believe this is out of the scope of docker. Docker provides all the primitives required to do what is required. Also the |
@benbro what about running timeout inside docker? docker run --rm ubuntu timeout 2 sh -c 'echo start && sleep 30 && echo finish' |
@andreisoare thanks for the suggestion. |
+1
When you run untrusted code, a timeout inside your container cannot be trusted. Consider the following: #include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main()
{
int pid;
if ((pid = fork()) == 0)
{
setsid();
sleep(5);
printf("Done here.\n");
}
else if (pid)
wait(NULL);
return (0);
} In this case: timeout 2 ./a.out, the child process will stay alive after the timeout. |
In the case you describe, the parent process would exit, and it would be pid 1, so the container would be destroyed and thus the child process also killed and reaped with the entire pid namespace. |
@tianon The point is that you shouldn't trust anything that's happening inside your container when you run untrusted code inside it. That's why I would prefer being able to set a timeout on the container itself. To give you another example: $> cat ./test.sh #!/bin/bash
pid=$(ps ax | grep timeout | grep -v grep | cut -d ' ' -f 2)
kill -19 $pid
sleep 5
echo "Done."
kill -18 $pid $> timeout 2 ./test.sh |
Thanks for the discussing. I am looking for exactly the same thing discussed in this issue. |
@tianon would it be possible to extend your script to work with infinite loops, at the moment the container gets stuck processing the request and is not killed. http://stackoverflow.com/questions/31266529/killing-a-docker-container-running-an-infinite-process ie: while True:
print "infinite loop" Will get stuck. |
+1 @CrashyBang |
If you run a docker entrypoint, which is a cli program (and not a deamon), would a viable option of limiting execution time be with the available programs, like timelimit? ie:
I'm doing some long running processing from a docker image, and need to limit the execution time of each docker run. I could do it with timelimit inside (entrypoint) or outside of docker as suggested... only thing I'm worried about if some kind of cleanup (--rm=true) will work with signal 15/9 sent to docker. |
Could someone please reconsider implementing this feature. It is trivial for Docker to add this timeout option but would make our implementations more elegant and less error prone. In understand that it is not strictly necessary as per @crosbymichael but it opens up possibilities like this: kubernetes/kubernetes#21925 |
it's probably not trivial... |
It's hard to believe it wouldn't be trivial. It seems to be a policy decision that is preventing the team. |
Perhaps think of something like a "killer" / garbage-collect container, containing a cron-job, that kills any container that's started with a specific label and has been running for xx seconds |
I'm aware of lots of work-arounds. But they all seem like overkill considering how much more elegant a |
Implementing it in docker would involve starting timers for these containers, and implementing logic to stop those containers; it may sound trivial, but can result in having to add a lot of moving parts that has to be supported and maintained. |
Firstly when you type in Therefore we know both essential functionality are already implemented. |
(worst-case scenario) Perhaps a few hours to code and perhaps max 1 week of unit testing after it has been implemented. |
Fyi, timelimit wrap around docker run seems to work as expected. Why is it not good enough? Perhaps you would be fine with more detailed documentation as to what happens to the docker container if not detached and gets a kill 15/9? If 'screen' or 'tmux' is fine for putting a foreground process in the background, why is timelimit not enough to kill a process and it's children after some time? |
I am probably misunderstanding the situation, but isn't |
@DesktopMan You can run the cleanup manually afterwards.
|
The container doesn't even stop though, is there documentation on how docker run reacts to signals anywhere? |
@DesktopMan you have to specify the signal which is sent from the
|
Interesting. That still doesn't stop the container for me. |
@DesktopMan Interesting. You're right! The container is still running. So a |
This is really a useful feature for testing purpose and any situation where ephemeral containers could be of use (i.e providing a customer a short lived sandbox environment to play with). |
You are regularly talking about The implementation of a timeout option on the docker API should be reconsidered. |
If the main process of a container does an infinite loop or sleep then The main benefit over previous solutions is that if the script process will be killed then it send |
It would be really handy if docker run has the timeout option. Use timeout is like in order to shutdown a computer, you need to pull the power plug off the wall instead of push some button on the machine itself. |
+1 @pipehappy1 |
Anyone else tried the --stop-timeout option yet? Did it work for you? I wasn't lucky enough to make it work last time I tried. |
@hifall That doesn't look relevant to me. It doesn't limit the time a container can run for, it just limits how long the container has to stop gracefully when it gets stopped. |
This may not work for everyone, but it was good enough for my use:
I utilized the fact that docker stop will send a SIGTERM by default, and then after a specified timeout, it will send a SIGKILL to the container. Normally, this would still stop the container once the command is issued (most things will stop to SIGTERM), but by setting This means If you need to run the container interactively, the two commands (run and stop) will have to be split and run in different processes e.g. open a new shell. |
My need is to stop (and possibly remove) a container after a week. A team of unreliable human testers should not be responsible for container deletion. |
I was looking for the feature and ended up in this issue. My use case is the following: inside of CI/CD you might have a number of containers fired to complete CI/CD tasks. In case the process managing these containers (kind of), which in this case would be the pipeline itself, crashes/dies, potentially you can have zombie containers running forever inside of your infra - or at least until they pile up and you discover that you have to kill them. I think it's not hard to implement a "watcher" container that would do the cleanup/garbage collection, but still would be nice to have such a flag in Docker itself. I won't argue though about how hard or easy it is to implement such a feature, as I've never seen the Docker codebase to know, so I wouldn't underestimate the effort. |
@ScottG489 As @jtpavlock mentioned, there are a number of things that has to be done to use stop work as we wanted. The requirement is, when we start a container, we want to set the maximum user time, the system can run after which, it should be stopped. Each solution proposed here are hacks not the cleanest solution. For example, we have to run 2-3 commands, to get it to work. In @jtpavlock's solution, he explicitly catches the sigterm and ignores it. That means, you are not giving any time for the service running in the container to gracefully handle sigterm and do cleanups. The hack I proposed has a different issue. You need to run even more commands - uuidgen, sleep, docker run and docker stop. It changes the container name :( It may be applicable to cases where you need a specific name... |
Sorry I deleted my comment on you @jayaprabhakar. I was under the impression that flag was a timeout to stop, not a timeout between In any case yeah, it's unfortunate these hacks are necessary, but I can see where they are coming from with wanting to be careful to not bloat on features. |
I had this issue and after searching a while, I ended up in here. I couldn't find a solution to this problem, so I wrote a bash script to remove containers which have been running for more than a specific time. the code is available here: |
@vafakaramzadegan wrote:
You might want to use |
I've read the comment from one of the maintainers that it's out of the scope. It would be very useful for the development environment or CI/CD process. We try all the ways not to have dangling containers lost in machines, but there are always exceptions in code/ process etc, that leave garbage behind. Sure, we can keep adding up guardrails to prevent it, but that is the point. It could be made much easier for default options. When we are talking about non controlled environment this scenarios just get worst (like devs machines) |
After almost a decade this is still being requested, can we please have this ? |
I wanted this feature at first too, but the workaround is so simple and works so well: Just preface the command you are running inside the Docker container with |
@esabol Please read the previous comments. Using timeout inside the container can't be trusted in many cases, if you cannot fully trust what's running in the container. Running the timeout on the host is reliable but it does not do the cleanup. |
This is a feature request to add a timeout option when calling the docker run command.
The option called be -to=5000 (5000 ms).
I'm using docker to run untrusted student code in a container (C, Python...).
It will be useful to be able to set a timeout to limit how much time the container is allowed to run before it docker stops it.
Thanks
The text was updated successfully, but these errors were encountered: