Browse Source

Touch up and integrate docs on deploying Flask.

pull/243/head
Ron DuPlain 14 years ago
parent
commit
207006f4c3
  1. 23
      docs/deploying/cgi.rst
  2. 96
      docs/deploying/fastcgi.rst
  3. 15
      docs/deploying/index.rst
  4. 69
      docs/deploying/mod_wsgi.rst
  5. 34
      docs/deploying/others.rst
  6. 31
      docs/deploying/uwsgi.rst

23
docs/deploying/cgi.rst

@ -1,23 +1,20 @@
CGI CGI
=== ===
If all other deployment methods do not work, CGI will work for sure. CGI If all other deployment methods do not work, CGI will work for sure.
is supported by all major servers but usually has a less-than-optimal CGI is supported by all major servers but usually has a sub-optimal
performance. performance.
This is also the way you can use a Flask application on Google's This is also the way you can use a Flask application on Google's `App
`App Engine`_, there however the execution does happen in a CGI-like Engine`_, where execution happens in a CGI-like environment.
environment. The application's performance is unaffected because of that.
.. admonition:: Watch Out .. admonition:: Watch Out
Please make sure in advance that your ``app.run()`` call you might Please make sure in advance that any ``app.run()`` calls you might
have in your application file, is inside an ``if __name__ == have in your application file are inside an ``if __name__ ==
'__main__':`` or moved to a separate file. Just make sure it's not '__main__':`` block or moved to a separate file. Just make sure it's
called because this will always start a local WSGI server which we do not called because this will always start a local WSGI server which
not want if we deploy that application to CGI / app engine. we do not want if we deploy that application to CGI / app engine.
.. _App Engine: http://code.google.com/appengine/
Creating a `.cgi` file Creating a `.cgi` file
---------------------- ----------------------
@ -45,3 +42,5 @@ In Apache for example you can put a like like this into the config:
ScriptAlias /app /path/to/the/application.cgi ScriptAlias /app /path/to/the/application.cgi
For more information consult the documentation of your webserver. For more information consult the documentation of your webserver.
.. _App Engine: http://code.google.com/appengine/

96
docs/deploying/fastcgi.rst

