<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>ionel's codelog</title><link href="https://blog.ionelmc.ro/" rel="alternate"></link><link href="https://blog.ionelmc.ro/feeds/all-en.atom.xml" rel="self"></link><id>https://blog.ionelmc.ro/</id><updated>2018-03-25T13:09:56+03:00</updated><entry><title>Proxy issues with Apache</title><link href="https://blog.ionelmc.ro/2018/03/25/proxy-issues-with-apache/" rel="alternate"></link><published>2018-03-25T00:00:00+02:00</published><updated>2018-03-25T13:09:56+03:00</updated><author><name>Ionel Cristian Mărieș</name></author><id>tag:blog.ionelmc.ro,2018-03-25:2018/03/25/proxy-issues-with-apache/</id><summary type="html">&lt;div class="document" style='font:19px/29px "Palatino Linotype", "Book Antiqua", "FPL Neu", "TeX Gyre Pagella", "URW Palladio L", "Palatino", "Century Schoolbook L", "Georgia", serif; margin:0; padding:0'&gt;&lt;p style="margin:25px 0 25px 0"&gt;So few days ago I had a very weird bug with an Apache httpd SSL terminator setup. So basically
just a proxy to Nginx+uWSGI serving plain http. Do not ask why such a contrived setup, it's beyond reason.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Sometimes httpd would give this sort of error and big file …&lt;/p&gt;&lt;/div&gt;</summary><content type="html">&lt;div class="document" style='font:19px/29px "Palatino Linotype", "Book Antiqua", "FPL Neu", "TeX Gyre Pagella", "URW Palladio L", "Palatino", "Century Schoolbook L", "Georgia", serif; margin:0; padding:0'&gt;&lt;p style="margin:25px 0 25px 0"&gt;So few days ago I had a very weird bug with an Apache httpd SSL terminator setup. So basically
just a proxy to Nginx+uWSGI serving plain http. Do not ask why such a contrived setup, it's beyond reason.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Sometimes httpd would give this sort of error and big file uploads:&lt;/p&gt;
&lt;div class="term docutils container"&gt;
&lt;pre class="literal-block" style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:none; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 6px #888; background:#000; background-image:radial-gradient(ellipse farthest-corner at center, #000 0%, #191919 100%); color:#aaa; display:inline-block' bgcolor="#FFFDFD"&gt;
[proxy:error] [pid 18:tid 140393219815168] (32)Broken pipe: [client 10.0.2.2:55239] AH01084: pass request body failed to 172.21.0.9:80 (web), referer: https://localhost/upload/
[proxy_http:error] [pid 18:tid 140393219815168] [client 10.0.2.2:55239] AH01097: pass request body failed to 172.21.0.9:80 (web) from 10.0.2.2 (), referer: https://localhost/upload/
&lt;/pre&gt;
&lt;/div&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Trying few requests locally didn't reproduce the problem.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Not considering it only happened with large files I suspected there's some sort of boundary or timeout that is being hit.
Firefox has a slow connection simulator in its Web Developer tools. Open up Responsive Design Mode and there are the
throttling settings:&lt;/p&gt;
&lt;img alt="A screenshot of Firefox connection throttling options" src="https://blog.ionelmc.ro/2018/03/25/proxy-issues-with-apache/ff-throttling.png" style="box-shadow:1px 1px 6px #CCC; display:block; margin:0 auto; max-width:100%"&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Note the funny "Good 3G" choice. As if someone would say "good devils" or "nice jerks".&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Fortunately for me this reproduced the problem, and after few tries it turned out it reproduced with small files. So not a
boundary, but a timeout problem.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Now I've tried to no avail making various Nginx settings like:&lt;/p&gt;
&lt;pre class="literal-block" style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:1px solid #DDD; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 3px #EFEFEF' bgcolor="#FFFDFD"&gt;
proxy_read_timeout 600s;
client_body_timeout 600s;
client_header_timeout 600s;
send_timeout 600s;
&lt;/pre&gt;
&lt;p style="margin:25px 0 25px 0"&gt;And in the Apache conf:&lt;/p&gt;
&lt;pre class="literal-block" style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:1px solid #DDD; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 3px #EFEFEF' bgcolor="#FFFDFD"&gt;
ProxyTimeout 600
&lt;/pre&gt;
&lt;p style="margin:25px 0 25px 0"&gt;So basically playing with this settings was a bit of &lt;a class="reference external" href="https://blog.ionelmc.ro/2016/02/18/notes-on-debugging/#find-the-cause-first" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;shotgun debugging&lt;/a&gt;. Time to get serious and break out &lt;a class="reference external" href="http://www.sysdig.org/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;sysdig&lt;/a&gt;:&lt;/p&gt;
&lt;div class="term docutils container"&gt;
&lt;pre class="literal-block" style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:none; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 6px #888; background:#000; background-image:radial-gradient(ellipse farthest-corner at center, #000 0%, #191919 100%); color:#aaa; display:inline-block' bgcolor="#FFFDFD"&gt;
sysdig container.name=app_ssl_1 or container.name=app_web_1 -A -s 1000 &amp;gt; log
&lt;/pre&gt;
&lt;/div&gt;
&lt;ul class="simple" style="margin:25px 0 25px 0"&gt;
&lt;li style="padding:0"&gt;I had two containers, thus the &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;container.name&lt;/tt&gt; filters. If you don't have containers then probably you'll want to &lt;a class="reference external" href="https://github.com/draios/sysdig/wiki/Sysdig-User-Guide#user-content-filtering" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;filter
by process name&lt;/a&gt;, as the output is already
very verbose.&lt;/li&gt;
&lt;li style="padding:0"&gt;The &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;&lt;span class="pre"&gt;-A&lt;/span&gt;&lt;/tt&gt; (or &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;&lt;span class="pre"&gt;--print-ascii&lt;/span&gt;&lt;/tt&gt;) is to strip non-ascii stuff from output.&lt;/li&gt;
&lt;li style="padding:0"&gt;The &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;&lt;span class="pre"&gt;-s&lt;/span&gt; 1000&lt;/tt&gt; is to see 1000 bytes from the various string being passed around.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style="margin:25px 0 25px 0"&gt;So at this point I have a 30mb log file. Grepping &lt;a class="footnote-reference" href="https://blog.ionelmc.ro/2018/03/25/proxy-issues-with-apache/#id2" id="id1" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:12px; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; vertical-align:top' valign="top"&gt;[1]&lt;/a&gt; backwards through the output for &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;close&lt;/tt&gt; or connections seems like a
good start. It turned out:&lt;/p&gt;
&lt;div class="term docutils container"&gt;
&lt;pre class="literal-block" style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:none; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 6px #888; background:#000; background-image:radial-gradient(ellipse farthest-corner at center, #000 0%, #191919 100%); color:#aaa; display:inline-block' bgcolor="#FFFDFD"&gt;
21:48:04.525468894 2 httpd (17039) &amp;lt; close res=0
21:48:04.525577726 2 httpd (17039) &amp;gt; close fd=10(&amp;lt;f&amp;gt;/tmp/modproxy.tmp.pmo53y)
21:48:04.525578150 2 httpd (17039) &amp;lt; close res=0
21:48:09.498690963 1 httpd (17064) &amp;gt; close fd=11(&amp;lt;4t&amp;gt;10.0.2.2:58997-&amp;gt;172.21.0.8:443)
21:48:09.498691856 1 httpd (17064) &amp;lt; close res=0
21:48:46.935441278 1 nginx (25919) &amp;gt; close fd=18(&amp;lt;4t&amp;gt;172.21.0.8:35834-&amp;gt;172.21.0.9:80)
21:48:46.935442465 1 nginx (25919) &amp;lt; close res=0
&lt;/pre&gt;
&lt;/div&gt;
&lt;p style="margin:25px 0 25px 0"&gt;So basically Apache closing some weird file and then the ssl socket. Then Nginx closes connection from Apache. Not very
helpful. At least I know from what port Apache connects to Nginx so I'll grep for &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;:35834&lt;/tt&gt;? Turns out this is a bogus
connection, not my POST file upload. When looking at syscalls it's very important to not get bogged down in irrelevant
details.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;So now I search backwards for &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;POST /upload&lt;/tt&gt;. This has turned out something very promising:&lt;/p&gt;
&lt;div class="term docutils container"&gt;
&lt;pre class="literal-block" style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:none; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 6px #888; background:#000; background-image:radial-gradient(ellipse farthest-corner at center, #000 0%, #191919 100%); color:#aaa; display:inline-block' bgcolor="#FFFDFD"&gt;
21:48:04.525366305 2 httpd (17039) &amp;gt; writev fd=13(&amp;lt;4t&amp;gt;172.21.0.8:35836-&amp;gt;172.21.0.9:80) size=882
21:48:04.525401643 2 httpd (17039) &amp;lt; writev res=882 data=
POST /upload/ HTTP/1.1
Host: web
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:58.0) Gecko/20100101 Firefox/58.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://localhost/upload/
Content-Type: multipart/form-data; boundary=---------------------------156582199825391
Cookie: ...
Upgrade-Insecure-Requests: 1
Pragma: no-cache
Cache-Control: no-cache
X-Forwarded-For: 10.0.2.2
X-Forwarded-Host: localhost
X-Forwarded-Server: localhost

21:48:04.525407958 2 httpd (17039) &amp;gt; mmap addr=0 length=4194304 prot=1(PROT_READ) flags=1(MAP_SHARED) fd=10(&amp;lt;f&amp;gt;/tmp/modproxy.tmp.pmo53y) offset=0
21:48:04.525417756 2 httpd (17039) &amp;lt; mmap res=7FE14C0AF000 vm_size=770340 vm_rss=14720 vm_swap=0
21:48:04.525420158 2 httpd (17039) &amp;gt; mmap addr=0 length=3093534 prot=1(PROT_READ) flags=1(MAP_SHARED) fd=10(&amp;lt;f&amp;gt;/tmp/modproxy.tmp.pmo53y) offset=4194304
21:48:04.525422012 2 httpd (17039) &amp;lt; mmap res=7FE13E4F9000 vm_size=773364 vm_rss=14720 vm_swap=0
21:48:04.525422762 2 httpd (17039) &amp;gt; writev fd=13(&amp;lt;4t&amp;gt;172.21.0.8:35836-&amp;gt;172.21.0.9:80) size=7304273
21:48:04.525424849 2 httpd (17039) &amp;lt; writev res=-32(EPIPE) data=
Connection: Keep-Alive
Content-Length: 7304222

-----------------------------156582199825391
... tons of form data ...
&lt;/pre&gt;
&lt;/div&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Very interesting, the &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;writev&lt;/tt&gt; syscall error matches the initial error I've seen in the Apache logs (&lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;Broken pipe: [client
10.0.2.2:55239] AH01084: pass request body failed to 172.21.0.9:80&lt;/tt&gt;). Can't be a simple coincidence.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;So at this point it makes sense to look at the whole lifecycle of &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;&lt;span class="pre"&gt;fd=13(&amp;lt;4t&amp;gt;172.21.0.8:35836-&amp;gt;172.21.0.9:80)&lt;/span&gt;&lt;/tt&gt;. Now because
FDs can easily have collisions (they get recycled, other processes can have a FD with same number) it's easier to just grep
for the host and port (&lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;172.21.0.8:35836&lt;/tt&gt;):&lt;/p&gt;
&lt;div class="term docutils container"&gt;
&lt;pre class="literal-block" style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:none; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 6px #888; background:#000; background-image:radial-gradient(ellipse farthest-corner at center, #000 0%, #191919 100%); color:#aaa; display:inline-block' bgcolor="#FFFDFD"&gt;
21:46:45.783868277 0 nginx (25919) &amp;gt; sendfile out_fd=19(&amp;lt;4t&amp;gt;172.21.0.8:35836-&amp;gt;172.21.0.9:80) in_fd=20(&amp;lt;f&amp;gt;/var/app/static/bower_components/jquery-ui/themes/smoothness/images/ui-icons_cd0a0a_256x240.png) offset=0 size=4599
21:46:45.783927701 0 nginx (25919) &amp;gt; recvfrom fd=19(&amp;lt;4t&amp;gt;172.21.0.8:35836-&amp;gt;172.21.0.9:80) size=1024
21:46:45.783936625 0 httpd (17039) &amp;gt; read fd=13(&amp;lt;4t&amp;gt;172.21.0.8:35836-&amp;gt;172.21.0.9:80) size=8000
21:46:45.790029511 0 httpd (17039) &amp;gt; writev fd=13(&amp;lt;4t&amp;gt;172.21.0.8:35836-&amp;gt;172.21.0.9:80) size=843
21:46:45.790072392 0 httpd (17039) &amp;gt; read fd=13(&amp;lt;4t&amp;gt;172.21.0.8:35836-&amp;gt;172.21.0.9:80) size=8000
21:46:45.790090824 0 nginx (25919) &amp;gt; recvfrom fd=19(&amp;lt;4t&amp;gt;172.21.0.8:35836-&amp;gt;172.21.0.9:80) size=1024
21:46:45.790214052 0 nginx (25919) &amp;gt; writev fd=19(&amp;lt;4t&amp;gt;172.21.0.8:35836-&amp;gt;172.21.0.9:80) size=323
21:46:45.790219039 0 nginx (25919) &amp;gt; sendfile out_fd=19(&amp;lt;4t&amp;gt;172.21.0.8:35836-&amp;gt;172.21.0.9:80) in_fd=20(&amp;lt;f&amp;gt;/var/app/static/bower_components/jquery-ui/themes/smoothness/images/ui-icons_888888_256x240.png) offset=0 size=7092
21:46:45.790298595 0 nginx (25919) &amp;gt; recvfrom fd=19(&amp;lt;4t&amp;gt;172.21.0.8:35836-&amp;gt;172.21.0.9:80) size=1024
21:46:45.790309355 0 httpd (17039) &amp;gt; read fd=13(&amp;lt;4t&amp;gt;172.21.0.8:35836-&amp;gt;172.21.0.9:80) size=8000
21:47:50.791539134 0 nginx (25919) &amp;gt; close fd=19(&amp;lt;4t&amp;gt;172.21.0.8:35836-&amp;gt;172.21.0.9:80)
21:48:04.525366305 2 httpd (17039) &amp;gt; writev fd=13(&amp;lt;4t&amp;gt;172.21.0.8:35836-&amp;gt;172.21.0.9:80) size=882
21:48:04.525422762 2 httpd (17039) &amp;gt; writev fd=13(&amp;lt;4t&amp;gt;172.21.0.8:35836-&amp;gt;172.21.0.9:80) size=7304273
21:48:04.525467926 2 httpd (17039) &amp;gt; close fd=13(&amp;lt;4t&amp;gt;172.21.0.8:35836-&amp;gt;172.21.0.9:80)
&lt;/pre&gt;
&lt;/div&gt;
&lt;p style="margin:25px 0 25px 0"&gt;So two things to learn from this:&lt;/p&gt;
&lt;ul style="margin:25px 0 25px 0"&gt;
&lt;li style="padding:0"&gt;&lt;p class="first" style="margin:25px 0 25px 0"&gt;Nginx suddenly decides to close connection after 65 seconds. Note that it closes connection before Apache tries to send the
request.&lt;/p&gt;
&lt;div class="term docutils container"&gt;
&lt;pre class="literal-block" style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:none; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 6px #888; background:#000; background-image:radial-gradient(ellipse farthest-corner at center, #000 0%, #191919 100%); color:#aaa; display:inline-block' bgcolor="#FFFDFD"&gt;
21:46:45.790298595 0 nginx (25919) &amp;gt; recvfrom fd=19(&amp;lt;4t&amp;gt;172.21.0.8:35836-&amp;gt;172.21.0.9:80) size=1024
21:47:50.791539134 0 nginx (25919) &amp;gt; close fd=19(&amp;lt;4t&amp;gt;172.21.0.8:35836-&amp;gt;172.21.0.9:80)
21:48:04.525366305 2 httpd (17039) &amp;gt; writev fd=13(&amp;lt;4t&amp;gt;172.21.0.8:35836-&amp;gt;172.21.0.9:80) size=882
21:48:04.525422762 2 httpd (17039) &amp;gt; writev fd=13(&amp;lt;4t&amp;gt;172.21.0.8:35836-&amp;gt;172.21.0.9:80) size=7304273
21:48:04.525467926 2 httpd (17039) &amp;gt; close fd=13(&amp;lt;4t&amp;gt;172.21.0.8:35836-&amp;gt;172.21.0.9:80)
&lt;/pre&gt;
&lt;/div&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Apache will do two writes before realising connection is busted, something is funny there (looks like a bug, or
some unrelenting optimization).&lt;/p&gt;
&lt;/li&gt;
&lt;li style="padding:0"&gt;&lt;p class="first" style="margin:25px 0 25px 0"&gt;Apache is &lt;a class="reference external" href="https://tools.ietf.org/html/rfc2616#section-8.1.2.2" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;pipelining&lt;/a&gt; the proxied requests (note the &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;sendfile&lt;/tt&gt;
for static files). Basically multiple HTTP requests and responses are sent/received on the same connection - an often tricky
feature of HTTP 1.1.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p style="margin:25px 0 25px 0"&gt;So now, a wtf-moment.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;In a situation like this the only way forward is to peel layers from the onion: &lt;a class="reference external" href="https://blog.ionelmc.ro/2016/02/18/notes-on-debugging/#rooting-it-out" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;remove code, disable components etc&lt;/a&gt;.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Since &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;mod_ssl&lt;/tt&gt; is the most annoying component around (we don't see any meaningful data in the sysdig logs because it's
encrypted) we could try to disable that first. Easy enough, just comment out the SSL stuff and leave the port:&lt;/p&gt;
&lt;pre class="literal-block" style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:1px solid #DDD; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 3px #EFEFEF' bgcolor="#FFFDFD"&gt;
&amp;lt;VirtualHost *:443&amp;gt;
     # SSLEngine On
     # SSLCertificateFile ...
     # SSLCertificateKeyFile ...
     ...
&lt;/pre&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Now we can send plain HTTP test requests to &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;&lt;span class="pre"&gt;http://localhost:443/&lt;/span&gt;&lt;/tt&gt;. It works why wouldn't it, and it also reproduces the
problem.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Digging again in the logs (grep for &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;POST /upload&lt;/tt&gt;) yields:&lt;/p&gt;
&lt;div class="term docutils container"&gt;
&lt;pre class="literal-block" style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:none; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 6px #888; background:#000; background-image:radial-gradient(ellipse farthest-corner at center, #000 0%, #191919 100%); color:#aaa; display:inline-block' bgcolor="#FFFDFD"&gt;
09:22:24.700375109 0 httpd (653) &amp;gt; read fd=10(&amp;lt;4t&amp;gt;10.0.2.2:57454-&amp;gt;172.20.0.6:443) size=8000
09:22:24.700381289 0 httpd (653) &amp;lt; read res=1460 data=
POST /upload/ HTTP/1.1
Host: localhost:443
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://localhost:443/upload/
Content-Type: multipart/form-data; boundary=---------------------------8182195208398
Content-Length: 8243581
Cookie: csrftoken=...
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Pragma: no-cache
Cache-Control: no-cache

-----------------------------8182195208398
...
150926 09:22:24.700635979 0 httpd (653) &amp;gt; read fd=10(&amp;lt;4t&amp;gt;10.0.2.2:57454-&amp;gt;172.20.0.6:443) size=8000
150927 09:22:24.700638437 0 httpd (653) &amp;lt; read res=-11(EAGAIN) data=
150928 09:22:24.700642986 0 httpd (653) &amp;gt; read fd=10(&amp;lt;4t&amp;gt;10.0.2.2:57454-&amp;gt;172.20.0.6:443) size=8000
150929 09:22:24.700644098 0 httpd (653) &amp;lt; read res=-11(EAGAIN) data=
150930 09:22:24.700645959 0 httpd (653) &amp;gt; poll fds=10:41 timeout=20875
&lt;/pre&gt;
&lt;/div&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Note the funny two subsequent reads failing with EAGAIN - another unrelenting optimization?&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;And some time later (depending on throttling settings) Apache decides it's time to send the headers:&lt;/p&gt;
&lt;div class="term docutils container"&gt;
&lt;pre class="literal-block" style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:none; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 6px #888; background:#000; background-image:radial-gradient(ellipse farthest-corner at center, #000 0%, #191919 100%); color:#aaa; display:inline-block' bgcolor="#FFFDFD"&gt;
09:23:49.386532541 3 httpd (653) &amp;gt; writev fd=11(&amp;lt;4t&amp;gt;172.20.0.6:56980-&amp;gt;172.20.0.5:80) size=1132
09:23:49.386624313 3 httpd (653) &amp;lt; writev res=1132 data=
POST /upload/ HTTP/1.1
Host: web
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://localhost:443/upload/
Content-Type: multipart/form-data; boundary=---------------------------8182195208398
Cookie: csrftoken=...
Upgrade-Insecure-Requests: 1
Pragma: no-cache
Cache-Control: no-cache
Proxy-Secret: 17610e1815bed35364ea65a8c723e10101b64e0c2e824fca6f67eb120b7b7fc6
X-Forwarded-For: 10.0.2.2
X-Forwarded-Host: localhost:443
X-Forwarded-Server: localhost

