By the end of 2015, we plan to have converted all our deployments using containers, migrating applications to Docker if they were not using it from the begining.
However, my fellow colleagues complain sometimes that Docker does not offer you the level of flexibility a code checkout + supervisor gives you, mostly in terms of debugging production code.
Some people take full snapshots of the containers running in production and spawn them locally to reproduce the bugs, but this does not come for free, as you need to copy a lot of data between the customer machines and your development laptop.
In my Dockerfile:
... CMD gunicorn -w $WORKERS -b $HOST:$PORT kabuto.api:app
Now I run this container:
7cffffa2f91e kabuto "/bin/sh -c 'gunicor 13 minutes ago Up 13 minutes demo_kabuto_1
Alas, there seem to be a bug in my code, triggered when a user logs in the application. I have my user on the phone, and we're trying to reproduce the problem.
I then have several options:
sshinto the container
12:37:37-eric@monarch:demo$ docker exec -u root -it b1f027b1baba /bin/bash root@b1f027b1baba:/source# ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND www-data 1 0.0 0.0 4448 776 ? Ss 10:24 0:00 /bin/sh -c gunicorn -w $WORKERS -b $HOST:$PORT kabuto:app www-data 8 0.0 0.9 58792 19404 ? S 10:24 0:00 /usr/bin/python3 /usr/local/bin/gunicorn -w 1 -b 0.0.0.0:5000 kabuto:app www-data 206 0.5 1.9 238328 39184 ? Sl 10:26 0:07 /usr/bin/python3 /usr/local/bin/gunicorn -w 1 -b 0.0.0.0:5000 kabuto:app root 210 0.0 0.1 18204 3336 ? Ss 10:46 0:00 /bin/bash root 243 0.0 0.1 15572 2148 ? R+ 10:49 0:00 ps aux root@b1f027b1baba:/source# export TERM=xterm && apt-get update && apt-get install -y vim Ign http://archive.ubuntu.com trusty InRelease Ign http://archive.ubuntu.com trusty-updates InRelease Ign http://archive.ubuntu.com trusty-security InRelease Hit http://archive.ubuntu.com trusty Release.gpg ... root@b1f027b1baba:/source# vim kabuto/api.py ... add some prints, logging, ...
Ok, great, I made changes to my code, but now how do I make the container use the new code ?
As I'm running gunicorn as PID 1, there is no way to restart this process without having Docker to consider the process is terminated and therefore terminate the whole container.
kill -HUPto reload gunicorn. Unfortunately, it does not seem to work in PID 1, so I had to loop each gunicorn worker to reload its threads
CMD gunicorn --reload -w $WORKERS -b $HOST:$PORT kabuto.api:app
So now, no more excuses not to use Docker everywhere !
Eric is a software engineer, founder of Adimian, splitting his time between making his customers lives better, filling the paperworks and doing puzzles with his twin boys.