@ -1,20 +1,22 @@
.. _deploying-fastcgi:
FastCGI FastCGI
======= =======
A very popular deployment setup on servers like `lighttpd`_ and `nginx`_ FastCGI is a deployment option on servers like `nginx`_, `lighttpd`_,
is FastCGI. To use your WSGI application with any of them you will need and `cherokee`_; see :ref:`deploying-uwsgi` and
a FastCGI server first. :ref:`deploying-other-servers` for other options. To use your WSGI
application with any of them you will need a FastCGI server first. The
The most popular one is `flup`_ which we will use for this guide. Make most popular one is `flup`_ which we will use for this guide. Make sure
sure to have it installed. to have it installed to follow along.
.. admonition:: Watch Out .. admonition:: Watch Out
Please make sure in advance that your ``app.run()`` call you might Please make sure in advance that any ``app.run()`` calls you might
have in your application file, is inside an ``if __name__ == have in your application file are inside an ``if __name__ ==
'__main__':`` or moved to a separate file. Just make sure it's not '__main__':`` block or moved to a separate file. Just make sure it's
called because this will always start a local WSGI server which we do not called because this will always start a local WSGI server which
not want if we deploy that application to FastCGI. we do not want if we deploy that application to FastCGI.
Creating a `.fcgi` file Creating a `.fcgi` file
----------------------- -----------------------
@ -25,14 +27,14 @@ First you need to create the FastCGI server file. Let's call it
#!/usr/bin/python #!/usr/bin/python
from flup.server.fcgi import WSGIServer from flup.server.fcgi import WSGIServer
from yourapplication import app from yourapplication import app
if __name__ == '__main__': if __name__ == '__main__':
WSGIServer(app).run() WSGIServer(app).run()
This is enough for Apache to work, however nginx and older versions of This is enough for Apache to work, however nginx and older versions of
lighttpd need a socket to be explicitly passed to communicate with the FastCGI lighttpd need a socket to be explicitly passed to communicate with the
server. For that to work you need to pass the path to the socket to the FastCGI server. For that to work you need to pass the path to the
:class:`~flup.server.fcgi.WSGIServer`:: socket to the :class:`~flup.server.fcgi.WSGIServer`::
WSGIServer(application, bindAddress='/path/to/fcgi.sock').run() WSGIServer(application, bindAddress='/path/to/fcgi.sock').run()
@ -72,22 +74,23 @@ A basic FastCGI configuration for lighttpd looks like that::
"^(/static.*)$" => "$1", "^(/static.*)$" => "$1",
"^(/.*)$" => "/yourapplication.fcgi$1" "^(/.*)$" => "/yourapplication.fcgi$1"
Remember to enable the FastCGI, alias and rewrite modules. This configuration Remember to enable the FastCGI, alias and rewrite modules. This
binds the application to `/yourapplication`. If you want the application to configuration binds the application to `/yourapplication`. If you want
work in the URL root you have to work around a lighttpd bug with the the application to work in the URL root you have to work around a
lighttpd bug with the
:class:`~werkzeug.contrib.fixers.LighttpdCGIRootFix` middleware. :class:`~werkzeug.contrib.fixers.LighttpdCGIRootFix` middleware.
Make sure to apply it only if you are mounting the application the URL Make sure to apply it only if you are mounting the application the URL
root. Also, see the Lighty docs for more information on `FastCGI and Python root. Also, see the Lighty docs for more information on `FastCGI and
<http://redmine.lighttpd.net/wiki/lighttpd/Docs:ModFastCGI>`_ (note that Python <http://redmine.lighttpd.net/wiki/lighttpd/Docs:ModFastCGI>`_
explicitly passing a socket to run() is no longer necessary). (note that explicitly passing a socket to run() is no longer necessary).
Configuring nginx Configuring nginx
----------------- -----------------
Installing FastCGI applications on nginx is a bit different because by default Installing FastCGI applications on nginx is a bit different because by
no FastCGI parameters are forwarded. default no FastCGI parameters are forwarded.
A basic flask FastCGI configuration for nginx looks like this:: A basic flask FastCGI configuration for nginx looks like this::
@ -101,9 +104,9 @@ A basic flask FastCGI configuration for nginx looks like this::
fastcgi_pass unix:/tmp/yourapplication-fcgi.sock; fastcgi_pass unix:/tmp/yourapplication-fcgi.sock;
} }
This configuration binds the application to `/yourapplication`. If you want This configuration binds the application to `/yourapplication`. If you
to have it in the URL root it's a bit simpler because you don't have to figure want to have it in the URL root it's a bit simpler because you don't
out how to calculate `PATH_INFO` and `SCRIPT_NAME`:: have to figure out how to calculate `PATH_INFO` and `SCRIPT_NAME`::
location / { try_files $uri @yourapplication; } location / { try_files $uri @yourapplication; }
location @yourapplication { location @yourapplication {
@ -113,9 +116,17 @@ out how to calculate `PATH_INFO` and `SCRIPT_NAME`::
fastcgi_pass unix:/tmp/yourapplication-fcgi.sock; fastcgi_pass unix:/tmp/yourapplication-fcgi.sock;
} }
Since Nginx doesn't load FastCGI apps, you have to do it by yourself. You Running FastCGI Processes
can either write an `init.d` script for that or execute it inside a screen -------------------------
session::
Since Nginx and others do not load FastCGI apps, you have to do it by
yourself. `Supervisor can manage FastCGI processes.
<http://supervisord.org/configuration.html#fcgi-program-x-section-settings>`_
You can look around for other FastCGI process managers or write a script
to run your `.fcgi` file at boot, e.g. using a SysV ``init.d`` script.
For a temporary solution, you can always run the ``.fcgi`` script inside
GNU screen. See ``man screen`` for details, and note that this is a
manual solution which does not persist across system restart::
$ screen $ screen
$ /var/www/yourapplication/yourapplication.fcgi $ /var/www/yourapplication/yourapplication.fcgi
@ -123,14 +134,14 @@ session::
Debugging Debugging
--------- ---------
FastCGI deployments tend to be hard to debug on most webservers. Very often the FastCGI deployments tend to be hard to debug on most webservers. Very
only thing the server log tells you is something along the lines of "premature often the only thing the server log tells you is something along the
end of headers". In order to debug the application the only thing that can lines of "premature end of headers". In order to debug the application
really give you ideas why it breaks is switching to the correct user and the only thing that can really give you ideas why it breaks is switching
executing the application by hand. to the correct user and executing the application by hand.
This example assumes your application is called `application.fcgi` and that your This example assumes your application is called `application.fcgi` and
webserver user is `www-data`:: that your webserver user is `www-data`::
$ su www-data $ su www-data
$ cd /var/www/yourapplication $ cd /var/www/yourapplication
@ -139,14 +150,15 @@ webserver user is `www-data`::
File "yourapplication.fcgi", line 4, in <module> File "yourapplication.fcgi", line 4, in <module>
ImportError: No module named yourapplication ImportError: No module named yourapplication
In this case the error seems to be "yourapplication" not being on the python In this case the error seems to be "yourapplication" not being on the
path. Common problems are: python path. Common problems are:
- relative paths being used. Don't rely on the current working directory - Relative paths being used. Don't rely on the current working directory
- the code depending on environment variables that are not set by the - The code depending on environment variables that are not set by the
web server. web server.
- different python interpreters being used. - Different python interpreters being used.
.. _lighttpd: http://www.lighttpd.net/
.. _nginx: http://nginx.org/ .. _nginx: http://nginx.org/
.. _lighttpd: http://www.lighttpd.net/
.. _cherokee: http://www.cherokee-project.com/
.. _flup: http://trac.saddi.com/flup .. _flup: http://trac.saddi.com/flup