09:23:49.386660855 3 httpd (653) &amp;gt; writev fd=11(&amp;lt;4t&amp;gt;172.20.0.6:56980-&amp;gt;172.20.0.5:80) size=8243632
09:23:49.386664671 3 httpd (653) &amp;lt; writev res=-32(EPIPE) data=
&lt;/pre&gt;
&lt;/div&gt;
&lt;p style="margin:25px 0 25px 0"&gt;So basically what happens here is that out keepalive connection times out. Turns out there was a Nginx setting for this, the
default being:&lt;/p&gt;
&lt;pre class="literal-block" style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:1px solid #DDD; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 3px #EFEFEF' bgcolor="#FFFDFD"&gt;
keepalive_timeout 75s;
&lt;/pre&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Now you don't really want to increase that, you'd end up with lots of tied up sockets and fds in dead connections.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;So the mystery remains: why does Apache only send out the request after buffering the whole request body?&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Unfortunately this is only clarified by looking at the not exactly short &lt;a class="reference external" href="https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#request-bodies" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;mod_proxy documentation&lt;/a&gt;. The fix ...&lt;/p&gt;
&lt;pre class="literal-block" style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:1px solid #DDD; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 3px #EFEFEF' bgcolor="#FFFDFD"&gt;
SetEnv proxy-sendchunked
&lt;/pre&gt;
&lt;p style="margin:25px 0 25px 0"&gt;And now I wasted your time too 👿&lt;/p&gt;
&lt;table class="docutils footnote" frame="void" id="id2" rules="none" style='margin:5px 0; box-shadow:none; background:transparent; border:none; border-collapse:separate; border-radius:5px; border-spacing:0; width:100%; font-family:Palatino, "Palatino Linotype", Georgia, serif; margin-bottom:8px' width="100%"&gt;
&lt;colgroup&gt;&lt;col class="label"&gt;&lt;col&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label" style='border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; border-left:1px solid #DDD; font-size:75%; background:transparent; text-decoration:none; text-shadow:none; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; width:5%; border-radius:0' width="5%"&gt;&lt;a class="fn-backref" href="https://blog.ionelmc.ro/2018/03/25/proxy-issues-with-apache/#id1" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:75%; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace'&gt;[1]&lt;/a&gt;&lt;/td&gt;&lt;td style="border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; font-size:15px; border-radius:0"&gt;&lt;p class="first" style="margin:0; margin-top:0"&gt;Pro tip: use &lt;cite&gt;rg&lt;/cite&gt; instead of &lt;cite&gt;grep&lt;/cite&gt;. You probably know the impressive silversearcher (&lt;cite&gt;ag&lt;/cite&gt;) but
&lt;a class="reference external" href="https://github.com/BurntSushi/ripgrep" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;https://github.com/BurntSushi/ripgrep&lt;/a&gt; buries everything else.&lt;/p&gt;
&lt;p class="last" style="margin:0; margin-top:15px"&gt;However, having the output already in a smallish file I've just used &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;less&lt;/tt&gt;. Just press &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;/&lt;/tt&gt; (search) or &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;&amp;gt;&lt;/tt&gt; (jump
to end) and &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;?&lt;/tt&gt; (search backwards) and fire way your regex.&lt;/p&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;img src="https://blog.ionelmc.ro/_/2018/03/25/proxy-issues-with-apache/?all-en.atom.xml" width="1" height="1" alt="" title=""&gt;</content><category term="apache"></category><category term="nginx"></category><category term="debugging"></category></entry><entry><title>Rehashing the src layout</title><link href="https://blog.ionelmc.ro/2017/09/25/rehashing-the-src-layout/" rel="alternate"></link><published>2017-09-25T00:00:00+03:00</published><updated>2017-11-20T16:52:18+02:00</updated><author><name>Ionel Cristian Mărieș</name></author><id>tag:blog.ionelmc.ro,2017-09-25:2017/09/25/rehashing-the-src-layout/</id><summary type="html">&lt;div class="document" style='font:19px/29px "Palatino Linotype", "Book Antiqua", "FPL Neu", "TeX Gyre Pagella", "URW Palladio L", "Palatino", "Century Schoolbook L", "Georgia", serif; margin:0; padding:0'&gt;&lt;p style="margin:25px 0 25px 0"&gt;Looking back at my &lt;a class="reference external" href="https://blog.ionelmc.ro/2014/05/25/python-packaging/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;Python packaging&lt;/a&gt; post, now it got
&lt;a class="reference external" href="https://hynek.me/articles/testing-packaging/#src" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;more&lt;/a&gt;
&lt;a class="reference external" href="https://docs.pytest.org/en/latest/goodpractices.html?highlight=src#choosing-a-test-layout-import-rules" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;popular&lt;/a&gt;.
Even &lt;a class="reference external" href="https://github.com/twisted/twisted" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;Twisted&lt;/a&gt; is using it now but
there's still confusion about it.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;I mean, places that you'd expect would use a &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;src&lt;/tt&gt;-layout don't. Take &lt;a class="reference external" href="http://flit.readthedocs.io/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;flit&lt;/a&gt; for instance, I
wrote &lt;a class="reference external" href="https://blog.ionelmc.ro/2015/02/24/the-problem-with-packaging-in-python/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;a rant on packaging&lt;/a&gt; almost 1 year later …&lt;/p&gt;&lt;/div&gt;</summary><content type="html">&lt;div class="document" style='font:19px/29px "Palatino Linotype", "Book Antiqua", "FPL Neu", "TeX Gyre Pagella", "URW Palladio L", "Palatino", "Century Schoolbook L", "Georgia", serif; margin:0; padding:0'&gt;&lt;p style="margin:25px 0 25px 0"&gt;Looking back at my &lt;a class="reference external" href="https://blog.ionelmc.ro/2014/05/25/python-packaging/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;Python packaging&lt;/a&gt; post, now it got
&lt;a class="reference external" href="https://hynek.me/articles/testing-packaging/#src" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;more&lt;/a&gt;
&lt;a class="reference external" href="https://docs.pytest.org/en/latest/goodpractices.html?highlight=src#choosing-a-test-layout-import-rules" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;popular&lt;/a&gt;.
Even &lt;a class="reference external" href="https://github.com/twisted/twisted" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;Twisted&lt;/a&gt; is using it now but
there's still confusion about it.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;I mean, places that you'd expect would use a &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;src&lt;/tt&gt;-layout don't. Take &lt;a class="reference external" href="http://flit.readthedocs.io/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;flit&lt;/a&gt; for instance, I
wrote &lt;a class="reference external" href="https://blog.ionelmc.ro/2015/02/24/the-problem-with-packaging-in-python/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;a rant on packaging&lt;/a&gt; almost 1 year later, and
that &lt;a class="reference external" href="https://www.reddit.com/r/Python/comments/3pasan/the_problem_with_packaging_in_python/cw51tjy/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;prompted&lt;/a&gt; Thomas
Kluyver to make flit but strangely enough it uses the ad-hoc layout &lt;a class="footnote-reference" href="https://blog.ionelmc.ro/2017/09/25/rehashing-the-src-layout/#id2" id="id1" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:12px; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; vertical-align:top' valign="top"&gt;[1]&lt;/a&gt;.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;And there are plenty of guides on the Internet with the ol' ad-hoc layout.&lt;/p&gt;
&lt;blockquote class="highlights" style='border-left:0; margin-left:0; padding:1ex 0 1ex 1em; quotes:"“" "”" "‘" "’"; color:#444; font-size:135%; font-style:italic; font-weight:bold; line-height:1.2; padding-left:0; text-align:center' align="center"&gt;
So people are wondering: "I don't understand this packaging mumbo-jumbo, what should I use?"&lt;/blockquote&gt;
&lt;p style="margin:25px 0 25px 0"&gt;It's not that complicated, just have these thoughts in mind when choosing:&lt;/p&gt;
&lt;ul style="margin:25px 0 25px 0"&gt;
&lt;li style="padding:0"&gt;&lt;p class="first" style="margin:25px 0 25px 0"&gt;If you use a project template (e.g.: &lt;a class="reference external" href="https://cookiecutter.readthedocs.io/en/latest/readme.html#python" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;cookiecutter&lt;/a&gt;) the
choice of layout is not so important. The template should solve all the annoying packaging problems.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;You should use a template anyway.&lt;/p&gt;
&lt;/li&gt;
&lt;li style="padding:0"&gt;&lt;p class="first" style="margin:25px 0 25px 0"&gt;If you already have a project using the ad-hoc layout, and you don't have problems with testing or packaging then there's
little value in switching over to a &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;src&lt;/tt&gt;-layout.&lt;/p&gt;
&lt;/li&gt;
&lt;li style="padding:0"&gt;&lt;p class="first" style="margin:25px 0 25px 0"&gt;The ad-hoc layout is more convenient and that's why there's high resistance to &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;src&lt;/tt&gt;-layouts.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;You need tooling to use the &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;src&lt;/tt&gt;-layout effectively. If you don't use a tool to manage virtualenvs and install your
project like &lt;a class="reference external" href="https://tox.readthedocs.io/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;Tox&lt;/a&gt; then it's going to be painful.&lt;/p&gt;
&lt;/li&gt;
&lt;li style="padding:0"&gt;&lt;p class="first" style="margin:25px 0 25px 0"&gt;Any layout will work. Mistakes can be corrected.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;If &lt;a class="reference external" href="https://blog.ionelmc.ro/2014/05/25/python-packaging/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;this&lt;/a&gt; don't make
sense (I agree it's a bit heavy on jargon and technicalities) and you don't want to use a template then perhaps you're
looking to learn packaging the hard way. Just flip a coin and start with something.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;table class="docutils footnote" frame="void" id="id2" rules="none" style='margin:5px 0; box-shadow:none; background:transparent; border:none; border-collapse:separate; border-radius:5px; border-spacing:0; width:100%; font-family:Palatino, "Palatino Linotype", Georgia, serif; margin-bottom:8px' width="100%"&gt;
&lt;colgroup&gt;&lt;col class="label"&gt;&lt;col&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label" style='border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; border-left:1px solid #DDD; font-size:75%; background:transparent; text-decoration:none; text-shadow:none; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; width:5%; border-radius:0' width="5%"&gt;&lt;a class="fn-backref" href="https://blog.ionelmc.ro/2017/09/25/rehashing-the-src-layout/#id1" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:75%; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace'&gt;[1]&lt;/a&gt;&lt;/td&gt;&lt;td style="border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; font-size:15px; border-radius:0"&gt;&lt;p class="first" style="margin:0; margin-top:0"&gt;Now people have already asked for flit to support the &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;src&lt;/tt&gt;-layout. I have even added my thoughts on
&lt;a class="reference external" href="https://github.com/takluyver/flit/issues/115" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;the issue&lt;/a&gt;.&lt;/p&gt;
&lt;p class="last" style="margin:0; margin-top:15px"&gt;Don't go over there and spam the issue with comments, I don't think there's anything new to add.&lt;/p&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;img src="https://blog.ionelmc.ro/_/2017/09/25/rehashing-the-src-layout/?all-en.atom.xml" width="1" height="1" alt="" title=""&gt;</content><category term="python"></category><category term="packaging"></category><category term="src"></category></entry><entry><title>Dealing with Docker</title><link href="https://blog.ionelmc.ro/2016/05/07/dealing-with-docker/" rel="alternate"></link><published>2016-05-07T00:00:00+03:00</published><updated>2016-05-28T15:15:25+03:00</updated><author><name>Ionel Cristian Mărieș</name></author><id>tag:blog.ionelmc.ro,2016-05-07:2016/05/07/dealing-with-docker/</id><summary type="html">&lt;div class="document" style='font:19px/29px "Palatino Linotype", "Book Antiqua", "FPL Neu", "TeX Gyre Pagella", "URW Palladio L", "Palatino", "Century Schoolbook L", "Georgia", serif; margin:0; padding:0'&gt;&lt;p style="margin:25px 0 25px 0"&gt;I'm giving &lt;a class="reference external" href="https://www.docker.com/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;Docker&lt;/a&gt; a shot again, after couple years, and this time I'm "dockerizing" an old Python
app that don't even have configuration management or orchestration. Docker is easy to install now. No more bullshit about
kernel features and filesystem support. They even claim it works seamlessly on OS X …&lt;/p&gt;&lt;/div&gt;</summary><content type="html">&lt;div class="document" style='font:19px/29px "Palatino Linotype", "Book Antiqua", "FPL Neu", "TeX Gyre Pagella", "URW Palladio L", "Palatino", "Century Schoolbook L", "Georgia", serif; margin:0; padding:0'&gt;&lt;p style="margin:25px 0 25px 0"&gt;I'm giving &lt;a class="reference external" href="https://www.docker.com/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;Docker&lt;/a&gt; a shot again, after couple years, and this time I'm "dockerizing" an old Python
app that don't even have configuration management or orchestration. Docker is easy to install now. No more bullshit about
kernel features and filesystem support. They even claim it works seamlessly on OS X and Windows &lt;a class="footnote-reference" href="https://blog.ionelmc.ro/2016/05/07/dealing-with-docker/#id9" id="id1" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:12px; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; vertical-align:top' valign="top"&gt;[*]&lt;/a&gt;.&lt;/p&gt;
&lt;div class="section" id="the-good-parts"&gt;
&lt;h2 style='font-family:"Candara", "Merriweather Sans", "Trebuchet Ms", "Segoe UI", sans-serif; text-shadow:1px 1px 1px #DDD; color:#333; font-weight:bold; line-height:1; font-size:2em'&gt;The good parts&lt;a class="headerlink" href="https://blog.ionelmc.ro/2016/05/07/dealing-with-docker/#the-good-parts" title="Permalink to this headline" style="color:#c60f0f; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; padding:0 4px 0 4px; vertical-align:middle; visibility:hidden" valign="middle"&gt;
*&lt;/a&gt;&lt;/h2&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Docker has several things going for it: a good name, huge community, &lt;a class="reference external" href="https://hub.docker.com/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;huge amount of images&lt;/a&gt; you
can start from. Sure, most images are not great, even the official images can have issues but you can always take out the
&lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;Dockerfile&lt;/tt&gt; and customize things.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Right now it's hard to find an alternative. &lt;a class="reference external" href="https://coreos.com/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;CoreOS&lt;/a&gt; is trying to make an alternative called "rkt".
With a flikr-esque name at that! How do you even read it? ercati? erkit? rocket? rockit? rackit? reckit? You know what,
&lt;cite&gt;wreckit&lt;/cite&gt;. If you think I'm lambasting the name unfairly then consider that most of the world don't speak very good English
and interpretable spelling is a problem.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Even if &lt;a class="reference external" href="https://coreos.com/rkt/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;rkt&lt;/a&gt; didn't have such a terrible name, it still has a long way to reaching Docker's
convenience.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="what-irks-me"&gt;
&lt;h2 style='font-family:"Candara", "Merriweather Sans", "Trebuchet Ms", "Segoe UI", sans-serif; text-shadow:1px 1px 1px #DDD; color:#333; font-weight:bold; line-height:1; font-size:2em'&gt;What irks me&lt;a class="headerlink" href="https://blog.ionelmc.ro/2016/05/07/dealing-with-docker/#what-irks-me" title="Permalink to this headline" style="color:#c60f0f; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; padding:0 4px 0 4px; vertical-align:middle; visibility:hidden" valign="middle"&gt;
*&lt;/a&gt;&lt;/h2&gt;
&lt;div class="admonition note" style="border:1px solid #DDD; border-radius:5px; box-shadow:0 1px 5px #EEE; margin:3ex 1ex 1ex 1ex; padding:0; background:white; float:right; width:200px" width="200"&gt;
&lt;p class="first admonition-title" style="margin:0; font-size:90%; border:none; border-radius:5px; box-shadow:0 1px 5px #EEE; padding:0; background:#F5F5F0; border-bottom:1px solid #DDD; font-style:italic; text-align:center" align="center"&gt;Note&lt;/p&gt;
&lt;p class="last" style="margin:0 0.5em 1em 0.5em; font-size:90%; margin-bottom:5px"&gt;If it matters, I'm using Docker version 1.11.0. They call it the "Engine" now.&lt;/p&gt;
&lt;/div&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Docker has some strange oversights and quirks. There's a very strong focus on not breaking any interfaces, it's a bit depressing
to look at the bug tracker if you're the impatient type.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;These things annoy me:&lt;/p&gt;
&lt;ul style="margin:25px 0 25px 0"&gt;
&lt;li style="padding:0"&gt;&lt;p class="first" style="margin:25px 0 25px 0"&gt;Documentation has no search. Seriously? I understand that there's Google but come on, I don't want to look at docs for old
Docker versions and other junk Google gives me.&lt;/p&gt;
&lt;/li&gt;
&lt;li style="padding:0"&gt;&lt;p class="first" style="margin:25px 0 25px 0"&gt;Command line seem clumsy:&lt;/p&gt;
&lt;ul style="margin:10px 0; padding:0 0 0 40px"&gt;
&lt;li style="padding:0"&gt;&lt;p class="first" style="margin:25px 0 25px 0"&gt;Inflexible parsing, eg: &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;docker build . &lt;span class="pre"&gt;--help&lt;/span&gt;&lt;/tt&gt; ain't valid. That makes no sense, there's only a single non-option argument,
why can't I have options after that single possible argument?&lt;/p&gt;
&lt;/li&gt;
&lt;li style="padding:0"&gt;&lt;p class="first" style="margin:25px 0 25px 0"&gt;Most arguments have short form (eg: &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;&lt;span class="pre"&gt;-i&lt;/span&gt;&lt;/tt&gt;) but not &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;&lt;span class="pre"&gt;--help&lt;/span&gt;&lt;/tt&gt;. Nooo, not that. No one needs a short form for that, God
forbid!&lt;/p&gt;
&lt;/li&gt;
&lt;li style="padding:0"&gt;&lt;p class="first" style="margin:25px 0 25px 0"&gt;Bad help for most options. Is this supposed to help?&lt;/p&gt;
&lt;pre class="code term literal-block" style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:none; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 6px #888; background:#000; background-image:radial-gradient(ellipse farthest-corner at center, #000 0%, #191919 100%); color:#aaa' bgcolor="#FFFDFD"&gt;
-v, --volume=[]                 Bind mount a volume
&lt;/pre&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Cause that sure as hell don't tell me anything about what I can pass in there. Now I have to go into the docs with no
search. After rummaging trough 10 useless pages of documentation I eventually I get to &lt;a class="reference external" href="https://docs.docker.com/engine/reference/run/#volume-shared-filesystems" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;this&lt;/a&gt;:&lt;/p&gt;
&lt;pre class="code term literal-block" style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:none; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 6px #888; background:#000; background-image:radial-gradient(ellipse farthest-corner at center, #000 0%, #191919 100%); color:#aaa' bgcolor="#FFFDFD"&gt;
-v, --volume=[host-src:]container-dest[:&amp;lt;options&amp;gt;]
                      Bind mount a volume. The comma-delimited
                      `options` are [rw|ro], [z|Z],
                      [[r]shared|[r]slave|[r]private], and
                      [nocopy]. The 'host-src' is an absolute path
                      or a name value.
&lt;/pre&gt;
&lt;p style="margin:25px 0 25px 0"&gt;What. Why can't that be in the command line?&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li style="padding:0"&gt;&lt;p class="first" style="margin:25px 0 25px 0"&gt;If you got a run or build error in &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;&lt;span class="pre"&gt;docker-compose&lt;/span&gt;&lt;/tt&gt; you're usually left with half running containers and you have to
manually cleanup the mess. If you don't pay attention you're left wondering why &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;&lt;span class="pre"&gt;docker-compose&lt;/span&gt; build&lt;/tt&gt; doesn't do anything.
I did some changes, ran &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;&lt;span class="pre"&gt;docker-compose&lt;/span&gt; build&lt;/tt&gt;, why don't &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;&lt;span class="pre"&gt;docker-compose&lt;/span&gt; up&lt;/tt&gt; don't run new images? Cause some stuff is
already running, that's why!&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;If you stop a &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;&lt;span class="pre"&gt;docker-compose&lt;/span&gt; up&lt;/tt&gt; all services stop. If you stop a &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;&lt;span class="pre"&gt;docker-compose&lt;/span&gt; up myservice&lt;/tt&gt; it leaves all the
dependencies running around. Argh! Why the inconsistency?&lt;/p&gt;
&lt;/li&gt;
&lt;li style="padding:0"&gt;&lt;p class="first" style="margin:25px 0 25px 0"&gt;There is no garbage collection. Leaves around huge piles of useless containers and images. Sure, there's
&lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;docker rmi $(docker images &lt;span class="pre"&gt;-q)&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;docker rm $(docker ps &lt;span class="pre"&gt;-a&lt;/span&gt; &lt;span class="pre"&gt;-q)&lt;/span&gt;&lt;/tt&gt; but that's like cleaning your computer dust with
a water hose. It sure does the job but your computer probably don't work after that.&lt;/p&gt;
&lt;/li&gt;
&lt;li style="padding:0"&gt;&lt;p class="first" style="margin:25px 0 25px 0"&gt;Dockerfiles are quirky and non-orthogonal. Similarly to command line interface, the &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;Dockerfile&lt;/tt&gt; syntax is a culmination
of ill-advised choices.&lt;/p&gt;
&lt;ul style="margin:10px 0; padding:0 0 0 40px"&gt;
&lt;li style="padding:0"&gt;&lt;p class="first" style="margin:25px 0 25px 0"&gt;Support for multiline values is an afterthought. Dockerfiles are littered with "&lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;\&lt;/tt&gt;" and "&lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;&amp;amp;&amp;amp;&lt;/tt&gt;" all over the place.
Lots of noise, lots of mistakes.&lt;/p&gt;
&lt;/li&gt;
&lt;li style="padding:0"&gt;&lt;p class="first" style="margin:25px 0 25px 0"&gt;There two ways to do the same thing. The parser takes JSON for most commands but if parse fails
then it takes whatever gunk is in there as a string.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;For example the &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;CMD&lt;/tt&gt; and &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;ENTRYPOINT&lt;/tt&gt; take this to the extreme: they have two &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;exec&lt;/tt&gt; mode. Take a look at this
crazy table:&lt;/p&gt;
&lt;table border="1" class="small docutils" style="margin:25px 0 25px 0; box-shadow:1px 1px 3px #EFEFEF; background:#FFFDFD; border:0; border-collapse:separate; border-radius:5px; border-spacing:0; width:100%; font-size:75%; margin-bottom:8px" width="100%"&gt;
&lt;colgroup&gt;
&lt;col width="25%"&gt;
&lt;col width="25%"&gt;
&lt;col width="25%"&gt;
&lt;col width="25%"&gt;
&lt;/colgroup&gt;
&lt;thead valign="bottom"&gt;
&lt;tr&gt;&lt;th class="head" style="border:0; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; border-left:1px solid #DDD; background:#f9f9f0; border-top:1px solid #DDD"&gt; &lt;/th&gt;
&lt;th class="head" style="border:0; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; background:#f9f9f0; border-top:1px solid #DDD"&gt;No &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;ENTRYPOINT&lt;/tt&gt;&lt;/th&gt;
&lt;th class="head" style="border:0; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; background:#f9f9f0; border-top:1px solid #DDD"&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre style='margin:0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:none; border-radius:5px; line-height:1.5; padding:0; white-space:pre-wrap; word-wrap:break-word; box-shadow:none; background:inherit' bgcolor="#FFFDFD"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k" style="font-weight:bold"&gt;ENTRYPOINT&lt;/span&gt;&lt;span class="s" style="color:#d14"&gt; exec_entry p1_entry&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/th&gt;
&lt;th class="head" style="border:0; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; background:#f9f9f0; border-top:1px solid #DDD"&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre style='margin:0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:none; border-radius:5px; line-height:1.5; padding:0; white-space:pre-wrap; word-wrap:break-word; box-shadow:none; background:inherit' bgcolor="#FFFDFD"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k" style="font-weight:bold"&gt;ENTRYPOINT&lt;/span&gt;&lt;span class="s" style="color:#d14"&gt; ["exec_entry", "p1_entry"]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td style="border:0; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; border-left:1px solid #DDD"&gt;No &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;CMD&lt;/tt&gt;&lt;/td&gt;
&lt;td style="border:0; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px"&gt;&lt;em&gt;error, not allowed&lt;/em&gt;&lt;/td&gt;
&lt;td style="border:0; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px"&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre style='margin:0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:none; border-radius:5px; line-height:1.5; padding:0; white-space:pre-wrap; word-wrap:break-word; box-shadow:none; background:inherit' bgcolor="#FFFDFD"&gt;&lt;span&gt;&lt;/span&gt;/bin/sh -c exec_entry p1_entry
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td style="border:0; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px"&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre style='margin:0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:none; border-radius:5px; line-height:1.5; padding:0; white-space:pre-wrap; word-wrap:break-word; box-shadow:none; background:inherit' bgcolor="#FFFDFD"&gt;&lt;span&gt;&lt;/span&gt;exec_entry p1_entry
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style="border:0; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; border-left:1px solid #DDD"&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre style='margin:0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:none; border-radius:5px; line-height:1.5; padding:0; white-space:pre-wrap; word-wrap:break-word; box-shadow:none; background:inherit' bgcolor="#FFFDFD"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k" style="font-weight:bold"&gt;CMD&lt;/span&gt;&lt;span class="s" style="color:#d14"&gt; ["exec_cmd", "p1_cmd"]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td style="border:0; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px"&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre style='margin:0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:none; border-radius:5px; line-height:1.5; padding:0; white-space:pre-wrap; word-wrap:break-word; box-shadow:none; background:inherit' bgcolor="#FFFDFD"&gt;&lt;span&gt;&lt;/span&gt;exec_cmd p1_cmd
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td style="border:0; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px"&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre style='margin:0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:none; border-radius:5px; line-height:1.5; padding:0; white-space:pre-wrap; word-wrap:break-word; box-shadow:none; background:inherit' bgcolor="#FFFDFD"&gt;&lt;span&gt;&lt;/span&gt;/bin/sh -c exec_entry p1_entry exec_cmd p1_cmd
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td style="border:0; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px"&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre style='margin:0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:none; border-radius:5px; line-height:1.5; padding:0; white-space:pre-wrap; word-wrap:break-word; box-shadow:none; background:inherit' bgcolor="#FFFDFD"&gt;&lt;span&gt;&lt;/span&gt;exec_entry p1_entry exec_cmd p1_cmd
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style="border:0; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; border-left:1px solid #DDD"&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre style='margin:0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:none; border-radius:5px; line-height:1.5; padding:0; white-space:pre-wrap; word-wrap:break-word; box-shadow:none; background:inherit' bgcolor="#FFFDFD"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k" style="font-weight:bold"&gt;CMD&lt;/span&gt;&lt;span class="s" style="color:#d14"&gt; ["p1_cmd", "p2_cmd"]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td style="border:0; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px"&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre style='margin:0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:none; border-radius:5px; line-height:1.5; padding:0; white-space:pre-wrap; word-wrap:break-word; box-shadow:none; background:inherit' bgcolor="#FFFDFD"&gt;&lt;span&gt;&lt;/span&gt;p1_cmd p2_cmd
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td style="border:0; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px"&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre style='margin:0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:none; border-radius:5px; line-height:1.5; padding:0; white-space:pre-wrap; word-wrap:break-word; box-shadow:none; background:inherit' bgcolor="#FFFDFD"&gt;&lt;span&gt;&lt;/span&gt;/bin/sh -c exec_entry p1_entry p1_cmd p2_cmd
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td style="border:0; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px"&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre style='margin:0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:none; border-radius:5px; line-height:1.5; padding:0; white-space:pre-wrap; word-wrap:break-word; box-shadow:none; background:inherit' bgcolor="#FFFDFD"&gt;&lt;span&gt;&lt;/span&gt;exec_entry p1_entry p1_cmd p2_cmd
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td style="border:0; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; border-left:1px solid #DDD"&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre style='margin:0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:none; border-radius:5px; line-height:1.5; padding:0; white-space:pre-wrap; word-wrap:break-word; box-shadow:none; background:inherit' bgcolor="#FFFDFD"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k" style="font-weight:bold"&gt;CMD&lt;/span&gt;&lt;span class="s" style="color:#d14"&gt; exec_cmd p1_cmd&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td style="border:0; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px"&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre style='margin:0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:none; border-radius:5px; line-height:1.5; padding:0; white-space:pre-wrap; word-wrap:break-word; box-shadow:none; background:inherit' bgcolor="#FFFDFD"&gt;&lt;span&gt;&lt;/span&gt;/bin/sh -c exec_cmd p1_cmd
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td style="border:0; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px"&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre style='margin:0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:none; border-radius:5px; line-height:1.5; padding:0; white-space:pre-wrap; word-wrap:break-word; box-shadow:none; background:inherit' bgcolor="#FFFDFD"&gt;&lt;span&gt;&lt;/span&gt;/bin/sh -c exec_entry p1_entry /bin/sh -c exec_cmd p1_cmd
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td style="border:0; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px"&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre style='margin:0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:none; border-radius:5px; line-height:1.5; padding:0; white-space:pre-wrap; word-wrap:break-word; box-shadow:none; background:inherit' bgcolor="#FFFDFD"&gt;&lt;span&gt;&lt;/span&gt;exec_entry p1_entry /bin/sh -c exec_cmd p1_cmd
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style="margin:25px 0 25px 0"&gt;There is clear overlap there. Maybe there are historical reasons for it but that's why we have version numbers. Why do we
need to keep all that cruft?&lt;/p&gt;
&lt;/li&gt;
&lt;li style="padding:0"&gt;&lt;p class="first" style="margin:25px 0 25px 0"&gt;No volumes/mounts during &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;docker build&lt;/tt&gt;. I have found ways to deal with this (read on) but still, it's an irk.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p style="margin:25px 0 25px 0"&gt;If you look in the bug tracker you'll notice that lots of people have come up with ideas to improve Dockerfiles, but these
issues just don't seem important enough.&lt;/p&gt;
&lt;/li&gt;
&lt;li style="padding:0"&gt;&lt;p class="first" style="margin:25px 0 25px 0"&gt;There's something rotten about how Docker run containers as &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;root&lt;/tt&gt; &lt;a class="reference external" href="https://blog.ionelmc.ro/2016/05/07/dealing-with-docker/#default-root-user" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;by default&lt;/a&gt;. Docker seems
to mitigate this by &lt;a class="reference external" href="https://blog.ionelmc.ro/2016/05/07/dealing-with-docker/#debugging" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;disabling some capabilities&lt;/a&gt; like &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;ptrace&lt;/tt&gt; by default. But this ain't purely a
security concern, it affects usability as well.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;For example, once you install docker on your Ubuntu you're faced with a choice: use &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;sudo&lt;/tt&gt; all over the place or give
your user full access to the daemon:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:1px solid #DDD; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 3px #EFEFEF' bgcolor="#FFFDFD"&gt;&lt;span&gt;&lt;/span&gt;sudo usermod -aG docker &lt;span class="nv" style="color:#008080"&gt;$USER&lt;/span&gt;

&lt;span class="c1" style="color:#998; font-style:italic"&gt;# then relogin, for the change to take effect - obvious right?&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Still not sure if that's better than a constant reminder that you're doing lots of stuff as root.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p style="margin:25px 0 25px 0"&gt;I know these might look like superficial complaints but they rile me up regardless. At least it's not &lt;a class="reference external" href="http://blog.ionelmc.ro/2014/12/28/terrible-choices-mysql/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;this&lt;/a&gt; bad. &amp;lt;/rant&amp;gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="the-ecosystem"&gt;
&lt;h2 style='font-family:"Candara", "Merriweather Sans", "Trebuchet Ms", "Segoe UI", sans-serif; text-shadow:1px 1px 1px #DDD; color:#333; font-weight:bold; line-height:1; font-size:2em'&gt;The ecosystem&lt;a class="headerlink" href="https://blog.ionelmc.ro/2016/05/07/dealing-with-docker/#the-ecosystem" title="Permalink to this headline" style="color:#c60f0f; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; padding:0 4px 0 4px; vertical-align:middle; visibility:hidden" valign="middle"&gt;
*&lt;/a&gt;&lt;/h2&gt;
&lt;p style="margin:25px 0 25px 0"&gt;There are &lt;a class="reference external" href="https://hub.docker.com/explore/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;a lot of images&lt;/a&gt;, and you'll probably find anything you'll ever want. And
there's even a set of specially branded images that pop up almost everywhere: the "official" images. They are pretty good: up
to date, they verify signatures for whatever they download, consistent presentation etc.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Though I have a problem with the &lt;a class="reference external" href="https://hub.docker.com/_/python/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;Python images&lt;/a&gt;. For some reason they decided to just
compile Python themselves. Sure, it's the latest point-release but they don't include any of the patches the Debian
maintainers made. I don't like those patches either (they customize package install paths and the import system) but it's
worse without them:&lt;/p&gt;
&lt;ul style="margin:25px 0 25px 0"&gt;
&lt;li style="padding:0"&gt;&lt;p class="first" style="margin:25px 0 25px 0"&gt;Suddenly &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;gdb&lt;/tt&gt; stops working. Just try a &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;docker run &lt;span class="pre"&gt;--rm&lt;/span&gt; &lt;span class="pre"&gt;-it&lt;/span&gt; python:2.7 sh&lt;/tt&gt;:&lt;/p&gt;
&lt;pre class="code term literal-block" style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:none; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 6px #888; background:#000; background-image:radial-gradient(ellipse farthest-corner at center, #000 0%, #191919 100%); color:#aaa' bgcolor="#FFFDFD"&gt;
# apt-get update
# apt-get install gdb
# gdb python
Traceback (most recent call last):
  File "/usr/lib/python2.7/site.py", line 563, in &amp;lt;module&amp;gt;
    main()
  File "/usr/lib/python2.7/site.py", line 545, in main
    known_paths = addusersitepackages(known_paths)
  File "/usr/lib/python2.7/site.py", line 272, in addusersitepackages
    user_site = getusersitepackages()
  File "/usr/lib/python2.7/site.py", line 247, in getusersitepackages
    user_base = getuserbase() # this will also set USER_BASE
  File "/usr/lib/python2.7/site.py", line 237, in getuserbase
    USER_BASE = get_config_var('userbase')
  File "/usr/lib/python2.7/sysconfig.py", line 582, in get_config_var
    return get_config_vars().get(name)
  File "/usr/lib/python2.7/sysconfig.py", line 528, in get_config_vars
    _init_posix(_CONFIG_VARS)
  File "/usr/lib/python2.7/sysconfig.py", line 412, in _init_posix
    from _sysconfigdata import build_time_vars
  File "/usr/lib/python2.7/_sysconfigdata.py", line 6, in &amp;lt;module&amp;gt;
    from _sysconfigdata_nd import *
ImportError: No module named _sysconfigdata_nd
&lt;/pre&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Looks like there's some import path trampling going on. I don't want broken debug tools when my app is broken.&lt;/p&gt;
&lt;/li&gt;
&lt;li style="padding:0"&gt;&lt;p class="first" style="margin:25px 0 25px 0"&gt;You can't use any Python package from the APT repos. Sure, most of them are old and easy to install with pip, but there are
exceptions &lt;a class="footnote-reference" href="https://blog.ionelmc.ro/2016/05/07/dealing-with-docker/#id11" id="id2" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:12px; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; vertical-align:top' valign="top"&gt;[2]&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li style="padding:0"&gt;&lt;p class="first" style="margin:25px 0 25px 0"&gt;Strange &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;&lt;span class="pre"&gt;C.UTF-8&lt;/span&gt;&lt;/tt&gt; locale. I can understand they don't want to put a specific language in there but if you run any locale
using applications you'll run into issues.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p style="margin:25px 0 25px 0"&gt;What I ended up was using the &lt;a class="reference external" href="https://hub.docker.com/_/ubuntu/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;ubuntu:xenial&lt;/a&gt; image (Xenial being the new LTS). It ships
latest point release for 2.7 so why compile it again? I took the good parts from &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;&lt;span class="pre"&gt;python:2.7-slim&lt;/span&gt;&lt;/tt&gt; and I got this
&lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;Dockerfile&lt;/tt&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:1px solid #DDD; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 3px #EFEFEF' bgcolor="#FFFDFD"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k" style="font-weight:bold"&gt;FROM&lt;/span&gt;&lt;span class="s" style="color:#d14"&gt; ubuntu:xenial&lt;/span&gt;

&lt;span class="k" style="font-weight:bold"&gt;RUN&lt;/span&gt; locale-gen en_US.UTF-8
&lt;span class="k" style="font-weight:bold"&gt;ENV&lt;/span&gt;&lt;span class="s" style="color:#d14"&gt; LANG en_US.UTF-8&lt;/span&gt;
&lt;span class="k" style="font-weight:bold"&gt;ENV&lt;/span&gt;&lt;span class="s" style="color:#d14"&gt; LANGUAGE en_US:en&lt;/span&gt;
&lt;span class="k" style="font-weight:bold"&gt;ENV&lt;/span&gt;&lt;span class="s" style="color:#d14"&gt; LC_ALL en_US.UTF-8&lt;/span&gt;

&lt;span class="k" style="font-weight:bold"&gt;RUN&lt;/span&gt; apt-get update &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
 &lt;span class="o" style="font-weight:bold"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get install -y --no-install-recommends &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
                    ca-certificates curl &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
                    strace gdb lsof locate net-tools htop &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
                    python2.7-dbg python2.7 libpython2.7 &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
 &lt;span class="o" style="font-weight:bold"&gt;&amp;amp;&amp;amp;&lt;/span&gt; rm -rf /var/lib/apt/lists/*

&lt;span class="k" style="font-weight:bold"&gt;ENV&lt;/span&gt;&lt;span class="s" style="color:#d14"&gt; PYTHON_PIP_VERSION 8.1.1&lt;/span&gt;
&lt;span class="k" style="font-weight:bold"&gt;RUN&lt;/span&gt; &lt;span class="nb" style="color:#0086B3"&gt;set&lt;/span&gt; -eEx &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
 &lt;span class="o" style="font-weight:bold"&gt;&amp;amp;&amp;amp;&lt;/span&gt; curl -fSL &lt;span class="s1" style="color:#d14"&gt;'https://bootstrap.pypa.io/get-pip.py'&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; python2.7 - &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
         --no-cache-dir --upgrade &lt;span class="nv" style="color:#008080"&gt;pip&lt;/span&gt;&lt;span class="o" style="font-weight:bold"&gt;==&lt;/span&gt;&lt;span class="nv" style="color:#008080"&gt;$PYTHON_PIP_VERSION&lt;/span&gt;

COPY .wheels /wheels
&lt;/pre&gt;&lt;/div&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Everything works great, and there's some magic in those debug packages that make &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;gdb&lt;/tt&gt; give me some real nice commands
like &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;&lt;span class="pre"&gt;py-bt&lt;/span&gt;&lt;/tt&gt; &lt;a class="footnote-reference" href="https://blog.ionelmc.ro/2016/05/07/dealing-with-docker/#id12" id="id3" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:12px; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; vertical-align:top' valign="top"&gt;[3]&lt;/a&gt;. Note that I snuck in some &lt;a class="reference external" href="https://blog.ionelmc.ro/2013/06/05/python-debugging-tools/#standard-linux-tools" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;other tools to help debugging&lt;/a&gt;.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;All I'm saying there is that even official images need scrutiny. Check their &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;Dockerfile&lt;/tt&gt; and decide if it really fits your
needs.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="the-challenges"&gt;
&lt;h2 style='font-family:"Candara", "Merriweather Sans", "Trebuchet Ms", "Segoe UI", sans-serif; text-shadow:1px 1px 1px #DDD; color:#333; font-weight:bold; line-height:1; font-size:2em'&gt;The challenges&lt;a class="headerlink" href="https://blog.ionelmc.ro/2016/05/07/dealing-with-docker/#the-challenges" title="Permalink to this headline" style="color:#c60f0f; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; padding:0 4px 0 4px; vertical-align:middle; visibility:hidden" valign="middle"&gt;
*&lt;/a&gt;&lt;/h2&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Docker has some interesting challenges, or limitations. The build system has something called "layers" and there's a hard limit of
how many layers you can have. Each command in your &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;Dockerfile&lt;/tt&gt; makes a new layer. If you look at the "official" &lt;a class="reference external" href="https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;best practices&lt;/a&gt; guide you'll see most of the stuff there
revolves around this limitation. You inevitably end up with some damn ugly &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;RUN&lt;/tt&gt; commands.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;There's a good thing about these layers - they are cached. However, the context is not. Never one layer needs all the context,
or the same part of the context. Layers should be able to have individual context, but alas, &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;docker build&lt;/tt&gt; wasn't designed
with that in mind.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Another limitation by design is that &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;docker build&lt;/tt&gt; doesn't allow any mounts or volumes during build. The only way to get
stuff in the container that eventually becomes the image is by network or by the "context".&lt;/p&gt;
&lt;div class="section" id="what-s-this-context"&gt;
&lt;span id="contexts"&gt;&lt;/span&gt;&lt;h3 style='font-family:"Candara", "Merriweather Sans", "Trebuchet Ms", "Segoe UI", sans-serif; text-shadow:1px 1px 1px #DDD; color:#333; font-weight:bold; line-height:1; font-size:1.56em'&gt;What's this context?&lt;a class="headerlink" href="https://blog.ionelmc.ro/2016/05/07/dealing-with-docker/#what-s-this-context" title="Permalink to this headline" style="color:#c60f0f; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; padding:0 4px 0 4px; vertical-align:middle; visibility:hidden" valign="middle"&gt;
*&lt;/a&gt;&lt;/h3&gt;
&lt;p style="margin:25px 0 25px 0"&gt;When you run &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;docker build foobar&lt;/tt&gt; Docker will make an archive of &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;foobar/*&lt;/tt&gt; (minus what you have in &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;.dockerignore&lt;/tt&gt;) and
build an image according to what you have in &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;foobar/Dockerfile&lt;/tt&gt;. You can specify the context path and &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;Dockerfile&lt;/tt&gt; path
individually but, never too odd, that &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;Dockerfile&lt;/tt&gt; must be in the context. You can't get creative here.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="optimizing-the-build-process"&gt;
&lt;h3 style='font-family:"Candara", "Merriweather Sans", "Trebuchet Ms", "Segoe UI", sans-serif; text-shadow:1px 1px 1px #DDD; color:#333; font-weight:bold; line-height:1; font-size:1.56em'&gt;Optimizing the build process&lt;a class="headerlink" href="https://blog.ionelmc.ro/2016/05/07/dealing-with-docker/#optimizing-the-build-process" title="Permalink to this headline" style="color:#c60f0f; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; padding:0 4px 0 4px; vertical-align:middle; visibility:hidden" valign="middle"&gt;
*&lt;/a&gt;&lt;/h3&gt;
&lt;p style="margin:25px 0 25px 0"&gt;You can parametrize this build process but the lack of mounts or volumes exposes you to some pretty annoying slowness if you
have to build external packages for example. This problem is still pervasive in Python, most of the stuff in &lt;a class="reference external" href="http://pypi.python.org/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;PyPI&lt;/a&gt; is just source packages. Even if now you can &lt;a class="reference external" href="https://www.python.org/dev/peps/pep-0513/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;publish Linux binaries on PyPI&lt;/a&gt; it's still years till most packages will publish those &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;manylinux1&lt;/tt&gt;
wheels &lt;a class="footnote-reference" href="https://blog.ionelmc.ro/2016/05/07/dealing-with-docker/#id10" id="id4" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:12px; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; vertical-align:top' valign="top"&gt;[1]&lt;/a&gt;. Even if we'd have wheels for everything there's still the question of network slowness. Setting up caching
proxies is inconvenient.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Most Dockerfiles I've seen have something like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:1px solid #DDD; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 3px #EFEFEF' bgcolor="#FFFDFD"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k" style="font-weight:bold"&gt;RUN&lt;/span&gt; mkdir -p /app

COPY requirements.txt /
&lt;span class="c" style="color:#998; font-style:italic"&gt;# slow as hell ...&lt;/span&gt;
&lt;span class="k" style="font-weight:bold"&gt;RUN&lt;/span&gt; pip install -r /requirements.txt

COPY app /app
&lt;/pre&gt;&lt;/div&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Now for simple projects this is fine, because you only have a handful of dependencies. But for a larger projects, hundreds of
dependencies is order of the day. Changing them or upgrading versions (as you should always pin versions &lt;a class="footnote-reference" href="https://blog.ionelmc.ro/2016/05/07/dealing-with-docker/#id13" id="id5" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:12px; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; vertical-align:top' valign="top"&gt;[4]&lt;/a&gt;) will introduce
serious delays in build times. Because the container running the build process is pretty insulated (no volumes or mount
remember?) &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;pip&lt;/tt&gt; can't really cache anything.&lt;/p&gt;
&lt;div class="section" id="staging-the-build-process"&gt;
&lt;h4 style='font-family:"Candara", "Merriweather Sans", "Trebuchet Ms", "Segoe UI", sans-serif; text-shadow:1px 1px 1px #DDD; color:#333; font-weight:bold; line-height:1; font-size:1.3em'&gt;Staging the build process&lt;a class="headerlink" href="https://blog.ionelmc.ro/2016/05/07/dealing-with-docker/#staging-the-build-process" title="Permalink to this headline" style="color:#c60f0f; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; padding:0 4px 0 4px; vertical-align:middle; visibility:hidden" valign="middle"&gt;
*&lt;/a&gt;&lt;/h4&gt;
&lt;p style="margin:25px 0 25px 0"&gt;A way to solve this is having a "builder image" that you run to build wheels for all your dependencies. When you run an
image you can use volumes and mounts.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Before jumping in, lets look briefly at file layout. I like to have a &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;docker&lt;/tt&gt; directory and then another level for each
kind of image. Quite similar to the layout the &lt;a class="reference external" href="https://github.com/tianon/docker-brew-ubuntu-core/tree/master" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;builder for official images&lt;/a&gt; have. And no weird filenames, just &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;Dockerfile&lt;/tt&gt;
everywhere:&lt;/p&gt;
&lt;pre class="literal-block" style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:1px solid #DDD; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 3px #EFEFEF' bgcolor="#FFFDFD"&gt;
docker
├── base
│   └── Dockerfile
├── builder
│   └── Dockerfile
├── deps
│   └── Dockerfile
├── web
│   └── Dockerfile
├── worker
│   └── Dockerfile
└── ...
&lt;/pre&gt;
&lt;p style="margin:25px 0 25px 0"&gt;In this scenario we'd deploy two images: &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;web&lt;/tt&gt; and &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;worker&lt;/tt&gt;. The inheritance chain would look like this:&lt;/p&gt;
&lt;ul class="simple" style="margin:25px 0 25px 0"&gt;
&lt;li style="padding:0"&gt;&lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;&lt;span class="pre"&gt;buildpack-deps:xenial&lt;/span&gt;&lt;/tt&gt; ➜ &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;builder&lt;/tt&gt;&lt;/li&gt;
&lt;li style="padding:0"&gt;&lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;ubuntu:xenial&lt;/tt&gt; ➜ &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;deps&lt;/tt&gt; ➜ &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;base&lt;/tt&gt; ➜ &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;web&lt;/tt&gt;&lt;/li&gt;
&lt;li style="padding:0"&gt;&lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;ubuntu:xenial&lt;/tt&gt; ➜ &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;deps&lt;/tt&gt; ➜ &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;base&lt;/tt&gt; ➜ &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;worker&lt;/tt&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style="margin:25px 0 25px 0"&gt;In which:&lt;/p&gt;
&lt;ul class="simple" style="margin:25px 0 25px 0"&gt;
&lt;li style="padding:0"&gt;&lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;builder&lt;/tt&gt; has development libraries, compilers and other stuff we don't want in production.&lt;/li&gt;
&lt;li style="padding:0"&gt;&lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;deps&lt;/tt&gt; only has python and the dependencies installed.&lt;/li&gt;
&lt;li style="padding:0"&gt;&lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;base&lt;/tt&gt; has the source code installed.&lt;/li&gt;
&lt;li style="padding:0"&gt;&lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;web&lt;/tt&gt; and &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;worker&lt;/tt&gt; have specific customizations (like installing &lt;a class="reference external" href="http://nginx.org/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;Nginx&lt;/a&gt; or different settings).&lt;/li&gt;
&lt;/ul&gt;
&lt;p style="margin:25px 0 25px 0"&gt;And in &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;.dockerignore&lt;/tt&gt; we'd have:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:1px solid #DDD; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 3px #EFEFEF' bgcolor="#FFFDFD"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1" style="color:#998; font-style:italic"&gt;# just ignore that directory, we don't need that stuff when we have "." as the context&lt;/span&gt;
docker
&lt;/pre&gt;&lt;/div&gt;
&lt;p style="margin:25px 0 25px 0"&gt;This layout might seem artificial but not quite:&lt;/p&gt;
&lt;ul class="simple" style="margin:25px 0 25px 0"&gt;
&lt;li style="padding:0"&gt;Both the &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;worker&lt;/tt&gt; and &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;web&lt;/tt&gt; need the same source code.&lt;/li&gt;
&lt;li style="padding:0"&gt;The &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;deps&lt;/tt&gt; and &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;base&lt;/tt&gt; are not in the same image because their contexts are distinct: one needs a bunch of wheels and
the other one only needs the sources. This setup allows us to skip building the &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;deps&lt;/tt&gt; image if the requirement files did
not change.&lt;/li&gt;
&lt;li style="padding:0"&gt;The &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;web&lt;/tt&gt; and &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;worker&lt;/tt&gt; images do not need to have the source code in the context. This allows faster build times. For
development purposes we can just mount the sourcecode. More about that later.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style="margin:25px 0 25px 0"&gt;In &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;builder/Dockerfile&lt;/tt&gt; there would be:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:1px solid #DDD; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 3px #EFEFEF' bgcolor="#FFFDFD"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c" style="color:#998; font-style:italic"&gt;# we start from an image with build deps preinstalled&lt;/span&gt;
&lt;span class="k" style="font-weight:bold"&gt;FROM&lt;/span&gt;&lt;span class="s" style="color:#d14"&gt; buildpack-deps:xenial&lt;/span&gt;

&lt;span class="c" style="color:#998; font-style:italic"&gt;# seems acceptable for building, note the notes above&lt;/span&gt;
&lt;span class="c" style="color:#998; font-style:italic"&gt;# about C.UTF-8 - it's not really good for running apps&lt;/span&gt;
&lt;span class="k" style="font-weight:bold"&gt;ENV&lt;/span&gt;&lt;span class="s" style="color:#d14"&gt; LANG C.UTF-8&lt;/span&gt;

&lt;span class="c" style="color:#998; font-style:italic"&gt;# we'd add all the "-dev" packages we need here&lt;/span&gt;
&lt;span class="k" style="font-weight:bold"&gt;RUN&lt;/span&gt; apt-get update &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
 &lt;span class="o" style="font-weight:bold"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get install -y --no-install-recommends &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
                    python2.7 python2.7-dbg python2.7-dev libpython2.7 &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
                    strace gdb lsof locate &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
 &lt;span class="o" style="font-weight:bold"&gt;&amp;amp;&amp;amp;&lt;/span&gt; rm -rf /var/lib/apt/lists/*

&lt;span class="k" style="font-weight:bold"&gt;ENV&lt;/span&gt;&lt;span class="s" style="color:#d14"&gt; PYTHON_PIP_VERSION 8.1.1&lt;/span&gt;
&lt;span class="k" style="font-weight:bold"&gt;RUN&lt;/span&gt; &lt;span class="nb" style="color:#0086B3"&gt;set&lt;/span&gt; -eEx &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
 &lt;span class="o" style="font-weight:bold"&gt;&amp;amp;&amp;amp;&lt;/span&gt; curl -fSL &lt;span class="s1" style="color:#d14"&gt;'https://bootstrap.pypa.io/get-pip.py'&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; python2.7 - &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
         --no-cache-dir --upgrade &lt;span class="nv" style="color:#008080"&gt;pip&lt;/span&gt;&lt;span class="o" style="font-weight:bold"&gt;==&lt;/span&gt;&lt;span class="nv" style="color:#008080"&gt;$PYTHON_PIP_VERSION&lt;/span&gt;

ARG USER
ARG UID
ARG GID

&lt;span class="c" style="color:#998; font-style:italic"&gt;# we set some default options for pip here&lt;/span&gt;
&lt;span class="c" style="color:#998; font-style:italic"&gt;# so we don't have to specify them all the time&lt;/span&gt;

&lt;span class="c" style="color:#998; font-style:italic"&gt;# this will make pip additionally look for available wheels here&lt;/span&gt;
&lt;span class="k" style="font-weight:bold"&gt;ENV&lt;/span&gt;&lt;span class="s" style="color:#d14"&gt; PIP_FIND_LINKS=/home/$USER/wheelcache&lt;/span&gt;
&lt;span class="c" style="color:#998; font-style:italic"&gt;# and this is the default output dir when we run `pip wheel`&lt;/span&gt;
&lt;span class="k" style="font-weight:bold"&gt;ENV&lt;/span&gt;&lt;span class="s" style="color:#d14"&gt; PIP_WHEEL_DIR=/home/$USER/wheelcache&lt;/span&gt;
&lt;span class="k" style="font-weight:bold"&gt;ENV&lt;/span&gt;&lt;span class="s" style="color:#d14"&gt; PIP_TIMEOUT=60&lt;/span&gt;
&lt;span class="c" style="color:#998; font-style:italic"&gt;# one network request less, we don't care about latest version&lt;/span&gt;
&lt;span class="k" style="font-weight:bold"&gt;ENV&lt;/span&gt;&lt;span class="s" style="color:#d14"&gt; PIP_DISABLE_PIP_VERSION_CHECK=true&lt;/span&gt;

&lt;span class="k" style="font-weight:bold"&gt;RUN&lt;/span&gt; &lt;span class="nb" style="color:#0086B3"&gt;echo&lt;/span&gt; &lt;span class="s2" style="color:#d14"&gt;"Creating user: &lt;/span&gt;&lt;span class="nv" style="color:#008080"&gt;$USER&lt;/span&gt;&lt;span class="s2" style="color:#d14"&gt; (&lt;/span&gt;&lt;span class="nv" style="color:#008080"&gt;$UID&lt;/span&gt;&lt;span class="s2" style="color:#d14"&gt;:&lt;/span&gt;&lt;span class="nv" style="color:#008080"&gt;$GID&lt;/span&gt;&lt;span class="s2" style="color:#d14"&gt;)"&lt;/span&gt; &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
 &lt;span class="o" style="font-weight:bold"&gt;&amp;amp;&amp;amp;&lt;/span&gt; groupadd --system --gid&lt;span class="o" style="font-weight:bold"&gt;=&lt;/span&gt;&lt;span class="nv" style="color:#008080"&gt;$GID&lt;/span&gt; &lt;span class="nv" style="color:#008080"&gt;$USER&lt;/span&gt; &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
 &lt;span class="o" style="font-weight:bold"&gt;&amp;amp;&amp;amp;&lt;/span&gt; useradd --system --create-home --gid&lt;span class="o" style="font-weight:bold"&gt;=&lt;/span&gt;&lt;span class="nv" style="color:#008080"&gt;$GID&lt;/span&gt; --uid&lt;span class="o" style="font-weight:bold"&gt;=&lt;/span&gt;&lt;span class="nv" style="color:#008080"&gt;$UID&lt;/span&gt; &lt;span class="nv" style="color:#008080"&gt;$USER&lt;/span&gt; &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
 &lt;span class="o" style="font-weight:bold"&gt;&amp;amp;&amp;amp;&lt;/span&gt; mkdir /home/&lt;span class="nv" style="color:#008080"&gt;$USER&lt;/span&gt;/wheelcache

&lt;span class="k" style="font-weight:bold"&gt;WORKDIR&lt;/span&gt;&lt;span class="s" style="color:#d14"&gt; /home/$USER&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p id="default-root-user" style="margin:25px 0 25px 0"&gt;The interesting part here is the &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;USER&lt;/tt&gt;, &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;UID&lt;/tt&gt; and &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;GID&lt;/tt&gt; build arguments. Unless you do something special the processes
inside the container runs with &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;root&lt;/tt&gt; user. This is fine, right? That's the whole point of using a container, processes in
the container actually have all sort of limitations - so it don't matter what user runs inside. However, if you mount
something from the host inside the container then the owner any new file inside that mount is going to be the same user that
the container runs with. The result is that you're going to get a bunch of files owned by root in the host. Not nice.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Because I don't do development with a &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;root&lt;/tt&gt; account and because user namespaces are &lt;a class="reference external" href="https://docs.docker.com/engine/reference/commandline/daemon/#daemon-user-namespace-options" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;surprisingly inconvenient to use&lt;/a&gt; &lt;a class="footnote-reference" href="https://blog.ionelmc.ro/2016/05/07/dealing-with-docker/#id15" id="id6" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:12px; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; vertical-align:top' valign="top"&gt;[6]&lt;/a&gt; I have resorted to
recreating my user inside the container. It needs to have the exact &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;uid&lt;/tt&gt; and &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;git&lt;/tt&gt;, otherwise I get files owned by
an account that don't exist.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Similarly to what was shown before, &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;deps/Dockerfile&lt;/tt&gt; would have:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:1px solid #DDD; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 3px #EFEFEF' bgcolor="#FFFDFD"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k" style="font-weight:bold"&gt;FROM&lt;/span&gt;&lt;span class="s" style="color:#d14"&gt; ubuntu:xenial&lt;/span&gt;

&lt;span class="k" style="font-weight:bold"&gt;RUN&lt;/span&gt; locale-gen en_US.UTF-8
&lt;span class="k" style="font-weight:bold"&gt;ENV&lt;/span&gt;&lt;span class="s" style="color:#d14"&gt; LANG en_US.UTF-8&lt;/span&gt;
&lt;span class="k" style="font-weight:bold"&gt;ENV&lt;/span&gt;&lt;span class="s" style="color:#d14"&gt; LANGUAGE en_US:en&lt;/span&gt;
&lt;span class="k" style="font-weight:bold"&gt;ENV&lt;/span&gt;&lt;span class="s" style="color:#d14"&gt; LC_ALL en_US.UTF-8&lt;/span&gt;

&lt;span class="k" style="font-weight:bold"&gt;RUN&lt;/span&gt; apt-get update &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
 &lt;span class="o" style="font-weight:bold"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get install -y --no-install-recommends &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
                    ca-certificates curl &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
                    strace gdb lsof locate net-tools htop &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
                    python2.7-dbg python2.7 libpython2.7 &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
 &lt;span class="o" style="font-weight:bold"&gt;&amp;amp;&amp;amp;&lt;/span&gt; rm -rf /var/lib/apt/lists/*

&lt;span class="k" style="font-weight:bold"&gt;ENV&lt;/span&gt;&lt;span class="s" style="color:#d14"&gt; PYTHON_PIP_VERSION 8.1.1&lt;/span&gt;
&lt;span class="k" style="font-weight:bold"&gt;RUN&lt;/span&gt; &lt;span class="nb" style="color:#0086B3"&gt;set&lt;/span&gt; -eEx &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
 &lt;span class="o" style="font-weight:bold"&gt;&amp;amp;&amp;amp;&lt;/span&gt; curl -fSL &lt;span class="s1" style="color:#d14"&gt;'https://bootstrap.pypa.io/get-pip.py'&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; python2.7 - &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
         --no-cache-dir --upgrade &lt;span class="nv" style="color:#008080"&gt;pip&lt;/span&gt;&lt;span class="o" style="font-weight:bold"&gt;==&lt;/span&gt;&lt;span class="nv" style="color:#008080"&gt;$PYTHON_PIP_VERSION&lt;/span&gt;

COPY .wheels /wheels
&lt;span class="k" style="font-weight:bold"&gt;RUN&lt;/span&gt; pip install --force-reinstall --ignore-installed --upgrade &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
                --no-index --use-wheel --no-deps /wheels/* &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
 &lt;span class="o" style="font-weight:bold"&gt;&amp;amp;&amp;amp;&lt;/span&gt; rm -rf /wheels
&lt;/pre&gt;&lt;/div&gt;
&lt;p style="margin:25px 0 25px 0"&gt;And &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;base/Dockerfile&lt;/tt&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:1px solid #DDD; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 3px #EFEFEF' bgcolor="#FFFDFD"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k" style="font-weight:bold"&gt;FROM&lt;/span&gt;&lt;span class="s" style="color:#d14"&gt; app-deps&lt;/span&gt;

&lt;span class="c" style="color:#998; font-style:italic"&gt;# copy the application files and add them on the import path&lt;/span&gt;
&lt;span class="k" style="font-weight:bold"&gt;RUN&lt;/span&gt; mkdir /app
&lt;span class="k" style="font-weight:bold"&gt;WORKDIR&lt;/span&gt;&lt;span class="s" style="color:#d14"&gt; /app&lt;/span&gt;
COPY setup.py /app/
COPY src /app/src
&lt;span class="c" style="color:#998; font-style:italic"&gt;# there are other ways (like .pth file) but this one allows&lt;/span&gt;
&lt;span class="c" style="color:#998; font-style:italic"&gt;# for easy setup of various bin scripts app might need&lt;/span&gt;
&lt;span class="k" style="font-weight:bold"&gt;RUN&lt;/span&gt; python2.7 setup.py develop

&lt;span class="c" style="color:#998; font-style:italic"&gt;# create an user for the application and install basic tools&lt;/span&gt;
&lt;span class="c" style="color:#998; font-style:italic"&gt;# to change user (pysu) and wait for services (holdup)&lt;/span&gt;
ARG &lt;span class="nv" style="color:#008080"&gt;USER&lt;/span&gt;&lt;span class="o" style="font-weight:bold"&gt;=&lt;/span&gt;app
&lt;span class="k" style="font-weight:bold"&gt;ENV&lt;/span&gt;&lt;span class="s" style="color:#d14"&gt; USER=$USER&lt;/span&gt;
&lt;span class="k" style="font-weight:bold"&gt;RUN&lt;/span&gt; &lt;span class="nb" style="color:#0086B3"&gt;echo&lt;/span&gt; &lt;span class="s2" style="color:#d14"&gt;"Creating user: &lt;/span&gt;&lt;span class="nv" style="color:#008080"&gt;$USER&lt;/span&gt;&lt;span class="s2" style="color:#d14"&gt;"&lt;/span&gt; &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
 &lt;span class="o" style="font-weight:bold"&gt;&amp;amp;&amp;amp;&lt;/span&gt; groupadd --system  &lt;span class="nv" style="color:#008080"&gt;$USER&lt;/span&gt; &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
 &lt;span class="o" style="font-weight:bold"&gt;&amp;amp;&amp;amp;&lt;/span&gt; useradd --system --create-home --gid&lt;span class="o" style="font-weight:bold"&gt;=&lt;/span&gt;&lt;span class="nv" style="color:#008080"&gt;$USER&lt;/span&gt; --base-dir&lt;span class="o" style="font-weight:bold"&gt;=&lt;/span&gt;/var &lt;span class="nv" style="color:#008080"&gt;$USER&lt;/span&gt; &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
 &lt;span class="o" style="font-weight:bold"&gt;&amp;amp;&amp;amp;&lt;/span&gt; pip install &lt;span class="nv" style="color:#008080"&gt;pysu&lt;/span&gt;&lt;span class="o" style="font-weight:bold"&gt;==&lt;/span&gt;&lt;span class="m" style="color:#099"&gt;0&lt;/span&gt;.1.0 &lt;span class="nv" style="color:#008080"&gt;holdup&lt;/span&gt;&lt;span class="o" style="font-weight:bold"&gt;==&lt;/span&gt;&lt;span class="m" style="color:#099"&gt;1&lt;/span&gt;.0.0 &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
 &lt;span class="o" style="font-weight:bold"&gt;&amp;amp;&amp;amp;&lt;/span&gt; pysu &lt;span class="nv" style="color:#008080"&gt;$USER&lt;/span&gt; id
&lt;span class="c" style="color:#998; font-style:italic"&gt;# this last one just tests that pysu works&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p style="margin:25px 0 25px 0"&gt;For &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;web/Dockerfile&lt;/tt&gt; we can have something like:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:1px solid #DDD; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 3px #EFEFEF' bgcolor="#FFFDFD"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k" style="font-weight:bold"&gt;FROM&lt;/span&gt;&lt;span class="s" style="color:#d14"&gt; app-base&lt;/span&gt;

&lt;span class="k" style="font-weight:bold"&gt;RUN&lt;/span&gt; apt-get update &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
 &lt;span class="o" style="font-weight:bold"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get install -yq --no-install-recommends nginx-core supervisor &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
 &lt;span class="o" style="font-weight:bold"&gt;&amp;amp;&amp;amp;&lt;/span&gt; rm -rf /var/lib/apt/lists/*

COPY site.conf /etc/nginx/sites-enabled/default
COPY supervisor.conf /etc/supervisor/conf.d/
COPY entrypoint.sh /

&lt;span class="k" style="font-weight:bold"&gt;RUN&lt;/span&gt; &lt;span class="nb" style="color:#0086B3"&gt;echo&lt;/span&gt; &lt;span class="s2" style="color:#d14"&gt;"daemon off;"&lt;/span&gt; &amp;gt;&amp;gt; /etc/nginx/nginx.conf

&lt;span class="k" style="font-weight:bold"&gt;EXPOSE&lt;/span&gt;&lt;span class="s" style="color:#d14"&gt; 80&lt;/span&gt;
&lt;span class="k" style="font-weight:bold"&gt;CMD&lt;/span&gt;&lt;span class="s" style="color:#d14"&gt; ["/entrypoint.sh"]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p style="margin:25px 0 25px 0"&gt;To build the images we can run this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:1px solid #DDD; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 3px #EFEFEF' bgcolor="#FFFDFD"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="ch"&gt;#!/bin/sh&lt;/span&gt;
&lt;span class="nb" style="color:#0086B3"&gt;set&lt;/span&gt; -eux

docker build --tag&lt;span class="o" style="font-weight:bold"&gt;=&lt;/span&gt;app-builder &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
             --build-arg &lt;span class="nv" style="color:#008080"&gt;USER&lt;/span&gt;&lt;span class="o" style="font-weight:bold"&gt;=&lt;/span&gt;&lt;span class="nv" style="color:#008080"&gt;$USER&lt;/span&gt; &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
             --build-arg &lt;span class="nv" style="color:#008080"&gt;UID&lt;/span&gt;&lt;span class="o" style="font-weight:bold"&gt;=&lt;/span&gt;&lt;span class="k" style="font-weight:bold"&gt;$(&lt;/span&gt;id --user &lt;span class="nv" style="color:#008080"&gt;$USER&lt;/span&gt;&lt;span class="k" style="font-weight:bold"&gt;)&lt;/span&gt; &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
             --build-arg &lt;span class="nv" style="color:#008080"&gt;GID&lt;/span&gt;&lt;span class="o" style="font-weight:bold"&gt;=&lt;/span&gt;&lt;span class="k" style="font-weight:bold"&gt;$(&lt;/span&gt;id --group &lt;span class="nv" style="color:#008080"&gt;$USER&lt;/span&gt;&lt;span class="k" style="font-weight:bold"&gt;)&lt;/span&gt; &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
             docker/builder
&lt;span class="c1" style="color:#998; font-style:italic"&gt;# we run this image two times, once to prime a wheel cache&lt;/span&gt;
mkdir -p .dockercache
docker run --rm &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
           --user&lt;span class="o" style="font-weight:bold"&gt;=&lt;/span&gt;&lt;span class="nv" style="color:#008080"&gt;$USER&lt;/span&gt; &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
           --volume&lt;span class="o" style="font-weight:bold"&gt;=&lt;/span&gt;&lt;span class="s2" style="color:#d14"&gt;"&lt;/span&gt;&lt;span class="nv" style="color:#008080"&gt;$PWD&lt;/span&gt;&lt;span class="s2" style="color:#d14"&gt;/requirements.txt"&lt;/span&gt;:/requirements.txt:ro &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
           --volume&lt;span class="o" style="font-weight:bold"&gt;=&lt;/span&gt;&lt;span class="s2" style="color:#d14"&gt;"&lt;/span&gt;&lt;span class="nv" style="color:#008080"&gt;$PWD&lt;/span&gt;&lt;span class="s2" style="color:#d14"&gt;/.dockercache"&lt;/span&gt;:/home/&lt;span class="nv" style="color:#008080"&gt;$USER&lt;/span&gt; &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
           app-builder &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
           pip wheel --requirement&lt;span class="o" style="font-weight:bold"&gt;=&lt;/span&gt;/requirements.txt
&lt;span class="c1" style="color:#998; font-style:italic"&gt;# and the second time to create the final wheel set&lt;/span&gt;
rm -rf &lt;span class="s2" style="color:#d14"&gt;"&lt;/span&gt;&lt;span class="nv" style="color:#008080"&gt;$PWD&lt;/span&gt;&lt;span class="s2" style="color:#d14"&gt;/docker/deps/.wheels"&lt;/span&gt;
mkdir  &lt;span class="s2" style="color:#d14"&gt;"&lt;/span&gt;&lt;span class="nv" style="color:#008080"&gt;$PWD&lt;/span&gt;&lt;span class="s2" style="color:#d14"&gt;/docker/deps/.wheels"&lt;/span&gt;
docker run --rm &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
           --user&lt;span class="o" style="font-weight:bold"&gt;=&lt;/span&gt;&lt;span class="nv" style="color:#008080"&gt;$USER&lt;/span&gt; &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
           --volume&lt;span class="o" style="font-weight:bold"&gt;=&lt;/span&gt;&lt;span class="s2" style="color:#d14"&gt;"&lt;/span&gt;&lt;span class="nv" style="color:#008080"&gt;$PWD&lt;/span&gt;&lt;span class="s2" style="color:#d14"&gt;/requirements.txt"&lt;/span&gt;:/requirements.txt:ro &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
           --volume&lt;span class="o" style="font-weight:bold"&gt;=&lt;/span&gt;&lt;span class="s2" style="color:#d14"&gt;"&lt;/span&gt;&lt;span class="nv" style="color:#008080"&gt;$PWD&lt;/span&gt;&lt;span class="s2" style="color:#d14"&gt;/.dockercache"&lt;/span&gt;:/home/&lt;span class="nv" style="color:#008080"&gt;$USER&lt;/span&gt; &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
           --volume&lt;span class="o" style="font-weight:bold"&gt;=&lt;/span&gt;&lt;span class="s2" style="color:#d14"&gt;"&lt;/span&gt;&lt;span class="nv" style="color:#008080"&gt;$PWD&lt;/span&gt;&lt;span class="s2" style="color:#d14"&gt;/docker/deps/.wheels"&lt;/span&gt;:/home/&lt;span class="nv" style="color:#008080"&gt;$USER&lt;/span&gt;/wheels &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
           app-builder &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
           pip wheel --wheel-dir&lt;span class="o" style="font-weight:bold"&gt;=&lt;/span&gt;wheels &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
                     --requirement&lt;span class="o" style="font-weight:bold"&gt;=&lt;/span&gt;/requirements.txt
&lt;span class="c1" style="color:#998; font-style:italic"&gt;# and now there are going to be tons of wheels in "docker/deps/.wheels/"&lt;/span&gt;
docker build --tag&lt;span class="o" style="font-weight:bold"&gt;=&lt;/span&gt;app-deps docker/deps

docker build --tag&lt;span class="o" style="font-weight:bold"&gt;=&lt;/span&gt;app-base --file&lt;span class="o" style="font-weight:bold"&gt;=&lt;/span&gt;docker/base/Dockerfile .
&lt;span class="c1" style="color:#998; font-style:italic"&gt;# this is why we simply ignore "docker/" in .dockerignore -- it&lt;/span&gt;
&lt;span class="c1" style="color:#998; font-style:italic"&gt;# would inflate the context a lot and we don't need the wheels in this step&lt;/span&gt;

docker build --tag&lt;span class="o" style="font-weight:bold"&gt;=&lt;/span&gt;app-web docker/web
&lt;/pre&gt;&lt;/div&gt;
&lt;p id="image-rebuilding-flaw" style="margin:25px 0 25px 0"&gt;If you look close enough you'll notice a small flaw here: rebuilding the base image will invalidate everything that depends on
it. Because the &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;&lt;span class="pre"&gt;app-base&lt;/span&gt;&lt;/tt&gt; image has the code in the context it will get invalidated often enough to be annoying. However,
there's a solution for that, and lets not forget the whole point of this - we can produce a large fleet of images cheaply
(context only includes &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;&lt;span class="pre"&gt;docker/&amp;lt;kind&amp;gt;&lt;/span&gt;&lt;/tt&gt;). This is quite good if you have a huge codebase and a large number of image types
(in addition to &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;&lt;span class="pre"&gt;app-web&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;&lt;span class="pre"&gt;app-worker&lt;/span&gt;&lt;/tt&gt; you could have various other services).&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="doing-development"&gt;
&lt;h3 style='font-family:"Candara", "Merriweather Sans", "Trebuchet Ms", "Segoe UI", sans-serif; text-shadow:1px 1px 1px #DDD; color:#333; font-weight:bold; line-height:1; font-size:1.56em'&gt;Doing development&lt;a class="headerlink" href="https://blog.ionelmc.ro/2016/05/07/dealing-with-docker/#doing-development" title="Permalink to this headline" style="color:#c60f0f; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; padding:0 4px 0 4px; vertical-align:middle; visibility:hidden" valign="middle"&gt;
*&lt;/a&gt;&lt;/h3&gt;
&lt;p style="margin:25px 0 25px 0"&gt;For development we don't really need to rebuild the &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;&lt;span class="pre"&gt;app-base&lt;/span&gt;&lt;/tt&gt; image (which includes the sources) - we can just mount our
project checkout in the right place. This could work for development:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:1px solid #DDD; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 3px #EFEFEF' bgcolor="#FFFDFD"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1" style="color:#998; font-style:italic"&gt;# no need to rebuild the base image (that has&lt;/span&gt;
&lt;span class="c1" style="color:#998; font-style:italic"&gt;# the /app/src) if we just mount it anyway&lt;/span&gt;
docker run --volume&lt;span class="o" style="font-weight:bold"&gt;=&lt;/span&gt;&lt;span class="nv" style="color:#008080"&gt;$PWD&lt;/span&gt;/src:/app/src:ro app-web
&lt;/pre&gt;&lt;/div&gt;
&lt;div class="section" id="enter-docker-compose"&gt;
&lt;h4 style='font-family:"Candara", "Merriweather Sans", "Trebuchet Ms", "Segoe UI", sans-serif; text-shadow:1px 1px 1px #DDD; color:#333; font-weight:bold; line-height:1; font-size:1.3em'&gt;Enter &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:inherit; background:none; border-radius:3px; padding:3px 6px; border:none'&gt;&lt;span class="pre"&gt;docker-compose&lt;/span&gt;&lt;/tt&gt;&lt;a class="headerlink" href="https://blog.ionelmc.ro/2016/05/07/dealing-with-docker/#enter-docker-compose" title="Permalink to this headline" style="color:#c60f0f; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; padding:0 4px 0 4px; vertical-align:middle; visibility:hidden" valign="middle"&gt;
*&lt;/a&gt;&lt;/h4&gt;
&lt;p style="margin:25px 0 25px 0"&gt;A nicer way to do it, especially if you depend on services like a database, is with &lt;a class="reference external" href="https://github.com/docker/compose" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;docker-compose&lt;/a&gt; - all you need is a &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;&lt;span class="pre"&gt;docker-compose.yml&lt;/span&gt;&lt;/tt&gt; file like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:1px solid #DDD; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 3px #EFEFEF' bgcolor="#FFFDFD"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;version&lt;/span&gt;&lt;span class="p p-Indicator"&gt;:&lt;/span&gt; &lt;span class="s" style="color:#d14"&gt;'2'&lt;/span&gt;
&lt;span class="l l-Scalar l-Scalar-Plain"&gt;services&lt;/span&gt;&lt;span class="p p-Indicator"&gt;:&lt;/span&gt;
  &lt;span class="l l-Scalar l-Scalar-Plain"&gt;web&lt;/span&gt;&lt;span class="p p-Indicator"&gt;:&lt;/span&gt;
    &lt;span class="l l-Scalar l-Scalar-Plain"&gt;build&lt;/span&gt;&lt;span class="p p-Indicator"&gt;:&lt;/span&gt; &lt;span class="s" style="color:#d14"&gt;'docker/web'&lt;/span&gt;
    &lt;span class="l l-Scalar l-Scalar-Plain"&gt;image&lt;/span&gt;&lt;span class="p p-Indicator"&gt;:&lt;/span&gt; &lt;span class="s" style="color:#d14"&gt;'app-web'&lt;/span&gt;
    &lt;span class="l l-Scalar l-Scalar-Plain"&gt;ports&lt;/span&gt;&lt;span class="p p-Indicator"&gt;:&lt;/span&gt;
    &lt;span class="p p-Indicator"&gt;-&lt;/span&gt; &lt;span class="s" style="color:#d14"&gt;'8080:80'&lt;/span&gt;
    &lt;span class="l l-Scalar l-Scalar-Plain"&gt;volumes&lt;/span&gt;&lt;span class="p p-Indicator"&gt;:&lt;/span&gt;
    &lt;span class="p p-Indicator"&gt;-&lt;/span&gt; &lt;span class="s" style="color:#d14"&gt;'${PWD}/src:/app/src:ro'&lt;/span&gt;
    &lt;span class="l l-Scalar l-Scalar-Plain"&gt;links&lt;/span&gt;&lt;span class="p p-Indicator"&gt;:&lt;/span&gt;
    &lt;span class="p p-Indicator"&gt;-&lt;/span&gt; &lt;span class="s" style="color:#d14"&gt;'pg'&lt;/span&gt;
    &lt;span class="l l-Scalar l-Scalar-Plain"&gt;environment&lt;/span&gt;&lt;span class="p p-Indicator"&gt;:&lt;/span&gt;
      &lt;span class="l l-Scalar l-Scalar-Plain"&gt;DATABASE_HOST&lt;/span&gt;&lt;span class="p p-Indicator"&gt;:&lt;/span&gt; &lt;span class="s" style="color:#d14"&gt;'pg'&lt;/span&gt;
  &lt;span class="l l-Scalar l-Scalar-Plain"&gt;pg&lt;/span&gt;&lt;span class="p p-Indicator"&gt;:&lt;/span&gt;
    &lt;span class="l l-Scalar l-Scalar-Plain"&gt;image&lt;/span&gt;&lt;span class="p p-Indicator"&gt;:&lt;/span&gt; &lt;span class="s" style="color:#d14"&gt;'postgres:9.5'&lt;/span&gt;
    &lt;span class="l l-Scalar l-Scalar-Plain"&gt;environment&lt;/span&gt;&lt;span class="p p-Indicator"&gt;:&lt;/span&gt;
      &lt;span class="l l-Scalar l-Scalar-Plain"&gt;POSTGRES_DB&lt;/span&gt;&lt;span class="p p-Indicator"&gt;:&lt;/span&gt; &lt;span class="s" style="color:#d14"&gt;'app'&lt;/span&gt;
      &lt;span class="l l-Scalar l-Scalar-Plain"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="p p-Indicator"&gt;:&lt;/span&gt; &lt;span class="s" style="color:#d14"&gt;'app'&lt;/span&gt;
      &lt;span class="l l-Scalar l-Scalar-Plain"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="p p-Indicator"&gt;:&lt;/span&gt; &lt;span class="s" style="color:#d14"&gt;'app'&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p style="margin:25px 0 25px 0"&gt;With this configuration we solve the problem with the &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;&lt;span class="pre"&gt;app-base&lt;/span&gt;&lt;/tt&gt; that was &lt;a class="reference external" href="https://blog.ionelmc.ro/2016/05/07/dealing-with-docker/#image-rebuilding-flaw" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;outlined earlier&lt;/a&gt;: note
the &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;&lt;span class="pre"&gt;'${PWD}/src:/app/src:ro'&lt;/span&gt;&lt;/tt&gt; mount.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="living-inside-the-container"&gt;
&lt;span id="debugging"&gt;&lt;/span&gt;&lt;h3 style='font-family:"Candara", "Merriweather Sans", "Trebuchet Ms", "Segoe UI", sans-serif; text-shadow:1px 1px 1px #DDD; color:#333; font-weight:bold; line-height:1; font-size:1.56em'&gt;Living inside the container&lt;a class="headerlink" href="https://blog.ionelmc.ro/2016/05/07/dealing-with-docker/#living-inside-the-container" title="Permalink to this headline" style="color:#c60f0f; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; padding:0 4px 0 4px; vertical-align:middle; visibility:hidden" valign="middle"&gt;
*&lt;/a&gt;&lt;/h3&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Working inside the container is not easy. Take debugging for example - normally you'd expect &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;strace&lt;/tt&gt; and &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;gdb&lt;/tt&gt; to just
work but they require some privileges that are disabled by default. Thus this pattern appears:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:1px solid #DDD; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 3px #EFEFEF' bgcolor="#FFFDFD"&gt;&lt;span&gt;&lt;/span&gt;docker run --privileged --rm -it myimage bash
&lt;span class="c1" style="color:#998; font-style:italic"&gt;# or, if you want to debug a running container&lt;/span&gt;
docker &lt;span class="nb" style="color:#0086B3"&gt;exec&lt;/span&gt; --privileged -it mycontainer bash
&lt;/pre&gt;&lt;/div&gt;
&lt;p style="margin:25px 0 25px 0"&gt;While &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;strace&lt;/tt&gt; can work from the outside &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;gdb&lt;/tt&gt; is not feasible to use from the host due to the library paths being
mismatched. It's unlikely that you have exact OS on the host, so you will lack the sorely needed debug symbols.&lt;/p&gt;
&lt;div class="section" id="avoiding-bash"&gt;
&lt;h4 style='font-family:"Candara", "Merriweather Sans", "Trebuchet Ms", "Segoe UI", sans-serif; text-shadow:1px 1px 1px #DDD; color:#333; font-weight:bold; line-height:1; font-size:1.3em'&gt;Avoiding &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:inherit; background:none; border-radius:3px; padding:3px 6px; border:none'&gt;bash&lt;/tt&gt;&lt;a class="headerlink" href="https://blog.ionelmc.ro/2016/05/07/dealing-with-docker/#avoiding-bash" title="Permalink to this headline" style="color:#c60f0f; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; padding:0 4px 0 4px; vertical-align:middle; visibility:hidden" valign="middle"&gt;
*&lt;/a&gt;&lt;/h4&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Turns out this is a thing, for example Alpine don't have &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;bash&lt;/tt&gt; by default. You can still install it but if you want the
smallest possible images then you should avoid it.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;My rule of thumb here is: if at any point you'll want to have an interactive session in a container just install it. Space
can't be be more important that tooling.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="container-dependencies"&gt;
&lt;h4 style='font-family:"Candara", "Merriweather Sans", "Trebuchet Ms", "Segoe UI", sans-serif; text-shadow:1px 1px 1px #DDD; color:#333; font-weight:bold; line-height:1; font-size:1.3em'&gt;Container dependencies&lt;a class="headerlink" href="https://blog.ionelmc.ro/2016/05/07/dealing-with-docker/#container-dependencies" title="Permalink to this headline" style="color:#c60f0f; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; padding:0 4px 0 4px; vertical-align:middle; visibility:hidden" valign="middle"&gt;
*&lt;/a&gt;&lt;/h4&gt;
&lt;p style="margin:25px 0 25px 0"&gt;A frequent problem with dependencies is that startup is slow. Take for instance the &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;pg&lt;/tt&gt; service shown in the
&lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;&lt;span class="pre"&gt;docker-compose.yml&lt;/span&gt;&lt;/tt&gt; example: it can take few seconds for it to start the first time due to setup. Then the &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;web&lt;/tt&gt; service
will fail to start if it needs to connect to the database at startup (e.g.: migrations).&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;People definitely &lt;a class="reference external" href="https://github.com/docker/docker/issues/7445" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;want&lt;/a&gt; a solution for this. Currently there are 3 ways to
handle this issue:&lt;/p&gt;
&lt;ul class="simple" style="margin:25px 0 25px 0"&gt;
&lt;li style="padding:0"&gt;Use one of Docker's &lt;a class="reference external" href="https://docs.docker.com/engine/reference/run/#restart-policies-restart" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;restart policies&lt;/a&gt;. This might
be a bit too coarse.&lt;/li&gt;
&lt;li style="padding:0"&gt;Use your orchestration tool's healthcheck features to handle this. This might be incovenient, for example &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;&lt;span class="pre"&gt;docker-compose&lt;/span&gt;&lt;/tt&gt;
don't have this feature. &lt;a class="reference external" href="http://kubernetes.io/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;Kubernetes&lt;/a&gt; &lt;a class="reference external" href="http://kubernetes.io/docs/user-guide/production-pods/#liveness-and-readiness-probes-aka-health-checks" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;has it&lt;/a&gt; but it's a bit
&lt;a class="reference external" href="http://kubernetes.io/docs/getting-started-guides/docker/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;more involved&lt;/a&gt;.&lt;/li&gt;
&lt;li style="padding:0"&gt;Make your container wait a bit for services by doing basic port or health checks. There are some recommendations &lt;a class="reference external" href="https://docs.docker.com/compose/startup-order/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;here&lt;/a&gt;, however, none of them support unix domain sockets so I made my own
tool: &lt;a class="reference external" href="https://github.com/ionelmc/python-holdup" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;holdup&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="process-handling"&gt;
&lt;h4 style='font-family:"Candara", "Merriweather Sans", "Trebuchet Ms", "Segoe UI", sans-serif; text-shadow:1px 1px 1px #DDD; color:#333; font-weight:bold; line-height:1; font-size:1.3em'&gt;Process handling&lt;a class="headerlink" href="https://blog.ionelmc.ro/2016/05/07/dealing-with-docker/#process-handling" title="Permalink to this headline" style="color:#c60f0f; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; padding:0 4px 0 4px; vertical-align:middle; visibility:hidden" valign="middle"&gt;
*&lt;/a&gt;&lt;/h4&gt;
&lt;p style="margin:25px 0 25px 0"&gt;An easy mistake is not using &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;exec&lt;/tt&gt; in the shell scripts you'll &lt;a class="reference external" href="https://blog.ionelmc.ro/2016/05/07/dealing-with-docker/#wait-for-services" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;inevitably need&lt;/a&gt;. If you forget
to do this then your container will fail to stop correctly and Docker will be forced to send a SIGKILL. This can lead to
data loss. If your &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;PID 1&lt;/tt&gt; is something like &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;/bin/bash&lt;/tt&gt; or &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;/bin/sh&lt;/tt&gt;, or you don't have any process with
&lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;PID 1&lt;/tt&gt; then you have this problem.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Suppose you have a &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;CMD ["script.sh"]&lt;/tt&gt; or &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;ENTRYPOINT ["script.sh"]&lt;/tt&gt;. Then:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:1px solid #DDD; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 3px #EFEFEF' bgcolor="#FFFDFD"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="ch"&gt;#!/bin/sh&lt;/span&gt;

&lt;span class="c1" style="color:#998; font-style:italic"&gt;# general good practice (stop on error, missing variables, verbose mode):&lt;/span&gt;
&lt;span class="nb" style="color:#0086B3"&gt;set&lt;/span&gt; -eux

&lt;span class="c1" style="color:#998; font-style:italic"&gt;# avoid this:&lt;/span&gt;
pure-ftpd

&lt;span class="c1" style="color:#998; font-style:italic"&gt;# do this instead:&lt;/span&gt;
&lt;span class="nb" style="color:#0086B3"&gt;exec&lt;/span&gt; pure-ftpd
&lt;/pre&gt;&lt;/div&gt;
&lt;p style="margin:25px 0 25px 0"&gt;To make it worse, the &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;su&lt;/tt&gt; bin doesn't support an "exec"-mode. Thus tools like &lt;a class="reference external" href="https://github.com/tianon/gosu/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;gosu&lt;/a&gt; &lt;a class="footnote-reference" href="https://blog.ionelmc.ro/2016/05/07/dealing-with-docker/#id14" id="id7" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:12px; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; vertical-align:top' valign="top"&gt;[5]&lt;/a&gt; were created.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Another problem are sloppy applications that don't cleanup after child processes. Containers don't have a "init" process
by default - so there's no "catch-all" for &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Zombie_process" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;zombie processes&lt;/a&gt;. If you
have that sort of application then your container will inevitably exhaust all available PIDs. You can work around this
with minimal init systems like &lt;a class="reference external" href="https://github.com/rciorba/pidunu" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;pidunu&lt;/a&gt; but a better solution is to fix your
application's code - it only needs a &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;&lt;span class="pre"&gt;os.waitpid(-1,&lt;/span&gt; WNOHANG)&lt;/tt&gt; &lt;a class="footnote-reference" href="https://blog.ionelmc.ro/2016/05/07/dealing-with-docker/#id16" id="id8" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:12px; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; vertical-align:top' valign="top"&gt;[7]&lt;/a&gt; in the right place.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="lack-of-standard-services"&gt;
&lt;h4 style='font-family:"Candara", "Merriweather Sans", "Trebuchet Ms", "Segoe UI", sans-serif; text-shadow:1px 1px 1px #DDD; color:#333; font-weight:bold; line-height:1; font-size:1.3em'&gt;Lack of standard services&lt;a class="headerlink" href="https://blog.ionelmc.ro/2016/05/07/dealing-with-docker/#lack-of-standard-services" title="Permalink to this headline" style="color:#c60f0f; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; padding:0 4px 0 4px; vertical-align:middle; visibility:hidden" valign="middle"&gt;
*&lt;/a&gt;&lt;/h4&gt;
&lt;p style="margin:25px 0 25px 0"&gt;This is a surprise problem, especially if you grew on well established services like &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;syslog&lt;/tt&gt; or &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;cron&lt;/tt&gt;.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;For example &lt;a class="reference external" href="https://www.pureftpd.org/project/pure-ftpd" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;pure-ftpd&lt;/a&gt; has an unhealthy marriage to syslog. You can either:&lt;/p&gt;
&lt;ul style="margin:25px 0 25px 0"&gt;
&lt;li style="padding:0"&gt;&lt;p class="first" style="margin:25px 0 25px 0"&gt;Get the source package, patch/configure it to log to stdout and recompile. Unfortunatelly this results in a bloated image,
unless you inconvenience yourself with layer merging tools or using a &lt;cite&gt;builder image&lt;/cite&gt;.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;There may be a distro having a package with all the right compile options but I haven't found it.&lt;/p&gt;
&lt;/li&gt;
&lt;li style="padding:0"&gt;&lt;p class="first" style="margin:25px 0 25px 0"&gt;Mount a syslog socket in the container (example: &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;/var/log&lt;/tt&gt;). But this goes against the grain of Docker managing the
logs. Good luck finding what container emitted the messages.&lt;/p&gt;
&lt;/li&gt;
&lt;li style="padding:0"&gt;&lt;p class="first" style="margin:25px 0 25px 0"&gt;Run &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;&lt;span class="pre"&gt;pure-ftpd&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;syslogd&lt;/tt&gt; with &lt;a class="reference external" href="http://supervisord.org/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;supervisord&lt;/a&gt; or similar. You'd need a Dockerfile like:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:1px solid #DDD; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 3px #EFEFEF' bgcolor="#FFFDFD"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k" style="font-weight:bold"&gt;FROM&lt;/span&gt;&lt;span class="s" style="color:#d14"&gt; ubuntu:xenial&lt;/span&gt;
&lt;span class="k" style="font-weight:bold"&gt;RUN&lt;/span&gt; apt-get update &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
 &lt;span class="o" style="font-weight:bold"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get install -y --no-install-recommends supervisor inetutils-syslogd &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
 &lt;span class="o" style="font-weight:bold"&gt;&amp;amp;&amp;amp;&lt;/span&gt; rm -rf /var/lib/apt/lists/* &lt;span class="se" style="color:#d14"&gt;\&lt;/span&gt;
 &lt;span class="o" style="font-weight:bold"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb" style="color:#0086B3"&gt;echo&lt;/span&gt; &lt;span class="s1" style="color:#d14"&gt;'*.* /dev/stdout'&lt;/span&gt; &amp;gt; /etc/syslog.conf
COPY supervisor.conf /etc/supervisor/conf.d/
&lt;/pre&gt;&lt;/div&gt;
&lt;p style="margin:25px 0 25px 0"&gt;And a &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;supervisor.conf&lt;/tt&gt; like:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:1px solid #DDD; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 3px #EFEFEF' bgcolor="#FFFDFD"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k" style="font-weight:bold"&gt;[program:syslog]&lt;/span&gt;
&lt;span class="na" style="color:#008080"&gt;command&lt;/span&gt;&lt;span class="o" style="font-weight:bold"&gt;=&lt;/span&gt;&lt;span class="s" style="color:#d14"&gt;syslogd -n --no-klog&lt;/span&gt;
&lt;span class="na" style="color:#008080"&gt;stdout_logfile&lt;/span&gt;&lt;span class="o" style="font-weight:bold"&gt;=&lt;/span&gt;&lt;span class="s" style="color:#d14"&gt;/dev/stdout&lt;/span&gt;
&lt;span class="na" style="color:#008080"&gt;stdout_logfile_maxbytes&lt;/span&gt;&lt;span class="o" style="font-weight:bold"&gt;=&lt;/span&gt;&lt;span class="s" style="color:#d14"&gt;0&lt;/span&gt;
&lt;span class="na" style="color:#008080"&gt;redirect_stderr&lt;/span&gt;&lt;span class="o" style="font-weight:bold"&gt;=&lt;/span&gt;&lt;span class="s" style="color:#d14"&gt;true&lt;/span&gt;
&lt;span class="na" style="color:#008080"&gt;priority&lt;/span&gt;&lt;span class="o" style="font-weight:bold"&gt;=&lt;/span&gt;&lt;span class="s" style="color:#d14"&gt;1&lt;/span&gt;

&lt;span class="k" style="font-weight:bold"&gt;[program:mystuff]&lt;/span&gt;
&lt;span class="na" style="color:#008080"&gt;command&lt;/span&gt;&lt;span class="o" style="font-weight:bold"&gt;=&lt;/span&gt;&lt;span class="s" style="color:#d14"&gt;mystuff&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p style="margin:25px 0 25px 0"&gt;But this creates some friction with the way things should be run in Docker: should &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;mystuff&lt;/tt&gt; fail to run, Docker won't
know.&lt;/p&gt;
&lt;/li&gt;
&lt;li style="padding:0"&gt;&lt;p class="first" style="margin:25px 0 25px 0"&gt;Run something like:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:1px solid #DDD; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 3px #EFEFEF' bgcolor="#FFFDFD"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1" style="color:#998; font-style:italic"&gt;# just forward everything to stdout&lt;/span&gt;
socat -u unix-recv:/dev/log - &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;

&lt;span class="nb" style="color:#0086B3"&gt;exec&lt;/span&gt; pure-ftpdexec
&lt;/pre&gt;&lt;/div&gt;
&lt;p style="margin:25px 0 25px 0"&gt;And hope &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;socat&lt;/tt&gt; never dies ...&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Cron is another kind of &lt;em&gt;I don't need this issue&lt;/em&gt;. In addition to Cron requiring a &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;/dev/log&lt;/tt&gt; (syslog), your cron jobs are
ran with a clean environment. All those environment variables are gone unless you have a contraption like this:&lt;/p&gt;
&lt;ul class="simple" style="margin:25px 0 25px 0"&gt;
&lt;li style="padding:0"&gt;Dump all the env vars somewhere: &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;gosu myuser env &amp;gt; &lt;span class="pre"&gt;/saved-environ&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li style="padding:0"&gt;And then in the cron job, make sure to load that: &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;env - `cat &lt;span class="pre"&gt;/saved-environ`&lt;/span&gt; python ... &amp;gt;/dev/null &lt;span class="pre"&gt;2&amp;gt;&amp;amp;1&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Alternatively you could (depending on what base image you use) dump all the env vars in this location: &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;gosu myuser env &amp;gt; /etc/environment&lt;/tt&gt;&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Output redirection is another issue with Cron, you can't simply log to stdout, so your only resort is, guess what, syslog: &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;&lt;span class="pre"&gt;2&amp;gt;&amp;amp;1&lt;/span&gt; | logger &lt;span class="pre"&gt;-t&lt;/span&gt; myjob&lt;/tt&gt;.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Is that all you say? Of course not. Cron also wants a mailer. You probably don't want that so you add a &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;&lt;span class="pre"&gt;MAILTO=""&lt;/span&gt;&lt;/tt&gt; in your
cron config.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="managing-configuration"&gt;
&lt;h4 style='font-family:"Candara", "Merriweather Sans", "Trebuchet Ms", "Segoe UI", sans-serif; text-shadow:1px 1px 1px #DDD; color:#333; font-weight:bold; line-height:1; font-size:1.3em'&gt;Managing configuration&lt;a class="headerlink" href="https://blog.ionelmc.ro/2016/05/07/dealing-with-docker/#managing-configuration" title="Permalink to this headline" style="color:#c60f0f; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; padding:0 4px 0 4px; vertical-align:middle; visibility:hidden" valign="middle"&gt;
*&lt;/a&gt;&lt;/h4&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Turns out Docker doesn't have anything builtin for this. You either have to use external services to store configuration
and orchestrate restarting the containers, or &lt;a class="reference external" href="https://medium.com/on-docker/data-packed-volume-containers-distribute-configuration-c23ff80987cd" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;rely on volumes&lt;/a&gt;. Using volumes has
some limitations but it seems way more approachable.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;The gist of this is having an image just for configuration, a &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;docker/conf/Dockerfile&lt;/tt&gt; like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:1px solid #DDD; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 3px #EFEFEF' bgcolor="#FFFDFD"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k" style="font-weight:bold"&gt;FROM&lt;/span&gt;&lt;span class="s" style="color:#d14"&gt; alpine:3.3&lt;/span&gt;

&lt;span class="k" style="font-weight:bold"&gt;RUN&lt;/span&gt; mkdir -p /etc/app/conf /etc/app/conf-update

&lt;span class="c" style="color:#998; font-style:italic"&gt;# this will be the default data, if volume wasn't created&lt;/span&gt;
COPY settings.conf /etc/app/conf/
&lt;span class="k" style="font-weight:bold"&gt;VOLUME&lt;/span&gt;&lt;span class="s" style="color:#d14"&gt; /etc/app/conf&lt;/span&gt;

&lt;span class="c" style="color:#998; font-style:italic"&gt;# this second copy is used for updating&lt;/span&gt;
COPY settings.conf /etc/app/conf-update

COPY update-conf.sh /
&lt;span class="c" style="color:#998; font-style:italic"&gt;# similarly to a cp command&lt;/span&gt;
&lt;span class="k" style="font-weight:bold"&gt;ENTRYPOINT&lt;/span&gt;&lt;span class="s" style="color:#d14"&gt; ["/update-conf.sh", "/etc/app/conf-update", "/etc/app/conf"]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p style="margin:25px 0 25px 0"&gt;This &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;&lt;span class="pre"&gt;update-conf.sh&lt;/span&gt;&lt;/tt&gt; script is the difference to Jeff Nickoloff's &lt;a class="reference external" href="https://medium.com/on-docker/data-packed-volume-containers-distribute-configuration-c23ff80987cd#0a8f" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;example&lt;/a&gt; - it logs what
gets changed:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:1px solid #DDD; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 3px #EFEFEF' bgcolor="#FFFDFD"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="ch"&gt;#!/bin/sh&lt;/span&gt;
&lt;span class="nb" style="color:#0086B3"&gt;set&lt;/span&gt; -eu
&lt;span class="nb" style="color:#0086B3"&gt;echo&lt;/span&gt; &lt;span class="s2" style="color:#d14"&gt;"Updating configuration in &lt;/span&gt;&lt;span class="nv" style="color:#008080"&gt;$2&lt;/span&gt;&lt;span class="s2" style="color:#d14"&gt; with files from &lt;/span&gt;&lt;span class="nv" style="color:#008080"&gt;$1&lt;/span&gt;&lt;span class="s2" style="color:#d14"&gt;"&lt;/span&gt;

&lt;span class="k" style="font-weight:bold"&gt;for&lt;/span&gt; to_update in &lt;span class="nv" style="color:#008080"&gt;$1&lt;/span&gt;/*&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k" style="font-weight:bold"&gt;do&lt;/span&gt;
    &lt;span class="nv" style="color:#008080"&gt;name&lt;/span&gt;&lt;span class="o" style="font-weight:bold"&gt;=&lt;/span&gt;&lt;span class="s2" style="color:#d14"&gt;"&lt;/span&gt;&lt;span class="si" style="color:#d14"&gt;${&lt;/span&gt;&lt;span class="nv" style="color:#008080"&gt;to_update&lt;/span&gt;&lt;span class="p"&gt;##*/&lt;/span&gt;&lt;span class="si" style="color:#d14"&gt;}&lt;/span&gt;&lt;span class="s2" style="color:#d14"&gt;"&lt;/span&gt;
    &lt;span class="nb" style="color:#0086B3"&gt;echo&lt;/span&gt; &lt;span class="s2" style="color:#d14"&gt;"Updating: &lt;/span&gt;&lt;span class="nv" style="color:#008080"&gt;$name&lt;/span&gt;&lt;span class="s2" style="color:#d14"&gt;"&lt;/span&gt;

    &lt;span class="nb" style="color:#0086B3"&gt;echo&lt;/span&gt; &lt;span class="s2" style="color:#d14"&gt;"* diff from: &lt;/span&gt;&lt;span class="nv" style="color:#008080"&gt;$to_update&lt;/span&gt;&lt;span class="s2" style="color:#d14"&gt; to: &lt;/span&gt;&lt;span class="nv" style="color:#008080"&gt;$2&lt;/span&gt;&lt;span class="s2" style="color:#d14"&gt;/&lt;/span&gt;&lt;span class="nv" style="color:#008080"&gt;$name&lt;/span&gt;&lt;span class="s2" style="color:#d14"&gt;"&lt;/span&gt;
    diff -U &lt;span class="m" style="color:#099"&gt;5&lt;/span&gt; &lt;span class="s2" style="color:#d14"&gt;"&lt;/span&gt;&lt;span class="nv" style="color:#008080"&gt;$to_update&lt;/span&gt;&lt;span class="s2" style="color:#d14"&gt;"&lt;/span&gt; &lt;span class="s2" style="color:#d14"&gt;"&lt;/span&gt;&lt;span class="nv" style="color:#008080"&gt;$2&lt;/span&gt;&lt;span class="s2" style="color:#d14"&gt;/&lt;/span&gt;&lt;span class="nv" style="color:#008080"&gt;$name&lt;/span&gt;&lt;span class="s2" style="color:#d14"&gt;"&lt;/span&gt;
    &lt;span class="nb" style="color:#0086B3"&gt;echo&lt;/span&gt; &lt;span class="s2" style="color:#d14"&gt;"* copying: &lt;/span&gt;&lt;span class="nv" style="color:#008080"&gt;$to_update&lt;/span&gt;&lt;span class="s2" style="color:#d14"&gt; to: &lt;/span&gt;&lt;span class="nv" style="color:#008080"&gt;$2&lt;/span&gt;&lt;span class="s2" style="color:#d14"&gt;/&lt;/span&gt;&lt;span class="nv" style="color:#008080"&gt;$name&lt;/span&gt;&lt;span class="s2" style="color:#d14"&gt;"&lt;/span&gt;
    cp &lt;span class="s2" style="color:#d14"&gt;"&lt;/span&gt;&lt;span class="nv" style="color:#008080"&gt;$to_update&lt;/span&gt;&lt;span class="s2" style="color:#d14"&gt;"&lt;/span&gt; &lt;span class="s2" style="color:#d14"&gt;"&lt;/span&gt;&lt;span class="nv" style="color:#008080"&gt;$2&lt;/span&gt;&lt;span class="s2" style="color:#d14"&gt;/&lt;/span&gt;&lt;span class="nv" style="color:#008080"&gt;$name&lt;/span&gt;&lt;span class="s2" style="color:#d14"&gt;"&lt;/span&gt;
