0

I am trying to make two apps accessible on my LAN server (raspberry pi).

  • lab_app: this one is a very simple app, made with flask from a third party, using a sqlite3 database, which results to be a file inside my app folder. It is located at path /var/www/lab_app/ and runs on internal port 8080, external port 80.
    if __name__ == "__main__":
        app.run(host='0.0.0.0', port=8080)
  • aqi_luftdaten: a more complex app, made with django by me, using postgresql database. It is located at path /var/www/aqi_luftdaten/ and runs on internal port 8000 - I have manually started it via command:

    python manage.py runserver 0.0.0.0:8000

For the moment, only lab_app is working and accessible:

Its web server is nginx and its application server is uWSGI.

nginx is configured in this way:

there is a configuration file /var/www/lab_app/lab_app_nginx.conf which is pointed by a simbolic link from directory /etc/nginx/conf.d

ln -s /var/www/lab_app/lab_app_nginx.conf /etc/nginx/conf.d/

Its content is

    server {
        listen      80;
        server_name localhost;
        charset     utf-8;
        client_max_body_size 75M;
    location /static {
        root /var/www/lab_app/;
    }

    location / { try_files $uri @labapp; }
    location @labapp {
        include uwsgi_params;
        uwsgi_pass unix:/var/www/lab_app/lab_app_uwsgi.sock;
    }
}

by following a tutorial, I have removed the default nginx sites-enabled config file, so that the directory /etc/nginx/sites-enabled is void.

Inside the directory /etc/nginx/sites-available/ there is only the default file /etc/nginx/sites-available/default.

Its content is

    server {
        listen 80 default_server;
        listen [::]:80 default_server;
    root /var/www/html;

    index index.html index.htm index.nginx-debian.html;

    server_name _;

    location / {
        try_files $uri $uri/ =404;
    }

}

uWSGI is configured in this way:

there is a file /var/www/lab_app/lab_app_uwsgi.ini having content:

    [uwsgi]
    #application's base folder
    base = /var/www/lab_app
#python module to import
app = lab_app
module = %(app)

home = %(base)
pythonpath = %(base)

#socket file's location
socket = /var/www/lab_app/%n.sock

#permissions for the socket file
chmod-socket    = 666

#the variable that holds a flask application inside the module imported at line #6
callable = app

#location of log files
logto = /var/log/uwsgi/%n.log

I have loaded its information to uWSGI by using the command

bin/uwsgi --ini /var/www/lab_app/lab_app_uwsgi.ini

and then there is a file /etc/systemd/system/emperor.uwsgi.service having content

    [Unit]
    Description=uWSGI Emperor
    After=syslog.target
[Service]
ExecStart=/var/www/lab_app/bin/uwsgi --ini /var/www/lab_app/lab_app_uwsgi.ini
# Requires systemd version 211 or newer
RuntimeDirectory=uwsgi
Restart=always
KillSignal=SIGQUIT
Type=notify
StandardError=syslog
NotifyAccess=all

[Install]
WantedBy=multi-user.target

This app runs fine on my LAN and is reachable at my server's ip from an external device browser.

Now I would like to expose app aqi_luftdaten on external port 80.

So the first thing I want to do is to configure nginx for this app.

So I have created an nginx config file /var/www/aqi_luftdaten/nginx/aqi_luftdaten_nginx.conf, having content

    server {
        listen      3000;
        server_name localhost;
        charset     utf-8;
        client_max_body_size 75M;
    location /static/ {
        root /var/www/aqi_luftdaten/static/;
    }

    location / { 
    proxy_pass http://localhost:8000;
    }
}

and linked it symbolically to directory /etc/nginx/conf.d/ via

ln -s /var/www/aqi_luftdaten/nginx/aqi_luftdaten_nginx.conf /etc/nginx/conf.d/

then restart nginx

/etc/init.d/nginx restart

and I get

[ ok ] Restarting nginx (via systemctl): nginx.service.

