Michael Merickel
2018-10-16 8eed333343e4e9e7f11f3aee67299030d6bf2783
docs/tutorials/modwsgi/index.rst
@@ -1,140 +1,141 @@
.. _modwsgi_tutorial:
Running a :mod:`repoze.bfg` Application under ``mod_wsgi``
==========================================================
Running a :app:`Pyramid` Application under ``mod_wsgi``
=======================================================
:term:`mod_wsgi` is an Apache module developed by Graham Dumpleton.
It allows :term:`WSGI` programs to be served using the Apache web
server.
This guide will outline broad steps that can be used to get a
:mod:`repoze.bfg` application running under Apache via ``mod_wsgi``.
This particular tutorial was developed under Apple's Mac OS X platform
(Snow Leopard, on a 32-bit Mac), but the instructions should be
largely the same for all systems, delta specific path information for
commands and files.
This guide will outline broad steps that can be used to get a :app:`Pyramid`
application running under Apache via ``mod_wsgi``.  This particular tutorial
was developed under Apple's macOS platform (Snow Leopard, on a 32-bit
Mac), but the instructions should be largely the same for all systems, delta
specific path information for commands and files.
.. note:: Unfortunately these instructions almost certainly won't work
   for deploying a :mod:`repoze.bfg` application on a Windows system
   using ``mod_wsgi``.  If you have experience with :mod:`repoze.bfg`
   and and ``mod_wsgi`` on Windows systems, please help us document
   this experience by submitting documentation to the `mailing list
   <http://lists.repoze.org/listinfo/repoze-dev>`_.
.. note:: Unfortunately these instructions almost certainly won't work for
   deploying a :app:`Pyramid` application on a Windows system using
   ``mod_wsgi``.  If you have experience with :app:`Pyramid` and ``mod_wsgi``
   on Windows systems, please help us document this experience by submitting
   documentation to the `Pylons-devel maillist
   <https://groups.google.com/forum/#!forum/pylons-devel>`_.
#.  The tutorial assumes you have Apache already installed on your
    system.  If you do not, install Apache 2.X for your platform in
    whatever manner makes sense.
#.  It is also assumed that you have satisfied the
    :ref:`requirements-for-installing-packages`.
#.  Once you have Apache installed, install ``mod_wsgi``.  Use the
    (excellent) `installation instructions
    <http://code.google.com/p/modwsgi/wiki/InstallationInstructions>`_
    <https://code.google.com/archive/p/modwsgi/wikis/InstallationInstructions.wiki>`_
    for your platform into your system's Apache installation.
#.  Install :term:`virtualenv` into the Python which mod_wsgi will
    run using the ``easy_install`` program.
#.  Create a :app:`Pyramid` application using our :term:`cookiecutter`. See
    :ref:`project_narr` for more in-depth information about creating a new
    project.
    .. code-block:: bash
       :linenos:
       $ sudo /usr/bin/easy_install-2.6 virtualenv
        cd ~
        cookiecutter gh:Pylons/pyramid-cookiecutter-starter --checkout 1.10-branch
    This command may need to be performed as the root user.
    If prompted for the first item, accept the default ``yes`` by hitting return.
#.  Create a :term:`virtualenv` which we'll use to install our
    application.
    .. code-block:: text
        You've cloned ~/.cookiecutters/pyramid-cookiecutter-starter before.
        Is it okay to delete and re-clone it? [yes]: yes
        project_name [Pyramid Scaffold]: myproject
        repo_name [myproject]: myproject
        Select template_language:
        1 - jinja2
        2 - chameleon
        3 - mako
        Choose from 1, 2, 3 [1]: 1
        Select backend:
        1 - none
        2 - sqlalchemy
        3 - zodb
        Choose from 1, 2, 3 [1]: 1
#.  Create a :term:`virtual environment` which we'll use to install our
    application. It is important to use the same base Python interpreter
    that was used to build ``mod_wsgi``. For example, if ``mod_wsgi`` was
    built against the system Python 3.x, then your project should use a
    virtual environment created from that same system Python 3.x.
    .. code-block:: bash
       :linenos:
       $ cd ~
       $ mkdir -p /projects/modwsgi
       $ cd projects/modwsgi
       $ /usr/local/bin/virtualenv --no-site-packages env
        cd myproject
        python3 -m venv env
#.  Install :mod:`repoze.bfg` into the newly created virtualenv:
#.  Install your :app:`Pyramid` application and its dependencies.
    .. code-block:: bash
       :linenos:
       $ cd ~/projects/modwsgi/env
       $ bin/easy_install -i http://dist.repoze.org/bfg/current/simple repoze.bfg
#.  Create and install your :mod:`repoze.bfg` application.  For the
    purposes of this tutorial, we'll just be using the ``bfg_starter``
    application as a baseline application.  Substitute your existing
    :mod:`repoze.bfg` application as necessary if you already have
    one.
        env/bin/pip install -e .
    .. code-block:: bash
       :linenos:
#.  Within the project directory (``~/myproject``), create a script
    named ``pyramid.wsgi``.  Give it these contents:
       $ cd ~/projects/modwsgi/env
       $ bin/paster create -t bfg_starter myapp
       $ cd myapp
       $ ../bin/python setup.py install
    .. code-block:: python
#.  Within the virtualenv directory (``~/projects/modwsgi/env``),
    create a script named ``bfg.wsgi``.  Give it these contents:
        from pyramid.paster import get_app, setup_logging
        ini_path = '/Users/chrism/myproject/production.ini'
        setup_logging(ini_path)
        application = get_app(ini_path, 'main')
    .. code-block:: bash
       :linenos:
    The first argument to :func:`pyramid.paster.get_app` is the project
    configuration file name.  It's best to use the ``production.ini`` file
    provided by your cookiecutter, as it contains settings appropriate for
    production.  The second is the name of the section within the ``.ini``
    file that should be loaded by ``mod_wsgi``.  The assignment to the name
    ``application`` is important: mod_wsgi requires finding such an
    assignment when it opens the file.
       from repoze.bfg.paster import get_app
       application = get_app('/Users/chrism/projects/modwsgi/env/myapp/myapp.ini', 'main')
    The call to :func:`pyramid.paster.setup_logging` initializes the standard
    library's `logging` module to allow logging within your application.
    See :ref:`logging_config`.
    The first argument to ``get_app`` is the project Paste
    configuration file name.  The second is the name of the section
    within the .ini file that should be loaded by ``mod_wsgi``.  The
    assignment to the name ``application`` is important: mod_wsgi
    requires finding such an assignment when it opens the file.
#.  Make the ``bfg.wsgi`` script executable.
    .. code-block:: bash
       :linenos:
       $ cd ~/projects/modwsgi/env
       $ chmod 755 bfg.wsgi
    There is no need to make the ``pyramid.wsgi`` script executable.
    However, you'll need to make sure that *two* users have access to change
    into the ``~/myproject`` directory: your current user (mine is
    ``chrism`` and the user that Apache will run as often named ``apache`` or
    ``httpd``).  Make sure both of these users can "cd" into that directory.
#.  Edit your Apache configuration and add some stuff.  I happened to
    create a file named ``/etc/apache2/other/modwsgi.conf`` on my own
    system while installing Apache, so this stuff went in there.
    .. code-block:: bash
       :linenos:
    .. code-block:: apache
       # Use only 1 Python sub-interpreter.  Multiple sub-interpreters
       # play badly with C extensions.
       WSGIApplicationGroup 0
        # Use only 1 Python sub-interpreter.  Multiple sub-interpreters
        # play badly with C extensions.  See
        # http://stackoverflow.com/a/10558360/209039
        WSGIApplicationGroup %{GLOBAL}
        WSGIPassAuthorization On
        WSGIDaemonProcess pyramid user=chrism group=staff threads=4 \
          python-path=/Users/chrism/myproject/env/lib/python3.5/site-packages
        WSGIScriptAlias /myapp /Users/chrism/myproject/pyramid.wsgi
       WSGIPassAuthorization On
        <Directory /Users/chrism/myproject>
         WSGIProcessGroup pyramid
         Require all granted
        </Directory>
       WSGIDaemonProcess bfg user=chrism group=staff processes=1 threads=6 \
         python-path=/Users/chrism/projects/modwsgi/env/lib/python2.6/site-packages
       WSGIScriptAlias /myapp /Users/chrism/projects/modwsgi/env/bfg.wsgi
       <Directory /Users/chrism/projects/modwsgi/env>
         WSGIProcessGroup bfg
         WSGIApplicationGroup %{GLOBAL}
         Order allow, deny
         Allow from all
       </Directory>
#.  Restart Apache
    .. code-block:: bash
       :linenos:
        $ sudo /usr/sbin/apachectl restart
        sudo /usr/sbin/apachectl restart
#.  Visit ``http://localhost/myapp`` in a browser.  You should see the
    sample application rendered in your browser.
:term:`mod_wsgi` has many knobs and a great variety of deployment
modes.  This is just one representation of how you might use it to
serve up a :mod:`repoze.bfg` application.  See the `mod_wsgi
configuration documentation
<http://code.google.com/p/modwsgi/wiki/ConfigurationGuidelines>`_ for
more in-depth configuration information.
:term:`mod_wsgi` has many knobs and a great variety of deployment modes. This
is just one representation of how you might use it to serve up a :app:`Pyramid`
application.  See the `mod_wsgi configuration documentation
<https://modwsgi.readthedocs.io/en/develop/configuration.html>`_
for more in-depth configuration information.