&lt;span class="k" style="font-weight:bold"&gt;done&lt;/span&gt;

&lt;span class="nb" style="color:#0086B3"&gt;echo&lt;/span&gt; Success. Configuration updated!
&lt;/pre&gt;&lt;/div&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Then to use this you just link the volumes (assuming &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;&lt;span class="pre"&gt;docker-compose&lt;/span&gt;&lt;/tt&gt;):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:1px solid #DDD; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 3px #EFEFEF' bgcolor="#FFFDFD"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;conf&lt;/span&gt;&lt;span class="p p-Indicator"&gt;:&lt;/span&gt;
  &lt;span class="l l-Scalar l-Scalar-Plain"&gt;image&lt;/span&gt;&lt;span class="p p-Indicator"&gt;:&lt;/span&gt; &lt;span class="s" style="color:#d14"&gt;'app-conf'&lt;/span&gt;
  &lt;span class="l l-Scalar l-Scalar-Plain"&gt;build&lt;/span&gt;&lt;span class="p p-Indicator"&gt;:&lt;/span&gt; &lt;span class="s" style="color:#d14"&gt;'docker/conf'&lt;/span&gt;
&lt;span class="l l-Scalar l-Scalar-Plain"&gt;web&lt;/span&gt;&lt;span class="p p-Indicator"&gt;:&lt;/span&gt;
  &lt;span class="l l-Scalar l-Scalar-Plain"&gt;...&lt;/span&gt;
  &lt;span class="l l-Scalar l-Scalar-Plain"&gt;volumes_from&lt;/span&gt;&lt;span class="p p-Indicator"&gt;:&lt;/span&gt;
  &lt;span class="p p-Indicator"&gt;-&lt;/span&gt; &lt;span class="s" style="color:#d14"&gt;'conf:ro'&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;hr class="docutils" style="background:#FFFDFD; border:0; border-radius:2px; padding:0; background-color:#F6F6F6; box-shadow:inset 0 0 2px #CCC; clear:both; height:6px; margin:0 1px" bgcolor="#F6F6F6" height="6"&gt;
