Skip to content

December 5, 2010

14

Compiling nginx on CentOS 5

Part of a series of posts on setting up a web software stack with modern and hella fast technologies, I help you install nginx, the world’s fastest and lightest web server.

Please ensure that, before attempting this guide, you have followed the previous article in this set.

Create some user accounts

For security reasons, it’s a bad idea to run web servers under the root account. We’re not going to go into it here, but it’s really bad practice and is a sure fire way to get your server broken into by some random script kiddie with no life.

  1. Add the web server account.
    This account is the one the web server will run under.

    mkdir -p /var/www/vhosts
    useradd -c "Web server system user" -d "/var/www/vhosts" www-server
  2. Add the virtual host file owner.
    This user account is the one which will be the owner of the files we’re going to be serving. We make the distinction between this user and the web server user to prevent the web server from having full control over the files you’re serving in the event that somebody managed to exploit it.

    useradd -c "Virtual host file owner" -d "/var/www/vhosts" www-data
  3. Set permissions.
    For these two user accounts to work as we need them to, we have to add the web server account to the virtual host file owner’s group.

    usermod -a -G www-data www-server

Install and configure nginx

  1. Switch to the sources directory.
    It’s good practice to keep all of the source code for applications you’ve compiled in a directory on your server somewhere, just in case you need to check your configuration options or reinstall the software. The directory below is the standard one.

    cd /usr/local/src
  2. Download the latest source code.
    As of the time of writing, the latest stable release of nginx was 0.8.53. This is subject to change in the future, so you might want to check the available releases before continuing with this guide.

    wget http://nginx.org/download/nginx-1.0.4.tar.gz
    tar -xvzf nginx-1.0.4.tar.gz
  3. Install some specific prerequisites.
    There’s certain libraries required in order for nginx to compile. Here, we install them.

    yum -y install openssl-devel pcre-devel
  4. Prepare the compile instructions for your system.
    This is where we customise exactly what we want to compile and install, and where the build process is determined based on what libraries you have, what architecture processor and the like. Here, we specify a basic installation that’s really lightweight yet provides enough to work perfectly for most people.

    cd nginx-1.0.4
    ./configure \
      --with-cc-opt="-w" \ # fixes overly-anxious GCCs that dislike unused variables
      --prefix=/usr/local/nginx \
      --with-ipv6 \
      --with-http_ssl_module \
      --with-http_stub_status_module
  5. Compile it.
    Now that make, the tool that coordinates the build process, knows what it needs to do, we can let it get on with it. This process should only take a few seconds and will generate quite a lot of output, showing all of the commands it is running. There may be some warnings about deprecated functions, too, but these won’t affect the application later.

    make
  6. Install it.
    So, make has now compiled the web server, we can install it to the location we specified above (/usr/local/nginx).

    make install
  7. Creating our configuration.
    If you’re already comfortable configuring nginx and don’t need assistance in creating its configuration files, feel free to skip on to the PHP-FPM section of this guide. I wrote this assuming no knowledge of these applications, and I plan to continue to do so.First, we should delete the existing configuration shipped with the application, since we’re keeping ours as simple and streamlined as possible.

    rm -f /usr/local/nginx/conf/*

    Now, edit /usr/local/nginx/conf/nginx.conf and enter the following:

    user www-server www-server;
    pid logs/nginx.pid;
    worker_processes 8;
    
    events {
        worker_connections 1024;
    }
    
    http {
        include mime_types;
        default_type application/octet-stream;
    
        server_names_hash_bucket_size 64;
    
        sendfile on;
        tcp_nopush on;
        keepalive_timeout 65;
        include vhosts/*;
    }

    Now, we need to define the MIME types (file types, basically) the server knows. Edit /usr/local/nginx/conf/mime_types and paste the following:

    types {
        text/html                             html htm shtml;
        text/css                              css;
        text/xml                              xml;
        image/gif                             gif;
        image/jpeg                            jpeg jpg;
        application/x-javascript              js;
        application/atom+xml                  atom;
        application/rss+xml                   rss;
        text/mathml                           mml;
        text/plain                            txt;
        text/vnd.sun.j2me.app-descriptor      jad;
        text/vnd.wap.wml                      wml;
        text/x-component                      htc;
        image/png                             png;
        image/tiff                            tif tiff;
        image/vnd.wap.wbmp                    wbmp;
        image/x-icon                          ico;
        image/x-jng                           jng;
        image/x-ms-bmp                        bmp;
        image/svg+xml                         svg;
        application/java-archive              jar war ear;
        application/mac-binhex40              hqx;
        application/msword                    doc;
        application/pdf                       pdf;
        application/postscript                ps eps ai;
        application/rtf                       rtf;
        application/vnd.ms-excel              xls;
        application/vnd.ms-powerpoint         ppt;
        application/vnd.wap.wmlc              wmlc;
        application/vnd.wap.xhtml+xml         xhtml;
        application/vnd.google-earth.kml+xml  kml;
        application/vnd.google-earth.kmz      kmz;
        application/x-cocoa                   cco;
        application/x-java-archive-diff       jardiff;
        application/x-java-jnlp-file          jnlp;
        application/x-makeself                run;
        application/x-perl                    pl pm;
        application/x-pilot                   prc pdb;
        application/x-rar-compressed          rar;
        application/x-redhat-package-manager  rpm;
        application/x-sea                     sea;
        application/x-shockwave-flash         swf;
        application/x-stuffit                 sit;
        application/x-tcl                     tcl tk;
        application/x-x509-ca-cert            der pem crt;
        application/x-xpinstall               xpi;
        application/zip                       zip;
        application/octet-stream              bin exe dll;
        application/octet-stream              deb;
        application/octet-stream              dmg;
        application/octet-stream              eot;
        application/octet-stream              iso img;
        application/octet-stream              msi msp msm;
        audio/midi                            mid midi kar;
        audio/mpeg                            mp3;
        audio/x-realaudio                     ra;
        video/3gpp                            3gpp 3gp;
        video/mpeg                            mpeg mpg;
        video/quicktime                       mov;
        video/x-flv                           flv;
        video/x-mng                           mng;
        video/x-ms-asf                        asx asf;
        video/x-ms-wmv                        wmv;
        video/x-msvideo                       avi;
    }

    Finally, notice the virtual host include line. This tells nginx to include all of the files it finds in the vhosts folder, which we’re going to create right now. This is where you’ll put all of your virtual hosts later.

    mkdir /usr/local/nginx/conf/vhosts
  8. Create an init script.
    To use the service tool to start, stop and restart nginx, we need to install an LSB init script. Edit /usr/local/nginx/sbin/lsb-init and paste the following into it:

    #!/bin/sh
    #
    # nginx - this script starts and stops the nginx daemon
    #
    # chkconfig:   - 85 15
    # description:  Nginx is an HTTP(S) server, HTTP(S) reverse \
    #               proxy and IMAP/POP3 proxy server
    # processname: nginx
    
    # Source function library.
    . /etc/rc.d/init.d/functions
    
    # Source networking configuration.
    . /etc/sysconfig/network
    
    # Check that networking is up.
    [ "$NETWORKING" = "no" ] && exit 0
    
    nginx="/usr/local/nginx/sbin/nginx"
    prog=$(basename $nginx)
    
    NGINX_CONF_FILE="/usr/local/nginx/conf/nginx.conf"
    
    [ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx
    
    lockfile=/usr/local/nginx/logs/nginx.lock
    
    make_dirs() {
       # make required directories
       user=`nginx -V 2>&1 | grep "configure arguments:" | sed 's/[^*]*--user=\([^ ]*\).*/\1/g' -`
       options=`$nginx -V 2>&1 | grep 'configure arguments:'`
       for opt in $options; do
           if [ `echo $opt | grep '.*-temp-path'` ]; then
               value=`echo $opt | cut -d "=" -f 2`
               if [ ! -d "$value" ]; then
                   # echo "creating" $value
                   mkdir -p $value && chown -R $user $value
               fi
           fi
       done
    }
    
    start() {
        [ -x $nginx ] || exit 5
        [ -f $NGINX_CONF_FILE ] || exit 6
        make_dirs
        echo -n $"Starting $prog: "
        daemon $nginx -c $NGINX_CONF_FILE
        retval=$?
        echo
        [ $retval -eq 0 ] && touch $lockfile
        return $retval
    }
    
    stop() {
        echo -n $"Stopping $prog: "
        killproc $prog -QUIT
        retval=$?
        echo
        [ $retval -eq 0 ] && rm -f $lockfile
        return $retval
    }
    
    restart() {
        configtest || return $?
        stop
        sleep 1
        start
    }
    
    reload() {
        configtest || return $?
        echo -n $"Reloading $prog: "
        killproc $nginx -HUP
        RETVAL=$?
        echo
    }
    
    force_reload() {
        restart
    }
    
    configtest() {
      $nginx -t -c $NGINX_CONF_FILE
    }
    
    rh_status() {
        status $prog
    }
    
    rh_status_q() {
        rh_status >/dev/null 2>&1
    }
    
    case "$1" in
        start)
            rh_status_q && exit 0
            $1
            ;;
        stop)
            rh_status_q || exit 0
            $1
            ;;
        restart|configtest)
            $1
            ;;
        reload)
            rh_status_q || exit 7
            $1
            ;;
        force-reload)
            force_reload
            ;;
        status)
            rh_status
            ;;
        condrestart|try-restart)
            rh_status_q || exit 0
                ;;
        *)
            echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"
            exit 2
    esac

    Now we need to make this file executable and create a symbolic link from to this file in /etc/init.d so the service utility knows where the file is.

    chmod a+x /usr/local/nginx/sbin/lsb-init
    ln -s /usr/local/nginx/sbin/lsb-init /etc/init.d/nginx

    If you want to start nginx at boot time, you can now. Just run the following:

    chkconfig nginx on

    Kudos to the lovely people on the nginx wiki for the above script – I only made a couple of path modifications in order to adapt it to work with the setup we’re creating here.

  9. We’re nearly there!
    If you’ve been concentrating, you’ve probably noticed that we’ve yet to create our default virtual host. You ccan think of this as a kind of catch-all; any requests that don’t belong anywhere else will make it here.I’m going to name this file 000-default, but you can call it whatever you want. Just make sure that you create it in /usr/local/nginx/conf/vhosts, and it will be included for you.

    server {
        listen 80 default;
    
        root /var/www/vhosts/000;
        index index.html;
    
        access_log /usr/local/nginx/logs/000-access;
        error_log /usr/local/nginx/logs/000-error;
    }

    Now, create the directory we’re going to place a ‘hello world’ page in. This directory must the one you mentioned as your ‘root’ one in the virtual host you just wrote.

    mkdir /var/www/vhosts/000
    chown -R www-data:www-data /var/www/vhosts/000

    Do whatever you want there, that’s where all of your web files can go. I’d create an index.html file and put some kind of welcome message there :)

  10. Finally – start the server.
    It’s time to see if everything works :o Run this, then go to http://{your server’s IP address}/ and see if you get the page you created in the previous step. If you did, awesome, if you get an error from either the command or the web page, you need to review each of the steps above and see where you went wrong. If you need help, post a comment and I’ll see what I can do.

    service nginx start
