{"id":376,"date":"2015-10-19T11:24:57","date_gmt":"2015-10-19T11:24:57","guid":{"rendered":"https:\/\/www.peopleperhour.com\/engineering\/?p=376"},"modified":"2016-04-22T11:10:29","modified_gmt":"2016-04-22T11:10:29","slug":"docker-file-modified-time-gotcha","status":"publish","type":"post","link":"https:\/\/www.peopleperhour.com\/engineering\/2015\/10\/19\/docker-file-modified-time-gotcha\/","title":{"rendered":"Docker File Modified time Gotcha"},"content":{"rendered":"<p>The key value proposition of Docker is that once you build a container image, you can run it anywhere. I like the way <a href=\"http:\/\/container-solutions.com\/docker-computation-containers\/\">Adrian Mouat<\/a> puts it:<\/p>\n<p>\n&gt; What is Software: program Q, when given input P, will produce output R.<br \/>\n&gt;HOWEVER: One of the major problems in modern computing is our Ps and Qs don\u2019t match when we move between environments, causing our Rs to differ unexpectedly.<br \/>\n&gt;<strong>Docker containers are essentially just a complete statement of P and Q<\/strong>. That is to say they specify the entire state of the runtime environment (P) and the program to run (Q).\n<\/p>\n<p>But be warned, this doesn&#8217;t hold up in several cases. One of those cases bit me last week. If you use the VOLUME keyword in the Dockerfile and your app is sensitive to the &#8220;file modified time&#8221; then watch out for a Gotcha:<\/p>\n<p>If you create a container image with some data exposed <em>in a volume<\/em>, <strong>when you run the container, the mtime of folders within the volume is set to when the container <em>was run<\/em> rather than when the container <em>image was created<\/em>.<\/strong><\/p>\n<p>If you are not using VOLUMEs, there&#8217;s no problem, the mtime of folders will be always be the same every time you run the container. Also, the problem only shows itself for folders, instead of files.<\/p>\n<p>I logged the issue here: <a href=\"https:\/\/github.com\/docker\/docker\/issues\/17018\">https:\/\/github.com\/docker\/docker\/issues\/17018<\/a><\/p>\n<p>The reason it affects us so much is that Yii v1 publishes assets (js\/css\/images) to a public url which is determined by the hash of the name and the <a href=\"http:\/\/php.net\/manual\/en\/function.filemtime.php\">filemtime<\/a> of the parent folder. Since our website runs on a cluster and the deployment of a new version will cause new containers to be started at slightly different times, we end up with a situation where each container generates assets at a different url.<\/p>\n<p>There are many solutions:<\/p>\n<ul>\n<li>We could turn on stickiness on the load balancer so all requests go to the same machine. This isn&#8217;t great because stickiness doesn&#8217;t load balance so well.\n<li>We could patch zii so it uses <code>publish(blah,true)<\/code> which would not take into account the modified time. This isn&#8217;t great because hacking Yii core isn&#8217;t good, it&#8217;s nice to use a clean copy of yii.\n<li>We could generate the assets before building the data-container. No, this wouldn&#8217;t work because yii would notice the new timestamp of the folder and assets would be generated again, differently for each server.\n<li>We could override the annoying Yii classes (e.g. CDetailView and use DetailView instead). This would require changing 50+ files and would mean we could never use the standard yii widgets which would be a source of mistakes from the devs.\n<li>We could use &#8220;<code>touch -d<\/code>&#8221; to reset the modification time of the affected folders so that every machine is in sync and generates the assets with the same name.\n<\/ul>\n<p>We went with the &#8220;<code>touch -d<\/code>&#8221; hack for the moment. However ugly it might be, it is a one-line fix in the deployment pipeline<\/p>\n<p><code><br \/>\ndocker run --rm --volumes-from app-data ubuntu bash -c 'touch --date=$(date +%Y%m%d) \/var\/www\/app\/vendor\/yiisoft\/yii\/framework\/zii\/widgets\/assets';<br \/>\n<\/code><\/p>\n<hr>\n<p>For reference: I was using Docker v1.8.3.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The key value proposition of Docker is that once you build a container image, you can run it anywhere. I like the way Adrian Mouat puts it: &gt; What is Software: program Q, when given input P, will produce output R. &gt;HOWEVER: One of the&#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":[24,39,31],"class_list":["post-376","post","type-post","status-publish","format-standard","hentry","category-devops-2","tag-docker","tag-gotcha","tag-yii"],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p2CA4w-64","jetpack_likes_enabled":true,"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.peopleperhour.com\/engineering\/wp-json\/wp\/v2\/posts\/376","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=376"}],"version-history":[{"count":13,"href":"https:\/\/www.peopleperhour.com\/engineering\/wp-json\/wp\/v2\/posts\/376\/revisions"}],"predecessor-version":[{"id":389,"href":"https:\/\/www.peopleperhour.com\/engineering\/wp-json\/wp\/v2\/posts\/376\/revisions\/389"}],"wp:attachment":[{"href":"https:\/\/www.peopleperhour.com\/engineering\/wp-json\/wp\/v2\/media?parent=376"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.peopleperhour.com\/engineering\/wp-json\/wp\/v2\/categories?post=376"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.peopleperhour.com\/engineering\/wp-json\/wp\/v2\/tags?post=376"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}