Docker version 17.09.0-ce, build afdb6d4
docker-compose version 1.17.0-rc1, build a0f95af
Setting timeout on docker-compose up
does not affect the shutdown timeout
docker-compose.yml
file
version: "3.3"
services:
test2:
image: debian:9
command: nohup sleep 1000
(Also tried with version 2.0, and 2.3)
$ docker-compose up -d --timeout 123 test2
$ docker inspect issue_test2_1 # Shows no StopTimeout set at all
$ time docker-compose stop
Stopping issue_test2_1 ... done
real 0m11.473s
user 0m0.908s
sys 0m0.144s
(Also tried down
)
$ docker run -it --rm --stop-timeout=121 --name test1 debian:9 nohup sleep 1000
$ docker inspect test1 # Show a StopTimeout of 121 set in the "Config" section
$ docker stop test1 # takes the ~121 seconds
Using stop_grace_period
does work when using docker-compose commands, but not docker commands, as it appears that docker-compose stop
or down
just re-reads the docker-compose.yml
file at stop time, and has nothing to do with how the container was started
I am trying to set the StopTimeout in the actual container, so the daemon knows what to respect when it is shutdown (for example during a full system shutdown). Something like stop_grace_period
doesn't help me, as that only tells docker-compose
how long to wait, not the docker daemon.
--timeout
is intended to be used in interactive mode to set the timeout when issuing SIGTERM
. This is in line with the option's help message: Use this timeout in seconds for container shutdown when attached or when containers are already running. (default: 10)
, but I agree it could be more explicit.
If you want to apply a timeout to docker-compose stop
, you'll have to use the -t
flag with that command.
We should also error out if the user attempts to use -d
and -t
together.
@shin- I see now that I misunderstood what the --timeout
was for, its for when you run docker-compose up
and it has to shutdown the container first to start a new one, that's the timeout associated with that shutdown only (if I read the code correctly). I can see how the help message is saying that now, but yes, it could use a little clarifying.
I think a better solution to my problem is... Can we make it so that when docker-compose
creates a new container, if stop_grace_period
is specified, then it adds StopTimeout
to the Config
? Just to clarify, that's the ONLY small change I'm suggesting. You already have the use of stop_grace_period
when you run docker-compose stop
, and I'm not suggesting changing how any of that already works. Simply adding that attribute to the Config
of the container. This way other docker apis (such as the docker
cli and dockerd
) know and respect this timeout too.
this change is really good for machine reboot, thanks for your solving it, which we are just looking for!^_^
With this change, what is the recommended way to set the timeout when doing an up
with new containers? Is it backwards compatible, so it can be used with 17.09?
@shin- Since this is a regression that removes functionality that had existed for quite some time, can we please get some guidance on the proper way to set the timeout using docker-compose?
It's not a regression? Everything that used to work, still works, unless you have a claim to the contrary, in which case please open a new issue with details and reproducible case.
Our use case is pulling an updated image and then calling docker-compose up
to restart with the new container, but here's a simpler example that demonstrates why --timeout
is needed and my question is what's the correct way to specify a timeout since --timeout
is no longer available.
test_timeout.py
import logging
import signal
import time
from datetime import datetime, timedelta
logging.basicConfig(level='INFO')
log = logging.getLogger(__name__)
g_running = True
def _stop(signum, _):
log.warning("Stopping: signum %d", signum)
global g_running
g_running = False
def main():
log.info('Registered signals')
signal.signal(signal.SIGINT, _stop)
signal.signal(signal.SIGTERM, _stop)
log.info('Starting processing')
done_time = datetime.now() + timedelta(seconds=15)
while g_running:
while datetime.now() < done_time:
time.sleep(0.1)
done_time = datetime.now() + timedelta(seconds=15)
log.info('Processed')
log.info('Stopped')
if __name__ == '__main__':
main()
Dockerfile
FROM python:3.6.4-alpine3.7
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY test_timeout.py .
CMD ["python", "test_timeout.py"]
test_timeout.yml
version: '2'
services:
test_timeout:
container_name: test_timeout
image: test_timeout
Then run the following:
docker build -t test_timeout .
docker-compose -f test_timeout.yml up --timeout 60
And in a separate terminal run the following after it prints Processed
:
docker restart test_timeout
--timeout
still works the same way it used to. Why are you saying it's "no longer available"?
Yes, I used to be able to run docker-compose -f my_file.yml up -d --timeout 60
and I can't anymore, so how do I specify the timeout value when running docker-compose with -d
?
Oh, I see what you mean now. We should probably revert the changes in #5435 . As a workaround in the meantime, you can use docker-compose stop --timeout X && docker-compose up -d
I am well aware that's possible, but that's a "stop the world" sort of thing and not an acceptable solution for our use case. Basically, this needs to go into a 17.12 release ASAP because it is a serious regression.
It'll be in Compose 1.19.0.
Sorry, that doesn't mean anything to me. Will I be able to update to 17.12.x at some point in the near future and have the same functionality that I had in 17.09?
The Docker Engine and Compose are separate components (which are sometimes packaged together, with Docker for Mac and Docker for Windows for example) and are updated and released independently.
If this is a critical issue for you, please install 1.17.1 until this is resolved.
I get that but those components are bundles as a release and Docker 17.12 ships with docker-compose 1.18.0 and I'm assuming that they won't be updating to 1.19.0 until the next release, so this needs to go into a point release of 1.18 so Docker users don't have to wait 3 months to get a fix for a serious regression.
@daveisfera They can update docker-compose
without waiting for the next version of docker to come out. They are separate components, it's not like docker compose 1.18.x only works with 17.12. So docker users can just update docker-compose, using their package manager or by downloading the new/old version. (docker-compose
is in fact just one file you'd need to replace).
I understand that "Docker" is made of multiple pieces and that you can update/install those independently. That's a great design and I'm grateful for that, but to most people (especially those on Mac and Windows) they go to docker.com and download the installer and that's "Docker", so a serious regression like this really needs to be fixed in a point release.
Basically, just because you're doing things right in one area (separation of responsibility) doesn't excuse you from doing the right thing in another area (proper release management), because most users of "Docker" have no idea how to manually upgrade/downgrade a single component, and even if they did do it, they'll be cursing your name the entire time. ;)
@daveisfera Thank you for the feedback! I just think we disagree about the impact of that issue on the userbase. 18.02 on the edge channel will receive the fix in a month or so.
Most helpful comment
I understand that "Docker" is made of multiple pieces and that you can update/install those independently. That's a great design and I'm grateful for that, but to most people (especially those on Mac and Windows) they go to docker.com and download the installer and that's "Docker", so a serious regression like this really needs to be fixed in a point release.
Basically, just because you're doing things right in one area (separation of responsibility) doesn't excuse you from doing the right thing in another area (proper release management), because most users of "Docker" have no idea how to manually upgrade/downgrade a single component, and even if they did do it, they'll be cursing your name the entire time. ;)