Gunicorn Permissions and IPv6 Certbot with Flask

Just a short post to talk about something since I’ve messed the permissions up multiple times. The IPv6 thing is new, though.

Whenever I install a web server with Flask and Gunicorn, there’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 www-data as group usually works for both fields.

I set up a virtualenv within the website directory via virtualenv /var/www/[website-name], so your file layout might be different.

First of all, make sure you set up the /etc/systemd/system/[website-name].service file properly. Here’s some example code:

[Unit]
Description=Gunicorn instance to serve [website-name]
After=nework.target

[Service]
User=[linux-user]
Group=www-data
WorkingDirectory=/var/www/[website-name]
Environment="PATH=/var/www/[website-name]/bin"
ExecStart=/var/www/[website-name]/bin/gunicorn --workers 3 --bind unix:[website-name].sock -m 007 wsgi:app

[Install]
WantedBy=multi-user.target

If you haven’t set this service to run automatically, here’s how you do that:

systemctl start [website-name] #starts the flask server
systemctl enable [website-name] #runs on startup

To adjust the permissions for the website files as well as [website-name].sock file, run these commands:

chown -R [linux-user]:[linux-user] /var/www/[website-name]
chmod -R 775 [linux-user]:[linux-user] /var/www/[website-name]

#might have to do this part while your flask server is running
chmod 770 /var/www/[website-name]/[website-name].sock
chown [linux-user]:www-data /var/www/[website-name]/[website-name].sock

There’s more to the setup with Flask, Nginx and Gunicorn, but those are the parts I usually get stuck on.

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.

One example is with the routes.py file, or the main Python code for Flask. I had to use ‘::’ instead of ‘0.0.0.0’ for the ‘host’ value. Here’s the code for that, which should be at the end of the file:

if __name__ == '__main__':
    app.run(host='::')

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:

server{
    listen[::]:80;
    ...
}

If you haven’t put your Nginx server block in sites-enabled with a symbolic link yet, do it with this command:

ln -s /etc/nginx/sites-available/[website-name] /etc/nginx/sites-enabled/

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.

Leave a Reply

Your email address will not be published. Required fields are marked *