Read more from Linux, nginx, Tutorials
14 Comments Post a comment
  1. Mert
    Dec 21 2010

    That is great. Thank so much

    Reply
  2. jacksprat
    Jan 6 2011

    Great writeup Luke.
    having a minor issue which I’m not able to resolve. Getting a 403 on the default index page and the error log shows error 3355 ..
    jacksprat

    Reply
    • Jan 6 2011

      Thanks for the kind words; it’s nice to know the time wasn’t wasted :)

      First of all, getting a 403 error when visiting your server’s IP address suggests one of two things: the permissions on the virtual host’s document root are invalid (755 for the directory, 644 for files with both owned by www-data) or your index.html file doesn’t exist or has the wrong name. Check that the index value in the virtual host matches the name of the index file.

      If you’re still having issues, please feel free to drop another comment. If you do post back, pasting your error log (or emailing it to hey@mydomain) would seriously help me diagnose this one :)

      Reply
  3. jacksprat
    Jan 6 2011

    so the error was b/c of the first line in nginx.conf
    it should read “user www-data www-server”
    also, line 30 in the init script is wrapped to line 31

    regards,
    jacksprat

    Reply
    • Jan 16 2011

      Thanks so much for your email! I can confirm that, as you suspected, creating the www-server user as a system one can cause issues with permissions. I’m just fixing this one now.

      Reply
  4. Jacob
    Jan 18 2011

    Just thought I would mention, the first useradd on this tutorial spits out an error :)

    # useradd -m -c “Web server system user” -d “/var/www/vhosts” www-server
    useradd: cannot create directory /var/www/vhosts

    Reply
  5. May 8 2011

    Updated for nginx 1.0.1 – the latest stable release :D

    Reply
  6. Jason
    Jun 1 2011

    lsb-init doesn’t seem to be working on CentOS 5.5 and nginx 1.0.4

    Reply
    • Jun 3 2011

      When you say it doesn’t work, do you get any errors or anything? I’ve just double-checked it here and it works fine with no modifications.

      Reply
  7. Alfie Cleveland
    Jun 10 2011

    Your wget link for nginx 1.0.4 is a bit weird… Downloading an href? yay!

    Reply

Trackbacks & Pingbacks

  1. Centos 5.5 with NginX | ZEROhype

Share your thoughts, post a comment.

(required)
(required)

Note: HTML is allowed. Your email address will never be published.

Subscribe to comments