&lt;p style="margin:25px 0 25px 0"&gt;This is all I got so far, more in a future article!&lt;/p&gt;
&lt;table class="docutils footnote" frame="void" id="id9" rules="none" style='margin:5px 0; box-shadow:none; background:transparent; border:none; border-collapse:separate; border-radius:5px; border-spacing:0; width:100%; font-family:Palatino, "Palatino Linotype", Georgia, serif; margin-bottom:8px' width="100%"&gt;
&lt;colgroup&gt;&lt;col class="label"&gt;&lt;col&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label" style='border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; border-left:1px solid #DDD; font-size:75%; background:transparent; text-decoration:none; text-shadow:none; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; width:5%; border-radius:0' width="5%"&gt;&lt;a class="fn-backref" href="https://blog.ionelmc.ro/2016/05/07/dealing-with-docker/#id1" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:75%; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace'&gt;[*]&lt;/a&gt;&lt;/td&gt;&lt;td style="border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; font-size:15px; border-radius:0"&gt;Haven't tried it on Windows but it does use VirtualBox so I expect a painfully slow experience.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id10" rules="none" style='margin:5px 0; box-shadow:none; background:transparent; border:none; border-collapse:separate; border-radius:5px; border-spacing:0; width:100%; font-family:Palatino, "Palatino Linotype", Georgia, serif; margin-bottom:8px' width="100%"&gt;
&lt;colgroup&gt;&lt;col class="label"&gt;&lt;col&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label" style='border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; border-left:1px solid #DDD; font-size:75%; background:transparent; text-decoration:none; text-shadow:none; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; width:5%; border-radius:0' width="5%"&gt;&lt;a class="fn-backref" href="https://blog.ionelmc.ro/2016/05/07/dealing-with-docker/#id4" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:75%; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace'&gt;[1]&lt;/a&gt;&lt;/td&gt;&lt;td style="border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; font-size:15px; border-radius:0"&gt;Wheels are binaries for Python packages.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id11" rules="none" style='margin:5px 0; box-shadow:none; background:transparent; border:none; border-collapse:separate; border-radius:5px; border-spacing:0; width:100%; font-family:Palatino, "Palatino Linotype", Georgia, serif; margin-bottom:8px' width="100%"&gt;
&lt;colgroup&gt;&lt;col class="label"&gt;&lt;col&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label" style='border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; border-left:1px solid #DDD; font-size:75%; background:transparent; text-decoration:none; text-shadow:none; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; width:5%; border-radius:0' width="5%"&gt;&lt;a class="fn-backref" href="https://blog.ionelmc.ro/2016/05/07/dealing-with-docker/#id2" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:75%; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace'&gt;[2]&lt;/a&gt;&lt;/td&gt;&lt;td style="border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; font-size:15px; border-radius:0"&gt;Try building GUI library bindings or pysvn. Enter a world of pain.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id12" rules="none" style='margin:5px 0; box-shadow:none; background:transparent; border:none; border-collapse:separate; border-radius:5px; border-spacing:0; width:100%; font-family:Palatino, "Palatino Linotype", Georgia, serif; margin-bottom:8px' width="100%"&gt;
&lt;colgroup&gt;&lt;col class="label"&gt;&lt;col&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label" style='border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; border-left:1px solid #DDD; font-size:75%; background:transparent; text-decoration:none; text-shadow:none; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; width:5%; border-radius:0' width="5%"&gt;&lt;a class="fn-backref" href="https://blog.ionelmc.ro/2016/05/07/dealing-with-docker/#id3" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:75%; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace'&gt;[3]&lt;/a&gt;&lt;/td&gt;&lt;td style="border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; font-size:15px; border-radius:0"&gt;&lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;&lt;span class="pre"&gt;py-bt&lt;/span&gt;&lt;/tt&gt; prints the callstack of Python code, while &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;bt&lt;/tt&gt; prints the C call stack which don't show python line
numbers or function names.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id13" rules="none" style='margin:5px 0; box-shadow:none; background:transparent; border:none; border-collapse:separate; border-radius:5px; border-spacing:0; width:100%; font-family:Palatino, "Palatino Linotype", Georgia, serif; margin-bottom:8px' width="100%"&gt;
&lt;colgroup&gt;&lt;col class="label"&gt;&lt;col&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label" style='border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; border-left:1px solid #DDD; font-size:75%; background:transparent; text-decoration:none; text-shadow:none; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; width:5%; border-radius:0' width="5%"&gt;&lt;a class="fn-backref" href="https://blog.ionelmc.ro/2016/05/07/dealing-with-docker/#id5" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:75%; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace'&gt;[4]&lt;/a&gt;&lt;/td&gt;&lt;td style="border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; font-size:15px; border-radius:0"&gt;&lt;p class="first" style="margin:0; margin-top:0"&gt;Pinning the versions is a best practice because:&lt;/p&gt;
&lt;ul class="simple" style="margin:25px 0 25px 0"&gt;
&lt;li style="padding:0"&gt;Even minor/patch releases can introduce regressions.&lt;/li&gt;
&lt;li style="padding:0"&gt;They allow faster installs: &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;pip&lt;/tt&gt; doesn't need to find all the available versions every time, there are less
network requests and generally shorter path to a cache hit.&lt;/li&gt;
&lt;/ul&gt;
&lt;p class="last" style="margin:0"&gt;You can read more about it &lt;a class="reference external" href="https://caremad.io/2013/07/setup-vs-requirement/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;here&lt;/a&gt;,
&lt;a class="reference external" href="http://nvie.com/posts/pin-your-packages/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;here&lt;/a&gt; or &lt;a class="reference external" href="https://carljm.github.io/tamingdeps/#11" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id14" rules="none" style='margin:5px 0; box-shadow:none; background:transparent; border:none; border-collapse:separate; border-radius:5px; border-spacing:0; width:100%; font-family:Palatino, "Palatino Linotype", Georgia, serif; margin-bottom:8px' width="100%"&gt;
&lt;colgroup&gt;&lt;col class="label"&gt;&lt;col&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label" style='border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; border-left:1px solid #DDD; font-size:75%; background:transparent; text-decoration:none; text-shadow:none; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; width:5%; border-radius:0' width="5%"&gt;&lt;a class="fn-backref" href="https://blog.ionelmc.ro/2016/05/07/dealing-with-docker/#id7" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:75%; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace'&gt;[5]&lt;/a&gt;&lt;/td&gt;&lt;td style="border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; font-size:15px; border-radius:0"&gt;If you already use Python and don't want an extra 1.7Mb binary use &lt;a class="reference external" href="https://github.com/ionelmc/python-su" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;pysu&lt;/a&gt;
instead.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id15" rules="none" style='margin:5px 0; box-shadow:none; background:transparent; border:none; border-collapse:separate; border-radius:5px; border-spacing:0; width:100%; font-family:Palatino, "Palatino Linotype", Georgia, serif; margin-bottom:8px' width="100%"&gt;
&lt;colgroup&gt;&lt;col class="label"&gt;&lt;col&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label" style='border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; border-left:1px solid #DDD; font-size:75%; background:transparent; text-decoration:none; text-shadow:none; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; width:5%; border-radius:0' width="5%"&gt;&lt;a class="fn-backref" href="https://blog.ionelmc.ro/2016/05/07/dealing-with-docker/#id6" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:75%; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace'&gt;[6]&lt;/a&gt;&lt;/td&gt;&lt;td style="border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; font-size:15px; border-radius:0"&gt;You need to configure your Docker daemon and &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;subuid&lt;/tt&gt;/&lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;subgid&lt;/tt&gt; (another system-wide thing). User namespace is a
security feature for deployment, not development. Imagine having to configure that on every developer's machine, good
grief!&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id16" rules="none" style='margin:5px 0; box-shadow:none; background:transparent; border:none; border-collapse:separate; border-radius:5px; border-spacing:0; width:100%; font-family:Palatino, "Palatino Linotype", Georgia, serif; margin-bottom:8px' width="100%"&gt;
&lt;colgroup&gt;&lt;col class="label"&gt;&lt;col&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label" style='border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; border-left:1px solid #DDD; font-size:75%; background:transparent; text-decoration:none; text-shadow:none; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; width:5%; border-radius:0' width="5%"&gt;&lt;a class="fn-backref" href="https://blog.ionelmc.ro/2016/05/07/dealing-with-docker/#id8" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:75%; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace'&gt;[7]&lt;/a&gt;&lt;/td&gt;&lt;td style="border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; font-size:15px; border-radius:0"&gt;See: &lt;a class="reference external" href="https://docs.python.org/3/library/os.html#os.waitpid" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;https://docs.python.org/3/library/os.html#os.waitpid&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;img src="https://blog.ionelmc.ro/_/2016/05/07/dealing-with-docker/?all-en.atom.xml" width="1" height="1" alt="" title=""&gt;</content><category term="python"></category><category term="linux"></category><category term="docker"></category><category term="debugging"></category><category term="packaging"></category><category term="pip"></category><category term="rant"></category></entry><entry><title>Notes on debugging</title><link href="https://blog.ionelmc.ro/2016/02/18/notes-on-debugging/" rel="alternate"></link><published>2016-02-18T00:00:00+02:00</published><updated>2016-02-18T17:37:57+02:00</updated><author><name>Ionel Cristian Mărieș</name></author><id>tag:blog.ionelmc.ro,2016-02-18:2016/02/18/notes-on-debugging/</id><summary type="html">&lt;div class="document" style='font:19px/29px "Palatino Linotype", "Book Antiqua", "FPL Neu", "TeX Gyre Pagella", "URW Palladio L", "Palatino", "Century Schoolbook L", "Georgia", serif; margin:0; padding:0'&gt;&lt;p style="margin:25px 0 25px 0"&gt;Debugging is a favourite subject of mine. It's an incredibly interesting area of programming but unfortunately not always a
trivial one. It's also very important - it plays a significant part in programmer's productivity. No matter how many QA
tools you have at your disposal, and no matter how hard you …&lt;/p&gt;&lt;/div&gt;</summary><content type="html">&lt;div class="document" style='font:19px/29px "Palatino Linotype", "Book Antiqua", "FPL Neu", "TeX Gyre Pagella", "URW Palladio L", "Palatino", "Century Schoolbook L", "Georgia", serif; margin:0; padding:0'&gt;&lt;p style="margin:25px 0 25px 0"&gt;Debugging is a favourite subject of mine. It's an incredibly interesting area of programming but unfortunately not always a
trivial one. It's also very important - it plays a significant part in programmer's productivity. No matter how many QA
tools you have at your disposal, and no matter how hard you try to create bug-free code you will need to do debugging.
It's just one of the intractable facets of programming.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Here's my attempt to define some concepts and guidelines. What are the tenets of debugging?&lt;/p&gt;
&lt;div class="section" id="find-the-cause-first"&gt;
&lt;h2 style='font-family:"Candara", "Merriweather Sans", "Trebuchet Ms", "Segoe UI", sans-serif; text-shadow:1px 1px 1px #DDD; color:#333; font-weight:bold; line-height:1; font-size:2em'&gt;Find the cause first&lt;a class="headerlink" href="https://blog.ionelmc.ro/2016/02/18/notes-on-debugging/#find-the-cause-first" title="Permalink to this headline" style="color:#c60f0f; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; padding:0 4px 0 4px; vertical-align:middle; visibility:hidden" valign="middle"&gt;
*&lt;/a&gt;&lt;/h2&gt;
&lt;p style="margin:25px 0 25px 0"&gt;This is the most important, for many reasons. Yes, some issues can be quite hard to understand but with time, as you build
up knowledge, it gets easier. If you just try random changes (&lt;a class="reference external" href="https://en.wikipedia.org/wiki/Shotgun_debugging" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;shotgun debugging&lt;/a&gt;) in hopes that it will fix the problem
then you're in fact depriving yourself of knowledge and assurance that you actually fixed the problem. It may seem easier,
especially if you get lucky but overall you'll waste inordinate amounts of time with that "technique". Focus on finding the
cause first.&lt;/p&gt;
&lt;div class="section" id="down-the-rabbit-hole"&gt;
&lt;h3 style='font-family:"Candara", "Merriweather Sans", "Trebuchet Ms", "Segoe UI", sans-serif; text-shadow:1px 1px 1px #DDD; color:#333; font-weight:bold; line-height:1; font-size:1.56em'&gt;Down the rabbit hole&lt;a class="headerlink" href="https://blog.ionelmc.ro/2016/02/18/notes-on-debugging/#down-the-rabbit-hole" title="Permalink to this headline" style="color:#c60f0f; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; padding:0 4px 0 4px; vertical-align:middle; visibility:hidden" valign="middle"&gt;
*&lt;/a&gt;&lt;/h3&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Unfortunately you have to accept the harsh reality that there are no shortcuts:&lt;/p&gt;
&lt;ul style="margin:25px 0 25px 0"&gt;
&lt;li style="padding:0"&gt;&lt;p class="first" style="margin:25px 0 25px 0"&gt;You'll have to read lots of code to understand what's going on. Yes, that includes other peoples code. You're using a
framework? You'll have to read the code.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Lots of people avoid this because it's hard and many frameworks are complicated. But understanding your libraries will pay
off.&lt;/p&gt;
&lt;/li&gt;
&lt;li style="padding:0"&gt;&lt;p class="first" style="margin:25px 0 25px 0"&gt;You won't see the problem by merely looking at the code &lt;a class="footnote-reference" href="https://blog.ionelmc.ro/2016/02/18/notes-on-debugging/#id4" id="id1" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:12px; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; vertical-align:top' valign="top"&gt;[1]&lt;/a&gt; so you'll have to inspect the execution of the
code and reason about it.&lt;/p&gt;
&lt;/li&gt;
&lt;li style="padding:0"&gt;&lt;p class="first" style="margin:25px 0 25px 0"&gt;Not understanding the cause can be grueling and frustrating; it can take a while. But once you figure it out it's pleasant.
It's totally worth the pain, plus next time it get easier - the accumulated knowledge helps. Don't give up!&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="rooting-it-out"&gt;
&lt;h3 style='font-family:"Candara", "Merriweather Sans", "Trebuchet Ms", "Segoe UI", sans-serif; text-shadow:1px 1px 1px #DDD; color:#333; font-weight:bold; line-height:1; font-size:1.56em'&gt;Rooting it out&lt;a class="headerlink" href="https://blog.ionelmc.ro/2016/02/18/notes-on-debugging/#rooting-it-out" title="Permalink to this headline" style="color:#c60f0f; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; padding:0 4px 0 4px; vertical-align:middle; visibility:hidden" valign="middle"&gt;
*&lt;/a&gt;&lt;/h3&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Assuming you got the &lt;a class="reference external" href="https://blog.ionelmc.ro/2013/06/05/python-debugging-tools/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;right tools&lt;/a&gt;, there are various
"techniques" you can use.&lt;/p&gt;
&lt;blockquote class="highlights" style='border-left:0; margin-left:0; padding:1ex 0 1ex 1em; quotes:"“" "”" "‘" "’"; color:#444; font-size:135%; font-style:italic; font-weight:bold; line-height:1.2; padding-left:0; text-align:center' align="center"&gt;
Simpler programs are easier to understand than complicated programs with lots of moving parts.&lt;/blockquote&gt;
&lt;p style="margin:25px 0 25px 0"&gt;One of the best approaches is to isolate the issue. Some call it &lt;a class="reference external" href="http://haypo-notes.readthedocs.org/misc.html#dichotomy" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;divide &amp;amp; conquer&lt;/a&gt;. The idea is to reduce the amount of code you need to comprehend.
It's similar to making a &lt;a class="reference external" href="http://sscce.org/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;very good bug report&lt;/a&gt;:&lt;/p&gt;
&lt;ul style="margin:25px 0 25px 0"&gt;
&lt;li style="padding:0"&gt;&lt;p class="first" style="margin:25px 0 25px 0"&gt;Remove code or don't run code that's unnecessary or unrelated. If you're not sure, take it out. If the issue doesn't
reproduce anymore then you know what to focus on. Just remove half of the code till you see where the problem is.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;For example, you'd do it when execution stops at some unknown point and you need to figure out where it is. It may
indicate you don't have good tooling (like an adequate tracer).&lt;/p&gt;
&lt;/li&gt;
&lt;li style="padding:0"&gt;&lt;p class="first" style="margin:25px 0 25px 0"&gt;If you're having a regression you can use &lt;a class="reference external" href="https://git-scm.com/docs/git-bisect" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;git bisect&lt;/a&gt; (or &lt;a class="reference external" href="https://selenic.com/hg/help/bisect" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;hg bisect&lt;/a&gt;) to find the offending commit. That tool will run a command of your choosing till
the first commit that makes it fail is found.&lt;/p&gt;
&lt;/li&gt;
&lt;li style="padding:0"&gt;&lt;p class="first" style="margin:25px 0 25px 0"&gt;Isolate any environment issues. Try a different OS, library or Python version. Note that this can be
misleading - if the problem doesn't reproduce with a different Python it doesn't mean that the issue is in the Python
interpreter - it may very well be an issue with your code (example: misusing some API).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p style="margin:25px 0 25px 0"&gt;A more risky way to approach things is "proving the hypothesis": you make some theory about what might be wrong and then test
it. There are some pitfalls:&lt;/p&gt;
&lt;ul class="simple" style="margin:25px 0 25px 0"&gt;
&lt;li style="padding:0"&gt;It's only good if you got some intuition in the problem space. Otherwise you'd practically be doing &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Shotgun_debugging" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;shotgun debugging&lt;/a&gt;.&lt;/li&gt;
&lt;li style="padding:0"&gt;If you find a way to make the bug disappear but don't understand why do not stop there. Understanding the cause is
paramount.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Another way is the "secret police" method: assume everything is bad, vet any component, including external ones. Usually this
is a "last resort" thing for
&lt;a class="reference external" href="https://medium.com/vijay-pandurangan/linux-kernel-bug-delivers-corrupt-tcp-ip-data-to-mesos-kubernetes-docker-containers-4986f88f7a19" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;crazy&lt;/a&gt;
&lt;a class="reference external" href="https://sandstorm.io/news/2015-04-08-osx-security-bug" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;issues&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="plan-for-disaster"&gt;
&lt;h2 style='font-family:"Candara", "Merriweather Sans", "Trebuchet Ms", "Segoe UI", sans-serif; text-shadow:1px 1px 1px #DDD; color:#333; font-weight:bold; line-height:1; font-size:2em'&gt;Plan for disaster&lt;a class="headerlink" href="https://blog.ionelmc.ro/2016/02/18/notes-on-debugging/#plan-for-disaster" title="Permalink to this headline" style="color:#c60f0f; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; padding:0 4px 0 4px; vertical-align:middle; visibility:hidden" valign="middle"&gt;
*&lt;/a&gt;&lt;/h2&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Everything is easier when you're prepared. When you write code, or choose what code to reuse have in mind that one fateful
day you will have to deal with the choices you've made. There are two aspects you should consider.&lt;/p&gt;
&lt;div class="section" id="tooling"&gt;
&lt;h3 style='font-family:"Candara", "Merriweather Sans", "Trebuchet Ms", "Segoe UI", sans-serif; text-shadow:1px 1px 1px #DDD; color:#333; font-weight:bold; line-height:1; font-size:1.56em'&gt;Tooling&lt;a class="headerlink" href="https://blog.ionelmc.ro/2016/02/18/notes-on-debugging/#tooling" title="Permalink to this headline" style="color:#c60f0f; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; padding:0 4px 0 4px; vertical-align:middle; visibility:hidden" valign="middle"&gt;
*&lt;/a&gt;&lt;/h3&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Think about what tooling and information you'll have available when you need to:&lt;/p&gt;
&lt;ul class="simple" style="margin:25px 0 25px 0"&gt;
&lt;li style="padding:0"&gt;Do post-mortem analysis. Things like &lt;a class="reference external" href="https://hynek.me/talks/beyond-grep/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;logs&lt;/a&gt;, core dumps,
&lt;a class="reference external" href="https://blog.ionelmc.ro/2013/06/05/python-debugging-tools/#having-segfaults-faulthandler" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;stacktraces&lt;/a&gt; and
&lt;a class="reference external" href="http://antirez.com/news/43" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;other details&lt;/a&gt; you might not have access to otherwise.&lt;/li&gt;
&lt;li style="padding:0"&gt;Inspect process state (memory, object, files, sockets and other resources).&lt;/li&gt;
&lt;li style="padding:0"&gt;Trace or step through execution.&lt;/li&gt;
&lt;li style="padding:0"&gt;Quickly change code and run it again.&lt;/li&gt;
&lt;li style="padding:0"&gt;Inspect code (jump to definition, usage search)&lt;/li&gt;
&lt;li style="padding:0"&gt;Look at logs. Reconfigure logging easily to get the firehose &lt;a class="footnote-reference" href="https://blog.ionelmc.ro/2016/02/18/notes-on-debugging/#id5" id="id2" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:12px; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; vertical-align:top' valign="top"&gt;[2]&lt;/a&gt; when you need it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Some design choices make some tools harder to use. Examples:&lt;/p&gt;
&lt;ul class="simple" style="margin:25px 0 25px 0"&gt;
&lt;li style="padding:0"&gt;Highly dynamic code make inspecting code harder. Not to mention reasoning about it ...&lt;/li&gt;
&lt;li style="padding:0"&gt;Some tools don't work with threads or other concurrency implementations like gevent or eventlet.&lt;/li&gt;
&lt;li style="padding:0"&gt;Some tools may depend on threads, which may interfere with other libraries (like gevent or eventlet).&lt;/li&gt;
&lt;li style="padding:0"&gt;Hardcoded configuration for logging.&lt;/li&gt;
&lt;li style="padding:0"&gt;Availability of debug builds for various things. Example: can you deploy your Python app with a debug build of the
interpreter?&lt;/li&gt;
&lt;li style="padding:0"&gt;Can you install tools or dependencies easily?&lt;/li&gt;
&lt;li style="padding:0"&gt;Can you elevate permissions for debugging purposes? &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Ptrace#Uses" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;Various tools&lt;/a&gt; may need
root access or special permissions.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="code"&gt;
&lt;h3 style='font-family:"Candara", "Merriweather Sans", "Trebuchet Ms", "Segoe UI", sans-serif; text-shadow:1px 1px 1px #DDD; color:#333; font-weight:bold; line-height:1; font-size:1.56em'&gt;Code&lt;a class="headerlink" href="https://blog.ionelmc.ro/2016/02/18/notes-on-debugging/#code" title="Permalink to this headline" style="color:#c60f0f; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; padding:0 4px 0 4px; vertical-align:middle; visibility:hidden" valign="middle"&gt;
*&lt;/a&gt;&lt;/h3&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Most certainly you'll have to read code, possibly not your own code. Factor that in when writing code or when choosing a
framework or library, along other factors like documentation quality, number of users and how well it is maintained.&lt;/p&gt;
&lt;blockquote class="highlights" style='border-left:0; margin-left:0; padding:1ex 0 1ex 1em; quotes:"“" "”" "‘" "’"; color:#444; font-size:135%; font-style:italic; font-weight:bold; line-height:1.2; padding-left:0; text-align:center' align="center"&gt;
Code you don't understand might as well be technical debt!&lt;/blockquote&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Have these ideas in mind when writing/reviewing code, or when choosing what library to use:&lt;/p&gt;
&lt;ul style="margin:25px 0 25px 0"&gt;
&lt;li style="padding:0"&gt;&lt;p class="first" style="margin:25px 0 25px 0"&gt;If it's big, complicated and hard to understand it will cost you. Plan the time you'll need to spend understanding
it. It's surprising how much time you'll waste on a library that's advertised to save time.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;It's not just the effort to understand the internals. Inordinate amounts of time are often wasted on shoehorning slightly
different (but unplanned for) use cases. Big fancy frameworks optimize for typical use-cases and make everything else hard to
accomplish. There are exceptions of course, but rare.&lt;/p&gt;
&lt;/li&gt;
&lt;li style="padding:0"&gt;&lt;p class="first" style="margin:25px 0 25px 0"&gt;A community can help a lot. Having a place to ask for help means that you don't need that much upfront knowledge.&lt;/p&gt;
&lt;/li&gt;
&lt;li style="padding:0"&gt;&lt;p class="first" style="margin:25px 0 25px 0"&gt;Code quality. Less bugs means less debugging right?&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;There are many practices but here are few ones:&lt;/p&gt;
&lt;ul style="margin:10px 0; padding:0 0 0 40px"&gt;
&lt;li style="padding:0"&gt;&lt;p class="first" style="margin:25px 0 25px 0"&gt;Code reviews.&lt;/p&gt;
&lt;/li&gt;
&lt;li style="padding:0"&gt;&lt;p class="first" style="margin:25px 0 25px 0"&gt;Good exception handling. Don't discard or &lt;a class="reference external" href="https://blog.ionelmc.ro/2014/08/03/the-most-underrated-feature-in-python-3/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;cripple exceptions&lt;/a&gt;. Give descriptive errors that indicates
what needs to be fixed.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Good error handling makes debugging more predictable, and less of a bottomless hole to sink your time in.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="plan-for-disaster-but-live-dangerously"&gt;
&lt;h3 style='font-family:"Candara", "Merriweather Sans", "Trebuchet Ms", "Segoe UI", sans-serif; text-shadow:1px 1px 1px #DDD; color:#333; font-weight:bold; line-height:1; font-size:1.56em'&gt;Plan for disaster, but live dangerously&lt;a class="headerlink" href="https://blog.ionelmc.ro/2016/02/18/notes-on-debugging/#plan-for-disaster-but-live-dangerously" title="Permalink to this headline" style="color:#c60f0f; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; padding:0 4px 0 4px; vertical-align:middle; visibility:hidden" valign="middle"&gt;
*&lt;/a&gt;&lt;/h3&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Safety don't present the same opportunities for acquiring knowledge. It's often necessary to do more tricky things, at
least for the sake of getting the information you need while debugging, if not for figuring why that metaclass-using ORM
don't work as you expect.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;For example, you wouldn't normally do monkey-patching in your code, but maybe it's &lt;a class="reference external" href="http://python-aspectlib.readthedocs.org/en/latest/reference/aspectlib.debug.html#aspectlib.debug.log" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;an option&lt;/a&gt; when otherwise you'd
have to patch up lots of files.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;On the other hand, experimentation is prone to failure so there's the open question of where's a good place to experiment ...&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="ask-for-help-but-understand"&gt;
&lt;h2 style='font-family:"Candara", "Merriweather Sans", "Trebuchet Ms", "Segoe UI", sans-serif; text-shadow:1px 1px 1px #DDD; color:#333; font-weight:bold; line-height:1; font-size:2em'&gt;Ask for help but understand&lt;a class="headerlink" href="https://blog.ionelmc.ro/2016/02/18/notes-on-debugging/#ask-for-help-but-understand" title="Permalink to this headline" style="color:#c60f0f; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; padding:0 4px 0 4px; vertical-align:middle; visibility:hidden" valign="middle"&gt;
*&lt;/a&gt;&lt;/h2&gt;
&lt;p style="margin:25px 0 25px 0"&gt;You got a bug, you ask your colleague and 5 minutes later it's sorted out. Don't leave it at that. Ask how and why. Understand
the process used to find the case. Identify best practices if possible.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="integration-tests-pay-off"&gt;
&lt;h2 style='font-family:"Candara", "Merriweather Sans", "Trebuchet Ms", "Segoe UI", sans-serif; text-shadow:1px 1px 1px #DDD; color:#333; font-weight:bold; line-height:1; font-size:2em'&gt;Integration tests pay off&lt;a class="headerlink" href="https://blog.ionelmc.ro/2016/02/18/notes-on-debugging/#integration-tests-pay-off" title="Permalink to this headline" style="color:#c60f0f; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; padding:0 4px 0 4px; vertical-align:middle; visibility:hidden" valign="middle"&gt;
*&lt;/a&gt;&lt;/h2&gt;
&lt;p style="margin:25px 0 25px 0"&gt;The interesting thing about tests it's not that they make debugging easier, it's that they force you to resolve bugs early.
They give you a warning early so you can fix it at a convenient time. Compare that to a production issue that you gotta fix on
a Friday night.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;To make an analogy: it's like owning a car - you'd want to get warning indicators and service it at an opportune time rather
than having it break down in the middle of nowhere.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Integration tests, and not unit tests because they reach out those areas between various components (interactions) where the
nasty bugs are in. Simply put, production won't run just a function, it will a combination thereof. Debate about what's the
right balance of unit tests vs functional tests &lt;a class="reference external" href="http://nedbatchelder.com/blog/201602/the_value_of_unit_tests.html" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;still rages on&lt;/a&gt;,
but you need to be aware that you can't simply go for a pure unit test suite and hope for the best.&lt;/p&gt;
&lt;!-- At the very least you can add an integration tests for bugs that involve multiple components (interaction issues). --&gt;
&lt;/div&gt;
&lt;div class="section" id="other-peoples-misery-is-gold"&gt;
&lt;h2 style='font-family:"Candara", "Merriweather Sans", "Trebuchet Ms", "Segoe UI", sans-serif; text-shadow:1px 1px 1px #DDD; color:#333; font-weight:bold; line-height:1; font-size:2em'&gt;Other peoples misery is gold&lt;a class="headerlink" href="https://blog.ionelmc.ro/2016/02/18/notes-on-debugging/#other-peoples-misery-is-gold" title="Permalink to this headline" style="color:#c60f0f; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; padding:0 4px 0 4px; vertical-align:middle; visibility:hidden" valign="middle"&gt;
*&lt;/a&gt;&lt;/h2&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Reading what &lt;a class="reference external" href="https://github.com/danluu/post-mortems" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;issues other people had&lt;/a&gt; &lt;a class="footnote-reference" href="https://blog.ionelmc.ro/2016/02/18/notes-on-debugging/#id6" id="id3" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:12px; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; vertical-align:top' valign="top"&gt;[3]&lt;/a&gt; is pure gold. There is simply no way
you can accumulate all that knowledge only from the software you develop yourself. It's a huge boost to your intuition as
well. Plus you won't feel that bad when you have a problem - there's always someone you had it worse.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;If you have the time you can also &lt;a class="reference external" href="http://pymust.watch/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;watch videos&lt;/a&gt; or &lt;a class="reference external" href="http://planet.python.org" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;read other peoples blogs&lt;/a&gt;.
Every so often there something describing an interesting problem or various obscure but useful details.&lt;/p&gt;
&lt;table class="docutils footnote" frame="void" id="id4" rules="none" style='margin:5px 0; box-shadow:none; background:transparent; border:none; border-collapse:separate; border-radius:5px; border-spacing:0; width:100%; font-family:Palatino, "Palatino Linotype", Georgia, serif; margin-bottom:8px' width="100%"&gt;
&lt;colgroup&gt;&lt;col class="label"&gt;&lt;col&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label" style='border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; border-left:1px solid #DDD; font-size:75%; background:transparent; text-decoration:none; text-shadow:none; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; width:5%; border-radius:0' width="5%"&gt;&lt;a class="fn-backref" href="https://blog.ionelmc.ro/2016/02/18/notes-on-debugging/#id1" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:75%; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace'&gt;[1]&lt;/a&gt;&lt;/td&gt;&lt;td style="border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; font-size:15px; border-radius:0"&gt;If you do code reviews that is ...&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id5" rules="none" style='margin:5px 0; box-shadow:none; background:transparent; border:none; border-collapse:separate; border-radius:5px; border-spacing:0; width:100%; font-family:Palatino, "Palatino Linotype", Georgia, serif; margin-bottom:8px' width="100%"&gt;
&lt;colgroup&gt;&lt;col class="label"&gt;&lt;col&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label" style='border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; border-left:1px solid #DDD; font-size:75%; background:transparent; text-decoration:none; text-shadow:none; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; width:5%; border-radius:0' width="5%"&gt;&lt;a class="fn-backref" href="https://blog.ionelmc.ro/2016/02/18/notes-on-debugging/#id2" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:75%; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace'&gt;[2]&lt;/a&gt;&lt;/td&gt;&lt;td style="border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; font-size:15px; border-radius:0"&gt;&lt;span class="bigger-baseline" style="display:inline-block; font-size:150%; margin:-1ex 0; vertical-align:baseline" valign="baseline"&gt;firehose&lt;/span&gt; &lt;cite&gt;noun&lt;/cite&gt; Something that carries a crushing stream of &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;DEBUG&lt;/tt&gt; level logging messages.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id6" rules="none" style='margin:5px 0; box-shadow:none; background:transparent; border:none; border-collapse:separate; border-radius:5px; border-spacing:0; width:100%; font-family:Palatino, "Palatino Linotype", Georgia, serif; margin-bottom:8px' width="100%"&gt;
&lt;colgroup&gt;&lt;col class="label"&gt;&lt;col&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label" style='border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; border-left:1px solid #DDD; font-size:75%; background:transparent; text-decoration:none; text-shadow:none; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; width:5%; border-radius:0' width="5%"&gt;&lt;a class="fn-backref" href="https://blog.ionelmc.ro/2016/02/18/notes-on-debugging/#id3" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:75%; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace'&gt;[3]&lt;/a&gt;&lt;/td&gt;&lt;td style="border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; font-size:15px; border-radius:0"&gt;Make sure you look over the other lists too: &lt;a class="reference external" href="https://github.com/danluu/post-mortems#other-lists-of-postmortems" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;https://github.com/danluu/post-mortems#other-lists-of-postmortems&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;img src="https://blog.ionelmc.ro/_/2016/02/18/notes-on-debugging/?all-en.atom.xml" width="1" height="1" alt="" title=""&gt;</content><category term="python"></category><category term="debugging"></category></entry><entry><title>Memory use and speed of JSON parsers</title><link href="https://blog.ionelmc.ro/2015/11/22/memory-use-and-speed-of-json-parsers/" rel="alternate"></link><published>2015-11-22T00:00:00+02:00</published><updated>2015-12-15T11:47:54+02:00</updated><author><name>Ionel Cristian Mărieș</name></author><id>tag:blog.ionelmc.ro,2015-11-22:2015/11/22/memory-use-and-speed-of-json-parsers/</id><summary type="html">&lt;div class="document" style='font:19px/29px "Palatino Linotype", "Book Antiqua", "FPL Neu", "TeX Gyre Pagella", "URW Palladio L", "Palatino", "Century Schoolbook L", "Georgia", serif; margin:0; padding:0'&gt;&lt;div class="admonition note" style="border:1px solid #DDD; border-radius:5px; box-shadow:0 1px 5px #EEE; margin:3ex 1ex 1ex 1ex; padding:0; background:white; float:right; width:200px" width="200"&gt;
&lt;p class="first admonition-title" style="margin:0; font-size:90%; border:none; border-radius:5px; box-shadow:0 1px 5px #EEE; padding:0; background:#F5F5F0; border-bottom:1px solid #DDD; font-style:italic; text-align:center" align="center"&gt;Note&lt;/p&gt;
&lt;p style="margin:0 0.5em 1em 0.5em; font-size:90%"&gt;TL;DR: In decode oriented use-case with big payloads JSON decoders often use disproportionate amounts of memory. I
gave up on JSON and switched to &lt;a class="reference external" href="http://msgpack.org/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;Msgpack&lt;/a&gt;.&lt;/p&gt;
&lt;p style="margin:0 0.5em 1em 0.5em; font-size:90%"&gt;You should draw your own conclusions by running the &lt;a class="reference external" href="https://gist.github.com/ionelmc/1521c5a87df8cf49a23d" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;test code&lt;/a&gt; yourself.&lt;/p&gt;
&lt;p style="margin:0 0.5em 1em 0.5em; font-size:90%"&gt;⸻&lt;/p&gt;
&lt;p style="margin:0 0.5em 1em 0.5em; font-size:90%"&gt;Based on various feedback &lt;a class="footnote-reference" href="https://blog.ionelmc.ro/2015/11/22/memory-use-and-speed-of-json-parsers/#id16" id="id1" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:12px; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; vertical-align:top' valign="top"&gt;[*]&lt;/a&gt; I've did the benchmarks again, using &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;ru_maxrss …&lt;/tt&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;</summary><content type="html">&lt;div class="document" style='font:19px/29px "Palatino Linotype", "Book Antiqua", "FPL Neu", "TeX Gyre Pagella", "URW Palladio L", "Palatino", "Century Schoolbook L", "Georgia", serif; margin:0; padding:0'&gt;&lt;div class="admonition note" style="border:1px solid #DDD; border-radius:5px; box-shadow:0 1px 5px #EEE; margin:3ex 1ex 1ex 1ex; padding:0; background:white; float:right; width:200px" width="200"&gt;
&lt;p class="first admonition-title" style="margin:0; font-size:90%; border:none; border-radius:5px; box-shadow:0 1px 5px #EEE; padding:0; background:#F5F5F0; border-bottom:1px solid #DDD; font-style:italic; text-align:center" align="center"&gt;Note&lt;/p&gt;
&lt;p style="margin:0 0.5em 1em 0.5em; font-size:90%"&gt;TL;DR: In decode oriented use-case with big payloads JSON decoders often use disproportionate amounts of memory. I
gave up on JSON and switched to &lt;a class="reference external" href="http://msgpack.org/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;Msgpack&lt;/a&gt;.&lt;/p&gt;
&lt;p style="margin:0 0.5em 1em 0.5em; font-size:90%"&gt;You should draw your own conclusions by running the &lt;a class="reference external" href="https://gist.github.com/ionelmc/1521c5a87df8cf49a23d" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;test code&lt;/a&gt; yourself.&lt;/p&gt;
&lt;p style="margin:0 0.5em 1em 0.5em; font-size:90%"&gt;⸻&lt;/p&gt;
&lt;p style="margin:0 0.5em 1em 0.5em; font-size:90%"&gt;Based on various feedback &lt;a class="footnote-reference" href="https://blog.ionelmc.ro/2015/11/22/memory-use-and-speed-of-json-parsers/#id16" id="id1" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:12px; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; vertical-align:top' valign="top"&gt;[*]&lt;/a&gt; I've did the benchmarks again, using &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;ru_maxrss&lt;/tt&gt; instead of &lt;a class="reference external" href="http://valgrind.org/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;Valgrind&lt;/a&gt; and with few more implementations.&lt;/p&gt;
&lt;p style="margin:0 0.5em 1em 0.5em; font-size:90%"&gt;&lt;span class="target" id="updated-results"&gt;Updated results:&lt;a class="headerlink" href="https://blog.ionelmc.ro/2015/11/22/memory-use-and-speed-of-json-parsers/#updated-results" id="updated-results" title="Permalink to this target" style="color:#c60f0f; outline-color:#FFF; outline-offset:10px; background:transparent; padding:0 4px 0 4px; text-decoration:none; text-shadow:none; vertical-align:middle; visibility:hidden" valign="middle"&gt;
*&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul class="popover last simple" style="margin:25px 0 25px 0"&gt;
&lt;li style="padding:0"&gt;&lt;a class="reference external" href="https://blog.ionelmc.ro/2015/11/22/memory-use-and-speed-of-json-parsers/fatstring.html" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;my data&lt;/a&gt; (240Mb)&lt;/li&gt;
&lt;li style="padding:0"&gt;&lt;a class="reference external" href="https://blog.ionelmc.ro/2015/11/22/memory-use-and-speed-of-json-parsers/citylots.html" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;citylots.json&lt;/a&gt; (189MB)&lt;/li&gt;
&lt;li style="padding:0"&gt;&lt;a class="reference external" href="https://blog.ionelmc.ro/2015/11/22/memory-use-and-speed-of-json-parsers/canada.html" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;canada.json&lt;/a&gt; (2.2Mb)&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p style="margin:25px 0 25px 0"&gt;I have a peculiar use-case where I need to move around big chunks of data (some client connects to some HTTP API and
gets some data). For whatever reason &lt;a class="footnote-reference" href="https://blog.ionelmc.ro/2015/11/22/memory-use-and-speed-of-json-parsers/#id10" id="id2" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:12px; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; vertical-align:top' valign="top"&gt;[1]&lt;/a&gt;, JSON was chosen as the transport format. And one day that big chunk became
very big - around few hundred megabytes. And it turned out that processes doing the JSON decoding were using lots of
RAM - 4.4GB for a mere 240MB JSON payload? Insane. &lt;a class="footnote-reference" href="https://blog.ionelmc.ro/2015/11/22/memory-use-and-speed-of-json-parsers/#id11" id="id3" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:12px; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; vertical-align:top' valign="top"&gt;[2]&lt;/a&gt;&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;I was using the builtin json library, and the first thing I thought - "there must be a better JSON parser".
So I've started measuring ...&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Now measuring memory usage is a tricky thing, you can look at &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;ps&lt;/tt&gt; or look around in &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;&lt;span class="pre"&gt;/proc/&amp;lt;pid&amp;gt;&lt;/span&gt;&lt;/tt&gt; but you'd get
very coarse snapshots and would be very hard to find out the real peak usage. Luckily enough &lt;a class="reference external" href="http://valgrind.org/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;Valgrind&lt;/a&gt; can instrument
any program to track allocations (as opposed to recompiling everything to use a custom memory allocator) and it has a
really nice tool called &lt;a class="reference external" href="http://valgrind.org/docs/manual/ms-manual.html" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;massif&lt;/a&gt;.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;So I've started building a &lt;a class="reference external" href="https://gist.github.com/ionelmc/1521c5a87df8cf49a23d#file-memory-py" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;little benchmark&lt;/a&gt;
using &lt;a class="reference external" href="http://valgrind.org/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;Valgrind&lt;/a&gt;. My input looks like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:1px solid #DDD; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 3px #EFEFEF' bgcolor="#FFFDFD"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2" style="color:#d14"&gt;"foo"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
        &lt;span class="s2" style="color:#d14"&gt;"bar"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="s1" style="color:#d14"&gt;'A"&lt;/span&gt;&lt;span class="se" style="color:#d14"&gt;\\&lt;/span&gt;&lt;span class="s1" style="color:#d14"&gt; :,;&lt;/span&gt;&lt;span class="se" style="color:#d14"&gt;\n&lt;/span&gt;&lt;span class="s1" style="color:#d14"&gt;1'&lt;/span&gt; &lt;span class="o" style="font-weight:bold"&gt;*&lt;/span&gt; &lt;span class="mi" style="color:#099"&gt;20000000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s2" style="color:#d14"&gt;"b"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="mi" style="color:#099"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf" style="color:#099"&gt;0.333&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp" style="color:#999"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s2" style="color:#d14"&gt;"c"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp" style="color:#999"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p style="margin:25px 0 25px 0"&gt;That generates a 240MB JSON with a structure pretty close to my app's problematic data.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Running &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;valgrind &lt;span class="pre"&gt;--tool=massif&lt;/span&gt; &lt;span class="pre"&gt;--pages-as-heap=yes&lt;/span&gt; &lt;span class="pre"&gt;--heap=yes&lt;/span&gt; &lt;span class="pre"&gt;--threshold=0&lt;/span&gt; &lt;span class="pre"&gt;--peak-inaccuracy=0&lt;/span&gt; &lt;span class="pre"&gt;--max-snapshots=1000&lt;/span&gt;
