Install on a server: Difference between revisions

From XPUB & Lens-Based wiki
(Created page with " Running Flask applications on the collective hub.xpub.nl servers is possible, but needs a couple of steps. There have been different attempts in the past: * use the officially recommended PrefixMiddleware! (100% success rate, see below) * for Kamo's notes: https://git.xpub.nl/kamo/pad-bis#nginx-configuration * use gunicorn: see Flask/Gunicorn * Flask official deployment page: https://flask.palletsprojects.com/en/stable/deploying/ ===PrefixMiddleware=== To insta...")
 
No edit summary
 
(16 intermediate revisions by 2 users not shown)
Line 1: Line 1:
''Part of the [[Flask]] page''


Running Flask applications on the collective hub.xpub.nl servers is possible, but needs a couple of steps.
Running Flask applications on the collective hub.xpub.nl servers is possible, but needs a couple of steps.
Line 13: Line 15:
To install your flask application on the sandbox server (sergio, cerealbox, etc), you need to take a few steps:
To install your flask application on the sandbox server (sergio, cerealbox, etc), you need to take a few steps:


# configure nginx
# add prefix.py to your flask applications OR put it in your 'app.py'
# upload your code to the server (i would recommend to work with a git repository!)
# upload your code to the server (i would recommend to work with a git repository!)
# add prefix.py to your flask applications
# configure nginx
# install your flask application as a systemd background process  
# install your flask application as a systemd background process  