If I try to reach the aqi_luftdaten application in the browser of another device http://<raspberrypi_IP>:3000/ I get

    <html><head><title>502 Bad Gateway</title></head>
    <body bgcolor="white">
    <center><h1>502 Bad Gateway</h1></center>
    <hr><center>nginx/1.14.2</center>
    </body></html>

which I guess is right, since the uWSGI is not configured yet.

now I would like to configure gunicorn.

There is a file /var/www/aqi_luftdaten/gunicorn/aqi_luftdaten.wsgi having the following content:

    import os
    from django.core.wsgi import get_wsgi_application
# environment settings for Django app
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'aqi_luftdaten.settings')

# Initialize app Django
application = get_wsgi_application()

so I run

sudo su
cd /var/www/aqi_luftdaten/
source venv/bin/activate
sudo venv/bin/gunicorn gunicorn.aqi_luftdaten.wsgi:application --bind localhost:8000

but I get

[2024-04-01 14:48:20 +0100] [7595] [INFO] Starting gunicorn 20.0.4
[2024-04-01 14:48:20 +0100] [7595] [INFO] Listening at: http://127.0.0.1:8000 (7595)
[2024-04-01 14:48:20 +0100] [7595] [INFO] Using worker: sync
[2024-04-01 14:48:20 +0100] [7597] [INFO] Booting worker with pid: 7597
[2024-04-01 14:48:20 +0100] [7597] [ERROR] Exception in worker process
Traceback (most recent call last):
  File "/var/www/aqi_luftdaten/venv/lib/python3.8/site-packages/gunicorn/arbiter.py", line 583, in spawn_worker
    worker.init_process()
  File "/var/www/aqi_luftdaten/venv/lib/python3.8/site-packages/gunicorn/workers/base.py", line 119, in init_process
    self.load_wsgi()
  File "/var/www/aqi_luftdaten/venv/lib/python3.8/site-packages/gunicorn/workers/base.py", line 144, in load_wsgi
    self.wsgi = self.app.wsgi()
  File "/var/www/aqi_luftdaten/venv/lib/python3.8/site-packages/gunicorn/app/base.py", line 67, in wsgi
    self.callable = self.load()
  File "/var/www/aqi_luftdaten/venv/lib/python3.8/site-packages/gunicorn/app/wsgiapp.py", line 49, in load
    return self.load_wsgiapp()
  File "/var/www/aqi_luftdaten/venv/lib/python3.8/site-packages/gunicorn/app/wsgiapp.py", line 39, in load_wsgiapp
    return util.import_app(self.app_uri)
  File "/var/www/aqi_luftdaten/venv/lib/python3.8/site-packages/gunicorn/util.py", line 358, in import_app
    mod = importlib.import_module(module)
  File "/usr/local/opt/python-3.8.1/lib/python3.8/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 961, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 973, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'gunicorn.aqi_luftdaten'
[2024-04-01 14:48:20 +0100] [7597] [INFO] Worker exiting (pid: 7597)
[2024-04-01 14:48:20 +0100] [7595] [INFO] Shutting down: Master
[2024-04-01 14:48:20 +0100] [7595] [INFO] Reason: Worker failed to boot.

so it seems it cannot find my file /var/www/aqi_luftdaten/gunicorn/aqi_luftdaten.wsgi , but I don't understand why.

I have also tried to launch

venv/bin/gunicorn gunicorn.aqi_luftdaten.wsgi:application --bind localhost:8000

without the sudo, but the error remains

Sybuser
  • 107
Tms91
  • 105

1 Answers1

0

By following this thread , I have moved my file /var/www/aqi_luftdaten/gunicorn/aqi_luftdaten.wsgi to /var/www/aqi_luftdaten/aqi_luftdaten.wsgi and then runned

PYTHONPATH=`pwd`/.. venv/bin/gunicorn aqi_luftdaten.wsgi:application --bind localhost:8000

and now the app works and is reachable at http://<RaspberryIP>:3000/ from any external device browser connected to the LAN

Tms91
  • 105