15
docs/deploying/index.rst

@ -1,14 +1,15 @@
Deployment Options Deployment Options
================== ==================
Depending on what you have available there are multiple ways to run Flask Depending on what you have available there are multiple ways to run
applications. A very common method is to use the builtin server during Flask applications. You can use the builtin server during development,
development and maybe behind a proxy for simple applications, but there but you should use a full deployment option for production applications.
are more options available. (Do not use the builtin development server in production.) Several
options are available and documented here.
If you have a different WSGI server look up the server documentation about If you have a different WSGI server look up the server documentation
how to use a WSGI app with it. Just remember that your application object about how to use a WSGI app with it. Just remember that your
is the actual WSGI application. :class:`Flask` application object is the actual WSGI application.
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 2

69
docs/deploying/mod_wsgi.rst

@ -3,35 +3,34 @@
mod_wsgi (Apache) mod_wsgi (Apache)
================= =================
If you are using the `Apache`_ webserver you should consider using `mod_wsgi`_. If you are using the `Apache`_ webserver, consider using `mod_wsgi`_.
.. admonition:: Watch Out .. admonition:: Watch Out
Please make sure in advance that your ``app.run()`` call you might Please make sure in advance that any ``app.run()`` calls you might
have in your application file, is inside an ``if __name__ == have in your application file are inside an ``if __name__ ==
'__main__':`` or moved to a separate file. Just make sure it's not '__main__':`` block or moved to a separate file. Just make sure it's
called because this will always start a local WSGI server which we do not called because this will always start a local WSGI server which
not want if we deploy that application to mod_wsgi. we do not want if we deploy that application to mod_wsgi.
.. _Apache: http://httpd.apache.org/ .. _Apache: http://httpd.apache.org/
Installing `mod_wsgi` Installing `mod_wsgi`
--------------------- ---------------------
If you don't have `mod_wsgi` installed yet you have to either install it using If you don't have `mod_wsgi` installed yet you have to either install it
a package manager or compile it yourself. using a package manager or compile it yourself. The mod_wsgi
`installation instructions`_ cover source installations on UNIX systems.
The mod_wsgi `installation instructions`_ cover source installations on UNIX If you are using Ubuntu/Debian you can apt-get it and activate it as
systems. follows:
If you are using Ubuntu/Debian you can apt-get it and activate it as follows:
.. sourcecode:: text .. sourcecode:: text
# apt-get install libapache2-mod-wsgi # apt-get install libapache2-mod-wsgi
On FreeBSD install `mod_wsgi` by compiling the `www/mod_wsgi` port or by using On FreeBSD install `mod_wsgi` by compiling the `www/mod_wsgi` port or by
pkg_add: using pkg_add:
.. sourcecode:: text .. sourcecode:: text
@ -40,8 +39,8 @@ pkg_add:
If you are using pkgsrc you can install `mod_wsgi` by compiling the If you are using pkgsrc you can install `mod_wsgi` by compiling the
`www/ap2-wsgi` package. `www/ap2-wsgi` package.
If you encounter segfaulting child processes after the first apache reload you If you encounter segfaulting child processes after the first apache
can safely ignore them. Just restart the server. reload you can safely ignore them. Just restart the server.
Creating a `.wsgi` file Creating a `.wsgi` file
----------------------- -----------------------
@ -61,14 +60,15 @@ instance you can directly import that one as `application`.
Store that file somewhere that you will find it again (e.g.: Store that file somewhere that you will find it again (e.g.:
`/var/www/yourapplication`) and make sure that `yourapplication` and all `/var/www/yourapplication`) and make sure that `yourapplication` and all
the libraries that are in use are on the python load path. If you don't the libraries that are in use are on the python load path. If you don't
want to install it system wide consider using a `virtual python`_ instance. want to install it system wide consider using a `virtual python`_
instance.
Configuring Apache Configuring Apache
------------------ ------------------
The last thing you have to do is to create an Apache configuration file for The last thing you have to do is to create an Apache configuration file
your application. In this example we are telling `mod_wsgi` to execute the for your application. In this example we are telling `mod_wsgi` to
application under a different user for security reasons: execute the application under a different user for security reasons:
.. sourcecode:: apache .. sourcecode:: apache
@ -100,15 +100,16 @@ If your application does not run, follow this guide to troubleshoot:
**Problem:** application does not run, errorlog shows SystemExit ignored **Problem:** application does not run, errorlog shows SystemExit ignored
You have a ``app.run()`` call in your application file that is not You have a ``app.run()`` call in your application file that is not
guarded by an ``if __name__ == '__main__':`` condition. Either remove guarded by an ``if __name__ == '__main__':`` condition. Either
that :meth:`~flask.Flask.run` call from the file and move it into a remove that :meth:`~flask.Flask.run` call from the file and move it
separate `run.py` file or put it into such an if block. into a separate `run.py` file or put it into such an if block.
**Problem:** application gives permission errors **Problem:** application gives permission errors
Probably caused by your application running as the wrong user. Make Probably caused by your application running as the wrong user. Make
sure the folders the application needs access to have the proper sure the folders the application needs access to have the proper
privileges set and the application runs as the correct user (``user`` privileges set and the application runs as the correct user
and ``group`` parameter to the `WSGIDaemonProcess` directive) (``user`` and ``group`` parameter to the `WSGIDaemonProcess`
directive)
**Problem:** application dies with an error on print **Problem:** application dies with an error on print
Keep in mind that mod_wsgi disallows doing anything with Keep in mind that mod_wsgi disallows doing anything with
@ -127,10 +128,10 @@ If your application does not run, follow this guide to troubleshoot:
sys.stdout = sys.stderr sys.stdout = sys.stderr
**Problem:** accessing resources gives IO errors **Problem:** accessing resources gives IO errors
Your application probably is a single .py file you symlinked into the Your application probably is a single .py file you symlinked into
site-packages folder. Please be aware that this does not work, the site-packages folder. Please be aware that this does not work,
instead you either have to put the folder into the pythonpath the file instead you either have to put the folder into the pythonpath the
is stored in, or convert your application into a package. file is stored in, or convert your application into a package.
The reason for this is that for non-installed packages, the module The reason for this is that for non-installed packages, the module
filename is used to locate the resources and for symlinks the wrong filename is used to locate the resources and for symlinks the wrong
@ -139,9 +140,9 @@ If your application does not run, follow this guide to troubleshoot:
Support for Automatic Reloading Support for Automatic Reloading
------------------------------- -------------------------------
To help deployment tools you can activate support for automatic reloading. To help deployment tools you can activate support for automatic
Whenever something changes the `.wsgi` file, `mod_wsgi` will reload all reloading. Whenever something changes the `.wsgi` file, `mod_wsgi` will
the daemon processes for us. reload all the daemon processes for us.
For that, just add the following directive to your `Directory` section: For that, just add the following directive to your `Directory` section:
@ -154,8 +155,8 @@ Working with Virtual Environments
Virtual environments have the advantage that they never install the Virtual environments have the advantage that they never install the
required dependencies system wide so you have a better control over what required dependencies system wide so you have a better control over what
is used where. If you want to use a virtual environment with mod_wsgi you is used where. If you want to use a virtual environment with mod_wsgi
have to modify your `.wsgi` file slightly. you have to modify your `.wsgi` file slightly.
Add the following lines to the top of your `.wsgi` file:: Add the following lines to the top of your `.wsgi` file::

