How I got Python 3.6.1 and WSGI working on CentOS 7.3

Categories
HerpDerp mod_wsgi Mucking About With Things Python

I set out to get WSGI going, with Python 3.x, on my CentOS 7.3 VPS. Initially, I began by trying to follow the path laid out in a 2011 blog post (Building mod_wsgi with EasyApache for WHM/cPanel) but with current equivalents of Python and mod_wsgi. That’s a very lucidly written article and it’s apparent from the comments appended to it that it’s been very helpful to a number of people but more than five years have passed and the landscape has changed a bit (e.g. the code.google.com link) and I ended up having to muddle through on my own, to the extent that anyone is truly roughing it when they have access to Google, Stackoverflow, etc.

By chipping away at the problem for an hour here and an hour there each day, with inevitable missteps, I arrived at a working setup after a few days. What follows is a condensed description of the steps that worked, to the best of my recollection, with all of the dead ends and fruitless side quests omitted. It’s not, I’m sure, the most correct or robust solution and I’ll be improving it as I gain more sysadmin-ish competence.

  1. Downloaded Python-3.6.1 (as Python-3.6.1.tgz), placed it in /usr/local/src on my VPS, and installed it:
    ./configure --enable-shared
    make
    make install
    That gave me Python 3.6 install in /usr/local/bin.
  2. Downloaded Graham Dumpleton’s latest build of mod_wsgi 4.5.15 to my and installed it:
    wget -q "https://codeload.github.com/GrahamDumpleton/mod_wsgi/tar.gz/4.5.15"
    tar -xzf mod_wsgi-4.5.15*
    cd ./mod*
    ./configure --with-python=/usr/local/bin/python3.6
    
    When the installation finished, it printed an informative message, part of which said:
    Libraries have been installed in:
       /usr/lib64/apache2/modules
  3. Edited /etc/apache2/conf.d/mod_wsgi.conf (after some hunting around to figure out where it was), commenting out the existing LoadModule directive like so: #LoadModule wsgi_module modules/mod_wsgi.so and adding: LoadModule wsgi_module /usr/lib64/apache2/modules/mod_wsgi.so
  4. Found the relevant VirtualHost entry (e.g. for example.com) in my VPS’s Apache httpd.conf and added the following bits: WSGIScriptAlias /test /home/exampledotcom/public_html/wsgi-app-root/test.wsgi <Directory /home/exampledotcom/public_html/wsgi-app-root> Order deny,allow Allow from all </Directory> ErrorLog /home/exampledotcom/public_html/wsgi-app-root/wsgi-error.log LogLevel info CustomLog /home/exampledotcom/public_html/wsgi-app-root/wsgi-requests.log combined Restarted Apache and visited http://www.example.com/test/ and my test script was working.
    1. Here’s my test script (the contents of test.wsgi):

      import sys
      
      def application(environ, start_response):
          status = '200 OK'
          output = 'Howdy! '+sys.version
      
          response_headers = [('Content-type', 'text/plain'),
                              ('Content-Length', str(len(output)))]
      
          start_response(status, response_headers)
      
          return [output.encode('utf8')]

      It kicks out the following:

      Howdy! 3.6.1 (default, Apr 12 2017, 08:44:19) 
      [GCC 4.8.5 20150623 (Red Hat 4.8.5-11)]

      And the first line of the Apache Status output in WHM reads:

      Server Version: Apache/2.4.25 (cPanel) OpenSSL/1.0.1e-fips mod_bwlimited/1.4 mod_wsgi/4.5.15 Python/3.6
      

      The above, with all of the stuff-which-turned-out-to-be-pointless removed, seems very straightforward and quick. I’ve made notes of questions and concerns that have occurred to me as I worked this out and will review them in the not-too-distant future. So far, so good (for now).