So I have noticed that the docs for various Application Servers (think Unicorn, Puma for Ruby, Warp for Haskell etc) always mentioned something similar to "it is optimized as an app server.” Typically this is mentioned when describing the standard setup of using a HTTP server (like Ngnix) in reverse-proxy in front of app servers.
So my question is: What exactly does the programming of a web application server make it more performant for serving data generated by code v/s HTTP server? Is there any particular engineering trade-offs? Or is it more the case where HTTP servers are optimized for serving files from a disk, and so they're merely trying to say that HTTP servers are not optimized for application code?
First, this really belongs in ServerFault or SuperUser.
But basically, Apache & Nginx strictly deliver static web content. Yes, you can install PHP as a module & it will parse scripts when the page is requested. But it is all on demand. Meaning the program runs only when the page is requested.
In contrast application servers run programs that are active in memory all the time. Which can have some engineering benefits depending on what you want your system to do. So Tomcat or Passenger (for Ruby) run Java & Ruby apps, and are optimized to do it in a production server environment.
Why does Apache or Nginx get attached as a front end? Because at the end of the day Apache & Nginx still are the best tools for simply delivering web content. And have better optimizations & security in place to do so.
So the application server focuses on making Java or Ruby run as cleanly as possible & deliver basic web content. And Apache & Nginx concentrate on the front-end side of web delivery.
As a systems administrator, I prefer to proxy via Apache or Nginx since I already know how to configure & optimize those tools for my use. If I have to learn how to fine tune Passenger or Tomcat, it should only be enough to allow me to get it running so I can place Apache or Nginx in front of that.
Related
I'm so confused as to what benefits I will be getting from using Apache to serve my Flask App in my EC2 instance if it's already out there to the public, & whether I have to think about using something like Apache or Nginx from the first place?
Why not just configure a production server like gunicorn (as I heard it's better to be used for security purposes even though this answer kinda made me doubt this a bit) and get a private domain and that's it for my flask app?
This question boils down to "application server vs web server". In your case gunicorn is an app server, and nginx/apache is a web server.
What is the difference between application server and web server?
To give some brief advice, you need to consider the scale and actual functionality of your app. If you expect to serve any consistent number of users, use web server, they are better optimized to serve concurrent requests. If your app serves some static files - also use web server, they do it more efficiently. If it's an internal app which only you and couple of guys use occasionally, you can get by only running a gunicorn.
There are a vast majority of tutorials and documentation on the web where Flask is running in development state. The log looks like this in development mode:
* Serving Flask app "app" (lazy loading)
* Environment: production
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://0.0.0.0:5555/ (Press CTRL+C to quit)
I want to know more about how to make it production ready. I've seen documentation on this as well using production ready WSGI servers and nginx as reverse proxy in front. But can somebody tell me why WSGI and reverse proxy is needed?
If my Flask application is dockerized and running in Google Kubernetes Engine is it even necessary then? Will GKE not take care of the purpose of WSGI and reverse proxy?
As Flask's documentation states:
Flask’s built-in server is not suitable for production
Why WSGI? It's a standard way to deploy Python web apps, it gives you options when choosing a server (i.e. you can choose the best fit for your application/workflow without changing your application), and it allows offloading scaling concerns to the server.
Why a reverse proxy? It depends on the server. Here is Gunicorn's rationale:
... we strongly advise that you use Nginx. If you choose another proxy server you need to make sure that it buffers slow clients when you use default Gunicorn workers. Without this buffering Gunicorn will be easily susceptible to denial-of-service attacks.
Here is Waitress's rationale for the same:
Often people will set up "pure Python" web servers behind reverse proxies, especially if they need TLS support (Waitress does not natively support TLS). Even if you don't need TLS support, it's not uncommon to see Waitress and other pure-Python web servers set up to only handle requests behind a reverse proxy; these proxies often have lots of useful deployment knobs.
Other practical reasons for a reverse proxy may include needing a reverse proxy for multiple backends (some of which may not be Python web apps), caching responses, and serving static content (something which Nginx, for example, happens to be good at). Not all WSGI servers need a reverse proxy: uWSGI and CherryPy treat it as optional.
P.S. Google App Engine seems to be WSGI-compliant and doesn't require any additional configuration.
I am writing a backend web api for a mobile app. It should support HTTPS. Most of my experience in .NET, but for this one I want to use Go/Golang. I have a sample service ready, now I need to make sure that it is production ready.
In .NET I will just use IIS, but I have no clue what would be a good approach for Go.
Should I have nginx as reverse proxy, or I better use FastCGI ? And how to make sure that my go app is up and will run on system reboot ? should I use upstart or something similar ?
I've been using Nginx FastCGI with a Go webservice - they work well together. It's no harder to set up than HTTP reverse proxying - except for having to learn how to do it. The performance ought in principle to be a lot better, but I have no measurements to justify that hunch. My web service can work in both HTTP mode and FastCGI mode (one or other at a time), so I suppose I ought to do some benchmarking (note to self!).
If you want proper system startup (and you should), you need to learn how init scripts work. I sometimes cheat and start with an existing working script someone else wrote for a similar application and customise it to work with mine.
I've used nginx as a reverse proxy for my Go projects. I've found that it's a lot easier to set up useful server settings such as TLS, compression, etc., in nginx rather than as a pure Go server.
Keeping it alive on server reboot is a more complicated question. I would suggest learning how to write a script/whatever for your server's init daemon and just doing it that way.
I'm currently writing a webservice (with node.js) for an AngularJS frontend which is hosted with node.js
It will later be available through a proxy under domain.com/api and therefore I don't need JSONP.
For local testing purposes i have my AngularJS app running on localhost:80 and my node.js backend on localhost:3000. Naturally I'm not able to query json requests. The easies
What would be the best setup to test my homepage locally without screwing to much in my setup?
I'm currently working on windows. Linux is also an option if it is easier.
Would it be possible to write a simple proxy for express that hosts both apps in the same domain?
You can use the hosts file to set the domain.com/api to localhost. This is done in /etc/hosts in Linux, but its present somewhere in Windows too. Another thing that helps me a lot is ssh tunneling. You can, for example, tunnel remote ports (where your backend is running) to localhost with ssh -L localPort:your.server:remotePort
It's not exactly what you asked for, but the easiest might be to have the node.js app serve the AngularJS app, too. It's quite efficient, certainly efficient enough to use for development.
If it's an expressjs app, you can just add
app.use(express['static'](__dirname + "/public"));
before your other routes to have it look for static files in ./public/
If your app is served by a template or build system that you can't easily reproduce in node.js, then another option would be to run nginx, apache or haproxy on some port (80 or 5000 or ...) and have that proxy to the current backend server for the app and port 3000 (the node.js app) for the API/data requests.
You might even be able to have your server currently running on port 80 do this.
As a final idea you could also setup the node.js app to proxy to port 80 for the "app files".
Edit - I just realized that both of your apps are written in node.js. Would it be possible to set it up so you run them separately in production but together in development? Put all the real functionality in modules and then have three separate "loaders" that start the apps, one together and then a loader for each individually.
Concerning the built in debugging server started with the manage.py runserver command, the Django docs state, "DON’T use this server in anything resembling a production environment."
If I wanted to develop a Django application over ssh on a remote machine, would using Nginx as a proxy to a running Django debug server be a reasonable thing to do? Is the Django debug server insecure, or just not built to handle large amounts of traffic?
From the Django docs:
DO NOT USE THIS SERVER IN A PRODUCTION SETTING. It has not gone through security audits or performance tests. (And that's how it's gonna stay. We're in the business of making Web frameworks, not Web servers, so improving this server to be able to handle a production environment is outside the scope of Django.)
So, that answers the latter two questions. As for the former, it depends on how your debug server is set up. If your server is exposed to the public Internet, doesn't have a firewall blocking port 8000, and you intend to use runserver with something other than the default 127.0.0.1 address, set up a more 'proper' application stack.
If you're going to use nginx, why not just use the suggested FastCGI configuration so that your debug environment will be more similar to the future production environment?
Modern web servers have all sorts of features, related to both security and performance, that the Django development server does not. It is a stripped-down, very basic, single-threaded server for the purposes of development. Hence why the docs say to not use it in a production setting.
However, people get way to afraid of this statement. The key defining point is that it's for development. Whether that development takes place on your local machine or a remote VPS or an entire cluster is besides the point.
If the server is publicly available, it will be open to hacking, breaches, DoS attacks, etc. But, if what's there isn't of any importance, just a development site running on dummy data, it doesn't matter. So, yes, you can use the development server on your remote server for development purposes. There's nothing at all wrong with that. My only caution would be to avoid using production data (such as using a dump from your production database to develop against) because that data could be compromised. Otherwise, it's no big deal.
Is the Django debug server insecure, or just not built to handle large amounts of traffic?
IT IS BOTH INSECURE AND NOT INTENDED FOR HEAVY TRAFFIC!
It might take care of a few of the issues by hiding the testing server behind a proxy, but if you're going to that much trouble you've done about the same amount of work as you need to do it right... right being WSGI. Use mod_wsgi, gunicorn, or check this out for more bleeding-edge solution: http://bartek.im/blog/2012/07/08/simplicity-nginx-uwsgi-deployment.html. Whatever you do.... DON'T USE THE DJANGO TEST SERVER FOR PRODUCTION ENVIRONMENTS!