This file is indexed.

/usr/share/doc/python-cherrypy3-doc/html/deploy.html is in python-cherrypy3-doc 8.9.1-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Deploy &#8212; CherryPy 8.9.1 documentation</title>
    <link rel="stylesheet" href="_static/classic.css" type="text/css" />
    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
    <script type="text/javascript">
      var DOCUMENTATION_OPTIONS = {
        URL_ROOT:    './',
        VERSION:     '8.9.1',
        COLLAPSE_INDEX: false,
        FILE_SUFFIX: '.html',
        HAS_SOURCE:  true,
        SOURCELINK_SUFFIX: '.txt'
      };
    </script>
    <script type="text/javascript" src="_static/jquery.js"></script>
    <script type="text/javascript" src="_static/underscore.js"></script>
    <script type="text/javascript" src="_static/doctools.js"></script>
    <link rel="index" title="Index" href="genindex.html" />
    <link rel="search" title="Search" href="search.html" />
    <link rel="next" title="Support" href="support.html" />
    <link rel="prev" title="Extend" href="extend.html" /> 
  </head>
  <body>
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="genindex.html" title="General Index"
             accesskey="I">index</a></li>
        <li class="right" >
          <a href="support.html" title="Support"
             accesskey="N">next</a> |</li>
        <li class="right" >
          <a href="extend.html" title="Extend"
             accesskey="P">previous</a> |</li>
        <li class="nav-item nav-item-0"><a href="index.html">CherryPy 8.9.1 documentation</a> &#187;</li> 
      </ul>
    </div>  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body" role="main">
            
  <div class="section" id="deploy">
<h1><a class="toc-backref" href="#id5">Deploy</a><a class="headerlink" href="#deploy" title="Permalink to this headline"></a></h1>
<p>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.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">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 <a class="reference external" href="http://nginx.org">nginx</a> or
CDN.</p>
</div>
<div class="contents topic" id="contents">
<p class="topic-title first">Contents</p>
<ul class="simple">
<li><a class="reference internal" href="#deploy" id="id5">Deploy</a><ul>
<li><a class="reference internal" href="#run-as-a-daemon" id="id6">Run as a daemon</a></li>
<li><a class="reference internal" href="#run-as-a-different-user" id="id7">Run as a different user</a></li>
<li><a class="reference internal" href="#pid-files" id="id8">PID files</a></li>
<li><a class="reference internal" href="#systemd-socket-activation" id="id9">Systemd socket activation</a></li>
<li><a class="reference internal" href="#control-via-supervisord" id="id10">Control via Supervisord</a></li>
<li><a class="reference internal" href="#ssl-support" id="id11">SSL support</a></li>
<li><a class="reference internal" href="#wsgi-servers" id="id12">WSGI servers</a><ul>
<li><a class="reference internal" href="#embedding-into-another-wsgi-framework" id="id13">Embedding into another WSGI framework</a></li>
<li><a class="reference internal" href="#tornado" id="id14">Tornado</a></li>
<li><a class="reference internal" href="#twisted" id="id15">Twisted</a></li>
<li><a class="reference internal" href="#uwsgi" id="id16">uwsgi</a></li>
</ul>
</li>
<li><a class="reference internal" href="#virtual-hosting" id="id17">Virtual Hosting</a></li>
<li><a class="reference internal" href="#reverse-proxying" id="id18">Reverse-proxying</a><ul>
<li><a class="reference internal" href="#apache" id="id19">Apache</a></li>
<li><a class="reference internal" href="#id4" id="id20">Nginx</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="run-as-a-daemon">
<h2><a class="toc-backref" href="#id6">Run as a daemon</a><a class="headerlink" href="#run-as-a-daemon" title="Permalink to this headline"></a></h2>
<p>CherryPy allows you to easily decouple the current process from the parent
environment, using the traditional double-fork:</p>
<div class="highlight-python"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">cherrypy.process.plugins</span> <span class="kn">import</span> <span class="n">Daemonizer</span>
<span class="n">d</span> <span class="o">=</span> <span class="n">Daemonizer</span><span class="p">(</span><span class="n">cherrypy</span><span class="o">.</span><span class="n">engine</span><span class="p">)</span>
<span class="n">d</span><span class="o">.</span><span class="n">subscribe</span><span class="p">()</span>
</pre></div>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">This <a class="reference internal" href="extend.html#busplugins"><span class="std std-ref">engine plugin</span></a> is only available on
Unix and similar systems which provide <cite>fork()</cite>.</p>
</div>
<p>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.</p>
<p>The plugin takes optional arguments to redirect standard streams: <code class="docutils literal"><span class="pre">stdin</span></code>,
<code class="docutils literal"><span class="pre">stdout</span></code>, and <code class="docutils literal"><span class="pre">stderr</span></code>. By default, these are all redirected to
<code class="file docutils literal"><span class="pre">/dev/null</span></code>, but you’re free to send them to log files or elsewhere.</p>
<div class="admonition warning">
<p class="first admonition-title">Warning</p>
<p class="last">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”. (<a class="reference external" href="http://www.opengroup.org/onlinepubs/000095399/functions/fork.html">ref</a>).
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.</p>
</div>
</div>
<div class="section" id="run-as-a-different-user">
<h2><a class="toc-backref" href="#id7">Run as a different user</a><a class="headerlink" href="#run-as-a-different-user" title="Permalink to this headline"></a></h2>
<p>Use this <a class="reference internal" href="extend.html#busplugins"><span class="std std-ref">engine plugin</span></a> 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.</p>
<p>This priority of this plugin’s “start” listener is slightly higher than the
priority for <cite>server.start</cite> in order to facilitate the most common use:
starting on a low port (which requires root) and then dropping to another user.</p>
<div class="highlight-python"><div class="highlight"><pre><span></span><span class="n">DropPrivileges</span><span class="p">(</span><span class="n">cherrypy</span><span class="o">.</span><span class="n">engine</span><span class="p">,</span> <span class="n">uid</span><span class="o">=</span><span class="mi">1000</span><span class="p">,</span> <span class="n">gid</span><span class="o">=</span><span class="mi">1000</span><span class="p">)</span><span class="o">.</span><span class="n">subscribe</span><span class="p">()</span>
</pre></div>
</div>
</div>
<div class="section" id="pid-files">
<h2><a class="toc-backref" href="#id8">PID files</a><a class="headerlink" href="#pid-files" title="Permalink to this headline"></a></h2>
<p>The PIDFile <a class="reference internal" href="extend.html#busplugins"><span class="std std-ref">engine plugin</span></a> 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:</p>
<div class="highlight-python"><div class="highlight"><pre><span></span><span class="n">PIDFile</span><span class="p">(</span><span class="n">cherrypy</span><span class="o">.</span><span class="n">engine</span><span class="p">,</span> <span class="s1">&#39;/var/run/myapp.pid&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">subscribe</span><span class="p">()</span>
</pre></div>
</div>
</div>
<div class="section" id="systemd-socket-activation">
<h2><a class="toc-backref" href="#id9">Systemd socket activation</a><a class="headerlink" href="#systemd-socket-activation" title="Permalink to this headline"></a></h2>
<p>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).</p>
<p>CherryPy has built-in socket activation support, if run from a systemd
service file it will detect the <cite>LISTEN_PID</cite> environment variable to know that
it should consider fd 3 to be the passed socket.</p>
<p>To read more about socket activation:
<a class="reference external" href="http://0pointer.de/blog/projects/socket-activation.html">http://0pointer.de/blog/projects/socket-activation.html</a></p>
</div>
<div class="section" id="control-via-supervisord">
<h2><a class="toc-backref" href="#id10">Control via Supervisord</a><a class="headerlink" href="#control-via-supervisord" title="Permalink to this headline"></a></h2>
<p><a class="reference external" href="http://supervisord.org">Supervisord</a> is a powerful process control
and management tool that can perform a lot of tasks around process monitoring.</p>
<p>Below is a simple supervisor configuration for your CherryPy
application.</p>
<div class="highlight-ini"><div class="highlight"><pre><span></span><span class="k">[unix_http_server]</span>
<span class="na">file</span><span class="o">=</span><span class="s">/tmp/supervisor.sock</span>

