{"id":928,"date":"2017-10-31T21:28:59","date_gmt":"2017-10-31T19:28:59","guid":{"rendered":"https:\/\/www.bartbarnard.nl\/blog\/?p=928"},"modified":"2019-07-15T15:52:52","modified_gmt":"2019-07-15T13:52:52","slug":"het-opzetten-van-nginx-op-ox-x","status":"publish","type":"post","link":"https:\/\/www.bartbarnard.nl\/blog\/het-opzetten-van-nginx-op-ox-x\/","title":{"rendered":"Het opzetten van nginx op os-x"},"content":{"rendered":"<p><strong>Introductie<\/strong><br \/>\nNu we bezig zijn met het opzetten van een nieuwe server, vond ik het een mooi moment een oud flask\/sqlalchemy weer wat nieuw leven in te blazen. Dit projectje is volgens de git-logs een jaar geleden tot stilstand gekomen, vlak voordat ik een eerste versie in productie wilde zetten. Ik had toen geen zin (want tijd maak je wel als je zin hebt) om uit te zoeken hoe dat exact moest en daarna is het in de dagelijkse drukte ondergesneeuwd.\u00a0 Maar die nieuwe server was een mooie aanleiding om een maandagavond op te offeren om er eens goed voor te gaan zitten.<\/p>\n<p><strong>Flask en nginx<\/strong><br \/>\nFlask levert een ingebouwde server mee, maar <a href=\"http:\/\/flask.pocoo.org\/docs\/0.12\/deploying\/\">die is niet geschikt voor productiedoeleinden<\/a>. Je kunt met mod_wsgi <a href=\"http:\/\/flask.pocoo.org\/docs\/0.12\/deploying\/mod_wsgi\/\">apache wel configureren om flask te serven<\/a>, maar gebruikelijk is het om hiervoor de server ngnix te gebruiken. Ik had al bedacht dat als ik de applicatie via ngnix op poort 8080 (of zo) zou kunnen laten draaien, dat het dan relatief eenvoudig zou moeten zijn om dat via apache weer door te sluizen (maar dat is voor later zorg).<\/p>\n<p>Voordat ik deze architectuur op de productieserver ging opzetten, wilde ik eerst eens alle noodzakelijke stappen op mijn eigen mac uitproberen en documenteren (en deze blog schrijven). Ik had al geruime tijd geleden <a href=\"http:\/\/vladikk.com\/2013\/09\/12\/serving-flask-with-nginx-on-ubuntu\/\">een vrij goede tutorial<\/a> gevonden, maar die is wel bedoeld voor Ubuntu en ook op details wat achterhaald. Dus ben ik zelf maar aan de slag gegaan, met die tutorial als basis.<\/p>\n<p>Vreemd genoeg kon ik geen package manager voor OS-X vinden die ngnix kon downloaden. Zowel pip3 als easy_install als brew gaven aan dat ze geen distributie hiervoor konden vinden. Dus toen maar gewoon <a href=\"http:\/\/nginx.org\/en\/download.html\">de tarball gedownload<\/a> en zelf de boel installeren. De eerste configuratie ging echter mis, omdat ik iets vergeten was:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n.\/configure --sbin-path=\/usr\/local\/nginx\/nginx\u00a0 --conf-path=\/usr\/local\/nginx\/nginx.conf\u00a0\u00a0 --pid-path=\/usr\/local\/nginx\/nginx.pid\u00a0\u00a0 --with-http_ssl_module\r\n\r\n.\/configure: error: the HTTP rewrite module requires the PCRE library.\r\nYou can either disable the module by using --without-http_rewrite_module\r\noption, or install the PCRE library into the system, or build the PCRE library\r\nstatically from the source with nginx by using --with-pcre=&lt;path&gt; option.\r\n<\/pre>\n<p>Ook best logisch, want zoals <a href=\"http:\/\/www.rexegg.com\/regex-uses.html#apache\">de meeste webservers<\/a> maakt ook nginx uitgebreid gebruik van reguliere expressies voor rewrite en dergelijke. Het is mogelijk om nginx te installeren zonder pcre, maar het is beter om ze wel mee te nemen. Dus eerst <a href=\"https:\/\/ftp.pcre.org\/pub\/pcre\/\">dat maar installeren<\/a>, waarbij het wel van belang is dat je onthoudt wat je als prefix meegeeft, want die heb je later weer nodig bij de configuratie van nginx zelf:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n$ cd pcre-8.41\r\n$ .\/configure --prefix=\/usr\/local\r\n$ sudo make install\r\n<\/pre>\n<p>Nu kunnen we nginx goed configureren:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n$ .\/configure\u00a0 --sbin-path=\/usr\/local\/nginx\/nginx --conf-path=\/usr\/local\/nginx\/nginx.conf --pid-path=\/usr\/local\/nginx\/nginx.pid --with-http_ssl_module --with-pcre=..\/pcre-8.41\r\n$ make\r\n$ sudo make install\r\n<\/pre>\n<p>Als je de boel dan wilt opstarten, kun je een foutmelding verwachten: nginx luistert standaard naar poort 80, maar ik heb (zoals de meeste mensen) ook apache al draaien die ook naar die poort luistert:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n$ sudo \/usr\/local\/nginx\/nginx\r\nnginx: [emerg] bind() to 0.0.0.0:80 failed (48: Address already in use)\r\nnginx: [emerg] bind() to 0.0.0.0:80 failed (48: Address already in use)\r\nnginx: [emerg] bind() to 0.0.0.0:80 failed (48: Address already in use)\r\nnginx: [emerg] bind() to 0.0.0.0:80 failed (48: Address already in use)\r\nnginx: [emerg] bind() to 0.0.0.0:80 failed (48: Address already in use)\r\nnginx: [emerg] still could not bind()\r\n<\/pre>\n<p>Eenvoudig de configuratie aanpassen, waarbij je de poort naar 8080 zet; dan werkt het.<\/p>\n<p><img loading=\"lazy\" class=\"aligncenter size-medium wp-image-929\" src=\"https:\/\/www.bartbarnard.nl\/blog\/wp-content\/uploads\/2017\/10\/nginx1-300x189.png\" alt=\"\" width=\"300\" height=\"189\" srcset=\"https:\/\/www.bartbarnard.nl\/blog\/wp-content\/uploads\/2017\/10\/nginx1-300x189.png 300w, https:\/\/www.bartbarnard.nl\/blog\/wp-content\/uploads\/2017\/10\/nginx1.png 683w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/p>\n<p><strong>nginx en uWSGI<\/strong><br \/>\nIn principe kan nginx alleen maar statische bestanden serven. Om python uit te kunnen laten voeren en het resultaat daarvan te serven heb je uWSGI nodig. Vreemd genoeg kon ik die wel gewoon met pip3 installeren:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n$ pip3 install uwsgi\r\nCollecting uwsgi\r\nDownloading uwsgi-2.0.15.tar.gz (795kB)\r\n100% |\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588| 798kB 712kB\/s\r\nInstalling collected packages: uwsgi\r\nRunning setup.py install for uwsgi ... done\r\nSuccessfully installed\u00a0 uwsgi-2.0.15\r\n$\r\n<\/pre>\n<p>Voor deze test had ik een eenvoudige flask applicatie geschreven in de directory \/Sites\/flask\/. Om nginx en uWSGI aan elkaar te knopen, veranderde ik eerst opnieuw het config-bestand van de eerste om hem naar de juiste directory te verwijzen:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nserver {\r\n  listen\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 8080;\r\n  server_name\u00a0 localhost;\r\n  charset utf-8;\r\n\r\n  location \/ { try_files $uri @the_application; }\r\n  location @the_application {\r\n    include uwsgi_params;\r\n    uwsgi_pass unix:\/Sites\/flask\/demoapp_uwsgi.sock;\r\n  }\r\n<\/pre>\n<p>Nu krijgen we een foutmelding; dat verwachtte ik ook, want dat .sock bestaat nog niet, omdat we uWSGI nog niet geconfigureerd:<\/p>\n<p><img loading=\"lazy\" class=\"aligncenter size-medium wp-image-930\" src=\"https:\/\/www.bartbarnard.nl\/blog\/wp-content\/uploads\/2017\/10\/nginx2-300x174.png\" alt=\"\" width=\"300\" height=\"174\" srcset=\"https:\/\/www.bartbarnard.nl\/blog\/wp-content\/uploads\/2017\/10\/nginx2-300x174.png 300w, https:\/\/www.bartbarnard.nl\/blog\/wp-content\/uploads\/2017\/10\/nginx2.png 753w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>De configuratie van uWSGI doen we via een .ini-bestand in de directory waar nginx naar kijkt, dus \/Sites\/flask\/. Hier kopieerde ik voornamelijk de code in die in de tutorial staan, met wat voor zichzelf sprekende aanpassingen. Nu kunnen we de boel opstarten met<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nsudo uwsgi --ini demoapp_uwsgi.ini\r\n<\/pre>\n<p><strong>Twee verschillende versies<\/strong><br \/>\nIn principe zou dit moeten werken, maar er gebeurde niks. Pas toen ik de error-logs keek, zag ik dat er bij het opstarten van uWSGI een foutmelding kwam:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nModuleNotFoundError: No module named 'encodings'\r\n<\/pre>\n<p>Het blijkt dat de python-versie die gelinkt is aan uWSGI<a href=\"https:\/\/stackoverflow.com\/questions\/42086692\/django-pyenv-uwsgi-modulenotfounderror-no-module-named-django\"> dezelfde moet zijn<\/a> als de versie die op het os draait. Stom genoeg draai ik nog standaard 2.7 (hoewel ik alles allang in 3.6 doe). Het makkelijkste is om even een virtuele omgeving op te zetten met de juiste python-versie en dan van daaruit uWSGI op te starten. Het enige is dat ik dan alle dependencies daar weer in moet installeren, maar dat is voorlopig alleen Flask dus dat valt wel mee.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n$ source venv\/bin\/activate\r\n(venv) argentina-minor:flask bart$ sudo uwsgi --ini demoapp_uwsgi.ini\r\nPassword:\r\n[uWSGI] getting INI configuration from demoapp_uwsgi.ini\r\n<\/pre>\n<p>Nu hebben we eindelijk het gewenste resultaat (let op het poortnummer):<\/p>\n<p><img loading=\"lazy\" class=\"aligncenter size-medium wp-image-931\" src=\"https:\/\/www.bartbarnard.nl\/blog\/wp-content\/uploads\/2017\/10\/nginx3-300x171.png\" alt=\"\" width=\"300\" height=\"171\" srcset=\"https:\/\/www.bartbarnard.nl\/blog\/wp-content\/uploads\/2017\/10\/nginx3-300x171.png 300w, https:\/\/www.bartbarnard.nl\/blog\/wp-content\/uploads\/2017\/10\/nginx3.png 755w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/p>\n<p><strong>De volgende stap<\/strong><br \/>\nDe volgende stap is dit alles als achtergrondproces te laten draaien, maar dat is een volgend projectje. Ik ga eerst proberen deze zelfde stappen op de productieserver uit te voeren.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introductie Nu we bezig zijn met het opzetten van een nieuwe server, vond ik het een mooi moment een oud flask\/sqlalchemy weer wat nieuw leven in te blazen. Dit projectje is volgens de git-logs een jaar geleden tot stilstand gekomen, vlak voordat ik een eerste versie in productie wilde zetten. Ik had toen geen zin<\/p>\n<p class=\"more-link\"><a href=\"https:\/\/www.bartbarnard.nl\/blog\/het-opzetten-van-nginx-op-ox-x\/\" class=\"themebutton2\">Read More<\/a><\/p>\n","protected":false},"author":1,"featured_media":929,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[19],"tags":[],"_links":{"self":[{"href":"https:\/\/www.bartbarnard.nl\/blog\/wp-json\/wp\/v2\/posts\/928"}],"collection":[{"href":"https:\/\/www.bartbarnard.nl\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.bartbarnard.nl\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.bartbarnard.nl\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.bartbarnard.nl\/blog\/wp-json\/wp\/v2\/comments?post=928"}],"version-history":[{"count":4,"href":"https:\/\/www.bartbarnard.nl\/blog\/wp-json\/wp\/v2\/posts\/928\/revisions"}],"predecessor-version":[{"id":961,"href":"https:\/\/www.bartbarnard.nl\/blog\/wp-json\/wp\/v2\/posts\/928\/revisions\/961"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.bartbarnard.nl\/blog\/wp-json\/wp\/v2\/media\/929"}],"wp:attachment":[{"href":"https:\/\/www.bartbarnard.nl\/blog\/wp-json\/wp\/v2\/media?parent=928"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.bartbarnard.nl\/blog\/wp-json\/wp\/v2\/categories?post=928"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.bartbarnard.nl\/blog\/wp-json\/wp\/v2\/tags?post=928"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}