From fe1a1eb79bf0f1df8bbc56d2402e32061af79d06 Mon Sep 17 00:00:00 2001 From: Sebastian Silva Date: Wed, 12 Oct 2011 00:54:31 +0000 Subject: Tidy up code a bit - added documentation --- (limited to 'studio/static/doc/flask-docs/_sources/deploying') diff --git a/studio/static/doc/flask-docs/_sources/deploying/cgi.txt b/studio/static/doc/flask-docs/_sources/deploying/cgi.txt new file mode 100644 index 0000000..a2fba90 --- /dev/null +++ b/studio/static/doc/flask-docs/_sources/deploying/cgi.txt @@ -0,0 +1,46 @@ +CGI +=== + +If all other deployment methods do not work, CGI will work for sure. +CGI is supported by all major servers but usually has a sub-optimal +performance. + +This is also the way you can use a Flask application on Google's `App +Engine`_, where execution happens in a CGI-like environment. + +.. admonition:: Watch Out + + Please make sure in advance that any ``app.run()`` calls you might + have in your application file are inside an ``if __name__ == + '__main__':`` block or moved to a separate file. Just make sure it's + not called because this will always start a local WSGI server which + we do not want if we deploy that application to CGI / app engine. + +Creating a `.cgi` file +---------------------- + +First you need to create the CGI application file. Let's call it +`yourapplication.cgi`:: + + #!/usr/bin/python + from wsgiref.handlers import CGIHandler + from yourapplication import app + + CGIHandler().run(app) + +Server Setup +------------ + +Usually there are two ways to configure the server. Either just copy the +`.cgi` into a `cgi-bin` (and use `mod_rewrite` or something similar to +rewrite the URL) or let the server point to the file directly. + +In Apache for example you can put a like like this into the config: + +.. sourcecode:: apache + + ScriptAlias /app /path/to/the/application.cgi + +For more information consult the documentation of your webserver. + +.. _App Engine: http://code.google.com/appengine/ diff --git a/studio/static/doc/flask-docs/_sources/deploying/fastcgi.txt b/studio/static/doc/flask-docs/_sources/deploying/fastcgi.txt new file mode 100644 index 0000000..6dace1a --- /dev/null +++ b/studio/static/doc/flask-docs/_sources/deploying/fastcgi.txt @@ -0,0 +1,164 @@ +.. _deploying-fastcgi: + +FastCGI +======= + +FastCGI is a deployment option on servers like `nginx`_, `lighttpd`_, +and `cherokee`_; see :ref:`deploying-uwsgi` and +:ref:`deploying-other-servers` for other options. To use your WSGI +application with any of them you will need a FastCGI server first. The +most popular one is `flup`_ which we will use for this guide. Make sure +to have it installed to follow along. + +.. admonition:: Watch Out + + Please make sure in advance that any ``app.run()`` calls you might + have in your application file are inside an ``if __name__ == + '__main__':`` block or moved to a separate file. Just make sure it's + not called because this will always start a local WSGI server which + we do not want if we deploy that application to FastCGI. + +Creating a `.fcgi` file +----------------------- + +First you need to create the FastCGI server file. Let's call it +`yourapplication.fcgi`:: + + #!/usr/bin/python + from flup.server.fcgi import WSGIServer + from yourapplication import app + + if __name__ == '__main__': + WSGIServer(app).run() + +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 server. For that to work you need to pass the path to the +socket to the :class:`~flup.server.fcgi.WSGIServer`:: + + WSGIServer(application, bindAddress='/path/to/fcgi.sock').run() + +The path has to be the exact same path you define in the server +config. + +Save the `yourapplication.fcgi` file somewhere you will find it again. +It makes sense to have that in `/var/www/yourapplication` or something +similar. + +Make sure to set the executable bit on that file so that the servers +can execute it: + +.. sourcecode:: text + + # chmod +x /var/www/yourapplication/yourapplication.fcgi + +Configuring lighttpd +-------------------- + +A basic FastCGI configuration for lighttpd looks like that:: + + fastcgi.server = ("/yourapplication.fcgi" => + (( + "socket" => "/tmp/yourapplication-fcgi.sock", + "bin-path" => "/var/www/yourapplication/yourapplication.fcgi", + "check-local" => "disable", + "max-procs" => 1 + )) + ) + + alias.url = ( + "/static/" => "/path/to/your/static" + ) + + url.rewrite-once = ( + "^(/static.*)$" => "$1", + "^(/.*)$" => "/yourapplication.fcgi$1" + +Remember to enable the FastCGI, alias and rewrite modules. This +configuration binds the application to `/yourapplication`. If you want +the application to work in the URL root you have to work around a +lighttpd bug with the +:class:`~werkzeug.contrib.fixers.LighttpdCGIRootFix` middleware. + +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 `_ +(note that explicitly passing a socket to run() is no longer necessary). + + +Configuring nginx +----------------- + +Installing FastCGI applications on nginx is a bit different because by +default no FastCGI parameters are forwarded. + +A basic flask FastCGI configuration for nginx looks like this:: + + location = /yourapplication { rewrite ^ /yourapplication/ last; } + location /yourapplication { try_files $uri @yourapplication; } + location @yourapplication { + include fastcgi_params; + fastcgi_split_path_info ^(/yourapplication)(.*)$; + fastcgi_param PATH_INFO $fastcgi_path_info; + fastcgi_param SCRIPT_NAME $fastcgi_script_name; + fastcgi_pass unix:/tmp/yourapplication-fcgi.sock; + } + +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 figure out how to calculate `PATH_INFO` and `SCRIPT_NAME`:: + + location / { try_files $uri @yourapplication; } + location @yourapplication { + include fastcgi_params; + fastcgi_param PATH_INFO $fastcgi_script_name; + fastcgi_param SCRIPT_NAME ""; + fastcgi_pass unix:/tmp/yourapplication-fcgi.sock; + } + +Running FastCGI Processes +------------------------- + +Since Nginx and others do not load FastCGI apps, you have to do it by +yourself. `Supervisor can manage FastCGI processes. +`_ +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 + $ /var/www/yourapplication/yourapplication.fcgi + +Debugging +--------- + +FastCGI deployments tend to be hard to debug on most webservers. Very +often the only thing the server log tells you is something along the +lines of "premature end of headers". In order to debug the application +the only thing that can really give you ideas why it breaks is switching +to the correct user and executing the application by hand. + +This example assumes your application is called `application.fcgi` and +that your webserver user is `www-data`:: + + $ su www-data + $ cd /var/www/yourapplication + $ python application.fcgi + Traceback (most recent call last): + File "yourapplication.fcgi", line 4, in + ImportError: No module named yourapplication + +In this case the error seems to be "yourapplication" not being on the +python path. Common problems are: + +- Relative paths being used. Don't rely on the current working directory +- The code depending on environment variables that are not set by the + web server. +- Different python interpreters being used. + +.. _nginx: http://nginx.org/ +.. _lighttpd: http://www.lighttpd.net/ +.. _cherokee: http://www.cherokee-project.com/ +.. _flup: http://trac.saddi.com/flup diff --git a/studio/static/doc/flask-docs/_sources/deploying/index.txt b/studio/static/doc/flask-docs/_sources/deploying/index.txt new file mode 100644 index 0000000..d258df8 --- /dev/null +++ b/studio/static/doc/flask-docs/_sources/deploying/index.txt @@ -0,0 +1,23 @@ +.. _deployment: + +Deployment Options +================== + +Depending on what you have available there are multiple ways to run +Flask applications. You can use the builtin server during development, +but you should use a full deployment option for production applications. +(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 how to use a WSGI app with it. Just remember that your +:class:`Flask` application object is the actual WSGI application. + +.. toctree:: + :maxdepth: 2 + + mod_wsgi + cgi + fastcgi + uwsgi + others diff --git a/studio/static/doc/flask-docs/_sources/deploying/mod_wsgi.txt b/studio/static/doc/flask-docs/_sources/deploying/mod_wsgi.txt new file mode 100644 index 0000000..c85ed64 --- /dev/null +++ b/studio/static/doc/flask-docs/_sources/deploying/mod_wsgi.txt @@ -0,0 +1,167 @@ +.. _mod_wsgi-deployment: + +mod_wsgi (Apache) +================= + +If you are using the `Apache`_ webserver, consider using `mod_wsgi`_. + +.. admonition:: Watch Out + + Please make sure in advance that any ``app.run()`` calls you might + have in your application file are inside an ``if __name__ == + '__main__':`` block or moved to a separate file. Just make sure it's + not called because this will always start a local WSGI server which + we do not want if we deploy that application to mod_wsgi. + +.. _Apache: http://httpd.apache.org/ + +Installing `mod_wsgi` +--------------------- + +If you don't have `mod_wsgi` installed yet you have to either install it +using a package manager or compile it yourself. The mod_wsgi +`installation instructions`_ cover source installations on UNIX systems. + +If you are using Ubuntu/Debian you can apt-get it and activate it as +follows: + +.. sourcecode:: text + + # apt-get install libapache2-mod-wsgi + +On FreeBSD install `mod_wsgi` by compiling the `www/mod_wsgi` port or by +using pkg_add: + +.. sourcecode:: text + + # pkg_add -r mod_wsgi + +If you are using pkgsrc you can install `mod_wsgi` by compiling the +`www/ap2-wsgi` package. + +If you encounter segfaulting child processes after the first apache +reload you can safely ignore them. Just restart the server. + +Creating a `.wsgi` file +----------------------- + +To run your application you need a `yourapplication.wsgi` file. This file +contains the code `mod_wsgi` is executing on startup to get the application +object. The object called `application` in that file is then used as +application. + +For most applications the following file should be sufficient:: + + from yourapplication import app as application + +If you don't have a factory function for application creation but a singleton +instance you can directly import that one as `application`. + +Store that file somewhere that you will find it again (e.g.: +`/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 +want to install it system wide consider using a `virtual python`_ +instance. + +Configuring Apache +------------------ + +The last thing you have to do is to create an Apache configuration file +for your application. In this example we are telling `mod_wsgi` to +execute the application under a different user for security reasons: + +.. sourcecode:: apache + + + ServerName example.com + + WSGIDaemonProcess yourapplication user=user1 group=group1 threads=5 + WSGIScriptAlias / /var/www/yourapplication/yourapplication.wsgi + + + WSGIProcessGroup yourapplication + WSGIApplicationGroup %{GLOBAL} + Order deny,allow + Allow from all + + + +For more information consult the `mod_wsgi wiki`_. + +.. _mod_wsgi: http://code.google.com/p/modwsgi/ +.. _installation instructions: http://code.google.com/p/modwsgi/wiki/QuickInstallationGuide +.. _virtual python: http://pypi.python.org/pypi/virtualenv +.. _mod_wsgi wiki: http://code.google.com/p/modwsgi/wiki/ + +Troubleshooting +--------------- + +If your application does not run, follow this guide to troubleshoot: + +**Problem:** application does not run, errorlog shows SystemExit ignored + You have a ``app.run()`` call in your application file that is not + guarded by an ``if __name__ == '__main__':`` condition. Either + remove that :meth:`~flask.Flask.run` call from the file and move it + into a separate `run.py` file or put it into such an if block. + +**Problem:** application gives permission errors + Probably caused by your application running as the wrong user. Make + sure the folders the application needs access to have the proper + privileges set and the application runs as the correct user + (``user`` and ``group`` parameter to the `WSGIDaemonProcess` + directive) + +**Problem:** application dies with an error on print + Keep in mind that mod_wsgi disallows doing anything with + :data:`sys.stdout` and :data:`sys.stderr`. You can disable this + protection from the config by setting the `WSGIRestrictStdout` to + ``off``: + + .. sourcecode:: apache + + WSGIRestrictStdout Off + + Alternatively you can also replace the standard out in the .wsgi file + with a different stream:: + + import sys + sys.stdout = sys.stderr + +**Problem:** accessing resources gives IO errors + Your application probably is a single .py file you symlinked into + 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 is stored in, or convert your application into a package. + + 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 picked up. + +Support for Automatic Reloading +------------------------------- + +To help deployment tools you can activate support for automatic +reloading. Whenever something changes the `.wsgi` file, `mod_wsgi` will +reload all the daemon processes for us. + +For that, just add the following directive to your `Directory` section: + +.. sourcecode:: apache + + WSGIScriptReloading On + +Working with Virtual Environments +--------------------------------- + +Virtual environments have the advantage that they never install the +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 have to modify your `.wsgi` file slightly. + +Add the following lines to the top of your `.wsgi` file:: + + activate_this = '/path/to/env/bin/activate_this.py' + execfile(activate_this, dict(__file__=activate_this)) + +This sets up the load paths according to the settings of the virtual +environment. Keep in mind that the path has to be absolute. diff --git a/studio/static/doc/flask-docs/_sources/deploying/others.txt b/studio/static/doc/flask-docs/_sources/deploying/others.txt new file mode 100644 index 0000000..6f3e5cc --- /dev/null +++ b/studio/static/doc/flask-docs/_sources/deploying/others.txt @@ -0,0 +1,102 @@ +.. _deploying-other-servers: + +Other Servers +============= + +There are popular servers written in Python that allow the execution of WSGI +applications as well. These servers stand alone when they run; you can proxy +to them from your web server. + +Tornado +-------- + +`Tornado`_ is an open source version of the scalable, non-blocking web +server and tools that power `FriendFeed`_. Because it is non-blocking and +uses epoll, it can handle thousands of simultaneous standing connections, +which means it is ideal for real-time web services. Integrating this +service with Flask is a trivial task:: + + from tornado.wsgi import WSGIContainer + from tornado.httpserver import HTTPServer + from tornado.ioloop import IOLoop + from yourapplication import app + + http_server = HTTPServer(WSGIContainer(app)) + http_server.listen(5000) + IOLoop.instance().start() + + +.. _Tornado: http://www.tornadoweb.org/ +.. _FriendFeed: http://friendfeed.com/ + +Gevent +------- + +`Gevent`_ is a coroutine-based Python networking library that uses +`greenlet`_ to provide a high-level synchronous API on top of `libevent`_ +event loop:: + + from gevent.wsgi import WSGIServer + from yourapplication import app + + http_server = WSGIServer(('', 5000), app) + http_server.serve_forever() + +.. _Gevent: http://www.gevent.org/ +.. _greenlet: http://codespeak.net/py/0.9.2/greenlet.html +.. _libevent: http://monkey.org/~provos/libevent/ + +Gunicorn +-------- + +`Gunicorn`_ 'Green Unicorn' is a WSGI HTTP Server for UNIX. It's a pre-fork +worker model ported from Ruby's Unicorn project. It supports both `eventlet`_ +and `greenlet`_. Running a Flask application on this server is quite simple:: + + 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/ +.. _eventlet: http://eventlet.net/ +.. _greenlet: http://codespeak.net/py/0.9.2/greenlet.html + +Proxy Setups +------------ + +If you deploy your application using one of these servers behind an HTTP +proxy you will need to rewrite a few headers in order for the +application to work. The two problematic values in the WSGI environment +usually are `REMOTE_ADDR` and `HTTP_HOST`. Werkzeug ships a fixer that +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` +and the remote address from `X-Forwarded-For`:: + + from werkzeug.contrib.fixers import ProxyFix + app.wsgi_app = ProxyFix(app.wsgi_app) + +Please keep in mind that it is a security issue to use such a middleware +in a non-proxy setup because it will blindly trust the incoming +headers which might be forged by malicious clients. + +If you want to rewrite the headers from another header, you might want to +use a fixer like this:: + + class CustomProxyFix(object): + + def __init__(self, app): + self.app = app + + def __call__(self, environ, start_response): + host = environ.get('HTTP_X_FHOST', '') + if host: + environ['HTTP_HOST'] = host + return self.app(environ, start_response) + + app.wsgi_app = CustomProxyFix(app.wsgi_app) diff --git a/studio/static/doc/flask-docs/_sources/deploying/uwsgi.txt b/studio/static/doc/flask-docs/_sources/deploying/uwsgi.txt new file mode 100644 index 0000000..bdee15b --- /dev/null +++ b/studio/static/doc/flask-docs/_sources/deploying/uwsgi.txt @@ -0,0 +1,68 @@ +.. _deploying-uwsgi: + +uWSGI +===== + +uWSGI is a deployment option on servers like `nginx`_, `lighttpd`_, and +`cherokee`_; see :ref:`deploying-fastcgi` and +:ref:`deploying-other-servers` for other options. To use your WSGI +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 uWSGI server is `uwsgi`_, which we will use for this +guide. Make sure to have it installed to follow along. + +.. admonition:: Watch Out + + Please make sure in advance that any ``app.run()`` calls you might + have in your application file are inside an ``if __name__ == + '__main__':`` block or moved to a separate file. Just make sure it's + not called because this will always start a local WSGI server which + we do not want if we deploy that application to uWSGI. + +Starting your app with uwsgi +---------------------------- + +`uwsgi` is designed to operate on WSGI callables found in python modules. + +Given a flask application in myapp.py, use the following command: + +.. sourcecode:: text + + $ uwsgi -s /tmp/uwsgi.sock --module myapp --callable app + +Or, if you prefer: + +.. sourcecode:: text + + $ uwsgi -s /tmp/uwsgi.sock -w myapp:app + +Configuring nginx +----------------- + +A basic flask uWSGI configuration for nginx looks like this:: + + location = /yourapplication { rewrite ^ /yourapplication/; } + location /yourapplication { try_files $uri @yourapplication; } + location @yourapplication { + include uwsgi_params; + uwsgi_param SCRIPT_NAME /yourapplication; + uwsgi_modifier1 30; + uwsgi_pass unix:/tmp/uwsgi.sock; + } + +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 +it the WSGI `SCRIPT_NAME` or set the uwsgi modifier to make use of it:: + + location / { try_files $uri @yourapplication; } + location @yourapplication { + include uwsgi_params; + uwsgi_pass unix:/tmp/uwsgi.sock; + } + +.. _nginx: http://nginx.org/ +.. _lighttpd: http://www.lighttpd.net/ +.. _cherokee: http://www.cherokee-project.com/ +.. _uwsgi: http://projects.unbit.it/uwsgi/ -- cgit v0.9.1