Nginx (pronounced “engine x”) is a free, open-source, high-performance HTTP server known for its stability, rich feature set, simple configuration, and low resource consumption.

I do this install several times a month for development servers but someone asked me for the quick version the other day. So here it is in a nutshell, how to install Nginx (nginx version: nginx/1.3.7 at time of posting), PHP5 (PHP5-FPM version 5.3.10-1 at posting), and and MySQL support on Ubuntu 10.04 LTS using apt-get.

This PPA is maintained by the Nginx team.

You can get the latest stable version of Nginx from the Nginx PPA on Launchpad.

You will need to have root privileges to perform the following commands.

root@corp:/# sudo -s
root@corp:/# apt-get install python-software-properties dialog
root@corp:/# nginx=development # use nginx=stable for latest stable version (1.2.4 at time of posting)
root@corp:/# add-apt-repository ppa:nginx/$nginx
root@corp:/# apt-get update
root@corp:/# apt-get install nginx

Nginx should already be started but if not start it

root@corp:/# service nginx start

At this point you should be able to access your servers public IP address and see the default “Welcome to Nginx” (or in my case a 404 page) screen.

Nginx default 404 page

Nginx default 404 page

Nginx should start at boot time but if not, run

root@corp:/# update-rc.d nginx defaults

Install MySQL

root@corp:/# apt-get install mysql-server mysql-client

If like me, you use a separate MySQL server, you don’t need to install mysql-server. If you install mysql-server, you will be asked for a “root” password for MySQL. Make it secure and write it down for later usage.

Install PHP

PHP-FPM became a part of PHP-5.4 and is also available in 5.3.3. The bad news would be that PHP-FPM is not in the Ubuntu repositories (atleast, not for 10.04 and lower since it uses 5.3.2). Luckily, there is a debian/ubuntu repository which does it all for you.
root@corp:/# add-apt-repository ppa:brianmercer/php5
root@corp:/# apt-get update
root@corp:/# apt-get upgrade
root@corp:/# apt-get install php5-fpm

Then open /etc/php5/fpm/php.ini and add the line cgi.fix_pathinfo = 1 right at the end of the file:

root@corp:/# nano -w /etc/php5/fpm/php.ini

Sample nginx.conf

user www-data;
worker_processes  4;

error_log  /var/log/nginx/error.log;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
    # multi_accept on;
}

http {
    include       /etc/nginx/mime.types;

    access_log  /var/log/nginx/access.log;

    sendfile            on;
    tcp_nopush          on;

    keepalive_timeout  65;
    tcp_nodelay        on;

    types_hash_max_size 2048;
    server_tokens off;

    index index.php index.html index.htm;

    gzip  on;
    gzip_disable "MSIE [1-6]\.(?!.*SV1)";



    upstream php {
        server 127.0.0.1:9000;
    }

    include /etc/nginx/conf.d/*.conf;
    #include /etc/nginx/sites-enabled/*;
}

Sample etc/nginx/conf.d/default.conf

server {
        fastcgi_buffer_size 4K;
        fastcgi_buffers 64 4k;

        server_name _;

        root /var/www/sites/$host;

        error_log /var/log/nginx/error.log notice;
        access_log /var/log/nginx/access.log combined;

        location = /favicon.ico {
                log_not_found off;
                access_log off;
        }

        location = /robots.txt {
                allow all;
                log_not_found off;
                access_log off;
        }

        # Very rarely should these ever be accessed outside of your lan
        location ~* \.(txt|log)$ {
                allow 127.0.0.1;
                deny all;
        }

        location ~ \..*/.*\.php$ {
                return 403;
        }

        location / {
                try_files $uri rewrite;
        }

        location @rewrite {
                # Some modules enforce no slash (/) at the end of the URL
                # Else this rewrite block wouldn't be needed (GlobalRedirect)
                rewrite ^/(.*)$ /index.php?q=$1;
        }

        location ~ \.php$ {
                # Zero-day exploit defense.
                # http://forum.nginx.org/read.php?2,88845,page=3
                # Won't work properly (404 error) if the file is not stored on this server, which is entirely possible with php-fpm/php-fcgi.
                # Comment the 'try_files' line out if you set up php-fpm/php-fcgi on another machine.  And then cross your fingers that you won't get hacked.
                try_files $uri =404;
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                #NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
                include fastcgi_params;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_intercept_errors on;
                fastcgi_pass php;
        }

        location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
                expires max;
                log_not_found off;
        }
}