34
docs/deploying/others.rst

@ -1,11 +1,11 @@
.. _deploying-other-servers:
Other Servers Other Servers
============= =============
There are popular servers written in Python that allow the execution of There are popular servers written in Python that allow the execution of WSGI
WSGI applications as well. Keep in mind though that some of these servers applications as well. These servers stand alone when they run; you can proxy
were written for very specific applications and might not work as well for to them from your web server.
standard WSGI application such as Flask powered ones.
Tornado Tornado
-------- --------
@ -15,12 +15,12 @@ server and tools that power `FriendFeed`_. Because it is non-blocking and
uses epoll, it can handle thousands of simultaneous standing connections, uses epoll, it can handle thousands of simultaneous standing connections,
which means it is ideal for real-time web services. Integrating this which means it is ideal for real-time web services. Integrating this
service with Flask is a trivial task:: service with Flask is a trivial task::
from tornado.wsgi import WSGIContainer from tornado.wsgi import WSGIContainer
from tornado.httpserver import HTTPServer from tornado.httpserver import HTTPServer
from tornado.ioloop import IOLoop from tornado.ioloop import IOLoop
from yourapplication import app from yourapplication import app
http_server = HTTPServer(WSGIContainer(app)) http_server = HTTPServer(WSGIContainer(app))
http_server.listen(5000) http_server.listen(5000)
IOLoop.instance().start() IOLoop.instance().start()
@ -29,7 +29,6 @@ service with Flask is a trivial task::
.. _Tornado: http://www.tornadoweb.org/ .. _Tornado: http://www.tornadoweb.org/
.. _FriendFeed: http://friendfeed.com/ .. _FriendFeed: http://friendfeed.com/
Gevent Gevent
------- -------
@ -47,7 +46,6 @@ event loop::
.. _greenlet: http://codespeak.net/py/0.9.2/greenlet.html .. _greenlet: http://codespeak.net/py/0.9.2/greenlet.html
.. _libevent: http://monkey.org/~provos/libevent/ .. _libevent: http://monkey.org/~provos/libevent/
Gunicorn Gunicorn
-------- --------
@ -57,19 +55,25 @@ and `greenlet`_. Running a Flask application on this server is quite simple::
gunicorn myproject:app gunicorn myproject:app
`Gunicorn`_ provides many command-line options -- see ``gunicorn -h``.
For example, to run a Flask application with 4 worker processes (``-w
4``) binding to localhost port 4000 (``-b 127.0.0.1:4000``)::
gunicorn -w 4 -b 127.0.0.1:4000 myproject:app
.. _Gunicorn: http://gunicorn.org/ .. _Gunicorn: http://gunicorn.org/
.. _eventlet: http://eventlet.net/ .. _eventlet: http://eventlet.net/
.. _greenlet: http://codespeak.net/py/0.9.2/greenlet.html .. _greenlet: http://codespeak.net/py/0.9.2/greenlet.html
Proxy Setups Proxy Setups
------------ ------------
If you deploy your application behind an HTTP proxy you will need to If you deploy your application using one of these servers behind an HTTP
rewrite a few headers in order for the application to work. The two proxy you will need to rewrite a few headers in order for the
problematic values in the WSGI environment usually are `REMOTE_ADDR` and application to work. The two problematic values in the WSGI environment
`HTTP_HOST`. Werkzeug ships a fixer that will solve some common setups, usually are `REMOTE_ADDR` and `HTTP_HOST`. Werkzeug ships a fixer that
but you might want to write your own WSGI middleware for specific setups. will solve some common setups, but you might want to write your own WSGI
middleware for specific setups.
The most common setup invokes the host being set from `X-Forwarded-Host` The most common setup invokes the host being set from `X-Forwarded-Host`
and the remote address from `X-Forwarded-For`:: and the remote address from `X-Forwarded-For`::