<span class="k">[supervisord]</span>
<span class="na">logfile</span><span class="o">=</span><span class="s">/tmp/supervisord.log ; (main log file;default $CWD/supervisord.log)</span>
<span class="na">logfile_maxbytes</span><span class="o">=</span><span class="s">50MB        ; (max main logfile bytes b4 rotation;default 50MB)</span>
<span class="na">logfile_backups</span><span class="o">=</span><span class="s">10           ; (num of main logfile rotation backups;default 10)</span>
<span class="na">loglevel</span><span class="o">=</span><span class="s">info                ; (log level;default info; others: debug,warn,trace)</span>
<span class="na">pidfile</span><span class="o">=</span><span class="s">/tmp/supervisord.pid ; (supervisord pidfile;default supervisord.pid)</span>
<span class="na">nodaemon</span><span class="o">=</span><span class="s">false               ; (start in foreground if true;default false)</span>
<span class="na">minfds</span><span class="o">=</span><span class="s">1024                  ; (min. avail startup file descriptors;default 1024)</span>
<span class="na">minprocs</span><span class="o">=</span><span class="s">200                 ; (min. avail process descriptors;default 200)</span>

<span class="k">[rpcinterface:supervisor]</span>
<span class="na">supervisor.rpcinterface_factory</span> <span class="o">=</span> <span class="s">supervisor.rpcinterface:make_main_rpcinterface</span>

<span class="k">[supervisorctl]</span>
<span class="na">serverurl</span><span class="o">=</span><span class="s">unix:///tmp/supervisor.sock</span>

<span class="k">[program:myapp]</span>
<span class="na">command</span><span class="o">=</span><span class="s">python server.py</span>
<span class="na">environment</span><span class="o">=</span><span class="s">PYTHONPATH=.</span>
<span class="na">directory</span><span class="o">=</span><span class="s">.</span>
</pre></div>
</div>
<p>This could control your server via the <code class="docutils literal"><span class="pre">server.py</span></code> module as
the application entry point.</p>
<div class="highlight-python"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">cherrypy</span>

<span class="k">class</span> <span class="nc">Root</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="nd">@cherrypy.expose</span>
    <span class="k">def</span> <span class="nf">index</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="s2">&quot;Hello World!&quot;</span>


