{"id":315,"date":"2015-03-04T08:54:32","date_gmt":"2015-03-04T08:54:32","guid":{"rendered":"https:\/\/www.peopleperhour.com\/engineering\/?p=315"},"modified":"2015-03-04T09:13:07","modified_gmt":"2015-03-04T09:13:07","slug":"why-the-t-docker-flag-should-not-be-used-for-background-processes","status":"publish","type":"post","link":"https:\/\/www.peopleperhour.com\/engineering\/2015\/03\/04\/why-the-t-docker-flag-should-not-be-used-for-background-processes\/","title":{"rendered":"Why the -t docker flag should not be used for background processes"},"content":{"rendered":"<p>I really like the way we configure crons in our <a href=\"yiiframework.com\">Yii<\/a> application &#8211; any developer can setup a cron with just a code comment. As example, look at this function header comment that will result in the function being triggered automatically every 3 minutes:<\/p>\n<p><code lang=\"php\"><br \/>\n    \/**<br \/>\n     * Requeue a task if undelivered after deadline has passed<br \/>\n     *<br \/>\n     * @cron *\\3 * * * *<br \/>\n     * @cron-tags live staging<br \/>\n     *\/<br \/>\n    public function actionRequeue()<br \/>\n    {<br \/>\n        ....<br \/>\n<\/code><br \/>\nThe magic that parses these comments and triggers the functions is a Yii extension called <a href=\"http:\/\/www.yiiframework.com\/extension\/phpdoc-crontab\/\">phpdoc-crontab<\/a> which itself needs to be run as a cron every minute. We run the phpdoc-crontab cron from a docker container as follows:<\/p>\n<p><code><br \/>\n* * * * * docker exec apprunner php \/var\/www\/ourapp\/yiic cron run live<br \/>\n<\/code><br \/>\nNotice that the <code>docker exec<\/code> command is not using the <code>-t<\/code> flag (i.e. <code>--tty=false<\/code> a.k.a. docker does not allocate a pseudo-TTY for us). This is critical. If the <code>-t<\/code> flag is used, <strong>it will not work<\/strong>. Docker (at least in v1.5) will kill any child processes once the <code>docker exec<\/code> command finishes. This was a gotcha for me that took a few hours to discover. The following is a verification:<\/p>\n<p>Start a busybox container in the background:<br \/>\n<code><br \/>\ndocker run -d --name busybox busybox \/bin\/sh -c \"while true; do echo Hello world; sleep 1; done\"<br \/>\n<\/code><br \/>\nRun a command in busybox that forks a child process into the background:<\/p>\n<p><code><br \/>\ndocker exec -t busybox sh -c \"(echo start);(sleep 60 &);(echo end)\"<br \/>\n<\/code><br \/>\nNotice that it returns immediately and Docker killed the &#8220;sleep 60&#8221; child process when the exec exited. This can be seen by doing a ps straight after:<\/p>\n<p><code><br \/>\ndocker exec busybox ps aux<br \/>\n<\/code><br \/>\nNow try again, but without the <code>-t<\/code> flag, this time notice how Docker waits for the child process to finish before returning:<\/p>\n<p><code><br \/>\ndocker exec busybox sh -c \"(echo start);(sleep 20 &);(echo end)\"<br \/>\n<\/code><br \/>\nSo, the morale of the story, if your <code>docker exec<\/code> command forks background processes, be sure to avoid the <code>-t<\/code> flag.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I really like the way we configure crons in our Yii application &#8211; any developer can setup a cron with just a code comment. As example, look at this function header comment that will result in the function being triggered automatically every 3 minutes: \/**&#8230;<\/p>\n","protected":false},"author":40,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[23],"tags":[32,14,24,31],"class_list":["post-315","post","type-post","status-publish","format-standard","hentry","category-devops-2","tag-cron","tag-devops","tag-docker","tag-yii"],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p2CA4w-55","jetpack_likes_enabled":true,"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.peopleperhour.com\/engineering\/wp-json\/wp\/v2\/posts\/315","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.peopleperhour.com\/engineering\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.peopleperhour.com\/engineering\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.peopleperhour.com\/engineering\/wp-json\/wp\/v2\/users\/40"}],"replies":[{"embeddable":true,"href":"https:\/\/www.peopleperhour.com\/engineering\/wp-json\/wp\/v2\/comments?post=315"}],"version-history":[{"count":8,"href":"https:\/\/www.peopleperhour.com\/engineering\/wp-json\/wp\/v2\/posts\/315\/revisions"}],"predecessor-version":[{"id":323,"href":"https:\/\/www.peopleperhour.com\/engineering\/wp-json\/wp\/v2\/posts\/315\/revisions\/323"}],"wp:attachment":[{"href":"https:\/\/www.peopleperhour.com\/engineering\/wp-json\/wp\/v2\/media?parent=315"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.peopleperhour.com\/engineering\/wp-json\/wp\/v2\/categories?post=315"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.peopleperhour.com\/engineering\/wp-json\/wp\/v2\/tags?post=315"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}