<commit_before>
Deploy
------

CherryPy stands on its own, but as an application server, it is often
located in shared or complex environments. For this reason,
it is not uncommon to run CherryPy behind a reverse proxy
or use other servers to host the application.

.. note::
   
   CherryPy's server has proven reliable and fast enough
   for years now. If the volume of traffic you receive is
   average, it will do well enough on its own. Nonetheless,
   it is common to delegate the serving of static content
   to more capable servers such as `nginx <http://nginx.org>`_ or
   CDN.

.. contents::
   :depth:  3


Run as a daemon
###############

CherryPy allows you to easily decouple the current process from the parent
environment, using the traditional double-fork:

.. code-block:: python

   from cherrypy.process.plugins import Daemonizer
   d = Daemonizer(cherrypy.engine)
   d.subscribe()

.. note::

    This :ref:`engine plugin <busplugins>` is only available on
    Unix and similar systems which provide `fork()`.

If a startup error occurs in the forked children, the return code from the
parent process will still be 0. Errors in the initial daemonizing process still
return proper exit codes, but errors after the fork won't. Therefore, if you use
this plugin to daemonize, don't use the return code as an accurate indicator of
whether the process fully started. In fact, that return code only indicates if
the process successfully finished the first fork.

The plugin takes optional arguments to redirect standard streams: ``stdin``,
``stdout``, and ``stderr``. By default, these are all redirected to
:file:`/dev/null`, but you're free to send them to log files or elsewhere.

.. warning::

    You should be careful to not start any threads before this plugin runs.
    The plugin will warn if you do so, because "...the effects of calling functions
    that require certain resources between the call to fork() and the call to an
    exec function are undefined". (`ref <http://www.opengroup.org/onlinepubs/000095399/functions/fork.html>`_).
    It is for this reason that the Server plugin runs at priority 75 (it starts
    worker threads), which is later than the default priority of 65 for the
    Daemonizer.

Run as a different user
#######################

Use this :ref:`engine plugin <busplugins>` to start your
CherryPy site as root (for example, to listen on a privileged port like 80)
and then reduce privileges to something more restricted.

This priority of this plugin's "start" listener is slightly higher than the
priority for `server.start` in order to facilitate the most common use:
starting on a low port (which requires root) and then dropping to another user.

.. code-block:: python

   DropPrivileges(cherrypy.engine, uid=1000, gid=1000).subscribe()

PID files
#########

The PIDFile :ref:`engine plugin <busplugins>` is pretty straightforward: it writes
the process id to a file on start, and deletes the file on exit. You must
provide a 'pidfile' argument, preferably an absolute path:

.. code-block:: python

   PIDFile(cherrypy.engine, '/var/run/myapp.pid').subscribe()


Control via Supervisord
#######################

`Supervisord <http://supervisord.org>`_ is a powerful process control 
and management tool that can perform a lot of tasks around process monitoring. 

Below is a simple supervisor configuration for your CherryPy
application.

.. code-block:: ini

   [unix_http_server]
   file=/tmp/supervisor.sock 

   [supervisord]
   logfile=/tmp/supervisord.log ; (main log file;default $CWD/supervisord.log)
   logfile_maxbytes=50MB        ; (max main logfile bytes b4 rotation;default 50MB)
   logfile_backups=10           ; (num of main logfile rotation backups;default 10)
   loglevel=info                ; (log level;default info; others: debug,warn,trace)
   pidfile=/tmp/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
   nodaemon=false               ; (start in foreground if true;default false)
   minfds=1024                  ; (min. avail startup file descriptors;default 1024)
   minprocs=200                 ; (min. avail process descriptors;default 200)
   
   [rpcinterface:supervisor]<commit_msg>add docs to deploy.rst<commit_after>
Deploy
------

CherryPy stands on its own, but as an application server, it is often
located in shared or complex environments. For this reason,
it is not uncommon to run CherryPy behind a reverse proxy
or use other servers to host the application.