<span class="n">cherrypy</span><span class="o">.</span><span class="n">config</span><span class="o">.</span><span class="n">update</span><span class="p">({</span><span class="s1">&#39;server.socket_port&#39;</span><span class="p">:</span> <span class="mi">8090</span><span class="p">,</span>
                        <span class="s1">&#39;engine.autoreload.on&#39;</span><span class="p">:</span> <span class="bp">False</span><span class="p">,</span>
                        <span class="s1">&#39;log.access_file&#39;</span><span class="p">:</span> <span class="s1">&#39;./access.log&#39;</span><span class="p">,</span>
                        <span class="s1">&#39;log.error_file&#39;</span><span class="p">:</span> <span class="s1">&#39;./error.log&#39;</span><span class="p">})</span>
<span class="n">cherrypy</span><span class="o">.</span><span class="n">quickstart</span><span class="p">(</span><span class="n">Root</span><span class="p">())</span>
</pre></div>
</div>
<p>To take the configuration (assuming it was saved in a file
called <code class="docutils literal"><span class="pre">supervisor.conf</span></code>) into account:</p>
<div class="highlight-bash"><div class="highlight"><pre><span></span>$ supervisord -c supervisord.conf
$ supervisorctl update
</pre></div>
</div>
<p>Now, you can point your browser at <a class="reference external" href="http://localhost:8090/">http://localhost:8090/</a>
and it will display <cite>Hello World!</cite>.</p>
<p>To stop supervisor, type:</p>
<div class="highlight-bash"><div class="highlight"><pre><span></span>$ supervisorctl shutdown
</pre></div>
</div>
<p>This will obviously shutdown your application.</p>
</div>
<div class="section" id="ssl-support">
<span id="ssl"></span><h2><a class="toc-backref" href="#id11">SSL support</a><a class="headerlink" href="#ssl-support" title="Permalink to this headline"></a></h2>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">You may want to test your server for SSL using the services
from <a class="reference external" href="https://www.ssllabs.com/ssltest/index.html">Qualys, Inc.</a></p>
</div>
<p>CherryPy can encrypt connections using SSL to create an https connection. This keeps your web traffic secure. Here’s how.</p>
<ol class="arabic simple">
<li>Generate a private key. We’ll use openssl and follow the <a class="reference external" href="https://www.openssl.org/docs/HOWTO/keys.txt">OpenSSL Keys HOWTO</a>.:</li>
</ol>
<div class="highlight-bash"><div class="highlight"><pre><span></span>$ openssl genrsa -out privkey.pem <span class="m">2048</span>
</pre></div>
</div>
<p>You can create either a key that requires a password to use, or one without a password. Protecting your private key with a password is much more secure, but requires that you enter the password every time you use the key. For example, you may have to enter the password when you start or restart your CherryPy server. This may or may not be feasible, depending on your setup.</p>
<p>If you want to require a password, add one of the <code class="docutils literal"><span class="pre">-aes128</span></code>, <code class="docutils literal"><span class="pre">-aes192</span></code> or <code class="docutils literal"><span class="pre">-aes256</span></code> switches to the command above. You should not use any of the DES, 3DES, or SEED algoritms to protect your password, as they are insecure.</p>
<p>SSL Labs recommends using 2048-bit RSA keys for security (see references section at the end).</p>
<ol class="arabic simple" start="2">
<li>Generate a certificate. We’ll use openssl and follow the <a class="reference external" href="https://www.openssl.org/docs/HOWTO/certificates.txt">OpenSSL Certificates HOWTO</a>. Let’s start off with a self-signed certificate for testing:</li>
</ol>
<div class="highlight-bash"><div class="highlight"><pre><span></span>$ openssl req -new -x509 -days <span class="m">365</span> -key privkey.pem -out cert.pem
</pre></div>
</div>
<p>openssl will then ask you a series of questions. You can enter whatever values are applicable, or leave most fields blank. The one field you <em>must</em> fill in is the ‘Common Name’: enter the hostname you will use to access your site. If you are just creating a certificate to test on your own machine and you access the server by typing ‘localhost’ into your browser, enter the Common Name ‘localhost’.</p>
<ol class="arabic" start="3">
<li><p class="first">Decide whether you want to use python’s built-in SSL library, or the pyOpenSSL library. CherryPy supports either.</p>
<blockquote>
<div><ol class="loweralpha simple">
<li><em>Built-in.</em> To use python’s built-in SSL, add the following line to your CherryPy config:</li>
</ol>
<div class="highlight-python"><div class="highlight"><pre><span></span><span class="n">cherrypy</span><span class="o">.</span><span class="n">server</span><span class="o">.</span><span class="n">ssl_module</span> <span class="o">=</span> <span class="s1">&#39;builtin&#39;</span>
</pre></div>
</div>
<ol class="loweralpha simple" start="2">
<li><em>pyOpenSSL</em>. Because python did not have a built-in SSL library when CherryPy was first created, the default setting is to use pyOpenSSL. To use it you’ll need to install it (we could recommend you install <a class="reference external" href="http://cython.org/">cython</a> first):</li>
</ol>
<div class="highlight-bash"><div class="highlight"><pre><span></span>$ pip install cython, pyOpenSSL
</pre></div>
</div>
</div></blockquote>
</li>
<li><p class="first">Add the following lines in your CherryPy config to point to your certificate files:</p>
</li>
</ol>
<div class="highlight-python"><div class="highlight"><pre><span></span><span class="n">cherrypy</span><span class="o">.</span><span class="n">server</span><span class="o">.</span><span class="n">ssl_certificate</span> <span class="o">=</span> <span class="s2">&quot;cert.pem&quot;</span>
<span class="n">cherrypy</span><span class="o">.</span><span class="n">server</span><span class="o">.</span><span class="n">ssl_private_key</span> <span class="o">=</span> <span class="s2">&quot;privkey.pem&quot;</span>
</pre></div>
</div>
<ol class="arabic simple" start="5">
<li>If you have a certificate chain at hand, you can also specify it:</li>
</ol>
<div class="highlight-python"><div class="highlight"><pre><span></span><span class="n">cherrypy</span><span class="o">.</span><span class="n">server</span><span class="o">.</span><span class="n">ssl_certificate_chain</span> <span class="o">=</span> <span class="s2">&quot;certchain.perm&quot;</span>
</pre></div>
</div>
<ol class="arabic simple" start="6">
<li>Start your CherryPy server normally. Note that if you are debugging locally and/or using a self-signed certificate, your browser may show you security warnings.</li>
</ol>
</div>
<div class="section" id="wsgi-servers">
<h2><a class="toc-backref" href="#id12">WSGI servers</a><a class="headerlink" href="#wsgi-servers" title="Permalink to this headline"></a></h2>
<div class="section" id="embedding-into-another-wsgi-framework">
<h3><a class="toc-backref" href="#id13">Embedding into another WSGI framework</a><a class="headerlink" href="#embedding-into-another-wsgi-framework" title="Permalink to this headline"></a></h3>
<p>Though CherryPy comes with a very reliable and fast enough HTTP server,
you may wish to integrate your CherryPy application within a
different framework. To do so, we will benefit from the WSGI
interface defined in <span class="target" id="index-0"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0333"><strong>PEP 333</strong></a> and <span class="target" id="index-1"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-3333"><strong>PEP 3333</strong></a>.</p>
<p>Note that you should follow some basic rules when embedding CherryPy
in a third-party WSGI server:</p>
<ul>
<li><p class="first">If you rely on the <cite>“main”</cite> channel to be published on, as
it would happen within the CherryPy’s mainloop, you should
find a way to publish to it within the other framework’s mainloop.</p>
</li>
<li><p class="first">Start the CherryPy’s engine. This will publish to the <cite>“start”</cite> channel
of the bus.</p>
<div class="highlight-python"><div class="highlight"><pre><span></span><span class="n">cherrypy</span><span class="o">.</span><span class="n">engine</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
</pre></div>
</div>
</li>
<li><p class="first">Stop the CherryPy’s engine when you terminate. This will publish
to the <cite>“stop”</cite> channel of the bus.</p>
<div class="highlight-python"><div class="highlight"><pre><span></span><span class="n">cherrypy</span><span class="o">.</span><span class="n">engine</span><span class="o">.</span><span class="n">stop</span><span class="p">()</span>
</pre></div>
</div>
</li>
<li><p class="first">Do not call <code class="docutils literal"><span class="pre">cherrypy.engine.block()</span></code>.</p>
</li>
<li><p class="first">Disable the built-in HTTP server since it will not be used.</p>
<div class="highlight-python"><div class="highlight"><pre><span></span><span class="n">cherrypy</span><span class="o">.</span><span class="n">server</span><span class="o">.</span><span class="n">unsubscribe</span><span class="p">()</span>
</pre></div>
</div>
</li>
<li><p class="first">Disable autoreload. Usually other frameworks won’t react well to it,
or sometimes, provide the same feature.</p>
<div class="highlight-python"><div class="highlight"><pre><span></span><span class="n">cherrypy</span><span class="o">.</span><span class="n">config</span><span class="o">.</span><span class="n">update</span><span class="p">({</span><span class="s1">&#39;engine.autoreload.on&#39;</span><span class="p">:</span> <span class="bp">False</span><span class="p">})</span>
</pre></div>
</div>
</li>
<li><p class="first">Disable CherryPy signals handling. This may not be needed, it depends
on how the other framework handles them.</p>
<div class="highlight-python"><div class="highlight"><pre><span></span><span class="n">cherrypy</span><span class="o">.</span><span class="n">engine</span><span class="o">.</span><span class="n">signals</span><span class="o">.</span><span class="n">subscribe</span><span class="p">()</span>
</pre></div>
</div>
</li>
<li><p class="first">Use the <code class="docutils literal"><span class="pre">&quot;embedded&quot;</span></code> environment configuration scheme.</p>
<div class="highlight-python"><div class="highlight"><pre><span></span><span class="n">cherrypy</span><span class="o">.</span><span class="n">config</span><span class="o">.</span><span class="n">update</span><span class="p">({</span><span class="s1">&#39;environment&#39;</span><span class="p">:</span> <span class="s1">&#39;embedded&#39;</span><span class="p">})</span>
</pre></div>
</div>
<p>Essentially this will disable the following:</p>
<ul class="simple">
<li>Stdout logging</li>
<li>Autoreloader</li>
<li>Configuration checker</li>
<li>Headers logging on error</li>
<li>Tracebacks in error</li>
<li>Mismatched params error during dispatching</li>
<li>Signals (SIGHUP, SIGTERM)</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="tornado">
<h3><a class="toc-backref" href="#id14">Tornado</a><a class="headerlink" href="#tornado" title="Permalink to this headline"></a></h3>
<p>You can use <a class="reference external" href="http://www.tornadoweb.org/">tornado</a> HTTP server as
follow:</p>
<div class="highlight-python"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">cherrypy</span>

<span class="k">class</span> <span class="nc">Root</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="nd">@cherrypy.expose</span>
    <span class="k">def</span> <span class="nf">index</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="s2">&quot;Hello World!&quot;</span>

<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="kn">import</span> <span class="nn">tornado</span>
    <span class="kn">import</span> <span class="nn">tornado.httpserver</span>
    <span class="kn">import</span> <span class="nn">tornado.wsgi</span>

    <span class="c1"># our WSGI application</span>
    <span class="n">wsgiapp</span> <span class="o">=</span> <span class="n">cherrypy</span><span class="o">.</span><span class="n">tree</span><span class="o">.</span><span class="n">mount</span><span class="p">(</span><span class="n">Root</span><span class="p">())</span>

    <span class="c1"># Disable the autoreload which won&#39;t play well</span>
    <span class="n">cherrypy</span><span class="o">.</span><span class="n">config</span><span class="o">.</span><span class="n">update</span><span class="p">({</span><span class="s1">&#39;engine.autoreload.on&#39;</span><span class="p">:</span> <span class="bp">False</span><span class="p">})</span>

    <span class="c1"># let&#39;s not start the CherryPy HTTP server</span>
    <span class="n">cherrypy</span><span class="o">.</span><span class="n">server</span><span class="o">.</span><span class="n">unsubscribe</span><span class="p">()</span>

    <span class="c1"># use CherryPy&#39;s signal handling</span>
    <span class="n">cherrypy</span><span class="o">.</span><span class="n">engine</span><span class="o">.</span><span class="n">signals</span><span class="o">.</span><span class="n">subscribe</span><span class="p">()</span>

    <span class="c1"># Prevent CherryPy logs to be propagated</span>
    <span class="c1"># to the Tornado logger</span>
    <span class="n">cherrypy</span><span class="o">.</span><span class="n">log</span><span class="o">.</span><span class="n">error_log</span><span class="o">.</span><span class="n">propagate</span> <span class="o">=</span> <span class="bp">False</span>

    <span class="c1"># Run the engine but don&#39;t block on it</span>
    <span class="n">cherrypy</span><span class="o">.</span><span class="n">engine</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>

    <span class="c1"># Run thr tornado stack</span>
    <span class="n">container</span> <span class="o">=</span> <span class="n">tornado</span><span class="o">.</span><span class="n">wsgi</span><span class="o">.</span><span class="n">WSGIContainer</span><span class="p">(</span><span class="n">wsgiapp</span><span class="p">)</span>
    <span class="n">http_server</span> <span class="o">=</span> <span class="n">tornado</span><span class="o">.</span><span class="n">httpserver</span><span class="o">.</span><span class="n">HTTPServer</span><span class="p">(</span><span class="n">container</span><span class="p">)</span>
    <span class="n">http_server</span><span class="o">.</span><span class="n">listen</span><span class="p">(</span><span class="mi">8080</span><span class="p">)</span>
    <span class="c1"># Publish to the CherryPy engine as if</span>
    <span class="c1"># we were using its mainloop</span>
    <span class="n">tornado</span><span class="o">.</span><span class="n">ioloop</span><span class="o">.</span><span class="n">PeriodicCallback</span><span class="p">(</span><span class="k">lambda</span><span class="p">:</span> <span class="n">cherrypy</span><span class="o">.</span><span class="n">engine</span><span class="o">.</span><span class="n">publish</span><span class="p">(</span><span class="s1">&#39;main&#39;</span><span class="p">),</span> <span class="mi">100</span><span class="p">)</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
    <span class="n">tornado</span><span class="o">.</span><span class="n">ioloop</span><span class="o">.</span><span class="n">IOLoop</span><span class="o">.</span><span class="n">instance</span><span class="p">()</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
</pre></div>
</div>
</div>
<div class="section" id="twisted">
<h3><a class="toc-backref" href="#id15">Twisted</a><a class="headerlink" href="#twisted" title="Permalink to this headline"></a></h3>
<p>You can use <a class="reference external" href="https://twistedmatrix.com/">Twisted</a> HTTP server as
follow:</p>
<div class="highlight-python"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">cherrypy</span>

<span class="kn">from</span> <span class="nn">twisted.web.wsgi</span> <span class="kn">import</span> <span class="n">WSGIResource</span>
<span class="kn">from</span> <span class="nn">twisted.internet</span> <span class="kn">import</span> <span class="n">reactor</span>
<span class="kn">from</span> <span class="nn">twisted.internet</span> <span class="kn">import</span> <span class="n">task</span>

<span class="c1"># Our CherryPy application</span>
<span class="k">class</span> <span class="nc">Root</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="nd">@cherrypy.expose</span>
    <span class="k">def</span> <span class="nf">index</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="s2">&quot;hello world&quot;</span>

<span class="c1"># Create our WSGI app from the CherryPy application</span>
<span class="n">wsgiapp</span> <span class="o">=</span> <span class="n">cherrypy</span><span class="o">.</span><span class="n">tree</span><span class="o">.</span><span class="n">mount</span><span class="p">(</span><span class="n">Root</span><span class="p">())</span>

<span class="c1"># Configure the CherryPy&#39;s app server</span>
<span class="c1"># Disable the autoreload which won&#39;t play well</span>
<span class="n">cherrypy</span><span class="o">.</span><span class="n">config</span><span class="o">.</span><span class="n">update</span><span class="p">({</span><span class="s1">&#39;engine.autoreload.on&#39;</span><span class="p">:</span> <span class="bp">False</span><span class="p">})</span>

<span class="c1"># We will be using Twisted HTTP server so let&#39;s</span>
<span class="c1"># disable the CherryPy&#39;s HTTP server entirely</span>
<span class="n">cherrypy</span><span class="o">.</span><span class="n">server</span><span class="o">.</span><span class="n">unsubscribe</span><span class="p">()</span>

<span class="c1"># If you&#39;d rather use CherryPy&#39;s signal handler</span>
<span class="c1"># Uncomment the next line. I don&#39;t know how well this</span>
<span class="c1"># will play with Twisted however</span>
<span class="c1">#cherrypy.engine.signals.subscribe()</span>

<span class="c1"># Publish periodically onto the &#39;main&#39; channel as the bus mainloop would do</span>
<span class="n">task</span><span class="o">.</span><span class="n">LoopingCall</span><span class="p">(</span><span class="k">lambda</span><span class="p">:</span> <span class="n">cherrypy</span><span class="o">.</span><span class="n">engine</span><span class="o">.</span><span class="n">publish</span><span class="p">(</span><span class="s1">&#39;main&#39;</span><span class="p">))</span><span class="o">.</span><span class="n">start</span><span class="p">(</span><span class="mf">0.1</span><span class="p">)</span>

<span class="c1"># Tie our app to Twisted</span>
<span class="n">reactor</span><span class="o">.</span><span class="n">addSystemEventTrigger</span><span class="p">(</span><span class="s1">&#39;after&#39;</span><span class="p">,</span> <span class="s1">&#39;startup&#39;</span><span class="p">,</span> <span class="n">cherrypy</span><span class="o">.</span><span class="n">engine</span><span class="o">.</span><span class="n">start</span><span class="p">)</span>
<span class="n">reactor</span><span class="o">.</span><span class="n">addSystemEventTrigger</span><span class="p">(</span><span class="s1">&#39;before&#39;</span><span class="p">,</span> <span class="s1">&#39;shutdown&#39;</span><span class="p">,</span> <span class="n">cherrypy</span><span class="o">.</span><span class="n">engine</span><span class="o">.</span><span class="n">exit</span><span class="p">)</span>
<span class="n">resource</span> <span class="o">=</span> <span class="n">WSGIResource</span><span class="p">(</span><span class="n">reactor</span><span class="p">,</span> <span class="n">reactor</span><span class="o">.</span><span class="n">getThreadPool</span><span class="p">(),</span> <span class="n">wsgiapp</span><span class="p">)</span>
</pre></div>
</div>
<p>Notice how we attach the bus methods to the Twisted’s own lifecycle.</p>
<p>Save that code into a module named <cite>cptw.py</cite> and run it as follows:</p>
<div class="highlight-bash"><div class="highlight"><pre><span></span>$ twistd -n web --port <span class="m">8080</span> --wsgi cptw.wsgiapp
</pre></div>
</div>
</div>
<div class="section" id="uwsgi">
<h3><a class="toc-backref" href="#id16">uwsgi</a><a class="headerlink" href="#uwsgi" title="Permalink to this headline"></a></h3>
<p>You can use <a class="reference external" href="http://projects.unbit.it/uwsgi/">uwsgi</a> HTTP server as
follow:</p>
<div class="highlight-python"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">cherrypy</span>

<span class="c1"># Our CherryPy application</span>
<span class="k">class</span> <span class="nc">Root</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="nd">@cherrypy.expose</span>
    <span class="k">def</span> <span class="nf">index</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="s2">&quot;hello world&quot;</span>

<span class="n">cherrypy</span><span class="o">.</span><span class="n">config</span><span class="o">.</span><span class="n">update</span><span class="p">({</span><span class="s1">&#39;engine.autoreload.on&#39;</span><span class="p">:</span> <span class="bp">False</span><span class="p">})</span>
<span class="n">cherrypy</span><span class="o">.</span><span class="n">server</span><span class="o">.</span><span class="n">unsubscribe</span><span class="p">()</span>
<span class="n">cherrypy</span><span class="o">.</span><span class="n">engine</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>

<span class="n">wsgiapp</span> <span class="o">=</span> <span class="n">cherrypy</span><span class="o">.</span><span class="n">tree</span><span class="o">.</span><span class="n">mount</span><span class="p">(</span><span class="n">Root</span><span class="p">())</span>
</pre></div>
</div>
<p>Save this into a Python module called <cite>mymod.py</cite> and run
it as follows:</p>
<div class="highlight-bash"><div class="highlight"><pre><span></span>$ uwsgi --socket <span class="m">127</span>.0.0.1:8080 --protocol<span class="o">=</span>http --wsgi-file mymod.py --callable wsgiapp
</pre></div>
</div>
</div>
</div>
<div class="section" id="virtual-hosting">
<h2><a class="toc-backref" href="#id17">Virtual Hosting</a><a class="headerlink" href="#virtual-hosting" title="Permalink to this headline"></a></h2>
<p>CherryPy has support for virtual-hosting. It does so through
a dispatchers that locate the appropriate resource based
on the requested domain.</p>
<p>Below is a simple example for it:</p>
<div class="highlight-python"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">cherrypy</span>

<span class="k">class</span> <span class="nc">Root</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">app1</span> <span class="o">=</span> <span class="n">App1</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">app2</span> <span class="o">=</span> <span class="n">App2</span><span class="p">()</span>

<span class="k">class</span> <span class="nc">App1</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="nd">@cherrypy.expose</span>
    <span class="k">def</span> <span class="nf">index</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="s2">&quot;Hello world from app1&quot;</span>

<span class="k">class</span> <span class="nc">App2</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="nd">@cherrypy.expose</span>
    <span class="k">def</span> <span class="nf">index</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="s2">&quot;Hello world from app2&quot;</span>

<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="n">hostmap</span> <span class="o">=</span> <span class="p">{</span>
        <span class="s1">&#39;company.com:8080&#39;</span><span class="p">:</span> <span class="s1">&#39;/app1&#39;</span><span class="p">,</span>
        <span class="s1">&#39;home.net:8080&#39;</span><span class="p">:</span> <span class="s1">&#39;/app2&#39;</span><span class="p">,</span>
    <span class="p">}</span>

    <span class="n">config</span> <span class="o">=</span> <span class="p">{</span>
        <span class="s1">&#39;request.dispatch&#39;</span><span class="p">:</span> <span class="n">cherrypy</span><span class="o">.</span><span class="n">dispatch</span><span class="o">.</span><span class="n">VirtualHost</span><span class="p">(</span><span class="o">**</span><span class="n">hostmap</span><span class="p">)</span>
    <span class="p">}</span>

    <span class="n">cherrypy</span><span class="o">.</span><span class="n">quickstart</span><span class="p">(</span><span class="n">Root</span><span class="p">(),</span> <span class="s1">&#39;/&#39;</span><span class="p">,</span> <span class="p">{</span><span class="s1">&#39;/&#39;</span><span class="p">:</span> <span class="n">config</span><span class="p">})</span>
</pre></div>
</div>
<p>In this example, we declare two domains and their ports:</p>
<ul class="simple">
<li>company.com:8080</li>
<li>home.net:8080</li>
</ul>
<p>Thanks to the <code class="xref py py-class docutils literal"><span class="pre">cherrypy.dispatch.VirtualHost</span></code> dispatcher,
we tell CherryPy which application to dispatch to when a request
arrives. The dispatcher looks up the requested domain and
call the according application.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p>To test this example, simply add the following rules to
your <cite>hosts</cite> file:</p>
<div class="last highlight-text"><div class="highlight"><pre><span></span>127.0.0.1       company.com
127.0.0.1       home.net
</pre></div>
</div>
</div>
</div>
<div class="section" id="reverse-proxying">
<h2><a class="toc-backref" href="#id18">Reverse-proxying</a><a class="headerlink" href="#reverse-proxying" title="Permalink to this headline"></a></h2>
<div class="section" id="apache">
<h3><a class="toc-backref" href="#id19">Apache</a><a class="headerlink" href="#apache" title="Permalink to this headline"></a></h3>
</div>
<div class="section" id="id4">
<h3><a class="toc-backref" href="#id20">Nginx</a><a class="headerlink" href="#id4" title="Permalink to this headline"></a></h3>
<p>nginx is a fast and modern HTTP server with a small footprint. It is
a popular choice as a reverse proxy to application servers such as
CherryPy.</p>
<p>This section will not cover the whole range of features nginx provides.
Instead, it will simply provide you with a basic configuration that can
be a good starting point.</p>
<div class="highlight-nginx"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="k">upstream</span> <span class="s">apps</span> <span class="p">{</span>
   <span class="kn">server</span> <span class="n">127.0.0.1</span><span class="p">:</span><span class="mi">8080</span><span class="p">;</span>
   <span class="kn">server</span> <span class="n">127.0.0.1</span><span class="p">:</span><span class="mi">8081</span><span class="p">;</span>
<span class="p">}</span>

<span class="k">gzip_http_version</span> <span class="mi">1</span><span class="s">.0</span><span class="p">;</span>
<span class="k">gzip_proxied</span>      <span class="s">any</span><span class="p">;</span>
<span class="k">gzip_min_length</span>   <span class="mi">500</span><span class="p">;</span>
<span class="k">gzip_disable</span>      <span class="s">&quot;MSIE</span> <span class="s">[1-6]\.&quot;</span><span class="p">;</span>
<span class="k">gzip_types</span>        <span class="s">text/plain</span> <span class="s">text/xml</span> <span class="s">text/css</span>
                  <span class="s">text/javascript</span>
                  <span class="s">application/javascript</span><span class="p">;</span>

<span class="k">server</span> <span class="p">{</span>
   <span class="kn">listen</span> <span class="mi">80</span><span class="p">;</span>
   <span class="kn">server_name</span>  <span class="s">www.example.com</span><span class="p">;</span>

   <span class="kn">access_log</span>  <span class="s">/app/logs/www.example.com.log</span> <span class="s">combined</span><span class="p">;</span>
   <span class="kn">error_log</span>  <span class="s">/app/logs/www.example.com.log</span><span class="p">;</span>

   <span class="kn">location</span> <span class="s">^~</span> <span class="s">/static/</span>  <span class="p">{</span>
      <span class="kn">root</span> <span class="s">/app/static/</span><span class="p">;</span>
   <span class="p">}</span>

   <span class="kn">location</span> <span class="s">/</span> <span class="p">{</span>
      <span class="kn">proxy_pass</span>         <span class="s">http://apps</span><span class="p">;</span>
      <span class="kn">proxy_redirect</span>     <span class="no">off</span><span class="p">;</span>
      <span class="kn">proxy_set_header</span>   <span class="s">Host</span> <span class="nv">$host</span><span class="p">;</span>
      <span class="kn">proxy_set_header</span>   <span class="s">X-Real-IP</span> <span class="nv">$remote_addr</span><span class="p">;</span>
      <span class="kn">proxy_set_header</span>   <span class="s">X-Forwarded-For</span> <span class="nv">$proxy_add_x_forwarded_for</span><span class="p">;</span>
      <span class="kn">proxy_set_header</span>   <span class="s">X-Forwarded-Host</span> <span class="nv">$server_name</span><span class="p">;</span>
   <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
<p>Edit this configuration to match your own paths. Then, save this configuration
into a file under <code class="docutils literal"><span class="pre">/etc/nginx/conf.d/</span></code> (assuming Ubuntu).
The filename is irrelevant. Then run the following commands:</p>
<div class="highlight-bash"><div class="highlight"><pre><span></span>$ sudo service nginx stop
$ sudo service nginx start
</pre></div>
</div>
<p>Hopefully, this will be enough to forward requests hitting
the nginx frontend to your CherryPy application. The <code class="docutils literal"><span class="pre">upstream</span></code>
block defines the addresses of your CherryPy instances.</p>
<p>It shows that you can load-balance between two application
servers. Refer to the nginx documentation to understand
how this achieved.</p>
<div class="highlight-nginx"><div class="highlight"><pre><span></span><span class="k">upstream</span> <span class="s">apps</span> <span class="p">{</span>
   <span class="kn">server</span> <span class="n">127.0.0.1</span><span class="p">:</span><span class="mi">8080</span><span class="p">;</span>
   <span class="kn">server</span> <span class="n">127.0.0.1</span><span class="p">:</span><span class="mi">8081</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Later on, this block is used to define the reverse
proxy section.</p>
<p>Now, let’s see our application:</p>
<div class="highlight-python"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">cherrypy</span>

<span class="k">class</span> <span class="nc">Root</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="nd">@cherrypy.expose</span>
    <span class="k">def</span> <span class="nf">index</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="s2">&quot;hello world&quot;</span>

<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="n">cherrypy</span><span class="o">.</span><span class="n">config</span><span class="o">.</span><span class="n">update</span><span class="p">({</span>
        <span class="s1">&#39;server.socket_port&#39;</span><span class="p">:</span> <span class="mi">8080</span><span class="p">,</span>
        <span class="s1">&#39;tools.proxy.on&#39;</span><span class="p">:</span> <span class="bp">True</span><span class="p">,</span>
        <span class="s1">&#39;tools.proxy.base&#39;</span><span class="p">:</span> <span class="s1">&#39;http://www.example.com&#39;</span>
    <span class="p">})</span>
    <span class="n">cherrypy</span><span class="o">.</span><span class="n">quickstart</span><span class="p">(</span><span class="n">Root</span><span class="p">())</span>
</pre></div>
</div>
<p>If you run two instances of this code, one on each
port defined in the nginx section, you will be able
to reach both of them via the load-balancing done
by nginx.</p>
<p>Notice how we define the proxy tool. It is not mandatory and
used only so that the CherryPy request knows about the true
client’s address. Otherwise, it would know only about the
nginx’s own address. This is most visible in the logs.</p>
<p>The <code class="docutils literal"><span class="pre">base</span></code> attribute should match the <code class="docutils literal"><span class="pre">server_name</span></code>
section of the nginx configuration.</p>
</div>
</div>
</div>


          </div>
        </div>
      </div>
      <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
        <div class="sphinxsidebarwrapper">
  <h3><a href="index.html">Table Of Contents</a></h3>
  <ul>
<li><a class="reference internal" href="#">Deploy</a><ul>
<li><a class="reference internal" href="#run-as-a-daemon">Run as a daemon</a></li>
<li><a class="reference internal" href="#run-as-a-different-user">Run as a different user</a></li>
<li><a class="reference internal" href="#pid-files">PID files</a></li>
<li><a class="reference internal" href="#systemd-socket-activation">Systemd socket activation</a></li>
<li><a class="reference internal" href="#control-via-supervisord">Control via Supervisord</a></li>
<li><a class="reference internal" href="#ssl-support">SSL support</a></li>
<li><a class="reference internal" href="#wsgi-servers">WSGI servers</a><ul>
<li><a class="reference internal" href="#embedding-into-another-wsgi-framework">Embedding into another WSGI framework</a></li>
<li><a class="reference internal" href="#tornado">Tornado</a></li>
<li><a class="reference internal" href="#twisted">Twisted</a></li>
<li><a class="reference internal" href="#uwsgi">uwsgi</a></li>
</ul>
</li>
<li><a class="reference internal" href="#virtual-hosting">Virtual Hosting</a></li>
<li><a class="reference internal" href="#reverse-proxying">Reverse-proxying</a><ul>
<li><a class="reference internal" href="#apache">Apache</a></li>
<li><a class="reference internal" href="#id4">Nginx</a></li>
</ul>
</li>
</ul>
</li>
</ul>

  <h4>Previous topic</h4>
  <p class="topless"><a href="extend.html"
                        title="previous chapter">Extend</a></p>
  <h4>Next topic</h4>
  <p class="topless"><a href="support.html"
                        title="next chapter">Support</a></p>
  <div role="note" aria-label="source link">
    <h3>This Page</h3>
    <ul class="this-page-menu">
      <li><a href="_sources/deploy.rst.txt"
            rel="nofollow">Show Source</a></li>
    </ul>
   </div>
<div id="searchbox" style="display: none" role="search">
  <h3>Quick search</h3>
    <form class="search" action="search.html" method="get">
      <div><input type="text" name="q" /></div>
      <div><input type="submit" value="Go" /></div>
      <input type="hidden" name="check_keywords" value="yes" />
      <input type="hidden" name="area" value="default" />
    </form>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
        </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="genindex.html" title="General Index"
             >index</a></li>
        <li class="right" >
          <a href="support.html" title="Support"
             >next</a> |</li>
        <li class="right" >
          <a href="extend.html" title="Extend"
             >previous</a> |</li>
        <li class="nav-item nav-item-0"><a href="index.html">CherryPy 8.9.1 documentation</a> &#187;</li> 
      </ul>
    </div>
    <div class="footer" role="contentinfo">
        &#169; Copyright 2001-2018 CherryPy Team.
      Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.6.6.
    </div>
  </body>
</html>