Skip to content

Commit

Permalink
modernize deployment docs
Browse files Browse the repository at this point in the history
  • Loading branch information
davidism committed Aug 8, 2022
1 parent 67dc99d commit 1c656e1
Show file tree
Hide file tree
Showing 13 changed files with 849 additions and 298 deletions.
82 changes: 82 additions & 0 deletions docs/deployment/apache-httpd.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
Apache httpd
============

`Apache httpd`_ is a fast, production level HTTP server. When serving
your application with one of the WSGI servers listed in :doc:`index`, it
is often good or necessary to put a dedicated HTTP server in front of
it. This "reverse proxy" can handle incoming requests, TLS, and other
security and performance concerns better than the WSGI server.

httpd can be installed using your system package manager, or a pre-built
executable for Windows. Installing and running httpd itself is outside
the scope of this doc. This page outlines the basics of configuring
httpd to proxy your application. Be sure to read its documentation to
understand what features are available.

.. _Apache httpd: https://httpd.apache.org/


Domain Name
-----------

Acquiring and configuring a domain name is outside the scope of this
doc. In general, you will buy a domain name from a registrar, pay for
server space with a hosting provider, and then point your registrar
at the hosting provider's name servers.

To simulate this, you can also edit your ``hosts`` file, located at
``/etc/hosts`` on Linux. Add a line that associates a name with the
local IP.

Modern Linux systems may be configured to treat any domain name that
ends with ``.localhost`` like this without adding it to the ``hosts``
file.

.. code-block:: python
:caption: ``/etc/hosts``
127.0.0.1 hello.localhost
Configuration
-------------

The httpd configuration is located at ``/etc/httpd/conf/httpd.conf`` on
Linux. It may be different depending on your operating system. Check the
docs and look for ``httpd.conf``.

Remove or comment out any existing ``DocumentRoot`` directive. Add the
config lines below. We'll assume the WSGI server is listening locally at
``http://127.0.0.1:8000``.

.. code-block:: apache
:caption: ``/etc/httpd/conf/httpd.conf``
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
ProxyPass / http://127.0.0.1:8000/
RequestHeader set X-Forwarded-Proto http
RequestHeader set X-Forwarded-Prefix /
The ``LoadModule`` lines might already exist. If so, make sure they are
uncommented instead of adding them manually.

Then :doc:`proxy_fix` so that your application uses the ``X-Forwarded``
headers. ``X-Forwarded-For`` and ``X-Forwarded-Host`` are automatically
set by ``ProxyPass``.


Static Files
------------

If your application has static files such as JavaScript, CSS, and
images, it will be more efficient to let Nginx serve them directly
rather than going through the Python application.

Assuming the static files are expected to be available under the
``/static/`` URL, and are stored at ``/home/project/static/``, add the
following to the config above.

.. code-block:: apache
Alias /static/ /home/project/static/
41 changes: 0 additions & 41 deletions docs/deployment/cgi.rst

This file was deleted.

80 changes: 80 additions & 0 deletions docs/deployment/eventlet.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
eventlet
========

Prefer using :doc:`gunicorn` with eventlet workers rather than using
`eventlet`_ directly. Gunicorn provides a much more configurable and
production-tested server.

`eventlet`_ allows writing asynchronous, coroutine-based code that looks
like standard synchronous Python. It uses `greenlet`_ to enable task
switching without writing ``async/await`` or using ``asyncio``.

:doc:`gevent` is another library that does the same thing. Certain
dependencies you have, or other considerations, may affect which of the
two you choose to use.

eventlet provides a WSGI server that can handle many connections at once
instead of one per worker process. You must actually use eventlet in
your own code to see any benefit to using the server.

.. _eventlet: https://eventlet.net/
.. _greenlet: https://greenlet.readthedocs.io/en/latest/


Installing
----------

When using eventlet, greenlet>=1.0 is required, otherwise context locals
such as ``request`` will not work as expected. When using PyPy,
PyPy>=7.3.7 is required.

Create a virtualenv, install your application, then install
``eventlet``.

.. code-block:: text
$ cd hello-app
$ python -m venv venv
$ . venv/bin/activate
$ pip install . # install your application
$ pip install eventlet
Running
-------

To use eventlet to serve your application, write a script that imports
its ``wsgi.server``, as well as your app or app factory.

.. code-block:: python
:caption: ``wsgi.py``
import eventlet
from eventlet import wsgi
from hello import create_app
app = create_app()
wsgi.server(eventlet.listen(("127.0.0.1", 8000), app)
.. code-block:: text
$ python wsgi.py
(x) wsgi starting up on http://127.0.0.1:8000
Binding Externally
------------------
eventlet should not be run as root because it would cause your
application code to run as root, which is not secure. However, this
means it will not be possible to bind to port 80 or 443. Instead, a
reverse proxy such as :doc:`nginx` or :doc:`apache-httpd` should be used
in front of eventlet.
You can bind to all external IPs on a non-privileged port by using
``0.0.0.0`` in the server arguments shown in the previous section.
Don't do this when using a reverse proxy setup, otherwise it will be
possible to bypass the proxy.
``0.0.0.0`` is not a valid address to navigate to, you'd use a specific
IP address in your browser.
138 changes: 0 additions & 138 deletions docs/deployment/fastcgi.rst

This file was deleted.

Loading

0 comments on commit 1c656e1

Please sign in to comment.