16

I want to run a command inside a docker container. If the command takes more than 3 seconds to finish, the container should be deleted.

I thought I can achieve this goal by using --stop-timeout option in docker run.

But it looks like something goes wrong with my command.

For example, docker run -d --stop-timeout 3 ubuntu:14.04 sleep 100 command creates a docker container that lasts for more than 3 seconds. The container is not stopped or deleted after the 3rd second.

Do I misunderstand the meaning of --stop-timeout?

The document says

--stop-timeout Timeout (in seconds) to stop a container

Here's my docker version:

Client:
 Version:       17.12.0-ce
 API version:   1.35
 Go version:    go1.9.2
 Git commit:    c97c6d6
 Built: Wed Dec 27 20:03:51 2017
 OS/Arch:       darwin/amd64

Server:
 Engine:
  Version:      17.12.0-ce
  API version:  1.35 (minimum version 1.12)
  Go version:   go1.9.2
  Git commit:   c97c6d6
  Built:        Wed Dec 27 20:12:29 2017
  OS/Arch:      linux/amd64
  Experimental: true

The API version is newer than 1.25.

Brian
  • 12,145
  • 20
  • 90
  • 153
  • --stop-timeout is tagged with api1.25. There may be some problem with version. You should check this – Arpit Solanki Jan 17 '18 at 10:58
  • 2
    `The --stop-timeout flag sets the timeout (in seconds) that a pre-defined (see --stop-signal) system call signal that will be sent to the container to exit. After timeout elapses the container will be killed with SIGKILL.` you have to use --stop-signal too – Edwin Jan 17 '18 at 10:58

5 Answers5

9

You can try

timeout 3 docker run...

there is a PR on that subject

https://github.com/moby/moby/issues/1905

See also

Docker timeout for container?

user2915097
  • 30,758
  • 6
  • 57
  • 59
8

The --stop-timeout option is the maximum amount of time docker should wait for your container to stop when using the docker stop command.

A container will stop when it's told to or when the command is running finishes, so if you change you sleep from 100 to 1, you'll see that the container is stopped after a second.

What I'll advice you to do is to change the ENTRYPOINT of your container to a script that you create, that will execute what you want and keep track of the execution time from within and exit when timeout.

After that you can start your container using the --rm option that will delete it once the script finishes.

A small example.

Dockerfile:

FROM ubuntu:16.04

ADD ./script.sh /script.sh

ENTRYPOINT /script.sh

script.sh:

#!/bin/bash

timeout=5
sleep_for=1

sleep 100 &

find_process=$(ps aux | grep -v "grep" | grep "sleep")

while [ ! -z "$find_process" ]; do
    find_process=$(ps aux | grep -v "grep" | grep "sleep")

    if [ "$timeout" -le "0" ]; then
      echo "Timeout"
      exit 1
    fi

    timeout=$(($timeout - $sleep_for))
    sleep $sleep_for
done

exit 0

Run it using:

docker build -t testing .
docker run --rm testing

This script will execute sleep 100 in background, check if its still running and if the timeout of 5 seconds is reach then exit.

This might not be the best way to do it, but if you want to do something simple it may help.

tgogos
  • 23,218
  • 20
  • 96
  • 128
Esteban Garcia
  • 2,171
  • 16
  • 24
5

Depending on what exactly you want to achieve, the --ulimit parameter to docker run may do what you need. For example:

docker run --rm -it --ulimit cpu=1 debian:buster bash -c '(while true; do true; done)'

After about 1s, this will print Killed and return. With the --ulimit option, it would rune forever.

However, note that this only limits the CPU time, not the wall clock time. You can happily run sleep 24h with a --ulimit cpu=1 because sleep does not consume CPU time.

ingomueller.net
  • 4,097
  • 2
  • 36
  • 33
4
docker run --rm ubuntu timeout 2 sh -c 'echo start && sleep 30 && echo finish'

will terminate after 2 seconds and finish will never be output

masterxilo
  • 2,503
  • 1
  • 30
  • 35
1

In my case, I had a docker container that started an Express server, and then remained running, and I wanted a simple test on CI to check that the container can start without any immediate error (such as configuration errors).

I made sure my code returned a non-zero exit code if something failed during start, and then ended up with this:

timeout 10 docker run [   container params   ]; test $? -eq 124 && echo "Container ran for 10 seconds without failing"

This will send SIGTERM to the docker container after 10 seconds if it has not already died. If it's alive long enough for the timeout to occur, it will return 124, which is what the test is for. In other words, this verifies that the docker ran long enough to reach a timeout, any error (or early exit with code 0!) will be considered an error.

JHH
  • 8,567
  • 8
  • 47
  • 91