I would honestly RECOMMEND that you go to the Nginx site for configuration information. This setup is on development server and temp production servers behind firewalls. Just because this works for me doesn’t mean that it will work for you!

VN:F [1.9.22_1171]
Rating: 5.0/5 (1 vote cast)

Installing SSL certificates for Nginx is a bit different than Apache but it’s not that hard.

Instead of re-eventing the wheel, check out the post on the personal blog of AfterDarkMike, the CEO of After Dark Communications, Inc.

How to generate an SSL Certificate Signing Request for your Nginx Web Server with OpenSSL and install your SSL Certificate on your Nginx web server.

Actually I was surprised how easy it was to install SSL certificates for Nginx on Ubuntu.

Check out the full post “SSL certificate installation on Ubuntu/Nginx“.

VN:F [1.9.22_1171]
Rating: 5.0/5 (1 vote cast)

Ubuntu and Nginx together doesn’t provide out-of-the-box support for password protected directories. I’ll show you how to do it.

First you will need to install “htpasswd”. (apt-get is our friend, yet again)

root@zero:/# apt-get install apache2-utils libapache-htpasswd-perl

Then open your configuration for the site you are working on and add:

location /my_procted_area {
    auth_basic "Restricted";
    auth_basic_user_file /var/www/example.com/.htpasswd;
}

Where “my_procted_area” is the folder you want to protect and “/var/www/example.com/.htpasswd” is a path outside your web root.

Then create the password file:

root@zero:/# htpasswd -c /var/www/example.com/.htpasswd USERNAME

Where “USERNAME” is the username you want to use and “/var/www/example.com/.htpasswd” is a path outside your web root (same as above).

After typing that command you’ll be prompted to enter a password and then confirm that password like this:

New password: 
Re-type new password: 
Adding password for user USERNAME

And finally, restart Nginx:

root@zero:/# /etc/init.d/nginx restart
VN:F [1.9.22_1171]
Rating: 5.0/5 (1 vote cast)

Nginx comes with a module called ngx_http_access_module that allows you to allow or deny access to IP address.

Simply open your nginx.conf and add to the server block:

allow my.ip.address;
deny all;

or

deny bad.ip.address;
allow all;
VN:F [1.9.22_1171]
Rating: 5.0/5 (2 votes cast)

Assuming you already have Nginx and FastCGI configured, setting up WordPress is a snap.

Download WordPress to your document root:

root@warzone:/#wget http://wordpress.org/latest.zip

Extract the WordPress package:

root@warzone:/#unzip latest.zip

Rename WordPress’s configuration file:

root@warzone:/#mv wp-config-sample.php wp-config.php

Edit the wp-config.php file and add your database info:

root@warzone:/#nano -w wp-config.php

File excerpt: wp-config.php

/** The name of the database for WordPress */
define('DB_NAME', 'database_name');

/** MySQL database username */
define('DB_USER', 'database_user_name');

/** MySQL database password */
define('DB_PASSWORD', 'database_password');

/** MySQL hostname */
define('DB_HOST', 'database_host');

/** Database Charset to use in creating database tables. */
define('DB_CHARSET', 'utf8');

Check your Nginx Configuration:

The file you need to edit is called “nginx.conf” and is installed in different locations depending on your Linux distribution. If you install Nginx from source, the default location is /usr/local/nginx/conf/nginx.conf, however it may be somewhere else like /etc/nginx/conf/nginx.conf or /etc/nginx/nginx.conf.

Since we are assuming you already have Nginx up and running, you just need to check your try_files line:

try_files $uri $uri/ /index.php;

Then all that’s left it to install WordPress from the web interface:

http://your-domain.com/wp-admin/install.php

VN:F [1.9.22_1171]
Rating: 5.0/5 (1 vote cast)

From time to time you need to know what version of Ubuntu you are running. Issuing the following command will show you.

root@warzone:/# cat /etc/lsb-release

returns:

DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=10.04
DISTRIB_CODENAME=lucid
DISTRIB_DESCRIPTION="Ubuntu 10.04.1 LTS"

Altenatly:

root@warzone:/# lsb_release -a

No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 10.04.1 LTS
Release:        10.04
Codename:       lucid
VN:F [1.9.22_1171]
Rating: 5.0/5 (1 vote cast)

This morning I was faced with yet another 404 not found page when attempting to login to the Install Nginx on Ubuntu blog.

The logs revealed:

2012/02/15 17:17:33 [error] 13788#0: *5525 connect() failed (111: Connection refused) while connecting to upstream, client: 99.250.236.245, server: installnginxonubuntu.com, request: "GET / HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "installnginxonubuntu.com"

This is not really an Nginx error. The problem is that the backend is not listening on port 9000 or its queue is filled up. I was unable to telnet to 127.0.0.1 9000. Restarting spawn-fcgi fixed this.

I’m not sure if this is a stability issue or configuration issue but will monitor the issue and post results.

Actually, after about 10 seconds of thought, I’m going to switch to PHP-FPM and test the stability.
VN:F [1.9.22_1171]
Rating: 5.0/5 (2 votes cast)

This morning I was faced with a 404 not found page when attempting to login to the Install Nginx on Ubuntu blog.

2012/02/13 15:06:08 [warn] 21936#0: *12 an upstream response is buffered to a temporary file /var/lib/nginx/fastcgi/3/00/0000000003 while reading upstream, client: 99.250.236.245, server: installnginxonubuntu.com, request: "GET /wp-admin/load-scripts.php?c=0&load=admin-bar,hoverIntent,common,jquery-color,wp-ajax-response,wp-lists,jquery-ui-core,jquery-ui-widget,jquery-ui-mouse,jquery-ui-sortable,postbox,thickbox,plugin-install&ver=c1f86f5c0f25cc2c1f94e898b9db8a7d HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "installnginxonubuntu.com", referrer: "http://installnginxonubuntu.com/wp-admin/plugins.php"

This is not a huge issue, just something I overlooked when setting up Nginx on this host.

Increasing fastcgi_buffer_size and fastcgi_buffers will fix this.

File excerpt: /etc/nginx/conf.d/installnginxonubuntu.com.conf

server {
    ...
    fastcgi_buffer_size 4K;
    fastcgi_buffers 64 4k;
    ...
}
VN:F [1.9.22_1171]
Rating: 5.0/5 (1 vote cast)

How to Update /etc/hosts

Edit your /etc/hosts file to something similar to the following example, replacing “alphabet” with your chosen hostname, “example.com” with your system’s domain name, and “66.66.66.66″ with your pubilc IP address.

root@zero:/# nano /etc/hosts

File: /etc/hosts

127.0.0.1        localhost.localdomain    localhost 
66.66.66.66      alphabet.example.com     alphabet

You may also need to Set your Hostname.

VN:F [1.9.22_1171]
Rating: 0.0/5 (0 votes cast)

How to set your system’s hostname and FQDN (fully qualified domain name).

Your hostname should be something unique! The system’s hostname has no relationship to websites or email services hosted on it – it just provides a name for the system itself. Your hostname should NOT be “www” or anything else overly generic.

Issue the following commands to set the hostname, replacing “alphabet” with the hostname of your choice:

root@zero:/# echo "alphabet" > /etc/hostname
root@zero:/# hostname -F /etc/hostname

Edit the file “/etc/default/dhcpcd” (ff it exists) to comment out the “SET_HOSTNAME” directive:

File excerpt: /etc/default/dhcpcd

#SET_HOSTNAME='yes'

And then Update /etc/hosts.

VN:F [1.9.22_1171]
Rating: 5.0/5 (1 vote cast)