31
docs/deploying/uwsgi.rst

@ -1,21 +1,25 @@
.. _deploying-uwsgi:
uWSGI uWSGI
===== =====
A newly popular deployment method on servers like `cherokee`_ and `nginx`_ uWSGI is a deployment option on servers like `nginx`_, `lighttpd`_, and
is uWSGI. To use your WSGI application with uWSGI protocol you will need `cherokee`_; see :ref:`deploying-fastcgi` and
a uWSGI server first. uWSGI is both a protocol and an application server; :ref:`deploying-other-servers` for other options. To use your WSGI
the application server can serve uWSGI, FastCGI, and HTTP protocols. application with uWSGI protocol you will need a uWSGI server
first. uWSGI is both a protocol and an application server; the
application server can serve uWSGI, FastCGI, and HTTP protocols.
The most popular server is `uwsgi`_, which we will use for this guide. The most popular uWSGI server is `uwsgi`_, which we will use for this
Make sure to have it installed. guide. Make sure to have it installed to follow along.
.. admonition:: Watch Out .. admonition:: Watch Out
Please make sure in advance that your ``app.run()`` call you might Please make sure in advance that any ``app.run()`` calls you might
have in your application file, is inside an ``if __name__ == have in your application file are inside an ``if __name__ ==
'__main__':`` or moved to a separate file. Just make sure it's not '__main__':`` block or moved to a separate file. Just make sure it's
called because this will always start a local WSGI server which we do not called because this will always start a local WSGI server which
not want if we deploy that application to uWSGI. we do not want if we deploy that application to uWSGI.
Starting your app with uwsgi Starting your app with uwsgi
---------------------------- ----------------------------
@ -50,7 +54,7 @@ A basic flask uWSGI configuration for nginx looks like this::
This configuration binds the application to `/yourapplication`. If you want This configuration binds the application to `/yourapplication`. If you want
to have it in the URL root it's a bit simpler because you don't have to tell to have it in the URL root it's a bit simpler because you don't have to tell
it the WSGI `SCRIPT_NAME` or set the uwsgi modifer to make use of it:: it the WSGI `SCRIPT_NAME` or set the uwsgi modifier to make use of it::
location / { try_files $uri @yourapplication; } location / { try_files $uri @yourapplication; }
location @yourapplication { location @yourapplication {
@ -58,6 +62,7 @@ it the WSGI `SCRIPT_NAME` or set the uwsgi modifer to make use of it::
uwsgi_pass unix:/tmp/uwsgi.sock; uwsgi_pass unix:/tmp/uwsgi.sock;
} }
.. _cherokee: http://www.cherokee-project.com/
.. _nginx: http://nginx.org/ .. _nginx: http://nginx.org/
.. _lighttpd: http://www.lighttpd.net/
.. _cherokee: http://www.cherokee-project.com/
.. _uwsgi: http://projects.unbit.it/uwsgi/ .. _uwsgi: http://projects.unbit.it/uwsgi/

Loading…
Cancel
Save