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 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816
|
========================
Configuration Guidelines
========================
The purpose of this document is to detail the basic configuration steps
required for running WSGI applications with mod_wsgi.
The WSGIScriptAlias Directive
-----------------------------
Configuring Apache to run WSGI applications using mod_wsgi is similar to
how Apache is configured to run CGI applications. To streamline this task
however, an additional configuration directive called WSGIScriptAlias is
provided. Like the ScriptAlias directive for CGI scripts, the mod_wsgi
directive combines together a number of steps so as to reduce the amount of
configuration required.
The first way of using the WSGIScriptAlias directive to indicate the WSGI
application to be used, is to associate a WSGI application against a
specific URL prefix::
WSGIScriptAlias /myapp /usr/local/wsgi/scripts/myapp.wsgi
The last option to the directive in this case must be a full pathname to
the actual code file containing the WSGI application. A trailing slash
should never be added to the last option when it is referring to an actual
file.
The WSGI application contained within the code file specified should be
called 'application'. For example::
def application(environ, start_response):
status = '200 OK'
output = b'Hello World!'
response_headers = [('Content-type', 'text/plain'),
('Content-Length', str(len(output)))]
start_response(status, response_headers)
return [output]
Note that an absolute pathname to a WSGI script file must be provided. It
is not possible to specify an application by Python module name alone. A
full path is used for a number of reasons, the main one being so that all
the Apache access controls can still be applied to indicate who can
actually access the WSGI application. Because these access controls will
apply, if the WSGI application is located outside of any directories
already known to Apache, it will be necessary to tell Apache that files
within that directory can be used. To do this the Directory directive must
be used::
<Directory /usr/local/wsgi/scripts>
<IfVersion < 2.4>
Order allow,deny
Allow from all
</IfVersion>
<IfVersion >= 2.4>
Require all granted
</IfVersion>
</Directory>
Note that Apache access control directives such as Order and Allow, or
Require in the case of Apache 2.4 or newer, should nearly always be applied
to Directory and never to a Location. Adding them to a Location would not
be regarded as best practice and would potentially weaken the security of
your Apache server, especially where the Location was for '/'.
As for CGI scripts and the ScriptAlias directive, it is not necessary to
have used the Options directive to enable the ExecCGI directive. This is
because it is automatically implied from the use of the WSGIScriptAlias
directive that the script must be executable.
For WSGIScriptAlias, to mount a WSGI application at the root of the web
site, simply use '/' as the mount point::
WSGIScriptAlias / /usr/local/wsgi/scripts/myapp.wsgi
If you need to mount multiple WSGI applications, the directives can be
listed more than once. When this occurs, those occuring first are given
precedence. As such, those which are mounted at what would be a sub URL to
another WSGI application, should always be listed earlier::
WSGIScriptAlias /wiki /usr/local/wsgi/scripts/mywiki.wsgi
WSGIScriptAlias /blog /usr/local/wsgi/scripts/myblog.wsgi
WSGIScriptAlias / /usr/local/wsgi/scripts/myapp.wsgi
The second way of using the WSGIScriptAlias directive is to use it to map
to a directory containing any number of WSGI applications::
WSGIScriptAlias /wsgi/ /usr/local/wsgi/scripts/
When this is used, the next part of the URL after the URL prefix is used to
identify which WSGI application script file within the target directory
should be used. Both the mount point and the directory path must have a
trailing slash.
If you want WSGI application scripts to use an extension, but don't wish
to have that extension appear in the URL, then it is possible to use the
WSGIScriptAliasMatch directive instead::
WSGIScriptAliasMatch ^/wsgi/([^/]+) /usr/local/wsgi/scripts/$1.wsgi
In this case, any path information appearing after the URL prefix, will be
mapped to a corresponding WSGI script file in the directory, but with a
'.wsgi' extension. The extension would though not need to be included in
the URL.
In all ways that the WSGIScriptAlias can be used, the target script is not
required to have any specific extension type and in particular it is not
necessary to use a '.py' extension just because it contains Python code.
Because the target script is not treated exactly like a traditional Python
module, if an extension is used, it is recommended that '.wsgi' be used
rather than '.py'.
The Apache Alias Directive
--------------------------
Although the WSGIScriptAlias directive is provided, the traditional Alias
directive can still be used to enable execution of WSGI applications for
specific URLs. The equivalent such configuration for::
WSGIScriptAlias /wsgi/ /usr/local/wsgi/scripts/
<Directory /usr/local/wsgi/scripts>
<IfVersion < 2.4>
Order allow,deny
Allow from all
</IfVersion>
<IfVersion >= 2.4>
Require all granted
</IfVersion>
</Directory>
using the Alias directive would be::
Alias /wsgi/ /usr/local/wsgi/scripts/
<Directory /usr/local/wsgi/scripts>
Options ExecCGI
SetHandler wsgi-script
<IfVersion < 2.4>
Order allow,deny
Allow from all
</IfVersion>
<IfVersion >= 2.4>
Require all granted
</IfVersion>
</Directory>
The additional steps required in this case are to enable the ability to
execute CGI like scripts using the Options directive and define the Apache
handler as 'wsgi-script'.
If wishing to hold a mixture of static files, normal CGI scripts and WSGI
applications within the one directory, the AddHandler directive can be
used instead of the SetHandler directive to distinguish between the various
resource types based on resource extension::
Alias /wsgi/ /usr/local/wsgi/scripts/
<Directory /usr/local/wsgi/scripts>
Options ExecCGI
AddHandler cgi-script .cgi
AddHandler wsgi-script .wsgi
<IfVersion < 2.4>
Order allow,deny
Allow from all
</IfVersion>
<IfVersion >= 2.4>
Require all granted
</IfVersion>
</Directory>
For whatever extension you use to identify a WSGI script file, ensure that
you do not have a conflicting definition for that extension marking it as a
CGI script file. For example, if you previously had all '.py' files being
handled as 'cgi-script', consider disabling that before marking '.py' file
as then being handled as 'wsgi-script' file in same context. If both are
defined in same context, which is used will depend on the order of the
directives and the wrong handler may be selected.
Because an extension is required to determine whether a script should be
processed as a CGI script versus a WSGI application, the extension would
need to appear in the URL. If this is not desired, then add the MultiViews
option and MultiviewsMatch directive::
Alias /wsgi/ /usr/local/wsgi/scripts/
<Directory /usr/local/wsgi/scripts>
Options ExecCGI MultiViews
MultiviewsMatch Handlers
AddHandler cgi-script .cgi
AddHandler wsgi-script .wsgi
<IfVersion < 2.4>
Order allow,deny
Allow from all
</IfVersion>
<IfVersion >= 2.4>
Require all granted
</IfVersion>
</Directory>
Adding of MultiViews in this instance and allowing multiviews to match
Apache handlers will allow the extension to be dropped from the URL.
Provided that for each resource there is only one alternative, Apache will
then automatically select either the CGI script or WSGI application as
appropriate for that resource. Use of multiviews in this way would make it
possible to transparently migrate from CGI scripts to WSGI applications
without the need to change any URLs.
A benefit of using the AddHandler directive as described above, is that it
also allows a directory index page or directory browsing to be enabled for
the directory. To enable directory browsing add the Indexes option::
Alias /wsgi/ /usr/local/wsgi/scripts/
<Directory /usr/local/wsgi/scripts>
Options ExecCGI Indexes
AddHandler cgi-script .cgi
AddHandler wsgi-script .wsgi
<IfVersion < 2.4>
Order allow,deny
Allow from all
</IfVersion>
<IfVersion >= 2.4>
Require all granted
</IfVersion>
</Directory>
If a directory index page is enabled, it may refer to either a static file,
CGI or WSGI application. The DirectoryIndex directive should be used to
designate what should be used for the index page::
Alias /wsgi/ /usr/local/wsgi/scripts/
<Directory /usr/local/wsgi/scripts>
Options ExecCGI Indexes
DirectoryIndex index.html index.wsgi index.cgi
AddHandler cgi-script .cgi
AddHandler wsgi-script .wsgi
<IfVersion < 2.4>
Order allow,deny
Allow from all
</IfVersion>
<IfVersion >= 2.4>
Require all granted
</IfVersion>
</Directory>
Using AddHandler or SetHandler to configure a WSGI application can also
be done from within the '.htaccess' file located within the directory which
a URL maps to. This will however only be possible where the directory has
been enabled to allow these directives to be used. This would be done using
the AllowOverride directive and enabling FileInfo for that directory.
It would also be necessary to allow the execution of scripts using the
Options directive by listing ExecCGI::
Alias /site/ /usr/local/wsgi/site/
<Directory /usr/local/wsgi/site>
AllowOverride FileInfo
Options ExecCGI MultiViews Indexes
MultiviewsMatch Handlers
<IfVersion < 2.4>
Order allow,deny
Allow from all
</IfVersion>
<IfVersion >= 2.4>
Require all granted
</IfVersion>
</Directory>
This done, the '.htaccess' file could then contain::
DirectoryIndex index.html index.wsgi index.cgi
AddHandler cgi-script .cgi
AddHandler wsgi-script .wsgi
Note that the DirectoryIndex directive can only be used to designate a
simple WSGI application which returns a single page for when the URL maps
to the actual directory. Because the DirectoryIndex directive is not
applied when the URL has additional path information beyond the leading
portion of the URL which mapped to the directory, it cannot be used as a
means of making a complex WSGI application responding to numerous URLs
appear at the root of a server.
When using the AddHandler directive, with WSGI applications identified by
the extension of the script file, the only way to make the WSGI application
appear as the root of the server is to perform on the fly rewriting of the
URL internal to Apache using mod_rewrite. The required rules for
mod_rewrite to ensure that a WSGI application, implemented by the script
file 'site.wsgi' in the root directory of the virtual host, appears as being
mounted on the root of the virtual host would be::
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /site.wsgi/$1 [QSA,PT,L]
Do note however that when the WSGI application is executed for a request
the 'SCRIPT_NAME' variable indicating what the mount point of the application
was will be '/site.wsgi'. This will mean that when a WSGI application
constructs an absolute URL based on 'SCRIPT_NAME', it will include
'site.wsgi' in the URL rather than it being hidden. As this would probably
be undesirable, many web frameworks provide an option to override what the
value for the mount point is. If such a configuration option isn't
available, it is just as easy to adjust the value of 'SCRIPT_NAME' in the
'site.wsgi' script file itself::
def _application(environ, start_response):
# The original application.
...
import posixpath
def application(environ, start_response):
# Wrapper to set SCRIPT_NAME to actual mount point.
environ['SCRIPT_NAME'] = posixpath.dirname(environ['SCRIPT_NAME'])
if environ['SCRIPT_NAME'] == '/':
environ['SCRIPT_NAME'] = ''
return _application(environ, start_response)
This wrapper will ensure that 'site.wsgi' never appears in the URL as long
as it wasn't included in the first place and that access was always via the
root of the web site instead.
Application Configuration
-------------------------
If it is necessary or desired to be able to pass configuration information
through to a WSGI application from the Apache configuration file, then the
SetEnv directive can be used::
WSGIScriptAlias / /usr/local/wsgi/scripts/demo.wsgi
SetEnv demo.templates /usr/local/wsgi/templates
SetEnv demo.mailhost mailhost
SetEnv demo.debugging 0
Any such variables added using the SetEnv directive will be automatically
added to the WSGI environment passed to the application when executed.
Note that the WSGI environment is passed upon each request to the
application in the 'environ' argument of the application object. This
environment is totally unrelated to the process environment which is
kept in 'os.environ'. The SetEnv directive has no effect on 'os.environ'
and there is no way through Apache configuration directives to affect
what is in the process environment.
If needing to dynamically set variables based on some aspects of the
request itself, the RewriteRule directive may also be useful in some cases
as an avenue to set application configuration variables.
For example, to enable additional debug only when the client is connecting
from the localhost, the following might be used::
SetEnv demo.debugging 0
RewriteEngine On
RewriteCond %{REMOTE_ADDR} ^127.0.0.1$
RewriteRule . - [E=demo.debugging:1]
More elaborate schemes involving RewriteMap could also be employed.
Where SetEnv and RewriteRule are insufficient, then any further
application configuration should be injected into an application using a
WSGI application wrapper within the WSGI application script file::
def _application(environ, start_response):
...
def application(environ, start_response):
if environ['REMOTE_ADDR'] in ['127.0.0.1']:
environ['demo.debugging'] = '1'
return _application(environ, start_response)
User Authentication
-------------------
As is the case when using CGI scripts with Apache, authorisation headers
are not passed through to WSGI applications. This is the case, as doing so
could leak information about passwords through to a WSGI application which
should not be able to see them when Apache is performing authorisation.
Unlike CGI scripts however, when using mod_wsgi, the WSGIPassAuthorization
directive can be used to control whether HTTP authorisation headers are
passed through to a WSGI application in the ``HTTP_AUTHORIZATION``
variable of the WSGI application environment when the equivalent HTTP
request headers are present. This option would need to be set to ``On``
if the WSGI application was to handle authorisation rather than Apache
doing it::
WSGIPassAuthorization On
If Apache is performing authorisation and not the WSGI application, a WSGI
application can still find out what type of authorisation scheme was used
by checking the variable ``AUTH_TYPE`` of the WSGI application
environment. The login name of the authorised user can be determined by
checking the variable ``REMOTE_USER``.
Hosting Of Static Files
-----------------------
When the WSGIScriptAlias directive is used to mount an application at the
root of the web server for a host, all requests for that host will be
processed by the WSGI application. If is desired for performance reasons
to still use Apache to host static files associated with the application,
then the Alias directive can be used to designate the files and directories
which should be served in this way::
Alias /robots.txt /usr/local/wsgi/static/robots.txt
Alias /favicon.ico /usr/local/wsgi/static/favicon.ico
AliasMatch /([^/]*\.css) /usr/local/wsgi/static/styles/$1
Alias /media/ /usr/local/wsgi/static/media/
<Directory /usr/local/wsgi/static>
<IfVersion < 2.4>
Order allow,deny
Allow from all
</IfVersion>
<IfVersion >= 2.4>
Require all granted
</IfVersion>
</Directory>
WSGIScriptAlias / /usr/local/wsgi/scripts/myapp.wsgi
<Directory /usr/local/wsgi/scripts>
<IfVersion < 2.4>
Order allow,deny
Allow from all
</IfVersion>
<IfVersion >= 2.4>
Require all granted
</IfVersion>
</Directory>
When listing the directives, list those for more specific URLs first. In
practice this shouldn't actually be required as the Alias directive should
take precedence over WSGIScriptAlias, but good practice all the same.
Do note though that if using Apache 1.3, the Alias directive will only take
precedence over WSGIScriptAlias if the mod_wsgi module is loaded prior to
the mod_alias module. To ensure this, the LoadModule/AddModule directives
are used.
Note that there is never a need to use SetHandler to reset the Apache
content handler back to 'None' for URLs mapped to static files. That this
is a requirement for mod_python is a short coming in mod_python, do not do
the same thing for mod_wsgi.
Limiting Request Content
------------------------
By default Apache does not limit the amount of data that may be pushed to
the server via a HTTP request such as a POST. That this is the case means
that malicious users could attempt to overload a server by attempting to
upload excessively large amounts of data.
If a WSGI application is not designed properly and doesn't limit this
itself in some way, and attempts to load the whole request content into
memory, it could cause an application to exhaust available memory.
If it is unknown if a WSGI application properly protects itself against
such attempts to upload excessively large amounts of data, then the Apache
LimitRequestBody directive can be used::
LimitRequestBody 1048576
The argument to the LimitRequestBody should be the maxumum number of bytes
that should be allowed in the content of a request.
When this directive is used, mod_wsgi will perform the check prior to
actually passing a request off to a WSGI application. When the limit is
exceeded mod_wsgi will immediately return the HTTP 413 error response
without even invoking the WSGI application to handle the request. Any
request content will not be read as the client connection will then be
closed.
Note that the HTTP 413 error response page will be that defined by Apache,
or as specified by the Apache ErrorDocument directive for that error type.
Defining Application Groups
---------------------------
By default each WSGI application is placed into its own distinct
application group. This means that each application will be given its own
distinct Python sub interpreter to run code within. Although this means
that applications will be isolated and cannot in general interfere with the
Python code components of each other, each will load its own copy of all
Python modules it requires into memory. If you have many applications and
they use a lot of different Python modules this can result in large process
sizes.
To avoid large process sizes, if you know that applications within a
directory can safely coexist and run together within the same Python sub
interpreter, you can specify that all applications within a certain context
should be placed in the same application group. This is indicated by using
the WSGIApplicationGroup directive::
<Directory /usr/local/wsgi/scripts>
WSGIApplicationGroup admin-scripts
<IfVersion < 2.4>
Order allow,deny
Allow from all
</IfVersion>
<IfVersion >= 2.4>
Require all granted
</IfVersion>
</Directory>
The argument to the WSGIApplicationGroup directive can in general be any
unique name of your choosing, although there are also a number of special
values which you can use as well. For further information about these
special values see the more detailed documentation on the
:doc:`../configuration-directives/WSGIApplicationGroup` directive. Two of the
special values worth highlighting are:
**%{GLOBAL}**
The application group name will be set to the empty string.
Any WSGI applications in the global application group will always be
executed within the context of the first interpreter created by Python
when it is initialised. Forcing a WSGI application to run within the
first interpreter can be necessary when a third party C extension
module for Python has used the simplified threading API for
manipulation of the Python GIL and thus will not run correctly within
any additional sub interpreters created by Python.
**%{ENV:variable}**
The application group name will be set to the value of the named
environment variable. The environment variable is looked-up via the
internal Apache notes and subprocess environment data structures and
(if not found there) via getenv() from the Apache server process.
In an Apache configuration file, environment variables accessible
using the ``%{ENV}`` variable reference can be setup by using directives
such as SetEnv and RewriteRule.
For example, to group all WSGI scripts for a specific user when using
mod_userdir within the same application group, the following could be used::
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/~([^/]+)
RewriteRule . - [E=APPLICATION_GROUP:~%1]
<Directory /home/*/public_html/wsgi-scripts/>
Options ExecCGI
SetHandler wsgi-script
WSGIApplicationGroup %{ENV:APPLICATION_GROUP}
</Directory>
Defining Process Groups
-----------------------
By default all WSGI applications will run in what is called 'embedded'
mode. That is, the applications are run within Python sub interpreters
hosted within the Apache child processes. Although this results in the best
performance possible, there are a few down sides.
First off, embedded mode is not recommended where you are not adept at
tuning Apache. This is because the default MPM settings are never usually
suitable for Python web applications, instead being biased towards static
file serving and PHP applications. If you run embedded mode without tuning
the MPM settings, you can experience problems with memory usage, due to
default number of processes being too many, and can also experience load
spikes, due to how Apache performs lazy creation of processes to meet
demand.
Secondly, embedded mode would not be suitable for shared web hosting
environments as all applications run as the same user and through various
means could interfere with each other.
Running multiple Python applications within the same process, even if
separated into distinct sub interpreters also presents other challenges and
problems. These include problems with Python extension modules not being
implemented correctly such that they work from a secondary sub interpreter,
or when used from multiple sub interpreters at the same time.
Where multiple applications, potentially owned by different users, need to
be run, 'daemon' mode of mod_wsgi should instead be used. Using daemon
mode, each application can be delegated to its own dedicated daemon process
running just the WSGI application, with the Apache child processes merely
acting as proxies for delivering the requests to the application. Any
static files associated with the application would still be served up by
the Apache child processes to ensure best performance possible.
To denote that a daemon process should be created the WSGIDaemonProcess
directive is used. The WSGIProcessGroup directive is then used to delegate
specific WSGI applications to execute within that daemon process::
WSGIDaemonProcess www.site.com threads=15 maximum-requests=10000
Alias /favicon.ico /usr/local/wsgi/static/favicon.ico
AliasMatch /([^/]*\.css) /usr/local/wsgi/static/styles/$1
Alias /media/ /usr/local/wsgi/static/media/
<Directory /usr/local/wsgi/static>
<IfVersion < 2.4>
Order allow,deny
Allow from all
</IfVersion>
<IfVersion >= 2.4>
Require all granted
</IfVersion>
</Directory>
WSGIScriptAlias / /usr/local/wsgi/scripts/myapp.wsgi
WSGIProcessGroup www.site.com
<Directory /usr/local/wsgi/scripts>
<IfVersion < 2.4>
Order allow,deny
Allow from all
</IfVersion>
<IfVersion >= 2.4>
Require all granted
</IfVersion>
</Directory>
Where Apache has been started as the ``root`` user, the daemon processes
can optionally be run as a user different to that which the Apache child
processes would normally be run as. The number of daemon processes making
up the process group and whether they are single or multithreaded can also
be controlled.
A further option which should be considered is that which dictates the
maximum number of requests that a daemon process should be allowed to
accept before the daemon process is shutdown and restarted. This should be
used where there are problems with increasing memory use due to problems
with the application itself or a third party extension module.
As a general recommendation it would probably be a good idea to use the
maximum requests option when running large installations of packages such
as Trac and MoinMoin. Any large web site based on frameworks such as
Django, TurboGears and Pylons or applications which use a database backend
may also benefit.
If an application does not shutdown cleanly when the maximum number of
requests has been reached, it will be killed off after the shutdown timeout
has expired. If this occurs on a regular basis you should run with more
than a single daemon process in the process group such that the other
process can still accept requests while the first is being restarted.
If the maximum requests option is not specified, then the daemon process
will never expire and will only be restarted if Apache is restarted or the
user explicitly signals it to restart.
For further information about the options that can be supplied to the
WSGIDaemonProcess directive see the more detailed documentation for
:doc:`../configuration-directives/WSGIDaemonProcess`. A few of the options
which can be supplied to the WSGIDaemonProcess directive worth highlighting
are:
**user=name | user=#uid**
Defines the UNIX user _name_ or numeric user _uid_ of the user that
the daemon processes should be run as. If this option is not supplied
the daemon processes will be run as the same user that Apache would
run child processes and as defined by the User directive.
Note that this option is ignored if Apache wasn't started as the root
user, in which case no matter what the settings, the daemon processes
will be run as the user that Apache was started as.
**group=name | group=#gid**
Defines the UNIX group _name_ or numeric group _gid_ of the primary
group that the daemon processes should be run as. If this option is not
supplied the daemon processes will be run as the same group that Apache
would run child processes and as defined by the Group directive.
Note that this option is ignored if Apache wasn't started as the root
user, in which case no matter what the settings, the daemon processes
will be run as the group that Apache was started as.
**processes=num**
Defines the number of daemon processes that should be started in this
process group. If not defined then only one process will be run in this
process group.
Note that if this option is defined as 'processes=1', then the WSGI
environment attribute called 'wsgi.multiprocess' will be set to be True
whereas not providing the option at all will result in the attribute
being set to be False. This distinction is to allow for where some form
of mapping mechanism might be used to distribute requests across
multiple process groups and thus in effect it is still a multiprocess
application. If you need to ensure that 'wsgi.multiprocess' is False so
that interactive debuggers will work, simply do not specify the
'processes' option and allow the default single daemon process to be
created in the process group.
**threads=num**
Defines the number of threads to be created to handle requests in each
daemon process within the process group.
If this option is not defined then the default will be to create 15
threads in each daemon process within the process group.
**maximum-requests=nnn**
Defines a limit on the number of requests a daemon process should
process before it is shutdown and restarted. Setting this to a non zero
value has the benefit of limiting the amount of memory that a process
can consume by (accidental) memory leakage.
If this option is not defined, or is defined to be 0, then the daemon
process will be persistent and will continue to service requests until
Apache itself is restarted or shutdown.
Note that the name of the daemon process group must be unique for the whole
server. That is, it is not possible to use the same daemon process group
name in different virtual hosts.
If the WSGIDaemonProcess directive is specified outside of all virtual
host containers, any WSGI application can be delegated to be run within
that daemon process group. If the WSGIDaemonProcess directive is specified
within a virtual host container, only WSGI applications associated with
virtual hosts with the same server name as that virtual host can be
delegated to that set of daemon processes.
When WSGIDaemonProcess is associated with a virtual host, the error log
associated with that virtual host will be used for all Apache error log
output from mod_wsgi rather than it appear in the main Apache error log.
For example, if a server is hosting two virtual hosts and it is desired
that the WSGI applications related to each virtual host run in distinct
processes of their own and as a user which is the owner of that virtual
host, the following could be used::
<VirtualHost *:80>
ServerName www.site1.com
CustomLog logs/www.site1.com-access_log common
ErrorLog logs/ww.site1.com-error_log
WSGIDaemonProcess www.site1.com user=joe group=joe processes=2 threads=25
WSGIProcessGroup www.site1.com
...
</VirtualHost>
<VirtualHost *:80>
ServerName www.site2.com
CustomLog logs/www.site2.com-access_log common
ErrorLog logs/www.site2.com-error_log
WSGIDaemonProcess www.site2.com user=bob group=bob processes=2 threads=25
WSGIProcessGroup www.site2.com
...
</VirtualHost>
When using the WSGIProcessGroup directive, the argument to the directive
can be either one of two special expanding variables or the actual name of
a group of daemon processes setup using the WSGIDaemonProcess directive.
The meaning of the special variables are:
**%{GLOBAL}**
The process group name will be set to the empty string.
Any WSGI applications in the global process group will always be
executed within the context of the standard Apache child processes.
Such WSGI applications will incur the least runtime overhead, however,
they will share the same process space with other Apache modules such
as PHP, as well as the process being used to serve up static file
content. Running WSGI applications within the standard Apache child
processes will also mean the application will run as the user that
Apache would normally run as.
**%{ENV:variable}**
The process group name will be set to the value of the named
environment variable. The environment variable is looked-up via the
internal Apache notes and subprocess environment data structures and
(if not found there) via getenv() from the Apache server process.
The result must identify a named process group setup using the
WSGIDaemonProcess directive.
In an Apache configuration file, environment variables accessible using
the `%{ENV}` variable reference can be setup by using directives such as
SetEnv and RewriteRule.
For example, to select which process group a specific WSGI application
should execute within based on entries in a database file, the following
could be used::
RewriteEngine On
RewriteMap wsgiprocmap dbm:/etc/httpd/wsgiprocmap.dbm
RewriteRule . - [E=PROCESS_GROUP:${wsgiprocmap:%{REQUEST_URI}}]
WSGIProcessGroup %{ENV:PROCESS_GROUP}
Note that the WSGIDaemonProcess directive and corresponding features are
not available on Windows or when running Apache 1.3.
|