It seems that uwsgi is capable of doing almost anything I am using nginx for: serving static content, execute PHP scripts, host python web apps, ...
So (in order to simplify my environment) can I replace nginx + uwsgi with uwsgi without loss of performance/functionality?
As they say in the documentation:
Can I use uWSGI’s HTTP capabilities in production?
If you need a load balancer/proxy it can be a very good idea. It will
automatically find new uWSGI instances and can load balance in various
ways. If you want to use it as a real webserver you should take into
account that serving static files in uWSGI instances is possible, but
not as good as using a dedicated full-featured web server. If you host
static assets in the cloud or on a CDN, using uWSGI’s HTTP
capabilities you can definitely avoid configuring a full webserver.
So yes, uWSGI is slower than a traditional web server.
Besides performance, in a really basic application you're right, uWSGI can do everything the webserver offers. However, should your application grow/change over time you may find that there are many things the traditional webserver offers which uWSGI does not.
I would recommend setting up deploy scripts in your language of choice (such as Fabric for Python). I would say my webserver is one of the simplest components to deploy & setup in our applications stack, and the least "needy" - it is rarely on my radar unless I'm configuring a new server.
Related
I intend to use Kubernetes and Ingress for load balancing. I'm trying to learn how to set up Flask, uWSGI and Nginx.
I see this tutorial that has all three installed in the same container, and I'm wondering whether I should use it or not.
https://ianlondon.github.io/blog/deploy-flask-docker-nginx/
I'm guessing the benefit of having them as separate containers and separate pods is that they can then all scale individually?
But also, should Flask and uwsgi even be in separate containers? (or Flask and Gunicorn, since uwsgi seems to be very similar to Gunicorn)
Flask is a web framework, any application written with it needs a WSGI server to host it. Although you could use the Flask builtin developer server, you shouldn't as that isn't suitable for production systems. You therefore need to use a WSGI server such as uWSGI, gunicorn or mod_wsgi (mod_wsgi-express). Since the web application is hosted by the WSGI server, it can only be in the same container, but there isn't a separate process for Flask, it runs in the web server process.
Whether you need a separate web server such as nginx then depends. In the case of mod_wsgi you don't as it uses the Apache web server and so draws direct benefits from that. When using mod_wsgi-express it also is already setup to run in an optimal base configuration and how it does that avoids the need to have a separate front facing web server like people often do with nginx when using uWSGI or gunicorn.
For containerised systems, where the platform already provides a routing layer for load balancing, as is the case for ingress in Kubernetes, using nginx in the mix could just add extra complexity you don't need and could reduce performance. This is because you either have to run nginx in the same container, or create a separate container in the same pod and use shared emptyDir volume type to allow them to communicate via a UNIX socket still. If you don't use a UNIX socket, and use INET socket, or run nginx in a completely different pod, then it is sort of pointless as you are introducing an additional hop for traffic which is going to be more expensive than having it closely bound using a UNIX socket. The uWSGI server doesn't perform as well when accepting requests over INET when coupled with nginx, and having nginx in a separate pod, potentially on different host, can make that worse.
Part of the reason for using nginx in front is that it can protect you from slow clients due to request buffering, as well as other potential issues. When using ingress though, you already have a haproxy or nginx front end load balancer that can to a degree protect you from that. So it is really going to depend on what you are doing as to whether there is a point in introducing an additional nginx proxy in the mix. It can be simpler to just put gunicorn or uWSGI directly behind the load balancer.
Suggestions are as follows.
Also look at mod_wsgi-express. It was specifically developed with containerised systems in mind to make it easier, and can be a better choice than uWSGI and gunicorn.
Test different WSGI servers and configurations with your actual application with real world traffic profiles, not benchmarks which just overload it. This is important as the dynamics of a Kubernetes based system, along with how its routing may be implemented, means it all could behave a lot differently to more traditional systems you may be used to.
I am a .net developer coming over to python. I have recently started using Flask and have some quick questions about serving files.
I noticed a lot of tutorials focused on nginix and flask. However, I am able to run flask without nginx. I'm just curious as to why this is used together (nginx and flask). Is nginx only for static files?
Nginx is a proxy server, imagine your apps have multiples microservices on differents languagues.
For more info NGINX REVERSE PROXY
On a development machine flask can be run without a webserver (nginx, apache etc) or an application container (eg uwsgi, gunicorn etc).
Things are different when you want to handle the load on a production server. For starters python is relatively very slow when it comes to serving static content where as apache / nginx do that very well.
When the application becomes big enough to be broken into multiple separate services or has to be horizontally scaled, the proxy server capabilities of nginx come in very handy.
In the architectures I build, nginx serves as the entry point where ssl is terminates and the rest of the application is behind a VPN and firewall.
Does this help?
From http://flask.pocoo.org/docs/1.0/deploying/ :
"While lightweight and easy to use, Flask’s built-in server is not suitable for production as it doesn’t scale well. Some of the options available for properly running Flask in production are documented here."
I'm new to linux development. I'm a bit confused on the documentation i read.
My ultimate goal is to host a simple python backed web service that would examine an incoming payload, and forward it to other server. This should be less than 30 lines of code in python.
I'm planning to use nginx to serve up python file. From my research, i also need a python web framework. I chose to go with uwsgi. I'm so confused. which one do I need? an nginx uwsgi module, or uwsgi server? i don't want to put django just for this simple purpose.
the nginx documentation mention that
Do not confuse the uwsgi protocol with the uWSGI server (that speaks the uwsgi protocol)
So, does that mean, i don't need to install uwsgi server separately? do i just install nginx, and start configuring? I'm using nginx 1.4.4
Could someone share a step by step configuration procedure on how to configure uwsgi with nginx, along with a sample python code(hello world maybe)? i can configure nginx just fine, but i don't know how to make it serve python pages. all the docs i could find involves having django on top.
You're mixing up things, so let me clarify.
Python's standard way of publishing applications via web servers is WSGI--you can think of it as a Python's native CGI. uWSGI is a WSGI-compliant server that uses uwsgi protocol to talk to other uWSGI instances or upstream servers. Usually the upstream server is nginx with HttpUwsgiModule that allows it to communicate using uwsgi protocol--with nginx you have additional layer of protection for your app server, load balancing and serving the static files. In most scenarios, You Should Be Using Nginx + UWSGI. To answer your question, uWSGI is installed and run separately from nginx, and they both need to be configured to communicate to each other.
Pure WSGI is pretty low-level, so you may want to use a WSGI-compliant framework. I guess the top two are Django and Flask.
For a hello world Flask setup, Serving Flask With Nginx seems to be a good article.
What type of server Django uses when "runserver" command is ran? Documentation says more or less that it's "lightweight development Web server". Is it for example Apache? Thanks in advance.
It's exactly what it says on the tin - a simple, lightweight web server implemented in Python that ships with Django and is intended for development purposes only. It's not a free-standing web server in its own right and is intended purely for developing applications with Django - you should never use it in production because it simply doesn't offer all the functionality you need in a production web server.
A web server can be implemented in virtually any programming language, and so it makes sense to ship one implemented in Python with Django in order that you can get working with it immediately without having to install something like Apache as well. Most web servers that might be used in production, such as Apache and Nginx, are written in C so it wouldn't really be practical to ship them with Django.
Also, shipping your own development server cuts down on complexity. Apache and Nginx are both complex pieces of software that require a fair amount of configuration, and while there are ways to automate that during development, it's not something you really want to have to deal with when you'd rather be writing code. All you need to get you started is something that will serve static and dynamic content - you don't need a lot of the other functionality required. It's notable that even PHP now ships with a development server.
When you go live with a Django project, you should use of course use a proper web server. It's generally recommended that with Django, in production you should use two web servers, one to serve static content, the other to serve dynamic content, because involving Django in serving static content will slow it down. This sounds odd at first, but it actually makes a lot of sense, because what you do is set one web server to serve all the static content, then have it reverse proxy to the other server, which is running on a non-standard port, and serves all the dynamic content. The setup I have for my current project is Nginx for the static content, with Gunicorn for the dynamic content.
Good morning.
As the title indicates, I've got some questions about using python for web development.
What is the best setup for a development environment, more specifically, what webserver to use, how to bind python with it. Preferably, I'd like it to be implementable in both, *nix and win environment.
My major concern when I last tried apache + mod_python + CherryPy was having to reload webserver to see the changes. Is it considered normal? For some reason cherrypy's autoreload didn't work at all.
What is the best setup to deploy a working Python app to production and why? I'm now using lighttpd for my PHP web apps, but how would it do for python compared to nginx for example?
Is it worth diving straight with a framework or to roll something simple of my own? I see that Django has got quite a lot of fans, but I'm thinking it would be overkill for my needs, so I've started looking into CherryPy.
How exactly are Python apps served if I have to reload httpd to see the changes? Something like a permanent process spawning child processes, with all the major file includes happening on server start and then just lazy loading needed resources?
Python supports multithreading, do I need to look into using that for a benefit when developing web apps? What would be that benefit and in what situations?
Big thanks!
What is the best setup for a development environment?
Doesn't much matter. We use Django, which runs in Windows and Unix nicely. For production, we use Apache in Red Hat.
Is having to reload webserver to see the changes considered normal?
Yes. Not clear why you'd want anything different. Web application software shouldn't be dynamic. Content yes. Software no.
In Django, we develop without using a web server of any kind on our desktop. The Django "runserver" command reloads the application under most circumstances. For development, this works great. The times when it won't reload are when we've damaged things so badly that the app doesn't properly.
What is the best setup to deploy a working Python app to production and why?
"Best" is undefined in this context. Therefore, please provide some qualification for "nest" (e.g., "fastest", "cheapest", "bluest")
Is it worth diving straight with a framework or to roll something simple of my own?
Don't waste time rolling your own. We use Django because of the built-in admin page that we don't have to write or maintain. Saves mountains of work.
How exactly are Python apps served if I have to reload httpd to see the changes?
Two methods:
Daemon - mod_wsgi or mod_fastcgi have a Python daemon process to which they connect. Change your software. Restart the daemon.
Embedded - mod_wsgi or mod_python have an embedded mode in which the Python interpreter is inside the mod, inside Apache. You have to restart httpd to restart that embedded interpreter.
Do I need to look into using multi-threaded?
Yes and no. Yes you do need to be aware of this. No, you don't need to do very much. Apache and mod_wsgi and Django should handle this for you.
So here are my thoughts about it:
I am using Python Paste for developing my app and eventually also running it (or any other python web server). I am usually not using mod_python or mod_wsgi as it makes development setup more complex.
I am using zc.buildout for managing my development environment and all dependencies together with virtualenv. This gives me an isolated sandbox which does not interfere with any Python modules installed system wide.
For deployment I am also using buildout/virtualenv, eventually with a different buildout.cfg. I am also using Paste Deploy and it's configuration mechanism where I have different config files for development and deployment.
As I am usually running paste/cherrypy etc. standalone I am using Apache, NGINX or maybe just a Varnish alone in front of it. It depends on what configuration options you need. E.g. if no virtual hosting, rewrite rules etc. are needed, then I don't need a full featured web server in front. When using a web server I usually use ProxyPass or some more complex rewriting using mod_rewrite.
The Python web framework I use at the moment is repoze.bfg right now btw.
As for your questions about reloading I know about these problems when running it with e.g. mod_python but when using a standalone "paster serve ... -reload" etc. it so far works really well. repoze.bfg additionally has some setting for automatically reloading templates when they change. If the framework you use has that should be documented.
As for multithreading that's usually used then inside the python web server. As CherryPy supports this I guess you don't have to worry about that, it should be used automatically. You should just eventually make some benchmarks to find out under what number of threads your application performs the best.
Hope that helps.
+1 to MrTopf's answer, but I'll add some additional opinions.
Webserver
Apache is the webserver that will give you the most configurability. Avoid mod_python because it is basically unsupported. On the other hand, mod_wsgi is very well supported and gives you better stability (in other words, easier to configure for cpu/memory usage to be stable as opposed to spikey and unpredictable).
Another huge benefit, you can configure mod_wsgi to reload your application if the wsgi application script is touched, no need to restart Apache. For development/testing servers you can even configure mod_wsgi to reload when any file in your application is changed. This is so helpful I even run Apache+mod_wsgi on my laptop during development.
Nginx and lighttpd are commonly used for webservers, either by serving Python apps directly through a fastCGI interface (don't bother with any WSGI interfaces on these servers yet) or by using them as a front end in front of Apache. Calls into the app get passed through (by proxy) to Apache+mod_wsgi and then nginx/lighttpd serve the static content directly.
Nginx has the added advantage of being able to serve content directly from memcached if you want to get that sophisticated. I've heard disparaging comments about lighttpd and it does seem to have some development problems, but there are certainly some big companies using it successfully.
Python stack
At the lowest level you can program to WSGI directly for the best performance. There are lots of helpful WSGI modules out there to help you in areas you don't want to develop yourself. At this level you'll probably want to pick third-party WSGI components to do things like URL resolving and HTTP request/response handling. A great request/response component is WebOb.
If you look at Pylons you can see their idea of "best-of-breed" WSGI components and a framework that makes it easier than Django to choose your own components like templating engine.
Django might be overkill but I don't think that's a really good argument against. Django makes the easy stuff easier. When you start to get into very complicated applications is where you really need to look at moving to lower level frameworks.
Look at Google App Engine. From their website:
Google App Engine lets you run your
web applications on Google's
infrastructure. App Engine
applications are easy to build, easy
to maintain, and easy to scale as your
traffic and data storage needs grow.
With App Engine, there are no servers
to maintain: You just upload your
application, and it's ready to serve
your users.
You can serve your app using a free
domain name on the appspot.com domain,
or use Google Apps to serve it from
your own domain. You can share your
application with the world, or limit
access to members of your
organization.
App Engine costs nothing to get
started. Sign up for a free account,
and you can develop and publish your
application for the world to see, at
no charge and with no obligation. A
free account can use up to 500MB of
persistent storage and enough CPU and
bandwidth for about 5 million page
views a month.
Best part of all: It includes Python support, including Django. Go to http://code.google.com/appengine/docs/whatisgoogleappengine.html
When you use mod_python on a threaded Apache server (the default on Windows), CherryPy runs in the same process as Apache. In that case, you almost certainly don't want CP to restart the process.
Solution: use mod_rewrite or mod_proxy so that CherryPy runs in its own process. Then you can autoreload to your heart's content. :)