Installing the API via WSGI

This document provides two WSGI methods as examples:

  • uWSGI

  • Apache mod_wsgi

The “wsgi.py” file

qinling/api/wsgi.py file sets up the API WSGI application, it has to be copied into /var/www/cgi-bin/qinling directory.

mkdir -p /var/www/cgi-bin/qinling
cp qinling/api/wsgi.py /var/www/cgi-bin/qinling
chown qinling:qinling -R /var/www/cgi-bin/qinling

Running with Apache and mod_wsgi

The etc/apache2/qinling-api.conf file contains an example of Apache virtualhost configured with mod_wsgi.

# Qinling API port
Listen 7070

#################
# Hardening 1/2 #
#################
ServerSignature Off
ServerTokens Prod
TraceEnable off

<VirtualHost *:7070>

  DocumentRoot "/var/www/cgi-bin/qinling"

  # Avoid this issue: https://bugs.launchpad.net/charm-heat/+bug/1717615
  AllowEncodedSlashes On

  ###########
  # Logging #
  ###########
  # Paths have to be changed to fit your deployment
  ErrorLog "/var/log/apache2/qinling_wsgi_error.log"
  LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b %D \"%{Referer}i\" \"%{User-Agent}i\"" logformat
  CustomLog "/var/log/apache2/qinling_wsgi_access.log" logformat

  ######################
  # WSGI configuration #
  ######################
  WSGIApplicationGroup %{GLOBAL}
  # Paths and user/group have to be changed to fit your deployment
  # Here Python 3.6 is issued.
  WSGIDaemonProcess qinling group=qinling processes=5 threads=1 user=qinling python-path=/var/lib/kolla/venv/lib/python3.6/site-packages
  WSGIProcessGroup qinling
  WSGIScriptAlias / "/var/www/cgi-bin/qinling/wsgi.py"
  WSGIPassAuthorization On

  #################
  # Hardening 2/2 #
  #################
  # Paths have to be changed to fit your deployment
  <Directory "/var/www/cgi-bin/qinling">
      <FilesMatch "^wsgi.py$">
        Options Indexes FollowSymLinks MultiViews
        Require all granted
      </FilesMatch>
  </Directory>

</VirtualHost>
  1. On deb-based systems copy or symlink the file to /etc/apache2/sites-available.

    For rpm-based systems the file will go in /etc/httpd/conf.d.

  2. Modify the WSGIDaemonProcess directive to set the user and group values to an appropriate user on your server. In many installations qinling will be correct. Modify the WSGIScriptAlias directive to set the path of the wsgi script.

    If you are using a virtualenv WSGIDaemonProcess requires python-path parameter, the value should be <your-venv-path>/lib/python<your-version>/site-packages.

  3. Enable the qinling-api virtualhost.

    On deb-based systems:

    a2ensite qinling-api
    systemctl reload apache2
    

    On rpm-based systems:

    systemctl reload httpd
    

Running with uWSGI

The etc/uwsgi/qinling-api.yaml file contains an example of uWSGI configuration.

  1. Create the qinling-api.yaml file.

    uwsgi:
      http-socket: 0.0.0.0:7070
      # Paths have to be changed to fit your deployment
      wsgi-file: /var/www/cgi-bin/qinling/wsgi.py
      chdir: /var/lib/kolla/venv/lib/python3.6/site-packages
      pythonpath: /var/lib/kolla/venv/lib/python3.6/site-packages
      virtualenv: /var/lib/kolla/venv
    
      plugins: python3
      # Set uid and gip to a appropriate user on your server. In many
      # installations qinling will be correct
      uid: qinling
      gid: qinling
    
      processes: 5
      threads: 1
      vacuum: true
      harakiri: 20
      buffer-size: 65535
      post-buffering: 8192
      # Set die-on-term and exit-on-reload so that uWSGI shuts down
      die-on-term: true
      exit-on-reload: true
      master: true
      enable-threads: true
      # uWSGI recommends this to prevent thundering herd on accept
      thunder-lock: true
      honour-stdin: true
      memory-report: false
    
  2. Then start the uWSGI server:

    uwsgi ./qinling-api.yaml
    

    Or start in background with:

    uwsgi -d ./qinling-api.yaml