.. index:: single: virtual hosting
"Virtual hosting" is, loosely, the act of serving a :app:`Pyramid` application or a portion of a :app:`Pyramid` application under a URL space that it does not "naturally" inhabit.
:app:`Pyramid` provides facilities for serving an application under a URL "prefix", as well as serving a portion of a :term:`traversal` based application under a root URL.
.. index:: single: hosting an app under a prefix
:app:`Pyramid` supports a common form of virtual hosting whereby you
can host a :app:`Pyramid` application as a "subset" of some other site
(e.g. under http://example.com/mypyramidapplication/
as opposed to
under http://example.com/
).
If you use a "pure Python" environment, this functionality can be provided by Paste's urlmap "composite" WSGI application. Alternately, you can use :term:`mod_wsgi` to serve your application, which handles this virtual hosting translation for you "under the hood".
If you use the urlmap
composite application "in front" of a
:app:`Pyramid` application or if you use :term:`mod_wsgi` to serve
up a :app:`Pyramid` application, nothing special needs to be done
within the application for URLs to be generated that contain a
prefix. :mod:`paste.urlmap` and :term:`mod_wsgi` manipulate the
:term:`WSGI` environment in such a way that the PATH_INFO
and
SCRIPT_NAME
variables are correct for some given prefix.
Here's an example of a PasteDeploy configuration snippet that includes
a urlmap
composite.
[app:mypyramidapp]
use = egg:mypyramidapp
[composite:main]
use = egg:Paste#urlmap
/pyramidapp = mypyramidapp
This "roots" the :app:`Pyramid` application at the prefix
/pyramidapp
and serves up the composite as the "main" application
in the file.
Note
If you're using an Apache server to proxy to a Paste
urlmap
composite, you may have to use the ProxyPreserveHost
directive to pass the original HTTP_HOST
header along to the
application, so URLs get generated properly. As of this writing
the urlmap
composite does not seem to respect the
HTTP_X_FORWARDED_HOST
parameter, which will contain the
original host header even if HTTP_HOST
is incorrect.
If you use :term:`mod_wsgi`, you do not need to use a composite
application in your .ini
file. The WSGIScriptAlias
configuration setting in a :term:`mod_wsgi` configuration does the
work for you:
WSGIScriptAlias /pyramidapp /Users/chrism/projects/modwsgi/env/pyramid.wsgi
In the above configuration, we root a :app:`Pyramid` application at
/pyramidapp
within the Apache configuration.
.. index:: single: virtual root
:app:`Pyramid` also supports "virtual roots", which can be used in :term:`traversal` -based (but not :term:`URL dispatch` -based) applications.
Virtual root support is useful when you'd like to host some resource in a
:app:`Pyramid` resource tree as an application under a URL pathname that does
not include the resource path itself. For example, you might want to serve the
object at the traversal path /cms
as an application reachable via
http://example.com/
(as opposed to http://example.com/cms
).
To specify a virtual root, cause an environment variable to be inserted into
the WSGI environ named HTTP_X_VHM_ROOT
with a value that is the absolute
pathname to the resource object in the resource tree that should behave as
the "root" resource. As a result, the traversal machinery will respect this
value during traversal (prepending it to the PATH_INFO before traversal
starts), and the :meth:`pyramid.request.Request.resource_url` API will
generate the "correct" virtually-rooted URLs.
An example of an Apache mod_proxy
configuration that will host the
/cms
subobject as http://www.example.com/
using this facility
is below:
NameVirtualHost *:80
<VirtualHost *:80>
ServerName www.example.com
RewriteEngine On
RewriteRule ^/(.*) http://127.0.0.1:6543/$1 [L,P]
ProxyPreserveHost on
RequestHeader add X-Vhm-Root /cms
</VirtualHost>
Note
Use of the RequestHeader
directive requires that the
Apache mod_headers module be
available in the Apache environment you're using.
For a :app:`Pyramid` application running under :term:`mod_wsgi`,
the same can be achieved using SetEnv
:
<Location />
SetEnv HTTP_X_VHM_ROOT /cms
</Location>
Setting a virtual root has no effect when using an application based on :term:`URL dispatch`.
The API documentation in :ref:`traversal_module` documents a :func:`pyramid.traversal.virtual_root` API. When called, it returns the virtual root object (or the physical root object if no virtual root has been specified).
:ref:`modwsgi_tutorial` has detailed information about using :term:`mod_wsgi` to serve :app:`Pyramid` applications.