...&lt;/tt&gt; for each parser gets me something like this on Python 2.7 (scroll down for results on Python 3.5):&lt;/p&gt;
&lt;pre class="code term literal-block" style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:none; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 6px #888; background:#000; background-image:radial-gradient(ellipse farthest-corner at center, #000 0%, #191919 100%); color:#aaa' bgcolor="#FFFDFD"&gt;
Peak memory usage (Python 2.7):

           cjson:   485.4 Mb
       rapidjson:   670.5 Mb
            yajl: 1,199.2 Mb
           ujson: 1,862.0 Mb
        jsonlib2: 2,882.7 Mb
         jsonlib: 2,884.2 Mb
      simplejson: 2,953.6 Mb
            json: 4,397.9 Mb
&lt;/pre&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Would you look at that. Now you can argue that my sample data is crazy but sadly, but that's just how my data looks
sometimes. Few of the strings blow up to horrid proportions once in a while.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;&lt;a class="reference external" href="https://docs.python.org/3/library/json.html" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;json&lt;/a&gt; has a severe weakness here, it needs a dozen more times memory than the input. WAT.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;&lt;a class="reference external" href="https://pypi.python.org/pypi/python-cjson" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;cjson&lt;/a&gt; is right there in my face, begging me to use it. There are some rumours that it has &lt;em&gt;VeryBadBugs™&lt;/em&gt; &lt;a class="footnote-reference" href="https://blog.ionelmc.ro/2015/11/22/memory-use-and-speed-of-json-parsers/#id15" id="id4" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:12px; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; vertical-align:top' valign="top"&gt;[6]&lt;/a&gt; but
I think the lack of a bug tracker is what makes that project ultimately unappealing.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;&lt;a class="reference external" href="https://pypi.python.org/pypi?%3Aaction=search&amp;amp;term=rapidjson&amp;amp;submit=search" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;rapidjson&lt;/a&gt; seems to be a new player &lt;a class="footnote-reference" href="https://blog.ionelmc.ro/2015/11/22/memory-use-and-speed-of-json-parsers/#id12" id="id5" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:12px; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; vertical-align:top' valign="top"&gt;[3]&lt;/a&gt;, however the &lt;a class="reference external" href="https://github.com/hhatto/pyrapidjson" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;Python 2 binding&lt;/a&gt; seems to have some
&lt;a class="reference external" href="https://github.com/hhatto/pyrapidjson/blob/4f7b8f2f7e45a9cff9b7c2671dd7233ff52b8487/pyrapidjson/_pyrapidjson.cpp#L333-L336" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;gaps&lt;/a&gt;
&lt;a class="reference external" href="https://github.com/hhatto/pyrapidjson/blob/4f7b8f2f7e45a9cff9b7c2671dd7233ff52b8487/pyrapidjson/_pyrapidjson.cpp#L374-L376" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;in&lt;/a&gt;
&lt;a class="reference external" href="https://github.com/hhatto/pyrapidjson/blob/4f7b8f2f7e45a9cff9b7c2671dd7233ff52b8487/pyrapidjson/_pyrapidjson.cpp#L144" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;essential&lt;/a&gt;
&lt;a class="reference external" href="https://github.com/hhatto/pyrapidjson/blob/4f7b8f2f7e45a9cff9b7c2671dd7233ff52b8487/pyrapidjson/_pyrapidjson.cpp#L187" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;parts&lt;/a&gt;.
Still, it's interesting to at least get an idea of how it performs. The &lt;a class="reference external" href="https://github.com/kenrobbins/python-rapidjson" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;Python 3-only binding&lt;/a&gt; looks more mature, but sadly this app only run on Python 2 right now.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;&lt;a class="reference external" href="https://pypi.python.org/pypi/yajl" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;yajl&lt;/a&gt; and &lt;a class="reference external" href="https://pypi.python.org/pypi/ujson" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;ujson&lt;/a&gt; appear to be mature enough but they simply still use lots of memory. There must be a better way ...&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;It looks like whatever I choose it's bad. There's a very good proverb &lt;a class="footnote-reference" href="https://blog.ionelmc.ro/2015/11/22/memory-use-and-speed-of-json-parsers/#id17" id="id6" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:12px; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; vertical-align:top' valign="top"&gt;[†]&lt;/a&gt; that applies here:&lt;/p&gt;
&lt;blockquote class="highlights" style='border-left:0; margin-left:0; padding:1ex 0 1ex 1em; quotes:"“" "”" "‘" "’"; color:#444; font-size:135%; font-style:italic; font-weight:bold; line-height:1.2; padding-left:0; text-align:center' align="center"&gt;
Best solution to problem is not having the problem in the first place.&lt;/blockquote&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Remember that time a customer asked for &lt;em&gt;a thing&lt;/em&gt; but in fact he only needed something simpler and less costly. Talking
through requirements and refining them solves lots of problems right there. This is that kind of situation. I wish I had
realized I don't really need JSON at all sooner ...&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;I have to do more changes to switch the format of the HTTP API but that can't be worse than maintaining/fixing the
&lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;cjson&lt;/tt&gt; or &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;rapidjson&lt;/tt&gt; bindings myself.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;If we try &lt;a class="reference external" href="http://msgpack.org/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;msgpack&lt;/a&gt; (and some &lt;em&gt;old friends&lt;/em&gt; &lt;a class="footnote-reference" href="https://blog.ionelmc.ro/2015/11/22/memory-use-and-speed-of-json-parsers/#id18" id="id7" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:12px; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; vertical-align:top' valign="top"&gt;[‡]&lt;/a&gt;, just for kicks) we get this:&lt;/p&gt;
&lt;pre class="code term literal-block" style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:none; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 6px #888; background:#000; background-image:radial-gradient(ellipse farthest-corner at center, #000 0%, #191919 100%); color:#aaa' bgcolor="#FFFDFD"&gt;
Peak memory usage (Python 2):

          pickle:   368.9 Mb
         marshal:   368.9 Mb
         msgpack:   373.2 Mb
           cjson:   485.4 Mb
       rapidjson:   670.4 Mb
            yajl: 1,199.2 Mb
           ujson: 1,862.0 Mb
        jsonlib2: 2,882.7 Mb
         jsonlib: 2,884.2 Mb
      simplejson: 2,953.6 Mb
            json: 4,397.9 Mb