.. note::
   
   CherryPy's server has proven reliable and fast enough
   for years now. If the volume of traffic you receive is
   average, it will do well enough on its own. Nonetheless,
   it is common to delegate the serving of static content
   to more capable servers such as `nginx <http://nginx.org>`_ or
   CDN.

.. contents::
   :depth:  3


Run as a daemon
###############

CherryPy allows you to easily decouple the current process from the parent
environment, using the traditional double-fork:

.. code-block:: python

   from cherrypy.process.plugins import Daemonizer
   d = Daemonizer(cherrypy.engine)
   d.subscribe()

.. note::

    This :ref:`engine plugin <busplugins>` is only available on
    Unix and similar systems which provide `fork()`.

If a startup error occurs in the forked children, the return code from the
parent process will still be 0. Errors in the initial daemonizing process still
return proper exit codes, but errors after the fork won't. Therefore, if you use
this plugin to daemonize, don't use the return code as an accurate indicator of
whether the process fully started. In fact, that return code only indicates if
the process successfully finished the first fork.

The plugin takes optional arguments to redirect standard streams: ``stdin``,
``stdout``, and ``stderr``. By default, these are all redirected to
:file:`/dev/null`, but you're free to send them to log files or elsewhere.

.. warning::

    You should be careful to not start any threads before this plugin runs.
    The plugin will warn if you do so, because "...the effects of calling functions
    that require certain resources between the call to fork() and the call to an
    exec function are undefined". (`ref <http://www.opengroup.org/onlinepubs/000095399/functions/fork.html>`_).
    It is for this reason that the Server plugin runs at priority 75 (it starts
    worker threads), which is later than the default priority of 65 for the
    Daemonizer.

Run as a different user
#######################

Use this :ref:`engine plugin <busplugins>` to start your
CherryPy site as root (for example, to listen on a privileged port like 80)
and then reduce privileges to something more restricted.

This priority of this plugin's "start" listener is slightly higher than the
priority for `server.start` in order to facilitate the most common use:
starting on a low port (which requires root) and then dropping to another user.

.. code-block:: python

   DropPrivileges(cherrypy.engine, uid=1000, gid=1000).subscribe()

PID files
#########

The PIDFile :ref:`engine plugin <busplugins>` is pretty straightforward: it writes
the process id to a file on start, and deletes the file on exit. You must
provide a 'pidfile' argument, preferably an absolute path:

.. code-block:: python

   PIDFile(cherrypy.engine, '/var/run/myapp.pid').subscribe()

Systemd socket activation
#######################

Socket Activation is a systemd feature that allows to setup a system so that
the systemd will sit on a port and start services 'on demand' (a little bit
like inetd and xinetd used to do).

CherryPy has built-in socket activation support, if run from a systemd
service file it will detect the `LISTEN_PID` environment variable to know that
it should consider fd 3 to be the passed socket.

To read more about socket activation:
http://0pointer.de/blog/projects/socket-activation.html

Control via Supervisord
#######################

`Supervisord <http://supervisord.org>`_ is a powerful process control 
and management tool that can perform a lot of tasks around process monitoring. 

Below is a simple supervisor configuration for your CherryPy
application.

.. code-block:: ini

   [unix_http_server]
   file=/tmp/supervisor.sock 

   [supervisord]
   logfile=/tmp/supervisord.log ; (main log file;default $CWD/supervisord.log)
   logfile_maxbytes=50MB        ; (max main logfile bytes b4 rotation;default 50MB)
   logfile_backups=10           ; (num of main logfile rotation backups;default 10)
   loglevel=info                ; (log level;default info; others: debug,warn,trace)
   pidfile=/tmp/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
   nodaemon=false               ; (start in foreground if true;default false)
   minfds=1024                  ; (min. avail startup file descriptors;default 1024)
   minprocs=200                 ; (min. avail process descriptors;default 200)
   
   [rpcinterface:supervisor]
{'fraction_non_alphanumeric': 0.08560224089635854, 'fraction_numerical': 0.010980392156862745, 'mean_word_length': 3.8118598382749327, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3897567', 'n_tokens_mistral': 2532, 'n_tokens_neox': 2324, 'n_words': 1147}