{"id":110,"date":"2024-01-09T16:09:28","date_gmt":"2024-01-10T00:09:28","guid":{"rendered":"https:\/\/blog.sacko.dev\/?p=110"},"modified":"2024-01-17T23:10:50","modified_gmt":"2024-01-18T07:10:50","slug":"gunicorn-permissions-and-ipv6-certbot-with-flask","status":"publish","type":"post","link":"https:\/\/blog.sacko.dev\/?p=110","title":{"rendered":"Gunicorn Permissions and IPv6 Certbot with Flask"},"content":{"rendered":"\n<p>Just a short post to talk about something since I&#8217;ve messed the permissions up multiple times. The IPv6 thing is new, though.<\/p>\n\n\n\n<p>Whenever I install a web server with Flask and Gunicorn, there&#8217;s always a problem with permissions with the \/var\/www\/[website-name]\/[website-name].sock. It also has to do with the file at \/etc\/systemd\/system\/[website-name].service; you want to make sure you set it up as a good user and group. Your linux username with <strong>www-data<\/strong> as group usually works for both fields.<\/p>\n\n\n\n<p>I set up a virtualenv within the website directory via <strong>virtualenv \/var\/www\/[website-name]<\/strong>, so your file layout might be different.<\/p>\n\n\n\n<p>First of all, make sure you set up the <strong>\/etc\/systemd\/system\/[website-name].service<\/strong> file properly. Here&#8217;s some example code:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;Unit]\nDescription=Gunicorn instance to serve <strong>&#91;website-name]<\/strong>\nAfter=nework.target\n\n&#91;Service]\nUser=<strong>&#91;linux-user]<\/strong>\nGroup=<strong>www-data<\/strong>\nWorkingDirectory=\/var\/www\/<strong>&#91;website-name]<\/strong>\nEnvironment=\"PATH=\/var\/www\/<strong>&#91;website-name]<\/strong>\/bin\"\nExecStart=\/var\/www\/<strong>&#91;website-name]<\/strong>\/bin\/gunicorn --workers 3 --bind unix:<strong>&#91;website-name]<\/strong>.sock -m 007 wsgi:app\n\n&#91;Install]\nWantedBy=multi-user.target\n<\/code><\/pre>\n\n\n\n<p>If you haven&#8217;t set this service to run automatically, here&#8217;s how you do that:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>systemctl start &#91;website-name] #starts the flask server\nsystemctl enable &#91;website-name] #runs on startup<\/code><\/pre>\n\n\n\n<p>To adjust the permissions for the website files as well as <strong>[website-name].sock<\/strong> file, run these commands:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>chown -R <strong>&#91;linux-user]:&#91;linux-user]<\/strong> \/var\/www\/<strong>&#91;website-name]<\/strong>\nchmod -R 775 <strong>&#91;linux-user]:&#91;linux-user]<\/strong> \/var\/www\/<strong>&#91;website-name]<\/strong>\n\n#might have to do this part while your flask server is running\nchmod 770 \/var\/www\/<strong>&#91;website-name]<\/strong>\/<strong>&#91;website-name]<\/strong>.sock\nchown <strong>&#91;linux-user]:www-data<\/strong> \/var\/www\/<strong>&#91;website-name]<\/strong>\/<strong>&#91;website-name]<\/strong>.sock<\/code><\/pre>\n\n\n\n<p>There&#8217;s more to the setup with Flask, Nginx and Gunicorn, but those are the parts I usually get stuck on.<\/p>\n\n\n\n<p>Another issue I ran into has to do with my VPS only allowing IPv6 on their cheapest plan. As a result, I have to set up some of my websites a bit differently to point them toward IPv6 to get the website to work and certbot to be able to successfully issue a certificate.<\/p>\n\n\n\n<p>One example is with the <strong>routes.py<\/strong> file, or the main Python code for Flask. I had to use &#8216;::&#8217; instead of &#8216;0.0.0.0&#8217; for the &#8216;host&#8217; value. Here&#8217;s the code for that, which should be at the end of the file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>if __name__ == '__main__':\n    app.run(host='::')<\/code><\/pre>\n\n\n\n<p>I also had to alter the Nginx server block for the website to make it work with ipv6. Just make sure to have this in it:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>server{\n    listen&#91;::]:80;\n    ...\n}<\/code><\/pre>\n\n\n\n<p>If you haven&#8217;t put your Nginx server block in sites-enabled with a symbolic link yet, do it with this command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ln -s \/etc\/nginx\/sites-available\/&#91;website-name] \/etc\/nginx\/sites-enabled\/<\/code><\/pre>\n\n\n\n<p>These changes should allow the website to connect and let you get a certbot certificate, as long as you have the appropriate AAAA ipv6 record for your domain.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Just a short post to talk about something since I&#8217;ve messed the permissions up multiple times. The IPv6 thing is new, though. Whenever I install a web server with Flask and Gunicorn, there&#8217;s always a problem with permissions with the \/var\/www\/[website-name]\/[website-name].sock. It also has to do with the file at \/etc\/systemd\/system\/[website-name].service; you want to make <a href=\"https:\/\/blog.sacko.dev\/?p=110\" class=\"more-link\">&#8230;<span class=\"screen-reader-text\">  Gunicorn Permissions and IPv6 Certbot with Flask<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[],"_links":{"self":[{"href":"https:\/\/blog.sacko.dev\/index.php?rest_route=\/wp\/v2\/posts\/110"}],"collection":[{"href":"https:\/\/blog.sacko.dev\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.sacko.dev\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.sacko.dev\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.sacko.dev\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=110"}],"version-history":[{"count":6,"href":"https:\/\/blog.sacko.dev\/index.php?rest_route=\/wp\/v2\/posts\/110\/revisions"}],"predecessor-version":[{"id":195,"href":"https:\/\/blog.sacko.dev\/index.php?rest_route=\/wp\/v2\/posts\/110\/revisions\/195"}],"wp:attachment":[{"href":"https:\/\/blog.sacko.dev\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=110"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.sacko.dev\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=110"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.sacko.dev\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=110"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}