{"id":2229,"date":"2018-05-15T10:38:22","date_gmt":"2018-05-15T14:38:22","guid":{"rendered":"https:\/\/www.danielpradilla.info\/blog\/?p=2229"},"modified":"2018-12-03T05:19:07","modified_gmt":"2018-12-03T09:19:07","slug":"linear-optimization-with-or-tools-containerizing-a-gunicorn-web-application","status":"publish","type":"post","link":"https:\/\/www.danielpradilla.info\/blog\/linear-optimization-with-or-tools-containerizing-a-gunicorn-web-application\/","title":{"rendered":"Linear optimization with or-tools: containerizing a gunicorn web application"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" data-attachment-id=\"2230\" data-permalink=\"https:\/\/www.danielpradilla.info\/blog\/linear-optimization-with-or-tools-containerizing-a-gunicorn-web-application\/1956-moby-dick\/\" data-orig-file=\"https:\/\/www.danielpradilla.info\/blog\/wp-content\/uploads\/2018\/05\/1956-MOBY-DICK-012.jpg\" data-orig-size=\"1954,1172\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;Photograph: Cinetext\/Allstar&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;Sportsphoto Ltd.\/Allstar&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;1956, MOBY DICK&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"1956, MOBY DICK\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/www.danielpradilla.info\/blog\/wp-content\/uploads\/2018\/05\/1956-MOBY-DICK-012-1024x614.jpg\" class=\"aligncenter size-full wp-image-2230\" src=\"https:\/\/www.danielpradilla.info\/blog\/wp-content\/uploads\/2018\/05\/1956-MOBY-DICK-012.jpg\" alt=\"\" width=\"1954\" height=\"1172\" srcset=\"https:\/\/www.danielpradilla.info\/blog\/wp-content\/uploads\/2018\/05\/1956-MOBY-DICK-012.jpg 1954w, https:\/\/www.danielpradilla.info\/blog\/wp-content\/uploads\/2018\/05\/1956-MOBY-DICK-012-300x180.jpg 300w, https:\/\/www.danielpradilla.info\/blog\/wp-content\/uploads\/2018\/05\/1956-MOBY-DICK-012-768x461.jpg 768w, https:\/\/www.danielpradilla.info\/blog\/wp-content\/uploads\/2018\/05\/1956-MOBY-DICK-012-1024x614.jpg 1024w\" sizes=\"auto, (max-width: 1954px) 100vw, 1954px\" \/><\/p>\n<p><a href=\"https:\/\/www.danielpradilla.info\/blog\/linear-optimization-with-or-tools-building-a-web-front-end-with-falcon-and-gunicorn\/\">Previously<\/a>, we left our app working with our local python+gunicorn+nginx installation. In order to get there we had to do quite a bit of configuration and if we wanted to deploy this in a server or send it to a friend, we would have to go through a very error-prone process subject to version changes and missing libraries. A potential nightmare if we contemplate switching from one operating system to another. Is there a way in which we could combine our code and configuration in a single easy to deploy multi-platform package?<\/p>\n<p><a href=\"https:\/\/github.com\/danielpradilla\/or-tools-playground\/tree\/master\/docker\">Get the code here<\/a><\/p>\n<p>One solution for this is to create a single <a href=\"https:\/\/docs.docker.com\/\">Docker<\/a> container that, when run, will create the environment and deploy our code in a controlled environment.<\/p>\n<p>In the <a href=\"https:\/\/hub.docker.com\/\">Docker hub<\/a> you will find thousands of preconfigured containers. The best way to start is to find the closest one that would suit us and customize it. That way you avoid laying the ground work and just focus on the specifics of your application.<\/p>\n<p>I tend to trust the containers built by larger vendors, organizations or open-source projects, because I find that they usually keep their containers up to date and \u2013most importantly\u2013 they are heavily battle-tested in dev and production.<\/p>\n<p>In this case, I chose <a href=\"https:\/\/github.com\/texastribune\/docks\/tree\/master\/gunicorn\">a gunicorn container created by the Texas Tribune<\/a>. To start, you download and install Docker, and then download your chosen container to your machine.<\/p>\n<p>The way to customize a Docker container is to edit the <a href=\"https:\/\/blog.hasura.io\/how-to-write-dockerfiles-for-python-web-apps-6d173842ae1d\">Dockerfile<\/a>. There you will specify commands to install, copy or run files specific to your project. In our case, I added an installation of python-dev, falcon and the google or-tools:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\n\r\n#install whats neccessary for or-tools\r\nRUN pip install --upgrade pip\r\nRUN pip install --upgrade wheel setuptools virtualenv\r\nRUN apt-get -y install flex bison\r\nRUN apt-get -y --fix-missing install autoconf libtool zlib1g-dev texinfo help2man gawk g++ curl texlive cmake subversion\r\n\r\n#install gunicorn and falcon for providing API endpoints\r\nRUN pip install gunicorn==19.6\r\nRUN pip install falcon\r\n\r\n#install or-tools\r\n#https:\/\/github.com\/google\/or-tools\/releases\/download\/v5.0\/or-tools_python_examples_v5.0.3919.tar.gz\r\nADD or-tools_python_examples_v5.0.3919.tar.gz \/app\r\nRUN mv \/app\/ortools* \/app\/ortools &amp;&amp; cd \/app\/ortools\/ &amp;&amp; python setup.py install --user\r\n\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>Then I created separate configuration files for gunicorn and nginx, and a couple of supervisor configurations. Supervisor will restart the services in case one of them goes down, which might happen if I introduce an unrecoverable error in the python script:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\n\r\n#copy configuration files\r\nADD gunicorn_conf.py \/app\/\r\nADD gunicorn.supervisor.conf \/etc\/supervisor\/conf.d\/\r\nADD nginx.conf \/app\/\r\nADD nginx.supervisor.conf \/etc\/supervisor\/conf.d\/\r\n\r\n\r\n<\/pre>\n<p>After the initial configuration, we build using the docker build command:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\n\r\ndocker build --no-cache -t danielpradilla\/or-tools .\r\n\r\n<\/pre>\n<p>And then, we run the container as a daemon:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\n\r\ndocker run -p 5000:80 -d --name or-tools-gunicorn danielpradilla\/or-tools\r\n\r\n<\/pre>\n<p>The web server port is specified as a parameter. This maps port 5000 in localhost to port 80 in the container.<\/p>\n<p>Now, time to install our code. You can copy your code to the Docker container, but what I prefer is to have my code in a local folder in my machine, outside##italics of the Docker container. That way, I don&#8217;t need to copy the code to the container every time I change it, and I keep a single unmistakable copy of the code.<\/p>\n<p>To do this, you mount the local folder as an extra folder inside the container. Change the Dockerfile and add<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\n\r\nVOLUME &#x5B;&quot;\/app\/logs&quot;,&quot;\/app\/www&quot;]\r\n\r\n<\/pre>\n<p>And then when, you run the container, you specify the location of your local folder:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\n\r\ndocker run -v :\/app\/www -p 5000:80 -d --name or-tools-gunicorn danielpradilla\/or-tools\r\n\r\n<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" data-attachment-id=\"2232\" data-permalink=\"https:\/\/www.danielpradilla.info\/blog\/linear-optimization-with-or-tools-containerizing-a-gunicorn-web-application\/docker\/\" data-orig-file=\"https:\/\/www.danielpradilla.info\/blog\/wp-content\/uploads\/2018\/05\/docker.jpg\" data-orig-size=\"614,229\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}\" data-image-title=\"docker\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/www.danielpradilla.info\/blog\/wp-content\/uploads\/2018\/05\/docker.jpg\" src=\"https:\/\/www.danielpradilla.info\/blog\/wp-content\/uploads\/2018\/05\/docker.jpg\" alt=\"\" width=\"614\" height=\"229\" class=\"aligncenter size-full wp-image-2232\" srcset=\"https:\/\/www.danielpradilla.info\/blog\/wp-content\/uploads\/2018\/05\/docker.jpg 614w, https:\/\/www.danielpradilla.info\/blog\/wp-content\/uploads\/2018\/05\/docker-300x112.jpg 300w\" sizes=\"auto, (max-width: 614px) 100vw, 614px\" \/><\/p>\n<p>This will allow you to experiment with multiple versions of the code (production and development) with a simple parameter change. You can run two docker containers pointing to different folders and opening different ports, and then compare the results side by side!<\/p>\n<p>&nbsp;<\/p>\n<p><a href=\"https:\/\/github.com\/danielpradilla\/or-tools-playground\/tree\/master\/docker\">Get the code here<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Previously, we left our app working with our local python+gunicorn+nginx installation. In order to get there we had to do quite a bit of configuration and if we wanted to deploy this in a server or send it to a friend, we would have to go through a very error-prone process subject to version changes&hellip; <a class=\"more-link\" href=\"https:\/\/www.danielpradilla.info\/blog\/linear-optimization-with-or-tools-containerizing-a-gunicorn-web-application\/\">Continue reading <span class=\"screen-reader-text\">Linear optimization with or-tools: containerizing a gunicorn web application<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_post_was_ever_published":false},"categories":[331],"tags":[344,359,342,340,343,337,338,339,341],"class_list":["post-2229","post","type-post","status-publish","format-standard","hentry","category-software","tag-api","tag-docker","tag-falcon","tag-google","tag-gunicorn","tag-linear-programming","tag-optimization","tag-or-tools","tag-python","entry"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Daniel Pradilla\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/www.danielpradilla.info\/blog\/linear-optimization-with-or-tools-containerizing-a-gunicorn-web-application\/\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"Daniel Pradilla | getting the most out of technology\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"Linear optimization with or-tools: containerizing a gunicorn web application | Daniel Pradilla\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/www.danielpradilla.info\/blog\/linear-optimization-with-or-tools-containerizing-a-gunicorn-web-application\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2018-05-15T14:38:22+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2018-12-03T09:19:07+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Linear optimization with or-tools: containerizing a gunicorn web application | Daniel Pradilla\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.danielpradilla.info\\\/blog\\\/linear-optimization-with-or-tools-containerizing-a-gunicorn-web-application\\\/#article\",\"name\":\"Linear optimization with or-tools: containerizing a gunicorn web application | Daniel Pradilla\",\"headline\":\"Linear optimization with or-tools: containerizing a gunicorn web application\",\"author\":{\"@id\":\"https:\\\/\\\/www.danielpradilla.info\\\/blog\\\/author\\\/danielpradilla\\\/#author\"},\"publisher\":{\"@id\":\"https:\\\/\\\/www.danielpradilla.info\\\/blog\\\/#organization\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/www.danielpradilla.info\\\/blog\\\/wp-content\\\/uploads\\\/2018\\\/05\\\/1956-MOBY-DICK-012.jpg\",\"@id\":\"https:\\\/\\\/www.danielpradilla.info\\\/blog\\\/linear-optimization-with-or-tools-containerizing-a-gunicorn-web-application\\\/#articleImage\",\"width\":1954,\"height\":1172},\"datePublished\":\"2018-05-15T10:38:22+00:00\",\"dateModified\":\"2018-12-03T05:19:07+00:00\",\"inLanguage\":\"en-US\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.danielpradilla.info\\\/blog\\\/linear-optimization-with-or-tools-containerizing-a-gunicorn-web-application\\\/#webpage\"},\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.danielpradilla.info\\\/blog\\\/linear-optimization-with-or-tools-containerizing-a-gunicorn-web-application\\\/#webpage\"},\"articleSection\":\"Software, api, docker, falcon, google, gunicorn, linear programming, optimization, or-tools, python\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.danielpradilla.info\\\/blog\\\/linear-optimization-with-or-tools-containerizing-a-gunicorn-web-application\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.danielpradilla.info\\\/blog#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.danielpradilla.info\\\/blog\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.danielpradilla.info\\\/blog\\\/category\\\/software\\\/#listItem\",\"name\":\"Software\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.danielpradilla.info\\\/blog\\\/category\\\/software\\\/#listItem\",\"position\":2,\"name\":\"Software\",\"item\":\"https:\\\/\\\/www.danielpradilla.info\\\/blog\\\/category\\\/software\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.danielpradilla.info\\\/blog\\\/linear-optimization-with-or-tools-containerizing-a-gunicorn-web-application\\\/#listItem\",\"name\":\"Linear optimization with or-tools: containerizing a gunicorn web application\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.danielpradilla.info\\\/blog#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.danielpradilla.info\\\/blog\\\/linear-optimization-with-or-tools-containerizing-a-gunicorn-web-application\\\/#listItem\",\"position\":3,\"name\":\"Linear optimization with or-tools: containerizing a gunicorn web application\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.danielpradilla.info\\\/blog\\\/category\\\/software\\\/#listItem\",\"name\":\"Software\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.danielpradilla.info\\\/blog\\\/#organization\",\"name\":\"Daniel Pradilla\",\"description\":\"getting the most out of technology\",\"url\":\"https:\\\/\\\/www.danielpradilla.info\\\/blog\\\/\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.danielpradilla.info\\\/blog\\\/author\\\/danielpradilla\\\/#author\",\"url\":\"https:\\\/\\\/www.danielpradilla.info\\\/blog\\\/author\\\/danielpradilla\\\/\",\"name\":\"Daniel Pradilla\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/www.danielpradilla.info\\\/blog\\\/linear-optimization-with-or-tools-containerizing-a-gunicorn-web-application\\\/#authorImage\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b91ffbe374d7c4bc65533da1aa8f8d3d2526f49ce25c0ea54bc8bd0519fedc43?s=96&d=mm&r=g\",\"width\":96,\"height\":96,\"caption\":\"Daniel Pradilla\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.danielpradilla.info\\\/blog\\\/linear-optimization-with-or-tools-containerizing-a-gunicorn-web-application\\\/#webpage\",\"url\":\"https:\\\/\\\/www.danielpradilla.info\\\/blog\\\/linear-optimization-with-or-tools-containerizing-a-gunicorn-web-application\\\/\",\"name\":\"Linear optimization with or-tools: containerizing a gunicorn web application | Daniel Pradilla\",\"inLanguage\":\"en-US\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.danielpradilla.info\\\/blog\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.danielpradilla.info\\\/blog\\\/linear-optimization-with-or-tools-containerizing-a-gunicorn-web-application\\\/#breadcrumblist\"},\"author\":{\"@id\":\"https:\\\/\\\/www.danielpradilla.info\\\/blog\\\/author\\\/danielpradilla\\\/#author\"},\"creator\":{\"@id\":\"https:\\\/\\\/www.danielpradilla.info\\\/blog\\\/author\\\/danielpradilla\\\/#author\"},\"datePublished\":\"2018-05-15T10:38:22+00:00\",\"dateModified\":\"2018-12-03T05:19:07+00:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.danielpradilla.info\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.danielpradilla.info\\\/blog\\\/\",\"name\":\"Daniel Pradilla\",\"description\":\"getting the most out of technology\",\"inLanguage\":\"en-US\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.danielpradilla.info\\\/blog\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"Linear optimization with or-tools: containerizing a gunicorn web application | Daniel Pradilla","description":"","canonical_url":"https:\/\/www.danielpradilla.info\/blog\/linear-optimization-with-or-tools-containerizing-a-gunicorn-web-application\/","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.danielpradilla.info\/blog\/linear-optimization-with-or-tools-containerizing-a-gunicorn-web-application\/#article","name":"Linear optimization with or-tools: containerizing a gunicorn web application | Daniel Pradilla","headline":"Linear optimization with or-tools: containerizing a gunicorn web application","author":{"@id":"https:\/\/www.danielpradilla.info\/blog\/author\/danielpradilla\/#author"},"publisher":{"@id":"https:\/\/www.danielpradilla.info\/blog\/#organization"},"image":{"@type":"ImageObject","url":"https:\/\/www.danielpradilla.info\/blog\/wp-content\/uploads\/2018\/05\/1956-MOBY-DICK-012.jpg","@id":"https:\/\/www.danielpradilla.info\/blog\/linear-optimization-with-or-tools-containerizing-a-gunicorn-web-application\/#articleImage","width":1954,"height":1172},"datePublished":"2018-05-15T10:38:22+00:00","dateModified":"2018-12-03T05:19:07+00:00","inLanguage":"en-US","mainEntityOfPage":{"@id":"https:\/\/www.danielpradilla.info\/blog\/linear-optimization-with-or-tools-containerizing-a-gunicorn-web-application\/#webpage"},"isPartOf":{"@id":"https:\/\/www.danielpradilla.info\/blog\/linear-optimization-with-or-tools-containerizing-a-gunicorn-web-application\/#webpage"},"articleSection":"Software, api, docker, falcon, google, gunicorn, linear programming, optimization, or-tools, python"},{"@type":"BreadcrumbList","@id":"https:\/\/www.danielpradilla.info\/blog\/linear-optimization-with-or-tools-containerizing-a-gunicorn-web-application\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/www.danielpradilla.info\/blog#listItem","position":1,"name":"Home","item":"https:\/\/www.danielpradilla.info\/blog","nextItem":{"@type":"ListItem","@id":"https:\/\/www.danielpradilla.info\/blog\/category\/software\/#listItem","name":"Software"}},{"@type":"ListItem","@id":"https:\/\/www.danielpradilla.info\/blog\/category\/software\/#listItem","position":2,"name":"Software","item":"https:\/\/www.danielpradilla.info\/blog\/category\/software\/","nextItem":{"@type":"ListItem","@id":"https:\/\/www.danielpradilla.info\/blog\/linear-optimization-with-or-tools-containerizing-a-gunicorn-web-application\/#listItem","name":"Linear optimization with or-tools: containerizing a gunicorn web application"},"previousItem":{"@type":"ListItem","@id":"https:\/\/www.danielpradilla.info\/blog#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/www.danielpradilla.info\/blog\/linear-optimization-with-or-tools-containerizing-a-gunicorn-web-application\/#listItem","position":3,"name":"Linear optimization with or-tools: containerizing a gunicorn web application","previousItem":{"@type":"ListItem","@id":"https:\/\/www.danielpradilla.info\/blog\/category\/software\/#listItem","name":"Software"}}]},{"@type":"Organization","@id":"https:\/\/www.danielpradilla.info\/blog\/#organization","name":"Daniel Pradilla","description":"getting the most out of technology","url":"https:\/\/www.danielpradilla.info\/blog\/"},{"@type":"Person","@id":"https:\/\/www.danielpradilla.info\/blog\/author\/danielpradilla\/#author","url":"https:\/\/www.danielpradilla.info\/blog\/author\/danielpradilla\/","name":"Daniel Pradilla","image":{"@type":"ImageObject","@id":"https:\/\/www.danielpradilla.info\/blog\/linear-optimization-with-or-tools-containerizing-a-gunicorn-web-application\/#authorImage","url":"https:\/\/secure.gravatar.com\/avatar\/b91ffbe374d7c4bc65533da1aa8f8d3d2526f49ce25c0ea54bc8bd0519fedc43?s=96&d=mm&r=g","width":96,"height":96,"caption":"Daniel Pradilla"}},{"@type":"WebPage","@id":"https:\/\/www.danielpradilla.info\/blog\/linear-optimization-with-or-tools-containerizing-a-gunicorn-web-application\/#webpage","url":"https:\/\/www.danielpradilla.info\/blog\/linear-optimization-with-or-tools-containerizing-a-gunicorn-web-application\/","name":"Linear optimization with or-tools: containerizing a gunicorn web application | Daniel Pradilla","inLanguage":"en-US","isPartOf":{"@id":"https:\/\/www.danielpradilla.info\/blog\/#website"},"breadcrumb":{"@id":"https:\/\/www.danielpradilla.info\/blog\/linear-optimization-with-or-tools-containerizing-a-gunicorn-web-application\/#breadcrumblist"},"author":{"@id":"https:\/\/www.danielpradilla.info\/blog\/author\/danielpradilla\/#author"},"creator":{"@id":"https:\/\/www.danielpradilla.info\/blog\/author\/danielpradilla\/#author"},"datePublished":"2018-05-15T10:38:22+00:00","dateModified":"2018-12-03T05:19:07+00:00"},{"@type":"WebSite","@id":"https:\/\/www.danielpradilla.info\/blog\/#website","url":"https:\/\/www.danielpradilla.info\/blog\/","name":"Daniel Pradilla","description":"getting the most out of technology","inLanguage":"en-US","publisher":{"@id":"https:\/\/www.danielpradilla.info\/blog\/#organization"}}]},"og:locale":"en_US","og:site_name":"Daniel Pradilla | getting the most out of technology","og:type":"article","og:title":"Linear optimization with or-tools: containerizing a gunicorn web application | Daniel Pradilla","og:url":"https:\/\/www.danielpradilla.info\/blog\/linear-optimization-with-or-tools-containerizing-a-gunicorn-web-application\/","article:published_time":"2018-05-15T14:38:22+00:00","article:modified_time":"2018-12-03T09:19:07+00:00","twitter:card":"summary","twitter:title":"Linear optimization with or-tools: containerizing a gunicorn web application | Daniel Pradilla"},"aioseo_meta_data":{"post_id":"2229","title":null,"description":null,"keywords":null,"keyphrases":{"focus":[],"additional":[]},"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"Article","isEnabled":true},"graphs":[]},"schema_type":"default","schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"breadcrumb_settings":null,"limit_modified_date":false,"ai":null,"created":"2021-12-15 18:15:19","updated":"2026-08-25 14:29:12","seo_analyzer_scan_date":null,"focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.danielpradilla.info\/blog\" title=\"Home\">Home<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.danielpradilla.info\/blog\/category\/software\/\" title=\"Software\">Software<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\tLinear optimization with or-tools: containerizing a gunicorn web application\n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/www.danielpradilla.info\/blog"},{"label":"Software","link":"https:\/\/www.danielpradilla.info\/blog\/category\/software\/"},{"label":"Linear optimization with or-tools: containerizing a gunicorn web application","link":"https:\/\/www.danielpradilla.info\/blog\/linear-optimization-with-or-tools-containerizing-a-gunicorn-web-application\/"}],"jetpack_shortlink":"https:\/\/wp.me\/p1tlzy-zX","jetpack_sharing_enabled":true,"jetpack-related-posts":[{"id":2205,"url":"https:\/\/www.danielpradilla.info\/blog\/linear-optimization-with-or-tools\/","url_meta":{"origin":2229,"position":0},"title":"Linear Optimization with or-tools","author":"Daniel Pradilla","date":"07\/06\/2017","format":false,"excerpt":"\u00a0 Getting started Over the last couple of months I've been getting my feet wet with linear programming and mathematical optimisation. I got a sense of how it all worked from this Discrete Optimisation course in Coursera and googling around I discovered that there are a ton of tools out\u2026","rel":"","context":"In &quot;Best of&quot;","block_context":{"text":"Best of","link":"https:\/\/www.danielpradilla.info\/blog\/category\/bestof\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.danielpradilla.info\/blog\/wp-content\/uploads\/2017\/06\/grocery_bag_brown_bag.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.danielpradilla.info\/blog\/wp-content\/uploads\/2017\/06\/grocery_bag_brown_bag.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/www.danielpradilla.info\/blog\/wp-content\/uploads\/2017\/06\/grocery_bag_brown_bag.jpg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/www.danielpradilla.info\/blog\/wp-content\/uploads\/2017\/06\/grocery_bag_brown_bag.jpg?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":2212,"url":"https:\/\/www.danielpradilla.info\/blog\/linear-optimization-with-or-tools-building-a-web-front-end-with-falcon-and-gunicorn\/","url_meta":{"origin":2229,"position":1},"title":"Linear Optimization with or-tools \u2014 building a web front-end with falcon and gunicorn","author":"Daniel Pradilla","date":"14\/11\/2017","format":false,"excerpt":"In a previous post, I put together a script for solving a linear optimisation problem using Google's OR-tools. This python script is callable from the command line and you kinda need to know what you are doing and how to organize the parameters. So, in order to address this difficulty,\u2026","rel":"","context":"In &quot;Software&quot;","block_context":{"text":"Software","link":"https:\/\/www.danielpradilla.info\/blog\/category\/software\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.danielpradilla.info\/blog\/wp-content\/uploads\/2017\/11\/groceryshopping.gif?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.danielpradilla.info\/blog\/wp-content\/uploads\/2017\/11\/groceryshopping.gif?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/www.danielpradilla.info\/blog\/wp-content\/uploads\/2017\/11\/groceryshopping.gif?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/www.danielpradilla.info\/blog\/wp-content\/uploads\/2017\/11\/groceryshopping.gif?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":2302,"url":"https:\/\/www.danielpradilla.info\/blog\/aws-lambda-python\/","url_meta":{"origin":2229,"position":2},"title":"10 things I learned while deploying my first python function to AWS Lambda","author":"Daniel Pradilla","date":"04\/01\/2019","format":false,"excerpt":"I spent a few days on and off trying to deploy a Flask REST service to AWS Lambda, just to experience what the cool kids were talking about. These are some of the things I learned along the way: \u00a0 Zappa is the easiest packager\/deployer for python (as of December\u2026","rel":"","context":"In &quot;Software&quot;","block_context":{"text":"Software","link":"https:\/\/www.danielpradilla.info\/blog\/category\/software\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.danielpradilla.info\/blog\/wp-content\/uploads\/2019\/01\/AWS-Lambda-290x300.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":2234,"url":"https:\/\/www.danielpradilla.info\/blog\/how-to-build-an-api-for-sap-hana-using-strongloop-loopback\/","url_meta":{"origin":2229,"position":3},"title":"How to build an API for SAP HANA using strongloop\/loopback","author":"Daniel Pradilla","date":"30\/05\/2018","format":false,"excerpt":"One of the aspects I like the most about SAP HANA is the cloud app development environment that allows you to quickly put together a data-entry app using Fiori. Recently, I wanted to build a small JavaScript app for data querying and entry using the awesome ag-grid. The data was\u2026","rel":"","context":"In &quot;Software&quot;","block_context":{"text":"Software","link":"https:\/\/www.danielpradilla.info\/blog\/category\/software\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.danielpradilla.info\/blog\/wp-content\/uploads\/2018\/05\/loopback-arc.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.danielpradilla.info\/blog\/wp-content\/uploads\/2018\/05\/loopback-arc.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/www.danielpradilla.info\/blog\/wp-content\/uploads\/2018\/05\/loopback-arc.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/www.danielpradilla.info\/blog\/wp-content\/uploads\/2018\/05\/loopback-arc.png?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":2399,"url":"https:\/\/www.danielpradilla.info\/blog\/my-python-logging-setup\/","url_meta":{"origin":2229,"position":4},"title":"My Python logging setup","author":"Daniel Pradilla","date":"24\/08\/2023","format":false,"excerpt":"Working on various Python projects has taught me the importance of consistent logging, especially when dealing with distributed computing frameworks like Spark. Logging is not just about keeping track of errors or information; it's about having a detailed and systematic record of the operations to understand the flow of your\u2026","rel":"","context":"In &quot;Software&quot;","block_context":{"text":"Software","link":"https:\/\/www.danielpradilla.info\/blog\/category\/software\/"},"img":{"alt_text":"My Python logging setup","src":"https:\/\/i0.wp.com\/www.danielpradilla.info\/blog\/wp-content\/uploads\/2023\/08\/5aadc010-b913-4eb0-9388-cd8d6c743271.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.danielpradilla.info\/blog\/wp-content\/uploads\/2023\/08\/5aadc010-b913-4eb0-9388-cd8d6c743271.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/www.danielpradilla.info\/blog\/wp-content\/uploads\/2023\/08\/5aadc010-b913-4eb0-9388-cd8d6c743271.jpg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/www.danielpradilla.info\/blog\/wp-content\/uploads\/2023\/08\/5aadc010-b913-4eb0-9388-cd8d6c743271.jpg?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":2157,"url":"https:\/\/www.danielpradilla.info\/blog\/a-swiss-railway-clock-in-d3\/","url_meta":{"origin":2229,"position":5},"title":"A swiss railway clock in D3.js","author":"Daniel Pradilla","date":"09\/06\/2015","format":false,"excerpt":"\u00a0 The other day I saw this cool JavaScript+CSS clock and I immediately thought that I wanted to create an analog clock in D3.js. First of all as an exercise, but also with the aim \u2013perhaps\u2013 of smuggling it in to a future dashboard ;) It seemed straightforward: just paint\u2026","rel":"","context":"In &quot;Best of&quot;","block_context":{"text":"Best of","link":"https:\/\/www.danielpradilla.info\/blog\/category\/bestof\/"},"img":{"alt_text":"Screen Shot 2015-06-05 at 5.26.54 PM","src":"https:\/\/i0.wp.com\/www.danielpradilla.info\/blog\/wp-content\/uploads\/2015\/06\/Screen-Shot-2015-06-05-at-5.26.54-PM.png?resize=350%2C200","width":350,"height":200},"classes":[]}],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/www.danielpradilla.info\/blog\/wp-json\/wp\/v2\/posts\/2229","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.danielpradilla.info\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.danielpradilla.info\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.danielpradilla.info\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.danielpradilla.info\/blog\/wp-json\/wp\/v2\/comments?post=2229"}],"version-history":[{"count":0,"href":"https:\/\/www.danielpradilla.info\/blog\/wp-json\/wp\/v2\/posts\/2229\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.danielpradilla.info\/blog\/wp-json\/wp\/v2\/media?parent=2229"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.danielpradilla.info\/blog\/wp-json\/wp\/v2\/categories?post=2229"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.danielpradilla.info\/blog\/wp-json\/wp\/v2\/tags?post=2229"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}