diff --git a/docs/deploying/cgi.rst b/docs/deploying/cgi.rst index 830ab28a..a2fba90d 100644 --- a/docs/deploying/cgi.rst +++ b/docs/deploying/cgi.rst @@ -1,23 +1,20 @@ 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 less-than-optimal +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`_, there however the execution does happen in a CGI-like -environment. The application's performance is unaffected because of that. +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 your ``app.run()`` call you might - have in your application file, is inside an ``if __name__ == - '__main__':`` 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. - -.. _App Engine: http://code.google.com/appengine/ + 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 ---------------------- @@ -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 For more information consult the documentation of your webserver. + +.. _App Engine: http://code.google.com/appengine/ diff --git a/docs/deploying/fastcgi.rst b/docs/deploying/fastcgi.rst index eeaee43e..0b5d887c 100644 --- a/docs/deploying/fastcgi.rst +++ b/docs/deploying/fastcgi.rst @@ -1,20 +1,22 @@ +.. _deploying-fastcgi: + FastCGI ======= -A very popular deployment setup on servers like `lighttpd`_ and `nginx`_ -is FastCGI. 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. +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 your ``app.run()`` call you might - have in your application file, is inside an ``if __name__ == - '__main__':`` 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. + 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 ----------------------- @@ -25,14 +27,14 @@ First you need to create the FastCGI server file. Let's call it #!/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`:: +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() @@ -72,22 +74,23 @@ A basic FastCGI configuration for lighttpd looks like that:: "^(/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 +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). +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. +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:: @@ -101,9 +104,9 @@ A basic flask FastCGI configuration for nginx looks like this:: 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`:: +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 { @@ -113,9 +116,17 @@ out how to calculate `PATH_INFO` and `SCRIPT_NAME`:: fastcgi_pass unix:/tmp/yourapplication-fcgi.sock; } -Since Nginx doesn't load FastCGI apps, you have to do it by yourself. You -can either write an `init.d` script for that or execute it inside a screen -session:: +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 @@ -123,14 +134,14 @@ session:: 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. +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`:: +This example assumes your application is called `application.fcgi` and +that your webserver user is `www-data`:: $ su www-data $ cd /var/www/yourapplication @@ -139,14 +150,15 @@ webserver user is `www-data`:: 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: +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 +- 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. +- Different python interpreters being used. +.. _nginx: http://nginx.org/ .. _lighttpd: http://www.lighttpd.net/ -.. _nginx: http://nginx.net/ +.. _cherokee: http://www.cherokee-project.com/ .. _flup: http://trac.saddi.com/flup diff --git a/docs/deploying/index.rst b/docs/deploying/index.rst index a59e4e9a..bd0d1626 100644 --- a/docs/deploying/index.rst +++ b/docs/deploying/index.rst @@ -1,14 +1,15 @@ Deployment Options ================== -Depending on what you have available there are multiple ways to run Flask -applications. A very common method is to use the builtin server during -development and maybe behind a proxy for simple applications, but there -are more options available. +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 application object -is the actual WSGI application. +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 @@ -16,4 +17,5 @@ is the actual WSGI application. mod_wsgi cgi fastcgi + uwsgi others diff --git a/docs/deploying/mod_wsgi.rst b/docs/deploying/mod_wsgi.rst index 40df522d..c85ed64f 100644 --- a/docs/deploying/mod_wsgi.rst +++ b/docs/deploying/mod_wsgi.rst @@ -3,35 +3,34 @@ 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 - Please make sure in advance that your ``app.run()`` call you might - have in your application file, is inside an ``if __name__ == - '__main__':`` 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. + 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. +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. -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: +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: +On FreeBSD install `mod_wsgi` by compiling the `www/mod_wsgi` port or by +using pkg_add: .. sourcecode:: text @@ -40,8 +39,8 @@ pkg_add: 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. +If you encounter segfaulting child processes after the first apache +reload you can safely ignore them. Just restart the server. 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.: `/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. +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: +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 @@ -100,15 +100,16 @@ 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. + 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) + 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 @@ -127,10 +128,10 @@ If your application does not run, follow this guide to troubleshoot: 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. + 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 @@ -139,9 +140,9 @@ If your application does not run, follow this guide to troubleshoot: 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. +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: @@ -154,8 +155,8 @@ 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. +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:: diff --git a/docs/deploying/others.rst b/docs/deploying/others.rst index 153fb7cf..6f3e5cc6 100644 --- a/docs/deploying/others.rst +++ b/docs/deploying/others.rst @@ -1,11 +1,11 @@ +.. _deploying-other-servers: + Other Servers ============= -There are popular servers written in Python that allow the execution of -WSGI applications as well. Keep in mind though that some of these servers -were written for very specific applications and might not work as well for -standard WSGI application such as Flask powered ones. - +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 -------- @@ -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, 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() @@ -29,7 +29,6 @@ service with Flask is a trivial task:: .. _Tornado: http://www.tornadoweb.org/ .. _FriendFeed: http://friendfeed.com/ - Gevent ------- @@ -47,7 +46,6 @@ event loop:: .. _greenlet: http://codespeak.net/py/0.9.2/greenlet.html .. _libevent: http://monkey.org/~provos/libevent/ - Gunicorn -------- @@ -57,19 +55,25 @@ 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 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. +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`:: diff --git a/docs/deploying/uwsgi.rst b/docs/deploying/uwsgi.rst new file mode 100644 index 00000000..6f373731 --- /dev/null +++ b/docs/deploying/uwsgi.rst @@ -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 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/ diff --git a/docs/patterns/appfactories.rst b/docs/patterns/appfactories.rst index e2bb46e7..2a6190ea 100644 --- a/docs/patterns/appfactories.rst +++ b/docs/patterns/appfactories.rst @@ -39,7 +39,7 @@ The idea is to set up the application in a function. Like this:: The downside is that you cannot use the application object in the blueprints at import time. You can however use it from within a request. How do you -get access the application with the config? Use +get access to the application with the config? Use :data:`~flask.current_app`:: from flask import current_app, Blueprint, render_template diff --git a/docs/quickstart.rst b/docs/quickstart.rst index 3875b296..8898911d 100644 --- a/docs/quickstart.rst +++ b/docs/quickstart.rst @@ -11,7 +11,7 @@ you do not, head over to the :ref:`installation` section. A Minimal Application --------------------- -A minimal Flask application looks something like that:: +A minimal Flask application looks something like this:: from flask import Flask app = Flask(__name__) diff --git a/docs/security.rst b/docs/security.rst index 35afd49e..07a5b942 100644 --- a/docs/security.rst +++ b/docs/security.rst @@ -95,6 +95,13 @@ the form validation framework, which does not exist in Flask. JSON Security ------------- +.. admonition:: ECMAScript 5 Changes + + Starting with ECMAScript 5 the behavior of literals changed. Now they + are not constructed with the constructor of ``Array`` and others, but + with the builtin constructor of ``Array`` which closes this particular + attack vector. + JSON itself is a high-level serialization format, so there is barely anything that could cause security problems, right? You can't declare recursive structures that could cause problems and the only thing that