====Add prefix.py====
==== Configure nginx ====
Add these two lines to your flask application script (there is an example [https://git.xpub.nl/manetta/flask-observations/src/branch/main/observations.py here]):
First, pick a '''port''' for your application, because we cannot all use port 5000! :)  


<syntaxhighlight lang="python">
<span style="color:magenta;">A suggestion: let's use the range 5100-5200, so anything in between these two port numbers.</span>
# there should be no slash at the end of this line!!
 
app.wsgi_app = PrefixMiddleware(app.wsgi_app, '/sergio/SI30/fieldwork-tools/YOURFOLDER')
<span style="color:magenta;">You can check the nginx config file to see which ones are used.</span>  
</syntaxhighlight>
 
<span style="color:magenta;">I used <code>5100</code> for the example flask application.</span>
 
'''Edit''' the nginx <code>hub.xpub.nl</code> config file and '''check for used ports''':
 
sudo nano /etc/nginx/sites-enabled/hub.xpub.nl
 
Scroll down until you find "FLASK APPLICATIONS HERE".
 
Paste this example into that section, and edit "YOUR_FOLDER" to your folder name.
 
        location /sergio/YOUR_FOLDER/ {
                proxy_pass [http://localhost:51??/sergio/your_name/ http://localhost:51??/sergio/YOUR_FOLDER/];
                include proxy_params;
        }
'''''!!! don't forget to include the <code>/</code> at the end + to put your new port'''''
 
====prefix.py====
Add these few lines to your flask application py script (there is an example [https://git.xpub.nl/manetta/flask-observations/src/branch/main/observations.py here]):


Add the following script to your flask folder and save it as <code>prefix.py</code>:
It can either be saved as a separated file as <code>prefix.py</code> '''or''' (better) being pasted into your main py file, like for example the usual <code>app.py</code>


<syntaxhighlight lang="python">
<syntaxhighlight lang="python">
Line 44: Line 64:
             start_response('404', [('Content-Type', 'text/plain')])
             start_response('404', [('Content-Type', 'text/plain')])
             return ["This url does not belong to the app.".encode()]
             return ["This url does not belong to the app.".encode()]
app.wsgi_app = PrefixMiddleware(app.wsgi_app, '/sergio/YOUR_FOLDER') #NO slash at the end of this line!!
</syntaxhighlight>
</syntaxhighlight>


====Configure nginx====
=== '''<big>Install as a systemd background process</big>''' ===
 
{{ :Service files }}
First, pick a '''port''' for your application, because we cannot all use port 5000! :)
 
<span style="color:magenta;">A suggestion: let's use the range 5100-5200, so anything in between these two port numbers. You can check the nginx config file below to see which ones are used. I used <code>5100</code> for the example flask application on sergio.</span>
 
Edit the nginx <code>hub.xpub.nl</code> config file:
 
sudo nano /etc/nginx/sites-enabled/hub.xpub.nl
 
Scroll down until you find "Flask applications here".
 
Copy this example into that section, and edit "YOURFOLDER" to your foldername.
 
<span style="color:magenta;">Tip! Give your tool a name. Wouldn't it be cool to not call it "Manetta's observations", but something else, so it describes what it does? And multiple people can use it?</span>
 
        location /sergio/SI30/fieldwork-tools/YOURFOLDER/ {
                proxy_pass http://localhost:5100/sergio/SI30/fieldwork-tools/YOURFOLDER/;
                include proxy_params;
        }
 
====Install as a systemd background process====


{{ :Service files }}
[[Category:Raspberry Pi]] [[Category:flask]]

Latest revision as of 13:58, 7 July 2026

Part of the Flask page


Running Flask applications on the collective hub.xpub.nl servers is possible, but needs a couple of steps.

There have been different attempts in the past:

PrefixMiddleware

To install your flask application on the sandbox server (sergio, cerealbox, etc), you need to take a few steps:

  1. configure nginx
  2. add prefix.py to your flask applications OR put it in your 'app.py'
  3. upload your code to the server (i would recommend to work with a git repository!)
  4. install your flask application as a systemd background process

Configure nginx

First, pick a port for your application, because we cannot all use port 5000! :)

A suggestion: let's use the range 5100-5200, so anything in between these two port numbers.

You can check the nginx config file to see which ones are used.

I used 5100 for the example flask application.

Edit the nginx hub.xpub.nl config file and check for used ports:

sudo nano /etc/nginx/sites-enabled/hub.xpub.nl

Scroll down until you find "FLASK APPLICATIONS HERE".

Paste this example into that section, and edit "YOUR_FOLDER" to your folder name.

        location /sergio/YOUR_FOLDER/ {
                proxy_pass http://localhost:51??/sergio/YOUR_FOLDER/;
                include proxy_params;
        }

!!! don't forget to include the / at the end + to put your new port

prefix.py

Add these few lines to your flask application py script (there is an example here):

It can either be saved as a separated file as prefix.py or (better) being pasted into your main py file, like for example the usual app.py

class PrefixMiddleware(object):

    def __init__(self, app, prefix=''):
        self.app = app
        self.prefix = prefix

    def __call__(self, environ, start_response):

        if environ['PATH_INFO'].startswith(self.prefix):
            environ['PATH_INFO'] = environ['PATH_INFO'][len(self.prefix):]
            environ['SCRIPT_NAME'] = self.prefix
            return self.app(environ, start_response)
        else:
            start_response('404', [('Content-Type', 'text/plain')])
            return ["This url does not belong to the app.".encode()]

app.wsgi_app = PrefixMiddleware(app.wsgi_app, '/sergio/YOUR_FOLDER') #NO slash at the end of this line!!

Install as a systemd background process

Making a systemd service file

When you deploy your application on a server, you need to make sure the application runs uninterrupted. If the application crashes, you'd want it to automatically restart, and if the server experiences a power outage, you'd want the application to start immediately once power is restored.

SEE: https://blog.miguelgrinberg.com/post/running-a-flask-application-as-a-service-with-systemd

Useful: https://containersolutions.github.io/runbooks/posts/linux/debug-systemd-service-units/

$ sudo nano /etc/systemd/system/YOUR_NAME_OF_THE_APP.service
[Unit]
Description=<a description of your application>
After=network.target

[Service]
User=<username>
WorkingDirectory=<path to your app>
ExecStart=<app start command>
Restart=always

[Install]
WantedBy=multi-user.target

Here is an example:

 [Unit]
 Description=Bla Bla Bla made in Flask
 After=network.target
 
 [Service]
 User=YOUR_USERNAME
 WorkingDirectory=/YOUR/PATH/
 ExecStart=/YOUR/PATH/.venv/bin/flask --app NAME_OF_YOUR_PY_FILE run --port 51?? #DO NOT PUT .py AT THE END + #PUT YOUR_PORT
 Restart=always
 
 [Install]
 WantedBy=multi-user.target

1st thing to do when your .service file is new or changed

$ sudo systemctl daemon-reload

Then in order:

$ sudo systemctl start YOUR_NAME_OF_THE_APP
$ sudo systemctl status YOUR_NAME_OF_THE_APP

When you see that it's working (checking its status, that it actually is running, etc...)

$ sudo systemctl enable YOUR_NAME_OF_THE_APP

Will make the "service" auto start when the pi restarts.

Additional commands:

$ sudo systemctl restart YOUR_NAME_OF_THE_APP
$ sudo systemctl stop YOUR_NAME_OF_THE_APP

To view the log file (errors):

$ sudo journalctl -u YOUR_NAME_OF_THE_APP -f

You can find documentation here:

https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html