Install on a FreeBSD machine using uWSGI and a local enviroment

There are plenty off more or less clear tutorials on the web. As the FreeBSD 12 has a new Python version (3.7.x), I followed the tutorial of this guy, but also looked into the uWSGI docs and some FreeBSD websites for hints.

  1. Use the packages of uWSGI and py37-sqlite to install all basic packages. We will install flask and ResearchNotes into a virtuell environment than. But having uWSGI available let’s later use the rc.conf to start up things automatically.

     pkg install uWSGI
     pkg install py37-sqlite3
    
  2. Create a virtual environment in the nginix www directory, we will use for everything. Later, we will fight with permissions, so use something, we can easy tinker with.

     python3.7 -m venv /usr/local/www/ResearchNotes/ResearchNotes
     source venv /usr/local/www/ResearchNotes/ResearchNotes/bin/activate
     pip install ResearchNotes-1.0.x-xxx.whl 
    

(make sure, you have the install package in the directory you call as it is not downloadable from any respotory like PyPi).

  1. Create a wsgi app (wsgi.py)

     from myapp import create_app
    
     app = create_app()
    
     if __name__ == "__main__":
         app.run(host='0.0.0.0')
    
  2. Create a .ini for calling the app. Make sure, you have a directory for the socket, nginx and uwsgi can access (e.g. /usr/local/www/ResearchNotes and make uWSGI run as www:www).

     [uwsgi]
     chdir = /usr/local/www/ResearchNotes/
     module = wsgi:app
    
     processes = 2
     threads = 4
     #plugin = python38
     virtualenv = /usr/local/www/ResearchNotes/ResearchNotes
    
     master = true
     socket = /usr/local/www/ResearchNotes/ResearchNotes.sock
     chmod-socket = 664
     vacuum = true
    
     die-on-term = true
    
  3. Test this by calling

     uswgi ResearchNotes.ini -uid www -gid www
    

If this works be happy. I spend 2h fighting with the right access to all sockets and directories. I changed owner of the directory and all it’s content to to www:www

   chown -R www:www LabSpace/
  1. Finally, modify the rc.conf to enable uWSGI on start, copy the .ini to the uWSGI ini or vassal directory. Make sure, that your ResearchNotes upload and database is accessible by www:www (or the uWSGI process you are using). Otherwise, you will have Bad Gateway error from nginx. Finally used uwsgi startup script in /usr/local/etc/rc.d

      : ${uwsgi_enable="NO"}
      : ${uwsgi_socket="/tmp/${name}.sock"}
      : ${uwsgi_socket_mode="664"}
      : ${uwsgi_socket_owner="www:www"}
      : ${uwsgi_configfile="/usr/local/etc/uwsgi/uwsgi.ini"}
      : ${uwsgi_profiles=""}
      : ${uwsgi_logfile="/var/log/${name}.log"}
      : ${uwsgi_pidfile="/var/run/${name}.pid"}
      : ${uwsgi_uid="www"}
      : ${uwsgi_gid="www"}
      : ${uwsgi_flags="-L"}
      : ${uwsgi_emperor="NO"}
      : ${uwsgi_vassals_dir="/usr/local/etc/uwsgi/vassals"}
    
  2. Make a first simple nginx.conf entry. I used the nginx.conf directly and none of the sub-configuration files. I prefer binding to a dedicated port and IP address as I have also a nextcloud and ampach installation on the same server. Ampache and ResearchNotes share the same jail. Relevant part of the nginx.conf:

       server {
         listen 192.168.2.25:80;
         server_name 192.168.2.25;
         charset utf-8;
    
         #Increase uplaod size to 100 MB as we have to get measurements uploaded.
         client_max_body_size 100M;
    
        # Use secure headers to avoid XSS and many other things
        add_header X-Content-Type-Options nosniff;
        add_header X-XSS-Protection "1; mode=block";
        add_header X-Robots-Tag none;
        add_header X-Download-Options noopen;
        add_header X-Permitted-Cross-Domain-Policies none;
        add_header X-Frame-Options "SAMEORIGIN" always;
        add_header Referrer-Policy "no-referrer";
        add_header Content-Security-Policy "script-src 'self' 'unsafe-inline' 'unsafe-eval'; frame-src 'self'; object-src 'self'";
    
        location ^~ /static  {
           alias /usr/local/www/ResearchNotes/ResearchNotes/lib/python3.7/site-packages/ResearchNotes/static;
        }
    
        location / {
           include uwsgi_params;
           uwsgi_pass unix:///usr/local/www/ResearchNotes/ResearchNotes.sock;
    
           uwsgi_param Host $host;
           uwsgi_param X-Real-IP $remote_addr;
           uwsgi_param X-Forwarded-For $proxy_add_x_forwarded_for;
           uwsgi_param X-Forwarded-Proto $http_x_forwarded_proto;
    
        }
      }
    

Reading configuration suggestions for nginx, we can optimize performance by letting nginx serve the static files and do micro-caching. Also, if we start using TLS/SSL some header forwarding might be needed. Maybe, define some access restruction to part of the directory for security.