&lt;/pre&gt;
&lt;p style="margin:25px 0 25px 0"&gt;If you look at the &lt;a class="reference external" href="https://gist.github.com/ionelmc/1521c5a87df8cf49a23d" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;test code&lt;/a&gt; you'll notice that I use msgpack with very specific options. Because the initial version
of &lt;a class="reference external" href="http://msgpack.org/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;Msgpack&lt;/a&gt; wasn't very smart about strings (it had a single string type &lt;a class="footnote-reference" href="https://blog.ionelmc.ro/2015/11/22/memory-use-and-speed-of-json-parsers/#id14" id="id8" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:12px; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; vertical-align:top' valign="top"&gt;[5]&lt;/a&gt;) some specific
options are needed:&lt;/p&gt;
&lt;ul style="margin:25px 0 25px 0"&gt;
&lt;li style="padding:0"&gt;&lt;p class="first" style="margin:25px 0 25px 0"&gt;&lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;msgpack.dumps(obj, use_bin_type=True)&lt;/tt&gt; - use a different type for byte-strings. By default &lt;a class="reference external" href="http://msgpack.org/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;Msgpack&lt;/a&gt; will lump all
kinds of strings into same type and you can't tell what the original type was.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;On Python 2:&lt;/p&gt;
&lt;ul class="simple" style="margin:10px 0; padding:0 0 0 40px"&gt;
&lt;li style="padding:0"&gt;&lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;str&lt;/tt&gt; goes into the &lt;em&gt;bin&lt;/em&gt; type&lt;/li&gt;
&lt;li style="padding:0"&gt;&lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;unicode&lt;/tt&gt; goes into the &lt;em&gt;string&lt;/em&gt; type&lt;/li&gt;
&lt;/ul&gt;
&lt;p style="margin:25px 0 25px 0"&gt;On Python 3:&lt;/p&gt;
&lt;ul class="simple" style="margin:10px 0; padding:0 0 0 40px"&gt;
&lt;li style="padding:0"&gt;&lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;bytes&lt;/tt&gt; goes into the &lt;em&gt;bin&lt;/em&gt; type&lt;/li&gt;
&lt;li style="padding:0"&gt;&lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;str&lt;/tt&gt; goes into the &lt;em&gt;string&lt;/em&gt; type&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li style="padding:0"&gt;&lt;p class="first" style="margin:25px 0 25px 0"&gt;&lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;msgpack.loads(payload, &lt;span class="pre"&gt;encoding='utf8')&lt;/span&gt;&lt;/tt&gt; - decode the strings (so you get &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;unicode&lt;/tt&gt; back).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="section" id="what-about-speed"&gt;
&lt;h2 style='font-family:"Candara", "Merriweather Sans", "Trebuchet Ms", "Segoe UI", sans-serif; text-shadow:1px 1px 1px #DDD; color:#333; font-weight:bold; line-height:1; font-size:2em'&gt;What about speed?&lt;a class="headerlink" href="https://blog.ionelmc.ro/2015/11/22/memory-use-and-speed-of-json-parsers/#what-about-speed" title="Permalink to this headline" style="color:#c60f0f; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; padding:0 4px 0 4px; vertical-align:middle; visibility:hidden" valign="middle"&gt;
*&lt;/a&gt;&lt;/h2&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Using &lt;a class="reference external" href="https://github.com/ionelmc/pytest-benchmark" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;pytest-benchmark&lt;/a&gt; we get this &lt;a class="footnote-reference" href="https://blog.ionelmc.ro/2015/11/22/memory-use-and-speed-of-json-parsers/#id14" id="id9" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:12px; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; vertical-align:top' valign="top"&gt;[5]&lt;/a&gt;:&lt;/p&gt;
&lt;pre class="term" style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:none; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 6px #888; background:#000; background-image:radial-gradient(ellipse farthest-corner at center, #000 0%, #191919 100%); color:#aaa' bgcolor="#FFFDFD"&gt;
Speed (Python 2.7):

    &lt;span class="ansi33" style="color:#adad27"&gt;-----------------------------------------------&lt;/span&gt;
    Name (time in ms)              Min
    &lt;span class="ansi33" style="color:#adad27"&gt;-----------------------------------------------&lt;/span&gt;
    test_speed[marshal]      &lt;span class="ansi1 ansi32" style="font-weight:bold; color:#25bc24"&gt;     59.2630 (1.0)    &lt;/span&gt;
    test_speed[pickle]       &lt;span class="ansi1" style="font-weight:bold"&gt;     59.4530 (1.00)   &lt;/span&gt;
    test_speed[msgpack]      &lt;span class="ansi1" style="font-weight:bold"&gt;     59.7100 (1.01)   &lt;/span&gt;
    test_speed[rapidjson]    &lt;span class="ansi1" style="font-weight:bold"&gt;    443.0561 (7.48)   &lt;/span&gt;
    test_speed[cjson]        &lt;span class="ansi1" style="font-weight:bold"&gt;    676.6071 (11.42)  &lt;/span&gt;
    test_speed[ujson]        &lt;span class="ansi1" style="font-weight:bold"&gt;    681.8101 (11.50)  &lt;/span&gt;
    test_speed[yajl]         &lt;span class="ansi1" style="font-weight:bold"&gt;  1,590.4601 (26.84)  &lt;/span&gt;
    test_speed[jsonlib]      &lt;span class="ansi1" style="font-weight:bold"&gt;  1,873.3799 (31.61)  &lt;/span&gt;
    test_speed[jsonlib2]     &lt;span class="ansi1" style="font-weight:bold"&gt;  2,006.7949 (33.86)  &lt;/span&gt;
    test_speed[simplejson]   &lt;span class="ansi1" style="font-weight:bold"&gt;  3,592.2401 (60.62)  &lt;/span&gt;
    test_speed[json]         &lt;span class="ansi1 ansi31" style="font-weight:bold; color:#c23621"&gt;  5,193.2762 (87.63)  &lt;/span&gt;
    &lt;span class="ansi33" style="color:#adad27"&gt;-----------------------------------------------&lt;/span&gt;
