Dummies Guide to Setting Up Nginx
Nginx is one of those things that many people want to try but don't. Why? Because it's scary. Well... Nginx itself isn't scary, but all of the poor guides out there make it a nightmare. The first step in making Nginx work for you is to not follow 95% of the guides found on Google. That sounds backward from what you usually hear and I do hate giving that advice. While many of the guides out there will get you going most of the time in most situations, they tend to be suboptimal. Many of these configurations tend to focus on reproducing how Apache does things. Fortunately, they are not the same thing and are in fact quite different. Even the guide in the Linode Library will yield poor results (which is uncommon for them).
So where should you go for help? Kind of easy actually. Nginx has a fantastic wiki for most of your questions at http://wiki.nginx.org/. There is an Nginx support channel (#nginx on irc.freenode.net) as well. Once you know what tends to be wrong in most examples you'll be able to start using Google. The reason being that most of the advanced stuff you find floating around is usually pretty solid. The issue is just that people get so excited by Nginx that when they see it's power they want to say something before they fully understand what's going on.
My aim here isn't to provide a dead simple solution for everything you will ever want to do with Nginx. Consider this more like a guide to the basics. Let's get started.
I use Debian and Ubuntu, you may have to alter things to fit your distribution.
Installing Stuff
A very common use case for web servers is PHP based Content Management Systems. A majority of the time, people settle on MySQL as their database. I'll also assume you want a self managed PHP system as you would get in Apache with mod_php. Do you also want the latest and greatest version of Nginx and PHP?
If your distribution does not have php5-fpm as an available package (think pre-ubuntu_11.04) you will want the new stuff. This is in a nice spiffy Personal Package Archive (PPA) which is maintained by the Nginx community. To add these PPA's for the latest and greatest:
aptitude install python-software-properties
add-apt-repository ppa:nginx/stable
echo 'deb http://packages.dotdeb.org squeeze all' >> /etc/apt/sources.list
wget http://www.dotdeb.org/dotdeb.gpg -0- | sudo apt-key add -
aptitude update
Note: If you'd like to use only PHP5 from dotdeb, which is probably a good idea, then copy the preferences.txt attachment to /etc/apt/preferences. This will make dotdeb the lowest priority except for php5* which will be the highest priority.
GREAT! Access to some super neat stuff. Let's get it all installed!
aptitude install nginx-light mysql-server php5-mysql php5-fpm php-apc
You'll get asked for a root password for MySQL. Pick something secure and don't forget it. At this point you have everything installed that you need. You just don't have it configured yet. We don't _have_ to stop these services while we're working on them but we should.
/etc/init.d/php5-fpm stop
/etc/init.d/mysql stop
/etc/init.d/nginx stop
Configuring Stuff
We may as well start with MySQL since it's the easiest. Edit the file /etc/mysql/my.cnf. Add this stuff to the very bottom.
default-storage-engine = innodb
innodb_buffer_pool_size = 128M
innodb_log_file_size = 10M # May need to purge (rm) /var/lib/mysql/ib_logfile*
innodb_flush_method = O_DIRECT
innodb_file_per_table = 1
innodb_flush_log_at_trx_commit = 2
innodb_log_buffer_size = 1M
innodb_additional_mem_pool_size = 20M
# num cpu's/cores *2 is a good base line for innodb_thread_concurrency
innodb_thread_concurrency = 8
innodb_open_files = 1024
ignore-builtin-innodb
innodb_file_per_table
plugin-load=innodb=ha_innodb_plugin.so;innodb_trx=ha_innodb_plugin.so;innodb_locks=ha_innodb_plugin.so;innodb_lock_waits=ha_innodb_plugin.so;innodb_cmp=ha_innodb_plugin.so;innodb_cmp_reset=ha_innodb_plugin.so;innodb_cmpmem=ha_innodb_plugin.so;innodb_cmpmem_reset=ha_innodb_plugin.so
I'd rather not go into detail about each piece here. I'll sum it up this way... It won't save you any RAM. In fact, this will use additional RAM. It will, however, make thing faster and more efficient. It's kind of a "MySQL Magic Sauce" I cooked up over some time that I have yet to find issues with.
Now for that PHP tuning. PHP-FPM works great out of the box. However, it's configured with defaults that are a little less than optimal. For starters, it uses a TCP socket as opposed to a UNIX socket. The TCP socket is more universal, but not more efficient. It is also configured to use dynamic processes which are not ideal either. Lastly, it is setup with huge amounts of RAM allocated to each PHP process. This is fine consiering all of the horribly inefficent PHP apps out there. If you're running something sane, then it's just crazy. Below, I included the lines that I changed in /etc/php5/fpm/pool.d/www.conf.
listen = /var/run/php5-fpm.sock
listen.allowed_clients = 127.0.0.1
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
user = www-data
group = www-data
pm = static
pm.max_children = 10
pm.max_requests = 1000
php_admin_value[memory_limit] = 32M
Now, we move onto Nginx configuration. The best part of this is that the most common cases already have templates for you. The default install comes with a default configuration file in /etc/nginx/sites-enabled/. Quite simply, this file should just be deleted if you have a clue what you're doing. It's useful because it's loaded with comments, examples, and links.
I personally prefer keeping site configs in /etc/nginx/conf.d/.config. Others prefer keeping configs in /etc/nginx/sites-enabled/ and then creating a symlink to it from /etc/nginx/sites-available/. Either option yields the exact same result. The only thing you should not do is keep everything in the same file. It creates a maintenance nightmare.
Let's say you're wanting to run a Drupal and you unpacked into /var/www/drupal/. Go to http://wiki.nginx.org/Drupal. Copy/paste that configuration example to your configuration file. Edit the line that says 'root /var/www/drupal6;' and point it to where you unpacked Drupal (/var/www/drupal). You will also want to edit the line that says 'server_name domain.tld;'. This should be the domain name that will be used to access your site.
Well... Let's see....
We installed the packages, configured them, tuned a few things, grabbed the source for a CMS, set it up, ect. What now? Let's fire it all up.
/etc/init.d/php5-fpm start
/etc/init.d/mysql start
/etc/init.d/nginx start
Of course you still need to create a database and user to access that database as well as configure your CMS or whatever it may be. This should give you an excellent start to your server.
Further reading can be found on the Nginx Wiki. You definitely want to check out this resource before consulting other resources.
http://wiki.nginx.org/Pitfalls
http://wiki.nginx.org/Configuration
My server is a Linode. I use their smallest plan because I can't peg the resources it offers.
Proc: 'Intel(R) Xeon(R) CPU L5630 @ 2.13GHz' 4-core
RAM: 512MB
The results:
Transactions: 44965 hits
Availability: 99.91 %
Elapsed time: 59.95 secs
Data transferred: 329.59 MB
Response time: 0.12 secs
Transaction rate: 750.04 trans/sec
Throughput: 5.50 MB/sec
Concurrency: 89.90
Successful transactions: 44965
Failed transactions: 40
Longest transaction: 0.20
Shortest transaction: 0.03
Those results are local (to avoid network bottlenecks) and from the largest page on my site which uses multipl db queries and runs the whole stack. The results are also nothing that exciting. I'm actually rather disappointed. I guess I'm not too worried about it though.
My advertisement... If you're interested in a low cost VPS with incredible support and uptime, check out Linode. If you use the link provided you will notice it has my referral code. I get a little gift from them, you get it too if you sign up and someone uses your referral code. When I say excellent support- I mean it. I accidentally deleted my virtual disk, and these guys grabbed it from the grave for me. I screwed up with recreating a node, these guys spent hours repairing my mistake.
| Attachment | Size |
|---|---|
| 2.32 KB |
Thanks for taking the time to
Thanks for taking the time to document the process. Nginx setup has always stumped me and it is great to read a simple concise setup guide.
Is it possible for you to
Is it possible for you to write a tutorial for Perl, FCGI and Nginx ? I'm suffering with huge amounts of issues... and there is nothing clear for me to follow. Thanks.
Module
Try the embedded Perl module. It's distributed with the official Nginx sources and it removes the need for FCGI or extensive configuration. It pretty much reduces the complexity to Nginx+Perl+minimal config, which is probably what you want.
Thanks
Thank you for the comprehensive and well-written guide. This is my first server config!
nginx php repo appears to have gone (as of Feb 8th 2012)
It's a shame since it was the easiest one to use. I found another PPA that is usable and very up to date (it has PHP 5.3.10), though it uses XML config for php-fpm and separates packages with php52 and php53 prefixes.
NO MORE PHP5 PPA
It was never the intention of the Nginx team to take on managing a complete clone and backport of PHP. The management of it has gone to an extreme level and the team has decided to no longer support this PPA. If you need PHP, dotdeb is now the recommended alternative. This blog will be updated to reflect this suggestion.
http://www.dotdeb.org/tag/php5/
Nginx PHP5 PPA
The Nginx PHP5 PPA was indeed a good option. What is more - it was being referenced by more and more tutorials on Nginx-PHP5-FPM. Nonetheless, it is up to the Nginx team to decide on its future.
I found this PPA that can provide PHP 5.3 (5.3.10) - https://launchpad.net/~l-mierzwa/+archive/lucid-php5. There is antoher (https://launchpad.net/~ondrej/+archive/php5) that tracks PHP releases more closely but I was not able to get the packages installed due to errors in the installation process related to dpkg.
This should cover us Ubuntu LTS users till 12.04 LTS comes out.
The Referencing Tutorials
The increasing number of tutorials that point to it was one of our concerns. This was never meant to be maintained for any significant lenght of time. The longer we left it there, the more people came to rely on it. We started getting bug reports about our version that should have gone to the Debian version. It became our responsibility to manage it and keep it up to date and follow closely with security updates which was significantly outside the scope of our original intention.
In short, it just became too much of a burden and took our attention away from Nginx.
Thanks for your links to alternative PPAs.
mysql fails to start with ignore-builtin-innodb
when i comment out ignore-builtin-innodb mysql starts. im not familiar with this setting. my guess is that there is something wrong in the plugin-load string of modules? what does this do exactly? im running 5.5.24-0ubuntu0.12.04.1 (Ubuntu) thanks!
innodb plugin now default in 5.5
i was reading and apparently the innodb plugin is now the default in mysql 5.5
possibly a little mistake in the guide
at this string:
cat 'deb http://packages.dotdeb.org squeeze all' >> /etc/apt/sources.list
I think "echo" must be used instead of "cat":
echo 'deb http://packages.dotdeb.org squeeze all' >> /etc/apt/sources.list
Thanks!
Yup, you're completely right. Thanks for catching my typo!
Add new comment