"Curiosity is the very basis of education and if you tell me that curiosity killed the cat, I say only the cat died nobly." - Arnold Edinborough

Performance is often important to people using nginx – and for good reason, of course. Sadly, while many people will optimize their software stack they will rarely work on optimizing the back-end code; and even more rarely will they eliminate single points of failure. Such was also the case when SitePoint recently published an article about uploading large files with PHP. This post will discuss a method to accept uploads that will scale far better and not offer malicious users an easy DoS vector.

The Problem

File uploads are used in many places, depending on your site people might be adding avatars, personal pictures, music or any other type of file. The size of uploads can vary a lot but in the end it doesn’t really matter much, you’re still offering a malicious user a single point of failure where he can direct his denial of service attack.

Allow me to illustrate. Lets say you have an upload form for people to upload pictures, you run Apache in pre-fork mode with mod_php and 50 max children, otherwise known as the standard Apache setup.

Each time Apache accepts an upload one of these processes is going to be busy for the duration of the upload. Do you see the problem here? File uploads to PHP are essentially really long-running scripts and you’re going to run out of Apache processes quickly. It might not even be a malicious user, you could be a victim of your own popularity.

If you’re using nginx then you’re already better off as nginx will buffer the file upload to disk and only pass it to your fastcgi back-end once the file upload is complete. If you’re uploading a 1 GB file nginx is still going to send 1 GB of data over fastcgi, though, but we can do something about that.

Read More

Nginx is a constantly evolving web server rapidly growing in popularity. In July of 2013 nginx even managed to become the most used web server amongst the top 1000 sites ranked by traffic. It’s safe to say that these days you cannot afford to not know about nginx or how to use it. Unfortunately the nginx documentation is more of an API documentation than it’s an introduction to how nginx actually works. This post is aimed at correcting that by walking you through the most important parts of the nginx configuration file in a logical order.

The Basics of the Nginx Configuration

Nginx is in all fairness a fairly simple HTTP server, however, because most people come from Apache there are a few gotchas in the nginx configuration that people need to be aware of before they start using this web server. The most important is that nginx is a reverse proxy first and HTTP server second, its first concern is not files but rather URLs, this changes the way we have to configure nginx.

The first thing you need to know is that the nginx configuration file uses an inheriting hierarchy, directives specified in a higher block will filter down to lower blocks as a default value, from this follows that we want to specify things in the top most hierarchy whenever possible. Since directives in top blocks filter down as default values it is still possible to override them in most cases.

There are 3 hierarchies which are usually referred to as blocks. The HTTP-block, the server-block and the location block of which the hierarchy goes like this: http -> server -> location.

Furthermore there are two special locations, an event block and the root which the event block and the http block reside in. Both of these contain only a minor amount of directives. The majority of your time will be spent in the other three blocks.

The blocks have a semantic meaning of sorts. The server block is what in Apache would be considered a virtual host. The location block usually referrers to the URI.

When using the documentation the context keyword specifies in which block a directive may be used, as mentioned earlier it is usually recommended to specify the directive in the top most block.

Read More