&lt;/pre&gt;&lt;p style="margin:25px 0 25px 0"&gt;Only the minimum time is shown. This is intentional - run the &lt;a class="reference external" href="https://gist.github.com/ionelmc/1521c5a87df8cf49a23d" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;test code&lt;/a&gt; on &lt;cite&gt;your own hardware&lt;/cite&gt; if you care about
anything else.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="python-3"&gt;
&lt;h2 style='font-family:"Candara", "Merriweather Sans", "Trebuchet Ms", "Segoe UI", sans-serif; text-shadow:1px 1px 1px #DDD; color:#333; font-weight:bold; line-height:1; font-size:2em'&gt;Python 3&lt;a class="headerlink" href="https://blog.ionelmc.ro/2015/11/22/memory-use-and-speed-of-json-parsers/#python-3" title="Permalink to this headline" style="color:#c60f0f; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; padding:0 4px 0 4px; vertical-align:middle; visibility:hidden" valign="middle"&gt;
*&lt;/a&gt;&lt;/h2&gt;
&lt;p style="margin:25px 0 25px 0"&gt;This app where I had the issue runs only on Python 2 for a very good (and also sad) reason. But no reason to dig myself
further into a hole - gotta see how this performs on the latest and greatest. It will get ported one day ...&lt;/p&gt;
&lt;pre class="term" style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:none; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 6px #888; background:#000; background-image:radial-gradient(ellipse farthest-corner at center, #000 0%, #191919 100%); color:#aaa' bgcolor="#FFFDFD"&gt;
Peak memory usage (Python 3.5):

         marshal:   372.1 Mb
          pickle:   372.9 Mb
         msgpack:   376.6 Mb
       rapidjson:   668.6 Mb
            yajl:   687.3 Mb
           ujson: 1,578.9 Mb
            json: 3,422.3 Mb
      simplejson: 6,681.4 Mb

Speed (Python 3.5)

    &lt;span class="ansi33" style="color:#adad27"&gt;-----------------------------------------------&lt;/span&gt;
    Name (time in ms)              Min
    &lt;span class="ansi33" style="color:#adad27"&gt;-----------------------------------------------&lt;/span&gt;
    test_speed[msgpack]      &lt;span class="ansi1 ansi32" style="font-weight:bold; color:#25bc24"&gt;     69.0613 (1.0)    &lt;/span&gt;
    test_speed[pickle]       &lt;span class="ansi1" style="font-weight:bold"&gt;     69.9465 (1.01)   &lt;/span&gt;
    test_speed[marshal]      &lt;span class="ansi1" style="font-weight:bold"&gt;     74.9914 (1.09)   &lt;/span&gt;
    test_speed[rapidjson]    &lt;span class="ansi1" style="font-weight:bold"&gt;    337.5243 (4.89)   &lt;/span&gt;
    test_speed[ujson]        &lt;span class="ansi1" style="font-weight:bold"&gt;    902.8647 (13.07)  &lt;/span&gt;
    test_speed[yajl]         &lt;span class="ansi1" style="font-weight:bold"&gt;  1,195.4298 (17.31)  &lt;/span&gt;
    test_speed[json]         &lt;span class="ansi1" style="font-weight:bold"&gt;  4,404.9523 (63.78)  &lt;/span&gt;
    test_speed[simplejson]   &lt;span class="ansi1 ansi31" style="font-weight:bold; color:#c23621"&gt;  6,524.9919 (94.48)  &lt;/span&gt;
    &lt;span class="ansi33" style="color:#adad27"&gt;-----------------------------------------------&lt;/span&gt;
&lt;/pre&gt;&lt;p style="margin:25px 0 25px 0"&gt;No &lt;a class="reference external" href="https://pypi.python.org/pypi/python-cjson" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;cjson&lt;/a&gt; or &lt;a class="reference external" href="https://pypi.python.org/pypi/jsonlib" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;jsonlib&lt;/a&gt; on Python 3. I don't even know what's the story behind &lt;a class="reference external" href="https://pypi.python.org/pypi/jsonlib2" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;jsonlib2&lt;/a&gt;. Looks like &lt;a class="reference external" href="http://msgpack.org/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;Msgpack&lt;/a&gt; is a safe
bet here.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="different-kind-of-data"&gt;
&lt;h2 style='font-family:"Candara", "Merriweather Sans", "Trebuchet Ms", "Segoe UI", sans-serif; text-shadow:1px 1px 1px #DDD; color:#333; font-weight:bold; line-height:1; font-size:2em'&gt;Different kind of data&lt;a class="headerlink" href="https://blog.ionelmc.ro/2015/11/22/memory-use-and-speed-of-json-parsers/#different-kind-of-data" title="Permalink to this headline" style="color:#c60f0f; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; padding:0 4px 0 4px; vertical-align:middle; visibility:hidden" valign="middle"&gt;
*&lt;/a&gt;&lt;/h2&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Now this is highly skewed towards some might call a completely atypical data shape. So I advise you take the &lt;a class="reference external" href="https://gist.github.com/ionelmc/1521c5a87df8cf49a23d" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;test code&lt;/a&gt;
and run the benchmarks with your own data.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;But if you're lazy here are some results with different kinds of data, just to get an idea of how much the input can
change memory use and speed.&lt;/p&gt;
&lt;div class="section" id="lots-off-small-objects"&gt;
&lt;h3 style='font-family:"Candara", "Merriweather Sans", "Trebuchet Ms", "Segoe UI", sans-serif; text-shadow:1px 1px 1px #DDD; color:#333; font-weight:bold; line-height:1; font-size:1.56em'&gt;Lots off small objects&lt;a class="headerlink" href="https://blog.ionelmc.ro/2015/11/22/memory-use-and-speed-of-json-parsers/#lots-off-small-objects" title="Permalink to this headline" style="color:#c60f0f; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; padding:0 4px 0 4px; vertical-align:middle; visibility:hidden" valign="middle"&gt;
*&lt;/a&gt;&lt;/h3&gt;
&lt;p style="margin:25px 0 25px 0"&gt;The 189MB &lt;a class="reference external" href="https://github.com/zemirco/sf-city-lots-json/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;citylots.json&lt;/a&gt; gets us wildly different results.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;It appears &lt;a class="reference external" href="https://pypi.python.org/pypi/simplejson" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;simplejson&lt;/a&gt; works way better on small objects, and &lt;a class="reference external" href="https://docs.python.org/3/library/json.html" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;json&lt;/a&gt; is quite improved on Python 3:&lt;/p&gt;
&lt;pre class="code term literal-block" style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:none; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 6px #888; background:#000; background-image:radial-gradient(ellipse farthest-corner at center, #000 0%, #191919 100%); color:#aaa' bgcolor="#FFFDFD"&gt;
Peak memory usage (Python 2.7):

      simplejson: 1,171.7 Mb
           cjson: 1,304.2 Mb
         msgpack: 1,357.2 Mb
         marshal: 1,385.2 Mb
            yajl: 1,457.1 Mb
            json: 1,468.0 Mb
       rapidjson: 1,561.6 Mb
          pickle: 1,854.1 Mb
        jsonlib2: 2,134.9 Mb
         jsonlib: 2,137.0 Mb
           ujson: 2,149.9 Mb

Peak memory usage (Python 3.5):

         marshal:   951.0 Mb
            json: 1,059.8 Mb
      simplejson: 1,063.6 Mb
          pickle: 1,098.4 Mb
         msgpack: 1,115.9 Mb
            yajl: 1,226.6 Mb
       rapidjson: 1,404.9 Mb
           ujson: 2,077.6 Mb
&lt;/pre&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Speed:&lt;/p&gt;
&lt;pre class="term" style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:none; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 6px #888; background:#000; background-image:radial-gradient(ellipse farthest-corner at center, #000 0%, #191919 100%); color:#aaa' bgcolor="#FFFDFD"&gt;
Speed (Python 2.7):

    &lt;span class="ansi33" style="color:#adad27"&gt;-----------------------------------------------&lt;/span&gt;
    Name (time in ms)              Min
    &lt;span class="ansi33" style="color:#adad27"&gt;-----------------------------------------------&lt;/span&gt;
    test_speed[marshal]      &lt;span class="ansi1 ansi32" style="font-weight:bold; color:#25bc24"&gt;   3.9999 (1.0)    &lt;/span&gt;
    test_speed[ujson]        &lt;span class="ansi1" style="font-weight:bold"&gt;   4.2569 (1.06)   &lt;/span&gt;
    test_speed[simplejson]   &lt;span class="ansi1" style="font-weight:bold"&gt;   5.1105 (1.28)   &lt;/span&gt;
    test_speed[cjson]        &lt;span class="ansi1" style="font-weight:bold"&gt;   5.2355 (1.31)   &lt;/span&gt;
    test_speed[msgpack]      &lt;span class="ansi1" style="font-weight:bold"&gt;   5.9742 (1.49)   &lt;/span&gt;
    test_speed[yajl]         &lt;span class="ansi1" style="font-weight:bold"&gt;   6.1059 (1.53)   &lt;/span&gt;
    test_speed[json]         &lt;span class="ansi1" style="font-weight:bold"&gt;   6.3822 (1.60)   &lt;/span&gt;
    test_speed[jsonlib2]     &lt;span class="ansi1" style="font-weight:bold"&gt;   6.7880 (1.70)   &lt;/span&gt;
    test_speed[jsonlib]      &lt;span class="ansi1" style="font-weight:bold"&gt;   6.9587 (1.74)   &lt;/span&gt;
    test_speed[rapidjson]    &lt;span class="ansi1" style="font-weight:bold"&gt;   7.4734 (1.87)   &lt;/span&gt;
    test_speed[pickle]       &lt;span class="ansi1 ansi31" style="font-weight:bold; color:#c23621"&gt;  18.8649 (4.72)   &lt;/span&gt;
    &lt;span class="ansi33" style="color:#adad27"&gt;-----------------------------------------------&lt;/span&gt;

Speed (Python 3.5):

    &lt;span class="ansi33" style="color:#adad27"&gt;-----------------------------------------------&lt;/span&gt;
    Name (time in ms)              Min
    &lt;span class="ansi33" style="color:#adad27"&gt;-----------------------------------------------&lt;/span&gt;
    test_speed[marshal]      &lt;span class="ansi1 ansi32" style="font-weight:bold; color:#25bc24"&gt;  1.1784 (1.0)    &lt;/span&gt;
    test_speed[ujson]        &lt;span class="ansi1" style="font-weight:bold"&gt;  3.6378 (3.09)   &lt;/span&gt;
    test_speed[msgpack]      &lt;span class="ansi1" style="font-weight:bold"&gt;  3.7226 (3.16)   &lt;/span&gt;
    test_speed[pickle]       &lt;span class="ansi1" style="font-weight:bold"&gt;  3.7739 (3.20)   &lt;/span&gt;
    test_speed[rapidjson]    &lt;span class="ansi1" style="font-weight:bold"&gt;  4.1379 (3.51)   &lt;/span&gt;
    test_speed[json]         &lt;span class="ansi1" style="font-weight:bold"&gt;  5.1150 (4.34)   &lt;/span&gt;
    test_speed[simplejson]   &lt;span class="ansi1" style="font-weight:bold"&gt;  5.1530 (4.37)   &lt;/span&gt;
    test_speed[yajl]         &lt;span class="ansi1 ansi31" style="font-weight:bold; color:#c23621"&gt;  5.9426 (5.04)   &lt;/span&gt;
    &lt;span class="ansi33" style="color:#adad27"&gt;-----------------------------------------------&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;div class="section" id="smaller-data"&gt;
&lt;h3 style='font-family:"Candara", "Merriweather Sans", "Trebuchet Ms", "Segoe UI", sans-serif; text-shadow:1px 1px 1px #DDD; color:#333; font-weight:bold; line-height:1; font-size:1.56em'&gt;Smaller data&lt;a class="headerlink" href="https://blog.ionelmc.ro/2015/11/22/memory-use-and-speed-of-json-parsers/#smaller-data" title="Permalink to this headline" style="color:#c60f0f; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; padding:0 4px 0 4px; vertical-align:middle; visibility:hidden" valign="middle"&gt;
*&lt;/a&gt;&lt;/h3&gt;
&lt;p style="margin:25px 0 25px 0"&gt;The tiny 2.2MB &lt;a class="reference external" href="https://github.com/miloyip/nativejson-benchmark/tree/master/data" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;canada.json&lt;/a&gt;, again, gives us very
different results. Memory use becomes irrelevant:&lt;/p&gt;
&lt;pre class="code term literal-block" style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:none; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 6px #888; background:#000; background-image:radial-gradient(ellipse farthest-corner at center, #000 0%, #191919 100%); color:#aaa' bgcolor="#FFFDFD"&gt;
Peak memory usage (Python 2.7):

         marshal:    35.2 Mb
           cjson:    38.9 Mb
            yajl:    39.0 Mb
            json:    39.3 Mb
         msgpack:    39.5 Mb
      simplejson:    40.5 Mb
          pickle:    42.1 Mb
        jsonlib2:    47.4 Mb
       rapidjson:    48.5 Mb
         jsonlib:    48.8 Mb
           ujson:    50.9 Mb

Peak memory usage (Python 3.5):

         marshal:    38.3 Mb
          pickle:    40.4 Mb
            yajl:    42.1 Mb
            json:    42.2 Mb
         msgpack:    42.7 Mb
      simplejson:    45.3 Mb
       rapidjson:    52.3 Mb
           ujson:    55.5 Mb
&lt;/pre&gt;
&lt;p style="margin:25px 0 25px 0"&gt;And speed is again different:&lt;/p&gt;
&lt;pre class="term" style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:none; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 6px #888; background:#000; background-image:radial-gradient(ellipse farthest-corner at center, #000 0%, #191919 100%); color:#aaa' bgcolor="#FFFDFD"&gt;
Speed (Python 2.7):

    &lt;span class="ansi33" style="color:#adad27"&gt;-----------------------------------------------&lt;/span&gt;
    Name (time in ms)              Min
    &lt;span class="ansi33" style="color:#adad27"&gt;-----------------------------------------------&lt;/span&gt;
    test_speed[msgpack]      &lt;span class="ansi1 ansi32" style="font-weight:bold; color:#25bc24"&gt;   12.3210 (1.0)    &lt;/span&gt;
    test_speed[marshal]      &lt;span class="ansi1" style="font-weight:bold"&gt;   15.1060 (1.23)   &lt;/span&gt;
    test_speed[ujson]        &lt;span class="ansi1" style="font-weight:bold"&gt;   19.8410 (1.61)   &lt;/span&gt;
    test_speed[json]         &lt;span class="ansi1" style="font-weight:bold"&gt;   48.0320 (3.90)   &lt;/span&gt;
    test_speed[cjson]        &lt;span class="ansi1" style="font-weight:bold"&gt;   48.6560 (3.95)   &lt;/span&gt;
    test_speed[simplejson]   &lt;span class="ansi1" style="font-weight:bold"&gt;   52.0709 (4.23)   &lt;/span&gt;
    test_speed[yajl]         &lt;span class="ansi1" style="font-weight:bold"&gt;   62.1090 (5.04)   &lt;/span&gt;
    test_speed[jsonlib2]     &lt;span class="ansi1" style="font-weight:bold"&gt;   81.6209 (6.62)   &lt;/span&gt;
    test_speed[jsonlib]      &lt;span class="ansi1" style="font-weight:bold"&gt;   83.2670 (6.76)   &lt;/span&gt;
    test_speed[rapidjson]    &lt;span class="ansi1" style="font-weight:bold"&gt;  102.3500 (8.31)   &lt;/span&gt;
    test_speed[pickle]       &lt;span class="ansi1 ansi31" style="font-weight:bold; color:#c23621"&gt;  258.6429 (20.99)  &lt;/span&gt;
    &lt;span class="ansi33" style="color:#adad27"&gt;-----------------------------------------------&lt;/span&gt;

Speed (Python 3.5):

    &lt;span class="ansi33" style="color:#adad27"&gt;-----------------------------------------------&lt;/span&gt;
    Name (time in ms)              Min
    &lt;span class="ansi33" style="color:#adad27"&gt;-----------------------------------------------&lt;/span&gt;
    test_speed[marshal]      &lt;span class="ansi1 ansi32" style="font-weight:bold; color:#25bc24"&gt;  10.0271 (1.0)    &lt;/span&gt;
    test_speed[msgpack]      &lt;span class="ansi1" style="font-weight:bold"&gt;  10.2731 (1.02)   &lt;/span&gt;
    test_speed[pickle]       &lt;span class="ansi1" style="font-weight:bold"&gt;  17.2853 (1.72)   &lt;/span&gt;
    test_speed[ujson]        &lt;span class="ansi1" style="font-weight:bold"&gt;  17.7634 (1.77)   &lt;/span&gt;
    test_speed[rapidjson]    &lt;span class="ansi1" style="font-weight:bold"&gt;  25.6136 (2.55)   &lt;/span&gt;
    test_speed[json]         &lt;span class="ansi1" style="font-weight:bold"&gt;  54.8634 (5.47)   &lt;/span&gt;
    test_speed[yajl]         &lt;span class="ansi1" style="font-weight:bold"&gt;  58.3519 (5.82)   &lt;/span&gt;
    test_speed[simplejson]   &lt;span class="ansi1 ansi31" style="font-weight:bold; color:#c23621"&gt;  65.0913 (6.49)   &lt;/span&gt;
    &lt;span class="ansi33" style="color:#adad27"&gt;-----------------------------------------------&lt;/span&gt;
