From d1a0b3f6f9d8904b1772d82733608e7fa98105de Mon Sep 17 00:00:00 2001 From: Martin Zimmermann Date: Sun, 16 Feb 2014 15:52:28 +0100 Subject: [PATCH] refactor docs a bit, add section for mod_fastcgi and uberspace.de --- docs/_isso/remove_heading.py | 12 ++ docs/_isso/sidebar-docs.html | 11 +- docs/_static/css/site.scss | 12 ++ docs/conf.py | 2 +- .../{ => extras}/advanced-integration.rst | 4 +- docs/docs/extras/deployment.rst | 181 ++++++++++++++++++ docs/docs/extras/uwsgi.rst | 57 ------ docs/docs/install.rst | 2 +- docs/docs/quickstart.rst | 117 ++--------- .../setup.rst => setup/multiple-sites.rst} | 33 ---- docs/docs/setup/sub-uri.rst | 29 +++ 11 files changed, 261 insertions(+), 199 deletions(-) create mode 100644 docs/_isso/remove_heading.py rename docs/docs/{ => extras}/advanced-integration.rst (93%) delete mode 100644 docs/docs/extras/uwsgi.rst rename docs/docs/{configuration/setup.rst => setup/multiple-sites.rst} (64%) create mode 100644 docs/docs/setup/sub-uri.rst diff --git a/docs/_isso/remove_heading.py b/docs/_isso/remove_heading.py new file mode 100644 index 0000000..48d7708 --- /dev/null +++ b/docs/_isso/remove_heading.py @@ -0,0 +1,12 @@ + +from docutils import nodes +from sphinx.writers.html import HTMLTranslator + + +class IssoTranslator(HTMLTranslator): + + def visit_title(self, node): + if self.section_level == 1: + raise nodes.SkipNode + HTMLTranslator.visit_title(self, node) + diff --git a/docs/_isso/sidebar-docs.html b/docs/_isso/sidebar-docs.html index 0363f6e..e1be02e 100644 --- a/docs/_isso/sidebar-docs.html +++ b/docs/_isso/sidebar-docs.html @@ -13,14 +13,19 @@ {{ doc("docs/quickstart", "Quickstart") }} {{ doc("docs/troubleshooting", "Troubleshooting") }} +Advanced Setup + Configuration -Advanced +Extras diff --git a/docs/_static/css/site.scss b/docs/_static/css/site.scss index 3c24238..99a7b23 100644 --- a/docs/_static/css/site.scss +++ b/docs/_static/css/site.scss @@ -349,4 +349,16 @@ main { dd { margin-left: 1.2em; } + + .admonition { + + p + p { + margin-top: 0.25em; + } + + p:not(:first-child) { + margin-left: 2em; + } + } + } diff --git a/docs/conf.py b/docs/conf.py index 330b04d..1699786 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -104,7 +104,7 @@ pygments_style = 'trac' # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. html_theme = '_isso' -html_translator_class = "html5.Isso" +html_translator_class = "remove_heading.IssoTranslator" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the diff --git a/docs/docs/advanced-integration.rst b/docs/docs/extras/advanced-integration.rst similarity index 93% rename from docs/docs/advanced-integration.rst rename to docs/docs/extras/advanced-integration.rst index 0deaceb..a5c87ae 100644 --- a/docs/docs/advanced-integration.rst +++ b/docs/docs/extras/advanced-integration.rst @@ -2,7 +2,7 @@ Advanced integration ==================== Comment counter ----------------- +--------------- If you want to display a comment counter for a given thread, simply put a link to that comments thread anchor: @@ -19,7 +19,7 @@ Alternatively, if guessing from `href` is not relevant, you could use a Now, either include `count.min.js` if you want to show only the comment count (e.g. on an index page) or `embed.min.js` for the full comment client (see -:doc:`quickstart`); do not mix both. +:doc:`../quickstart`); do not mix both. You can have as many comments counters as you want in a page but be aware that it implies one `GET` request per comment anchor. diff --git a/docs/docs/extras/deployment.rst b/docs/docs/extras/deployment.rst index e69de29..a2ac1dd 100644 --- a/docs/docs/extras/deployment.rst +++ b/docs/docs/extras/deployment.rst @@ -0,0 +1,181 @@ +Deployment +---------- + +Isso ships with a built-in web server, which is useful for the initial setup +and may be used in production for low-traffic sites (up to 20 requests per +second). Running a "real" WSGI server supports nice things such as UNIX domain +sockets, daemonization and solid HTTP handler while being more stable, secure +and web-scale than the built-in web server. + +* gevent_, coroutine-based network library +* uWSGI_, full-featured uWSGI server +* gunicorn_, Python WSGI HTTP Server for UNIX +* mod_wsgi_, Apache interface to WSGI +* mod_fastcgi_, Apache interface to FastCGI +* uberspace.de, `try this guide (in german) `_ + + +`gevent `__ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Probably the easiest deployment method. Install with PIP (requires libevent): + +.. code-block:: sh + + $ pip install gevent + +Then, just use the ``isso`` executable as usual. Gevent monkey-patches Python's +standard library to work with greenlets. + +To execute Isso, just use the commandline interface: + +.. code-block:: sh + + $ isso -c my.cfg run + +Unfortunately, gevent 0.13.2 does not support UNIX domain sockets (see `#295 +`_ and `#299 +`_ for details). + + +`uWSGI `__ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Isso has special support for uWSGI, namely fast IPC caching, job spooling and +delayed jobs. It is the author's choice, but not the only one. You need +uWSGI 1.9 or higher, fortunately you can install it from PyPi: + +.. code-block:: sh + + ~> apt-get install build-essential python-dev + ~> pip install uwsgi + +For convenience, I recommend a INI-style configuration (you can also +supply everything as command-line arguments): + +.. code-block:: ini + + [uwsgi] + http = :8080 + master = true + ; set to `nproc` + processes = 4 + cache2 = name=hash,items=1024,blocksize=32 + ; you may change this + spooler = /tmp/isso/mail + module = isso.run + ; uncomment if you use a virtual environment + ; virtualenv = /path/to/isso + env = ISSO_SETTINGS=/path/to/isso.cfg + +Then, create the spooling directory and start Isso via uWSGI: + +.. code-block:: sh + + ~> mkdir /tmp/isso/mail + ~> uwsgi /path/to/uwsgi.ini + + +`gunicorn `__ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Gunicorn 'Green Unicorn' is a Python WSGI HTTP Server for UNIX with a pre-fork +worker ported from Ruby's Unicorn project. Install gunicorn_ via PIP: + +.. code-block:: sh + + $ pip install gunicorn + +To execute Isso, use a command similar to: + +.. code-block:: sh + + $ export ISSO_SETTINGS="/path/to/isso.cfg" + $ gunicorn -b localhost:8080 -w 4 --preload isso.run + + +`mod_wsgi `__ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. note:: This information may be incorrect, if you have more knowledge on how + to deploy Python via `mod_wsgi`, consider extending/correcting this section. + + For more information, see `Flask: Configuring Apache + `_. + +.. code-block:: apache + + + ServerName example.org + + WSGIDaemonProcess isso user=www-data group=www-data threads=5 + WSGIScriptAlias / /var/www/isso.wsgi + + +Next, copy'n'paste to `/var/www/isso.wsgi`: + +.. code-block:: python + + from isso import make_app + from isso.core import Config + + application = make_app(Config.load("/path/to/isso.cfg")) + +Also make sure, you set a static key because `mod_wsgi` generates a session +key per thread/process. This may result in random 403 errors when you edit or +delete comments. + +.. code-block:: ini + + [general] + ; cat /dev/urandom | strings | grep -o '[[:alnum:]]' | head -n 30 | tr -d '\n' + session-key = superrandomkey1 + +`mod_fastcgi `__ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. note:: This information may be incorrect, if you have more knowledge on how + to deploy Python via `mod_fastcgi`, consider extending/correcting this section. + + For more information, see `Flask: Configuring Apache + `_. + +.. code-block:: apache + + LoadModule fastcgi_module /usr/lib64/httpd/modules/mod_fastcgi.so + + FastCgiServer /var/www/html/yourapplication/app.fcgi -idle-timeout 300 -processes 5 + + + ServerName example.org + + AddHandler fastcgi-script fcgi + ScriptAlias / /var/www/isso.fcgi + + + SetHandler fastcgi-script + + + +Next, copy'n'paste to `/var/www/isso.fcgi` (or whatever location you prefer): + +.. code-block:: python + + #!/usr/bin/env python2.7 + + from isso import make_app + from isso.core import Config + + from flup.server.fcgi import WSGIServer + + application = make_app(Config.load("/path/to/isso.cfg")) + WSGIServer(application).run() + +Similar to mod_wsgi_, set a static session key if you are using more than one process +to avoid random errors. + +.. code-block:: ini + + [general] + ; cat /dev/urandom | strings | grep -o '[[:alnum:]]' | head -n 30 | tr -d '\n' + session-key = superrandomkey1 diff --git a/docs/docs/extras/uwsgi.rst b/docs/docs/extras/uwsgi.rst deleted file mode 100644 index 9569e62..0000000 --- a/docs/docs/extras/uwsgi.rst +++ /dev/null @@ -1,57 +0,0 @@ -uWSGI -===== - -In short: `uWSGI `_ is awesome. Isso -has builtin support for it (and simple fallback if uWSGI is not -available). Use uWSGI if you think that the builtin WSGI server is a bad -choice or slow (hint: it's both). - -With uWSGI, you have roughly 100% performance improvements for just -using it. Instead of one thread per request, you can use multiple -processes, hence it is more "web scale". Other side effects: spooling, -fast inter-process caching. - -Installation ------------- - -You need uWSGI 1.9 or higher, fortunately you can install it with -Python: - -.. code-block:: sh - - ~> apt-get install build-essential python-dev - ~> pip install uwsgi - -Configuration -------------- - -For convenience, I recommend a INI-style configuration (you can also -supply everything as command-line arguments): - -.. code-block:: ini - - [uwsgi] - http = :8080 - master = true - processes = 4 - cache2 = name=hash,items=1024,blocksize=32 - spooler = %d/mail - module = isso.run - virtualenv = %d - env = ISSO_SETTINGS=%d/sample.cfg - -You shoud adjust ``processes`` to your CPU count. Then, save this file -to a directory if choice. Next to this file, create an empty directory -called ``mail``: - -.. code-block:: sh - - ~> mkdir mail/ - ~> ls - uwsgi.ini mail/ - -Now start Isso: - -.. code-block:: sh - - ~> uwsgi /path/to/uwsgi.ini diff --git a/docs/docs/install.rst b/docs/docs/install.rst index d83b5b1..5e32bce 100644 --- a/docs/docs/install.rst +++ b/docs/docs/install.rst @@ -3,7 +3,7 @@ Installation Requirements: -- Python 2.6, 2.7 or 3.3 +- Python 2.6, 2.7 or 3.3 (+ devel headers) - a working C compiler Install Isso with `pip `_: diff --git a/docs/docs/quickstart.rst b/docs/docs/quickstart.rst index 6a1a70b..bdc98d5 100644 --- a/docs/docs/quickstart.rst +++ b/docs/docs/quickstart.rst @@ -89,8 +89,7 @@ To run Isso, simply execute: Next, we configure Nginx_ to proxy Isso. Do not run Isso on a public interface! A popular but often error-prone (because of CORS_) setup to host Isso uses a -dedicated domain such as ``comments.example.tld``; see -:doc:`configuration/setup` for alternate ways. +dedicated domain such as ``comments.example.tld``. Assuming both, your website and Isso are on the same server, the nginx configuration looks like this: @@ -122,8 +121,8 @@ Now, you embed Isso to your website: .. code-block:: html - +
@@ -133,105 +132,19 @@ Note, that `data-isso` is optional, but when a website includes a script using That's it. When you open your website, you should see a commenting form. Leave a comment to see if the setup works. If not, see :doc:`troubleshooting`. +Going Further +------------- -For further integration, look at :doc:`advanced-integration`. - -.. _Nginx: http://nginx.org/ -.. _CORS: https://developer.mozilla.org/en/docs/HTTP/Access_control_CORS - - -Deployment ----------- - -Isso ships with a built-in web server, which is useful for the initial setup -and may be used in production for low-traffic sites (up to 20 requests per -second). It is recommended to use a "real" WSGI server to run Isso, e.g: - -* gevent_, coroutine-based network library -* uWSGI_, full-featured uWSGI server -* gunicorn_, Python WSGI HTTP Server for UNIX - -.. _gevent: http://www.gevent.org/ -.. _uWSGI: http://uwsgi-docs.readthedocs.org/en/latest/ -.. _gunicorn: http://gunicorn.org/ - -gevent -^^^^^^ - -Probably the easiest deployment method. Install with PIP (requires libevent): - -.. code-block:: sh - - $ pip install gevent - -Then, just use the ``isso`` executable as usual. Gevent monkey-patches Python's -standard library to work with greenlets. - -To execute Isso, just use the commandline interface: - -.. code-block:: sh - - $ isso -c my.cfg run - -Unfortunately, gevent 0.13.2 does not support UNIX domain sockets (see `#295 -`_ and `#299 -`_ for details). - -uWSGI -^^^^^ - -The author's favourite WSGI server. Due the complexity of uWSGI, there is a -:doc:`separate document ` on how to setup uWSGI for use -with Isso. - -gunicorn -^^^^^^^^ - -Install gunicorn_ via PIP: - -.. code-block:: sh - - $ pip install gunicorn - -To execute Isso, use a command similar to: - -.. code-block:: sh - - $ export ISSO_SETTINGS="/path/to/isso.cfg" - $ gunicorn -b localhost:8080 -w 4 --preload isso.run - -mod_wsgi -^^^^^^^^ - -I have no experience at all with `mod_wsgi`, most things are taken from -`Flask: Configuring Apache `_: - -.. code-block:: apache - - - ServerName example.org - - WSGIDaemonProcess isso user=... group=... threads=5 - WSGIScriptAlias / /var/www/isso.wsgi - - -Now, you need to create a new `isso.wsgi` file: - -.. code-block:: python - - import os - - from isso import make_app - from isso.core import Config - - application = make_app(Config.load("/path/to/isso.cfg")) - -Unless you know how to preload the application, add a static session key to -your `isso.cfg`: +There are several server and client configuration options uncovered in this +quickstart, check out :doc:`configuration/server` and +:doc:`configuration/client` for more information. For further website +integration, see :doc:`extras/advanced-integration`. -.. code-block:: ini +If you wondered how to automatically start Isso you may find a short script +for various popular init/supervisor daemons here: :doc:`install`. Another +important topic is the actual :doc:`deployment of Isso ` +(and every Python web application in general). - [general] - ; cat /dev/urandom | strings | grep -o '[[:alnum:]]' | head -n 30 | tr -d '\n' - session-key = superrandomkey1 +.. _Nginx: http://nginx.org/ +.. _CORS: https://developer.mozilla.org/en/docs/HTTP/Access_control_CORS diff --git a/docs/docs/configuration/setup.rst b/docs/docs/setup/multiple-sites.rst similarity index 64% rename from docs/docs/configuration/setup.rst rename to docs/docs/setup/multiple-sites.rst index 8f1fa9c..bc39bac 100644 --- a/docs/docs/configuration/setup.rst +++ b/docs/docs/setup/multiple-sites.rst @@ -1,36 +1,3 @@ -Setup -===== - -Sub-URI -------- - -You can run Isso on the same domain as your website, which circumvents issues -originating from CORS_. Also, privacy-protecting browser addons such as -`Request Policy`_ wont block comments. - -.. code-block:: nginx - - server { - listen [::]:80; - listen [::]:443 ssl; - server_name example.tld; - root /var/www/example.tld; - - location /isso { - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Script-Name /isso; - proxy_set_header Host $host; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_pass http://localhost:8080; - } - } - -Now, the website integration is just as described in :doc:`../quickstart` but -with a different location. - -.. _CORS: https://developer.mozilla.org/en/docs/HTTP/Access_control_CORS -.. _Request Policy: https://www.requestpolicy.com/ - .. _configure-multiple-sites: diff --git a/docs/docs/setup/sub-uri.rst b/docs/docs/setup/sub-uri.rst new file mode 100644 index 0000000..a646574 --- /dev/null +++ b/docs/docs/setup/sub-uri.rst @@ -0,0 +1,29 @@ +Sub-URI +======= + +You can run Isso on the same domain as your website, which circumvents issues +originating from CORS_. Also, privacy-protecting browser addons such as +`Request Policy`_ wont block comments. + +.. code-block:: nginx + + server { + listen [::]:80; + listen [::]:443 ssl; + server_name example.tld; + root /var/www/example.tld; + + location /isso { + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Script-Name /isso; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_pass http://localhost:8080; + } + } + +Now, the website integration is just as described in :doc:`../quickstart` but +with a different location. + +.. _CORS: https://developer.mozilla.org/en/docs/HTTP/Access_control_CORS +.. _Request Policy: https://www.requestpolicy.com/