&lt;/pre&gt;&lt;p style="margin:25px 0 25px 0"&gt;I suppose better use of &lt;a class="reference external" href="http://effbot.org/pyfaq/why-doesnt-python-release-the-memory-when-i-delete-a-large-object.htm" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;freelists&lt;/a&gt; happens here?&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="bottom-line"&gt;
&lt;h2 style='font-family:"Candara", "Merriweather Sans", "Trebuchet Ms", "Segoe UI", sans-serif; text-shadow:1px 1px 1px #DDD; color:#333; font-weight:bold; line-height:1; font-size:2em'&gt;Bottom line&lt;a class="headerlink" href="https://blog.ionelmc.ro/2015/11/22/memory-use-and-speed-of-json-parsers/#bottom-line" title="Permalink to this headline" style="color:#c60f0f; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; padding:0 4px 0 4px; vertical-align:middle; visibility:hidden" valign="middle"&gt;
*&lt;/a&gt;&lt;/h2&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Both speed and memory are affected by data shape. Speed is not always proportional to memory use.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Again, don't trust the numbers, run the benchmarks yourself, with your own data. Even if your data is identical in shape
your hardware might behave differently than mine. Even the memory use can be different on your machine (example:
different architecture, different shared libraries). And what's the chance your data has the exact shape as whatever
was used in the benchmark?&lt;/p&gt;
&lt;hr class="docutils" style="background:#FFFDFD; border:0; border-radius:2px; padding:0; background-color:#F6F6F6; box-shadow:inset 0 0 2px #CCC; clear:both; height:6px; margin:0 1px" bgcolor="#F6F6F6" height="6"&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Test setup:&lt;/p&gt;
&lt;ul class="simple" style="margin:25px 0 25px 0"&gt;
&lt;li style="padding:0"&gt;Ubuntu 14.04 (a VM on an &lt;em&gt;unoccupied&lt;/em&gt; host, at least in theory)&lt;/li&gt;
&lt;li style="padding:0"&gt;Sandy Bridge i7 (TurboBoost off, but frequency scaling was on)&lt;/li&gt;
&lt;li style="padding:0"&gt;Python 2.7.6&lt;/li&gt;
&lt;li style="padding:0"&gt;Python 3.5.0&lt;/li&gt;
&lt;li style="padding:0"&gt;Valgrind 3.11.0&lt;/li&gt;
&lt;/ul&gt;
&lt;p style="margin:25px 0 25px 0"&gt;As you can see the setup is less then perfect. If you really care you'd run the &lt;a class="reference external" href="https://gist.github.com/ionelmc/1521c5a87df8cf49a23d" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;test code&lt;/a&gt; yourself.&lt;/p&gt;
&lt;table class="docutils footnote" frame="void" id="id10" rules="none" style='margin:5px 0; box-shadow:none; background:transparent; border:none; border-collapse:separate; border-radius:5px; border-spacing:0; width:100%; font-family:Palatino, "Palatino Linotype", Georgia, serif; margin-bottom:8px' width="100%"&gt;
&lt;colgroup&gt;&lt;col class="label"&gt;&lt;col&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label" style='border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; border-left:1px solid #DDD; font-size:75%; background:transparent; text-decoration:none; text-shadow:none; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; width:5%; border-radius:0' width="5%"&gt;&lt;a class="fn-backref" href="https://blog.ionelmc.ro/2015/11/22/memory-use-and-speed-of-json-parsers/#id2" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:75%; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace'&gt;[1]&lt;/a&gt;&lt;/td&gt;&lt;td style="border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; font-size:15px; border-radius:0"&gt;I believe I've fallen victim to cargo-culting ...&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id11" rules="none" style='margin:5px 0; box-shadow:none; background:transparent; border:none; border-collapse:separate; border-radius:5px; border-spacing:0; width:100%; font-family:Palatino, "Palatino Linotype", Georgia, serif; margin-bottom:8px' width="100%"&gt;
&lt;colgroup&gt;&lt;col class="label"&gt;&lt;col&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label" style='border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; border-left:1px solid #DDD; font-size:75%; background:transparent; text-decoration:none; text-shadow:none; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; width:5%; border-radius:0' width="5%"&gt;&lt;a class="fn-backref" href="https://blog.ionelmc.ro/2015/11/22/memory-use-and-speed-of-json-parsers/#id3" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:75%; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace'&gt;[2]&lt;/a&gt;&lt;/td&gt;&lt;td style="border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; font-size:15px; border-radius:0"&gt;But not more insane than Linux doing it's memory overcommit thing and swapping everything. You can dismiss this as
an ignorant remark about the kernel but bottom line is the same: trashing the swap is very bad.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id12" rules="none" style='margin:5px 0; box-shadow:none; background:transparent; border:none; border-collapse:separate; border-radius:5px; border-spacing:0; width:100%; font-family:Palatino, "Palatino Linotype", Georgia, serif; margin-bottom:8px' width="100%"&gt;
&lt;colgroup&gt;&lt;col class="label"&gt;&lt;col&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label" style='border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; border-left:1px solid #DDD; font-size:75%; background:transparent; text-decoration:none; text-shadow:none; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; width:5%; border-radius:0' width="5%"&gt;&lt;a class="fn-backref" href="https://blog.ionelmc.ro/2015/11/22/memory-use-and-speed-of-json-parsers/#id5" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:75%; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace'&gt;[3]&lt;/a&gt;&lt;/td&gt;&lt;td style="border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; font-size:15px; border-radius:0"&gt;I've noticed &lt;strong&gt;rapidjson&lt;/strong&gt; in this &lt;a class="reference external" href="https://github.com/miloyip/nativejson-benchmark" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;C++ JSON library benchmark&lt;/a&gt;. It seems it was the only library with a working Python binding.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id13" rules="none" style='margin:5px 0; box-shadow:none; background:transparent; border:none; border-collapse:separate; border-radius:5px; border-spacing:0; width:100%; font-family:Palatino, "Palatino Linotype", Georgia, serif; margin-bottom:8px' width="100%"&gt;
&lt;colgroup&gt;&lt;col class="label"&gt;&lt;col&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label" style='border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; border-left:1px solid #DDD; font-size:75%; background:transparent; text-decoration:none; text-shadow:none; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; width:5%; border-radius:0' width="5%"&gt;[4]&lt;/td&gt;&lt;td style="border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; font-size:15px; border-radius:0"&gt;The fact that there are lots of languages you can use &lt;a class="reference external" href="http://msgpack.org/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;Msgpack&lt;/a&gt; on and they don't have an Unicode type doesn't help
either.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id14" rules="none" style='margin:5px 0; box-shadow:none; background:transparent; border:none; border-collapse:separate; border-radius:5px; border-spacing:0; width:100%; font-family:Palatino, "Palatino Linotype", Georgia, serif; margin-bottom:8px' width="100%"&gt;
&lt;colgroup&gt;&lt;col class="label"&gt;&lt;col&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label" style='border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; border-left:1px solid #DDD; font-size:75%; background:transparent; text-decoration:none; text-shadow:none; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; width:5%; border-radius:0' width="5%"&gt;[5]&lt;/td&gt;&lt;td style="border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; font-size:15px; border-radius:0"&gt;&lt;em&gt;(&lt;a class="fn-backref" href="https://blog.ionelmc.ro/2015/11/22/memory-use-and-speed-of-json-parsers/#id8" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;1&lt;/a&gt;, &lt;a class="fn-backref" href="https://blog.ionelmc.ro/2015/11/22/memory-use-and-speed-of-json-parsers/#id9" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;2&lt;/a&gt;)&lt;/em&gt; Generated with something like &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;script &lt;span class="pre"&gt;-c&lt;/span&gt; tox | ansi2html&lt;/tt&gt;.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id15" rules="none" style='margin:5px 0; box-shadow:none; background:transparent; border:none; border-collapse:separate; border-radius:5px; border-spacing:0; width:100%; font-family:Palatino, "Palatino Linotype", Georgia, serif; margin-bottom:8px' width="100%"&gt;
&lt;colgroup&gt;&lt;col class="label"&gt;&lt;col&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label" style='border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; border-left:1px solid #DDD; font-size:75%; background:transparent; text-decoration:none; text-shadow:none; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; width:5%; border-radius:0' width="5%"&gt;&lt;a class="fn-backref" href="https://blog.ionelmc.ro/2015/11/22/memory-use-and-speed-of-json-parsers/#id4" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:75%; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace'&gt;[6]&lt;/a&gt;&lt;/td&gt;&lt;td style="border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; font-size:15px; border-radius:0"&gt;&lt;p class="first" style="margin:0; margin-top:0"&gt;It seems that no one can really point out what's wrong with &lt;a class="reference external" href="https://pypi.python.org/pypi/python-cjson" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;cjson&lt;/a&gt;. The author of &lt;a class="reference external" href="https://pypi.python.org/pypi/jsonlib" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;jsonlib&lt;/a&gt; even did this &lt;a class="reference external" href="https://news.ycombinator.com/item?id=529104" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;FUD post&lt;/a&gt; and it seems people have been buying that bullshit. StackOverflow
is practically plastered with transcriptions of that.&lt;/p&gt;
&lt;p style="margin:0; margin-top:15px"&gt;He may be right, and there are actual issues with encoding and conformance in &lt;a class="reference external" href="https://pypi.python.org/pypi/python-cjson" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;cjson&lt;/a&gt;, but that ain't the right way
to explain it.&lt;/p&gt;
&lt;p class="last" style="margin:0; margin-top:15px"&gt;Also, kinda ironic that &lt;a class="reference external" href="https://pypi.python.org/pypi/jsonlib" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;jsonlib&lt;/a&gt; was abandoned one year later after that post ...&lt;/p&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id16" rules="none" style='margin:5px 0; box-shadow:none; background:transparent; border:none; border-collapse:separate; border-radius:5px; border-spacing:0; width:100%; font-family:Palatino, "Palatino Linotype", Georgia, serif; margin-bottom:8px' width="100%"&gt;
&lt;colgroup&gt;&lt;col class="label"&gt;&lt;col&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label" style='border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; border-left:1px solid #DDD; font-size:75%; background:transparent; text-decoration:none; text-shadow:none; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; width:5%; border-radius:0' width="5%"&gt;&lt;a class="fn-backref" href="https://blog.ionelmc.ro/2015/11/22/memory-use-and-speed-of-json-parsers/#id1" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:75%; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace'&gt;[*]&lt;/a&gt;&lt;/td&gt;&lt;td style="border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; font-size:15px; border-radius:0"&gt;Feedback from commenters here,
&lt;a class="reference external" href="https://www.reddit.com/r/Python/comments/3w2qcw/memory_use_and_speed_of_json_parsers/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;Reddit&lt;/a&gt;,
&lt;a class="reference external" href="https://news.ycombinator.com/item?id=10715012" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;HackerNews&lt;/a&gt; and
&lt;a class="reference external" href="https://plus.google.com/u/0/103495234945808025312/posts/fcfMBmApT2J" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;Google+&lt;/a&gt;.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id17" rules="none" style='margin:5px 0; box-shadow:none; background:transparent; border:none; border-collapse:separate; border-radius:5px; border-spacing:0; width:100%; font-family:Palatino, "Palatino Linotype", Georgia, serif; margin-bottom:8px' width="100%"&gt;
&lt;colgroup&gt;&lt;col class="label"&gt;&lt;col&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label" style='border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; border-left:1px solid #DDD; font-size:75%; background:transparent; text-decoration:none; text-shadow:none; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; width:5%; border-radius:0' width="5%"&gt;&lt;a class="fn-backref" href="https://blog.ionelmc.ro/2015/11/22/memory-use-and-speed-of-json-parsers/#id6" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:75%; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace'&gt;[†]&lt;/a&gt;&lt;/td&gt;&lt;td style="border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; font-size:15px; border-radius:0"&gt;Where did this idea originate from? If you got a source please comment.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id18" rules="none" style='margin:5px 0; box-shadow:none; background:transparent; border:none; border-collapse:separate; border-radius:5px; border-spacing:0; width:100%; font-family:Palatino, "Palatino Linotype", Georgia, serif; margin-bottom:8px' width="100%"&gt;
&lt;colgroup&gt;&lt;col class="label"&gt;&lt;col&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label" style='border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; border-left:1px solid #DDD; font-size:75%; background:transparent; text-decoration:none; text-shadow:none; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; width:5%; border-radius:0' width="5%"&gt;&lt;a class="fn-backref" href="https://blog.ionelmc.ro/2015/11/22/memory-use-and-speed-of-json-parsers/#id7" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:75%; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace'&gt;[‡]&lt;/a&gt;&lt;/td&gt;&lt;td style="border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; font-size:15px; border-radius:0"&gt;Not something that you would use in a HTTP API at all. Put security concerns aside, the problem is mixing
different versions of python. But they are still interesting to look at, for ideas of what's possible
performance-wise.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;img src="https://blog.ionelmc.ro/_/2015/11/22/memory-use-and-speed-of-json-parsers/?all-en.atom.xml" width="1" height="1" alt="" title=""&gt;</content><category term="json"></category><category term="python"></category><category term="memory"></category><category term="benchmark"></category><category term="msgpack"></category></entry><entry><title>Publishing to GitHub Pages from Travis CI</title><link href="https://blog.ionelmc.ro/2015/07/11/publishing-to-github-pages-from-travis-ci/" rel="alternate"></link><published>2015-07-11T00:00:00+03:00</published><updated>2015-07-15T22:26:56+03:00</updated><author><name>Ionel Cristian Mărieș</name></author><id>tag:blog.ionelmc.ro,2015-07-11:2015/07/11/publishing-to-github-pages-from-travis-ci/</id><summary type="html">&lt;div class="document" style='font:19px/29px "Palatino Linotype", "Book Antiqua", "FPL Neu", "TeX Gyre Pagella", "URW Palladio L", "Palatino", "Century Schoolbook L", "Georgia", serif; margin:0; padding:0'&gt;&lt;p style="margin:25px 0 25px 0"&gt;One neat trick you can do is publish to GitHub Pages is publish to GitHub Pages from Travis.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;I needed to do this for a &lt;a class="reference external" href="http://ropython.org/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;static blog&lt;/a&gt;. However, the repository is under an organization and
multiple people have commit access there. Using my &lt;cite&gt;Personal access token&lt;/cite&gt; &lt;a class="footnote-reference" href="https://blog.ionelmc.ro/2015/07/11/publishing-to-github-pages-from-travis-ci/#existing-guides" id="id1" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:12px; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; vertical-align:top' valign="top"&gt;[1]&lt;/a&gt; is not the …&lt;/p&gt;&lt;/div&gt;</summary><content type="html">&lt;div class="document" style='font:19px/29px "Palatino Linotype", "Book Antiqua", "FPL Neu", "TeX Gyre Pagella", "URW Palladio L", "Palatino", "Century Schoolbook L", "Georgia", serif; margin:0; padding:0'&gt;&lt;p style="margin:25px 0 25px 0"&gt;One neat trick you can do is publish to GitHub Pages is publish to GitHub Pages from Travis.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;I needed to do this for a &lt;a class="reference external" href="http://ropython.org/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;static blog&lt;/a&gt;. However, the repository is under an organization and
multiple people have commit access there. Using my &lt;cite&gt;Personal access token&lt;/cite&gt; &lt;a class="footnote-reference" href="https://blog.ionelmc.ro/2015/07/11/publishing-to-github-pages-from-travis-ci/#existing-guides" id="id1" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:12px; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; vertical-align:top' valign="top"&gt;[1]&lt;/a&gt; is not the right way to
do the authentication because:&lt;/p&gt;
&lt;ul class="simple" style="margin:25px 0 25px 0"&gt;
&lt;li style="padding:0"&gt;&lt;cite&gt;Personal access tokens&lt;/cite&gt; can only restrict kinds of operations, restricting to specific repository is not possible.&lt;/li&gt;
&lt;li style="padding:0"&gt;If something bad happens all my public repositories are at risk, as the &lt;cite&gt;Personal access token&lt;/cite&gt; is the &lt;a class="reference external" href="https://developer.github.com/guides/managing-deploy-keys/#https-cloning-with-oauth-tokens" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;equivalent of
a password&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style="margin:25px 0 25px 0"&gt;There's a better way to solve the authentication: repositories can have &lt;a class="reference external" href="https://developer.github.com/guides/managing-deploy-keys/#deploy-keys" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;deploy keys&lt;/a&gt;. The idea is that we'll use a brand new ssh
key to perform the authentication. We do not use that key for anything else.&lt;/p&gt;
&lt;p style="margin:25px 0 25px 0"&gt;First we need to make a new ssh key:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:1px solid #DDD; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 3px #EFEFEF' bgcolor="#FFFDFD"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="gp" style="color:#555"&gt;ionel@localhost$&lt;/span&gt; ssh-keygen -f publish-key
&lt;span class="go" style="color:#888"&gt;Generating public/private rsa key pair.&lt;/span&gt;
&lt;span class="go" style="color:#888"&gt;Enter passphrase (empty for no passphrase):&lt;/span&gt;
&lt;span class="go" style="color:#888"&gt;Enter same passphrase again:&lt;/span&gt;
&lt;span class="go" style="color:#888"&gt;Your identification has been saved in publish-key.&lt;/span&gt;
&lt;span class="go" style="color:#888"&gt;Your public key has been saved in publish-key.pub.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Then use use the &lt;a class="reference external" href="https://github.com/travis-ci/travis.rb" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;Travis CLI&lt;/a&gt; (use &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;gem install travis&lt;/tt&gt; to install it) to
encrypt it:&lt;/p&gt;
&lt;div class="admonition note" style="border:1px solid #DDD; border-radius:5px; box-shadow:0 1px 5px #EEE; margin:3ex 1ex 1ex 1ex; padding:0; background:white; float:right; width:200px" width="200"&gt;
&lt;p class="first admonition-title" style="margin:0; font-size:90%; border:none; border-radius:5px; box-shadow:0 1px 5px #EEE; padding:0; background:#F5F5F0; border-bottom:1px solid #DDD; font-style:italic; text-align:center" align="center"&gt;Note&lt;/p&gt;
&lt;p class="last" style="margin:0 0.5em 1em 0.5em; font-size:90%; margin-bottom:5px"&gt;I didn't use &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;&lt;span class="pre"&gt;--add&lt;/span&gt;&lt;/tt&gt; cause it reformats my &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;.travis.yml&lt;/tt&gt;, and it needs editing anyway.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:1px solid #DDD; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 3px #EFEFEF' bgcolor="#FFFDFD"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="gp" style="color:#555"&gt;ionel@localhost$&lt;/span&gt; travis encrypt-file publish-key
&lt;span class="go" style="color:#888"&gt;Detected repository as ionelmc/sphinx-py3doc-enhanced-theme, is this correct? |yes|&lt;/span&gt;
&lt;span class="go" style="color:#888"&gt;encrypting publish-key for ionelmc/sphinx-py3doc-enhanced-theme&lt;/span&gt;
&lt;span class="go" style="color:#888"&gt;storing result as publish-key.enc&lt;/span&gt;
&lt;span class="go" style="color:#888"&gt;storing secure env variables for decryption&lt;/span&gt;

&lt;span class="go" style="color:#888"&gt;Please add the following to your build script (before_install stage in your .travis.yml, for instance):&lt;/span&gt;

&lt;span class="go" style="color:#888"&gt;    openssl aes-256-cbc -K ionel@localhost$encrypted_87d9ccdaebfd_key -iv ionel@localhost$encrypted_87d9ccdaebfd_iv -in publish-key.enc -out publish-key -d&lt;/span&gt;

&lt;span class="go" style="color:#888"&gt;Pro Tip: You can add it automatically by running with --add.&lt;/span&gt;

&lt;span class="go" style="color:#888"&gt;Make sure to add publish-key.enc to the git repository.&lt;/span&gt;
&lt;span class="go" style="color:#888"&gt;Make sure not to add publish-key to the git repository.&lt;/span&gt;
&lt;span class="go" style="color:#888"&gt;Commit all changes to your .travis.yml.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p style="margin:25px 0 25px 0"&gt;The unencrypted secret key should be removed (we don't want to add it by accident in a commit 😅):&lt;/p&gt;
&lt;pre class="literal-block" style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:1px solid #DDD; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 3px #EFEFEF' bgcolor="#FFFDFD"&gt;
rm publish-key
&lt;/pre&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Then we add the encrypted key:&lt;/p&gt;
&lt;pre class="literal-block" style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:1px solid #DDD; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 3px #EFEFEF' bgcolor="#FFFDFD"&gt;
git add publish-key.enc
&lt;/pre&gt;
&lt;p style="margin:25px 0 25px 0"&gt;We need to change the decode command as the decoded file will go into a different path and some other fixups for the ssh
authentication. In &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;.travis.yml&lt;/tt&gt; we need to have:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:1px solid #DDD; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 3px #EFEFEF' bgcolor="#FFFDFD"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;before_install&lt;/span&gt;&lt;span class="p p-Indicator"&gt;:&lt;/span&gt;
&lt;span class="p p-Indicator"&gt;-&lt;/span&gt; &lt;span class="l l-Scalar l-Scalar-Plain"&gt;openssl aes-256-cbc -K ionel@localhost$encrypted_87d9ccdaebfd_key -iv ionel@localhost$encrypted_87d9ccdaebfd_iv -in publish-key.enc -out ~/.ssh/publish-key -d&lt;/span&gt;
&lt;span class="p p-Indicator"&gt;-&lt;/span&gt; &lt;span class="l l-Scalar l-Scalar-Plain"&gt;chmod u=rw,og= ~/.ssh/publish-key&lt;/span&gt;
&lt;span class="p p-Indicator"&gt;-&lt;/span&gt; &lt;span class="l l-Scalar l-Scalar-Plain"&gt;echo "Host github.com" &amp;gt;&amp;gt; ~/.ssh/config&lt;/span&gt;
&lt;span class="p p-Indicator"&gt;-&lt;/span&gt; &lt;span class="l l-Scalar l-Scalar-Plain"&gt;echo "  IdentityFile ~/.ssh/publish-key" &amp;gt;&amp;gt; ~/.ssh/config&lt;/span&gt;
&lt;span class="p p-Indicator"&gt;-&lt;/span&gt; &lt;span class="l l-Scalar l-Scalar-Plain"&gt;git --version&lt;/span&gt;
&lt;span class="p p-Indicator"&gt;-&lt;/span&gt; &lt;span class="l l-Scalar l-Scalar-Plain"&gt;git remote set-url origin git@github.com:ionelmc/sphinx-py3doc-enhanced-theme.git&lt;/span&gt;
&lt;span class="p p-Indicator"&gt;-&lt;/span&gt; &lt;span class="l l-Scalar l-Scalar-Plain"&gt;git fetch origin -f gh-pages:gh-pages&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p style="margin:25px 0 25px 0"&gt;Now we can use a tool like &lt;a class="reference external" href="https://pypi.python.org/pypi/ghp-import" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;ghp-import&lt;/a&gt; to simply publish (somewhere in
&lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;.travis.yml&lt;/tt&gt; after you generate the HTML in &lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;output&lt;/tt&gt;):&lt;/p&gt;
&lt;pre class="literal-block" style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:1px solid #DDD; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 3px #EFEFEF' bgcolor="#FFFDFD"&gt;
ghp-import -n -p -m "Update gh-pages." output
&lt;/pre&gt;
&lt;p style="margin:25px 0 25px 0"&gt;All is left is to add the public key in your repo's &lt;cite&gt;deploy keys&lt;/cite&gt; (make sure to tick the &lt;cite&gt;write access&lt;/cite&gt; checkbox):&lt;/p&gt;
&lt;img alt='A screenshot of the "Add a deploy key" form.' src="https://blog.ionelmc.ro/2015/07/11/publishing-to-github-pages-from-travis-ci/deploy-keys.png" style="box-shadow:1px 1px 6px #CCC; display:block; margin:0 auto; max-width:100%"&gt;
&lt;p style="margin:25px 0 25px 0"&gt;In some cases you only want to publish for the changes made on the &lt;cite&gt;master&lt;/cite&gt; branch. Make sure you have this in your
&lt;tt class="docutils literal" style='font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:95%; background:#F7F7F5; border-radius:3px; padding:3px 6px'&gt;.travis.yml&lt;/tt&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre style='margin:1ex 0; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; font-size:75%; background-color:#FFFDFD; border:1px solid #DDD; border-radius:5px; line-height:1.5; padding:10px; white-space:pre-wrap; word-wrap:break-word; box-shadow:1px 1px 3px #EFEFEF' bgcolor="#FFFDFD"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;branches&lt;/span&gt;&lt;span class="p p-Indicator"&gt;:&lt;/span&gt;
  &lt;span class="l l-Scalar l-Scalar-Plain"&gt;only&lt;/span&gt;&lt;span class="p p-Indicator"&gt;:&lt;/span&gt;
  &lt;span class="p p-Indicator"&gt;-&lt;/span&gt; &lt;span class="l l-Scalar l-Scalar-Plain"&gt;master&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;div class="line-block" style="margin:25px 0 25px 0"&gt;
&lt;div class="line"&gt;&lt;br&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;hr class="docutils" style="background:#FFFDFD; border:0; border-radius:2px; padding:0; background-color:#F6F6F6; box-shadow:inset 0 0 2px #CCC; clear:both; height:6px; margin:0 1px" bgcolor="#F6F6F6" height="6"&gt;
&lt;p style="margin:25px 0 25px 0"&gt;You can see the working examples of this in &lt;a class="reference external" href="https://github.com/RoPython/ropython-site" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;ropython-site&lt;/a&gt; or &lt;a class="reference external" href="https://github.com/ionelmc/sphinx-py3doc-enhanced-theme" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;sphinx-py3doc-enhanced-theme&lt;/a&gt;.&lt;/p&gt;
&lt;table class="docutils footnote" frame="void" id="existing-guides" rules="none" style='margin:5px 0; box-shadow:none; background:transparent; border:none; border-collapse:separate; border-radius:5px; border-spacing:0; width:100%; font-family:Palatino, "Palatino Linotype", Georgia, serif; margin-bottom:8px' width="100%"&gt;
&lt;colgroup&gt;&lt;col class="label"&gt;&lt;col&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label" style='border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; border-left:1px solid #DDD; font-size:75%; background:transparent; text-decoration:none; text-shadow:none; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace; width:5%; border-radius:0' width="5%"&gt;&lt;a class="fn-backref" href="https://blog.ionelmc.ro/2015/07/11/publishing-to-github-pages-from-travis-ci/#id1" style='color:#15C; outline-color:#FFF; outline-offset:10px; background:transparent; text-decoration:none; text-shadow:none; font-size:75%; font-family:"Consolas", "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", "Source Code Pro", "Courier New", monospace'&gt;[1]&lt;/a&gt;&lt;/td&gt;&lt;td style="border:none; border-bottom:1px solid #DDD; border-right:1px solid #DDD; padding:5px; font-size:15px; border-radius:0"&gt;Sadly, there are several guides
&lt;a rel="nofollow" href="http://awestruct.org/auto-deploy-to-github-pages/" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;out&lt;/a&gt;
&lt;a rel="nofollow" href="http://blog.mathieu-leplatre.info/publish-your-pelican-blog-on-github-pages-via-travis-ci.html" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;there&lt;/a&gt;
&lt;a rel="nofollow" href="http://zonca.github.io/2013/09/automatically-build-pelican-and-publish-to-github-pages.html" style="color:#15C; outline-color:#FFF; outline-offset:10px"&gt;that&lt;/a&gt;
recommend using a &lt;cite&gt;Personal access token&lt;/cite&gt;.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;img src="https://blog.ionelmc.ro/_/2015/07/11/publishing-to-github-pages-from-travis-ci/?all-en.atom.xml" width="1" height="1" alt="" title=""&gt;</content><category term="python"></category><category term="travis"></category><category term="github"></category></entry></feed>