Top

Perfect Setup: Ubuntu Hardy+Nginx+MySQL5+PHP5+Wordress

August 16, 2008 by admin 

The Perfect Setup:

Ubuntu Server 8.04.1 LTS Hardy (supported to 2013) + EngineX (NGINX) Web Server built from sources + MySQL 5 + PHP 5.
(Or LEMP )

Tested on 256MB VPS slice at SliceHost. Should work for other hardware.

From baremetal/barebone/empty fresh install of Ubuntu Server to shiny, fast and SEO-friendly Wordpress Portal propelled by WP Super Cache plugin.
All configured and powered by NGinx WEB Server.
Step by step copy/paste instructions - from "zero to hero" with everything on a single page (albeit long one) and in the right order. Just what your granma was asking for!

Every time I need to quickly utilize new product or technology it always made me wonder "why don't someone came up with a simple step by step instructions on which buttons to press to make this thing work?". So instead of waiting for someone to do it this time I decided to make one myself.

After spending countless hours and days hunting for scripts, searching for clues, scrolling through misleading posts, extracting bits from articles, eliminating blubber and fluff, bugging busy geeky people for hints and getting all necessary pieces together in the right order I finally came up with this instructional post. It all boils down to step-by-step copy/paste instructions that should take you less than 1 hour to get from freshly installed Ubunty server to fully functioning, search engine optimized business-ready Wordpress-powered website.

I tested it all on 256MB VPS image offered by SliceHost but the same instructions should work just just fine on any real hardware as well.
Most credits goes to excellent set of articles by PickedOnion at SliceHost plus to some more sources, acknowledged within this post.

This article assumes your username is 'jsmith' and your domain is 'mydomain.com'.

Now it's time to get our hands dirty!

Secure and tidy-up your fresh Ubuntu Server installation
  • Login as root.
  • Change root password:
    passwd
  • Add new username - yourself:
    adduser jsmith
    visudo
  • Append this line to end of file (to navigate within 'vi' editor to create next line - use these: L, $, a, <ENTER>):
    jsmith ALL=(ALL) ALL
    To save and exit do: <ESC>, :wq, <ENTER>

  • SSH configuration:
    nano /etc/ssh/sshd_config - Find
    Port 22 - and change number to something different (12345) to make hacking more difficult.
    - Set these to:
    PermitRootLogin no
    X11Forwarding no
    UsePAM no
    - Append these lines to the very end:
    UseDNS no
    AllowUsers jsmith

  • Secure slice with iptables
    iptables-save > /etc/iptables.up.rules
    nano /etc/iptables.test.rules
  • 1. Copy contents of this file -> and paste it into 'iptables.test.rules'.
    2. Change port number to your port number on this line:
    ...
    -A INPUT -p tcp -m state --state NEW --dport 30000 -j ACCEPT
    ...
    3. Save and exit (Ctrl+O, Ctrl+X).

  • Apply new iptables rules:
    iptables-restore < /etc/iptables.test.rules
  • Save iptables rules permanently:
    iptables-save > /etc/iptables.up.rules
  • Make sure iptables rules will apply when server is rebooted as well: nano /etc/network/interfaces
  • Add new line after these 2:
    auto lo
    iface lo inet loopback
    pre-up iptables-restore < /etc/iptables.up.rules
    Save and exit.
  • Reload SSH to use new ports and configurations:
    /etc/init.d/ssh reload
  • Keep 'root' session running and open second session.
    SSH login to your slice to new port, with your new username and password:
    - Linux: ssh -p 12345 jsmith@123.45.6.78 - Windows: putty jsmith@123.45.6.78 12345
  • If you logged on successfully via your new username: 'jsmith' - you may close 'root' session now.
    If not - you still have 'root' session opened to fix problems. In the worst case - you can use web based console shell login from your manage.slicehost.com dashboard to fix issues. sudo aptitude -y install screen
  • Enter screen:
    screen Screen is the great little utility that allows your terminal session activity to keep running (say lengthy builds) even if you were cut off or disconnected. You may reenter your abandoned screen session at a later time to check progress and continue working.
    - Usage notes:
    - new screen session: screen
    - attach to existing screen session: screen -r
    - list all existing screen sessions: screen -list (output: 12045.pts-0.MENSK (Detached), etc...)
    - attach to existing screen session by number: screen -r 12045
    - detach from screen session and back to main terminal: Ctrl+A, D
    - to rename screen session from inside of it: Ctrl+A, Shift+A - and enter it's name.
    - to kill current screen session: exit or Ctrl+A
    - to kill all screen sessions: Ctrl+A,\

  • Edit .bashrc file to make terminal window a bit more helpful:
    nano ~/.bashrc
  • Append these lines to the end of it:
    export PS1="\[\e[32;1m\]\u\[\e[0m\]\[\e[32m\]@\h\[\e[36m\]\w \[\e[33m\]\$ \[\e[0m\]"
    alias ll="ls -la"
    alias a2r="sudo /etc/init.d/apache2 stop && sleep 2 && sudo /etc/init.d/apache2 start"
    alias n2r="sudo /etc/init.d/nginx stop && sleep 2 && sudo /etc/init.d/nginx start"
    alias ver="cat /etc/lsb-release"
    Save and exit.

  • Reload .bashrc to make changes active:
    source ~/.bashrc
  • Update sources: sudo aptitude update
  • Set system locale:
    sudo locale-gen en_US.UTF-8
    sudo /usr/sbin/update-locale LANG=en_US.UTF-8
  • Upgrade system now:
    sudo aptitude -y safe-upgrade
    sudo aptitude -y full-upgrade
Install PHP 5, Build Essentials and related libraries
  • Install Build essentials:
    sudo aptitude -y install build-essential
  • Install PHP with php client and without apache (one long line):
    sudo aptitude -y install php5-common php5-dev php5-mysql php5-sqlite php5-tidy php5-xmlrpc php5-xsl php5-cgi php5-mcrypt php5-curl php5-gd php5-memcache php5-mhash php5-pspell php5-snmp php5-sqlite libmagick9-dev php5-cli
  • Fix issues with imagick:
    sudo aptitude -y install make php-pear
    sudo pecl install imagick
    (Just press <ENTER> at prompt)

  • Adjust php.ini:
    sudo nano /etc/php5/cgi/php.ini Adjust memory limit to accomodate Wordpress requirements:
    Find line:
    memory_limit = 16M and change it to: memory_limit = 48M

    Append to the end of this file this line:
    extension=imagick.so

  • Install MySQL server, secure it and create database for wordpress (or other dynamic web app you will be using)
    sudo aptitude -y install mysql-server mysql-client libmysqlclient15-devSecure MySQL server:
    mysql_secure_installation
  • Install subversion (best to install and upgrade wordpress is via subversion):
    sudo aptitude -y install subversion
Install Postfix to prepare e-mail capabilities for your web application
  • First - login into slicemanager at manage.slicehost.com, click "DNS" tab and "Reverse DNS".
    Replace record with: mail.mydomain.com.
  • sudo nano /etc/hostname Replace slicename with mail.mydomain.com

  • sudo nano /etc/hosts
    Replace 127.0.0.1 slicename with 127.0.0.1 mail.mydomain.com
  • Reboot slice:
    sudo reboot
  • When rebooted - check slice hostname (it must be mail.mydomain.com):
    hostname -f
  • Install dns utils and check RDNS (by using your slice's IP address)
    sudo aptitude -y install dnsutils
  • Check if RDNS propagated already:
    dig -x 123.45.6.78
    If "ANSWER SECTION" still shows old name (or anytihng other than mail.mydomain.com) - you'll have to wait until propagation will finish before proceeding.
  • sudo aptitude -y install postfix telnet mailx Select "Internet Site", and then for "System mail name:" -> "mail.mydomain.com".
  • Redirect all email destined to 'root' toward 'jsmith':
    sudo nano /etc/aliasesAppend this line to the end of file:
    root: jsmith
  • Refresh aliases database now:
    sudo newaliases
  • Edit main.cf file:
    sudo nano /etc/postfix/main.cf
    - Replace: myorigin = /etc/mailname
    - with this: myorigin = $mydomain

    - Replace this: mydestination = mail.mydomain.com, localhost.mydomain.com, , localhost
    - with this: mydestination = $mydomain, localhost.$mydomain, localhost

    - Replace this: mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
    - with this: mynetworks = 127.0.0.0/8

  • Restart postfix to make changes take effect: sudo /etc/init.d/postfix restart
  • Test email sending capabilities. Run little php console prog to do it. Check if you receive email message.
    php -a
    mail ('your@email.com', "Hello from slice!", "My email setup works!");
    exit ();
  • Follow this article if you want to setup postfix to receive emails as well (opening port 25 in firewall and configuring stuff):
    But what we've done already is enough to have hosted portal with full outgoing email capabilities.
Install and configure NGINX
  • Install NGINX. Dependencies first. Check sysoev.ru website first for newer versions though.
    sudo aptitude -y install libpcre3 libpcre3-dev libpcrecpp0 libssl-dev zlib1g-dev
    mkdir ~/sources
    cd ~/sources/
    wget http://sysoev.ru/nginx/nginx-0.6.32.tar.gz
    tar -zxvf nginx-0.6.32.tar.gz
    cd nginx-0.6.32
    ./configure --sbin-path=/usr/local/sbin --with-http_ssl_module
    make
    sudo make install
  • Start Nginx:
    sudo /usr/local/sbin/nginx
  • Navigate to your slice's IP address to test that it works: http://123.45.6.78
  • Stop Nginx:
    sudo kill `cat /usr/local/nginx/logs/nginx.pid`
  • Create NGINX init script
    sudo nano /etc/init.d/nginx Copy/paste this text into it:
    #! /bin/sh
    
    ### BEGIN INIT INFO
    # Provides:          nginx
    # Required-Start:    $all
    # Required-Stop:     $all
    # Default-Start:     2 3 4 5
    # Default-Stop:      0 1 6
    # Short-Description: starts the nginx web server
    # Description:       starts nginx using start-stop-daemon
    ### END INIT INFO
    
    PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
    
    
    
    
    
    DAEMON=/usr/local/sbin/nginx
    NAME=nginx
    DESC=nginx
    
    test -x $DAEMON || exit 0
    
    # Include nginx defaults if available
    if [ -f /etc/default/nginx ] ; then
            . /etc/default/nginx
    fi
    
    set -e
    
    case "$1" in
      start)
            echo -n "Starting $DESC: "
            start-stop-daemon --start --quiet --pidfile /usr/local/nginx/logs/$NAME.pid \
                    --exec $DAEMON -- $DAEMON_OPTS
            echo "$NAME."
            ;;
      stop)
            echo -n "Stopping $DESC: "
            start-stop-daemon --stop --quiet --pidfile /usr/local/nginx/logs/$NAME.pid \
                    --exec $DAEMON
            echo "$NAME."
            ;;
    
      restart|force-reload)
            echo -n "Restarting $DESC: "
            start-stop-daemon --stop --quiet --pidfile \
                    /usr/local/nginx/logs/$NAME.pid --exec $DAEMON
            sleep 1
            start-stop-daemon --start --quiet --pidfile \
                    /usr/local/nginx/logs/$NAME.pid --exec $DAEMON -- $DAEMON_OPTS
            echo "$NAME."
            ;;
      reload)
          echo -n "Reloading $DESC configuration: "
          start-stop-daemon --stop --signal HUP --quiet --pidfile /usr/local/nginx/logs/$NAME.pid \
              --exec $DAEMON
          echo "$NAME."
          ;;
      *)
            N=/etc/init.d/$NAME
            echo "Usage: $N {start|stop|restart|reload|force-reload}" >&2
            exit 1
            ;;
    esac
    
    exit 0
    
  • Set it executable:
    sudo chmod +x /etc/init.d/nginx
  • Add it to the default run levels:
    sudo /usr/sbin/update-rc.d -f nginx defaults
  • Create folder layout:
    sudo mkdir /usr/local/nginx/sites-available
    sudo mkdir /usr/local/nginx/sites-enabled
  • Adjust main NGINX configuration file to look in sites-enabled folder for vhosts: sudo nano /usr/local/nginx/conf/nginx.conf Delete all contents of this file and replace it with this:
    user www-data www-data;
    worker_processes  4;
    
    events {
        worker_connections  1024;
    }
    
    http {
        include       mime.types;
        default_type  application/octet-stream;
    
        sendfile        on;
        tcp_nopush      on;
        tcp_nodelay     off;
        keepalive_timeout  5;
    
        gzip  on;
        gzip_comp_level 2;
        gzip_proxied any;
        gzip_types      text/plain text/html text/css application/x-javascript text/xml application/xml
        application/xml+rss text/javascript;
    
        include /usr/local/nginx/sites-enabled/*;
    }
        

  • Create default vhost in 'sites-available' folder:
    sudo nano /usr/local/nginx/sites-available/defaultCopy/paste this text into it:
    server {
        listen       80;
        server_name  localhost;
    
        location / {
            root   html;
            index  index.php index.html index.htm;
        }
    
    
        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    
    }
    
  • Enable vhost by creating symlink:
    sudo ln -s /usr/local/nginx/sites-available/mydomain.com /usr/local/nginx/sites-enabled/mydomain.com
  • Start NGINX:
    sudo /etc/init.d/nginx start Make sure that navigating to slice IP will show "Welcome to nginx!" default page.

  • Create layouts for domains to be served.
    sudo mkdir /home/public_html
    sudo mkdir -p /home/public_html/mydomain.com/{public,private,log,backup}
  • Setup users and groups to manage portal:
    sudo -i
    addgroup webmasters
    usermod -G webmasters jsmith
    OPTIONAL: Do it for every user who will be allowed to manage files for the portal:
    usermod -G webmasters user_2
    usermod -G webmasters user_3
    Change ownership of main web files directory:
    chown -R jsmith.webmasters /home/public_html
    chmod -R g+w /home/public_html
    Set group id to 'webmasters' for all newly created files and dirs.
    find /home/public_html -type d -exec chmod g+s {} \;
    exit
  • Create initial index.html file for the domain:
    sudo nano /home/public_html/mydomain.com/public/index.phpPaste this into the file:
    <?php echo phpinfo(); ?>        
    First - create supporting wordpress-specific configuration files. 'wordpress_params.regular' - is basic wordpress config file that allows support for nice permalinks.
    sudo nano /usr/local/nginx/conf/wordpress_params.regular...And paste into it the following contents:
      # WordPress pretty URLs: (as per dominiek.com)
      if (-f $request_filename) {
      break;
      }
      if (-d $request_filename) {
      break;
      }
      rewrite ^(.+)$ /index.php?q=$1 last;
    
    
      # Enable nice permalinks for WordPress: (as per Yawn.it)
      error_page  404  = //index.php?q=$uri;
    
    
    Save and exit.
    Next - create second version of NGinx-specific Wordpress config file that allows support for nice permalinks + WP Super Cache plugin. WP Super Caching gives you extra horse power and juice to handle intense traffic and getting your portal seriously ready to be DIGG-ed.
    sudo nano /usr/local/nginx/conf/wordpress_params.super_cache...And paste into it the following contents (Credits: Matt Stevens):
    # if the requested file exists, return it immediately
    if (-f $request_filename) {
    break;
    }
    
    set $supercache_file '';
    set $supercache_uri $request_uri;
    
    if ($request_method = POST) {
    set $supercache_uri '';
    }
    
    # Using pretty permalinks, so bypass the cache for any query string
    if ($query_string) {
    set $supercache_uri '';
    }
    
    if ($http_cookie ~* "comment_author_|wordpress|wp-postpass_" ) {
    set $supercache_uri '';
    }
    
    # if we haven't bypassed the cache, specify our supercache file
    if ($supercache_uri ~ ^(.+)$) {
    set $supercache_file /wp-content/cache/supercache/$http_host/$1index.html;
    }
    
    # only rewrite to the supercache file if it actually exists
    if (-f $document_root$supercache_file) {
    rewrite ^(.*)$ $supercache_file break;
    }
    
    # all other requests go to Wordpress
    if (!-e $request_filename) {
    rewrite . /index.php last;
    }
    
    
    Create vhost for domain mydomain.com:
    sudo nano /usr/local/nginx/sites-available/mydomain.com...And paste into it the following contents:
    server {
    
                listen   80;
                server_name  mydomain.com;
                rewrite ^/(.*) http://www.mydomain.com/$1 permanent;
    
               }
    
    
    server {
    
                listen   80;
                server_name www.mydomain.com;
    
                access_log /home/public_html/mydomain.com/log/access.log;
                error_log /home/public_html/mydomain.com/log/error.log;
    
                location / {
    
                            root   /home/public_html/mydomain.com/public/;
                            index  index.php index.html;
    
                            # Basic version of Wordpress parameters, supporting nice permalinks.
                            # include /usr/local/nginx/conf/wordpress_params.regular;
                            # Advanced version of Wordpress parameters supporting nice permalinks and WP Super Cache plugin
                            include /usr/local/nginx/conf/wordpress_params.super_cache;
                            }
    
                # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
                #
                location ~ \.php$ {
                fastcgi_pass 127.0.0.1:9000;
                fastcgi_index index.php;
                include /usr/local/nginx/conf/fastcgi_params;
                fastcgi_param SCRIPT_FILENAME /home/public_html/mydomain.com/public/$fastcgi_script_name;
                }
          }
       
      
    Above will append 'www' to all non-www requests - all requests for http://mydomain.com/dir/page will be redirected to -> http://www.mydomain.com/dir/page.
    As you can also see above we enabled 'wordpress_params.super_cache' settings. If for some reason you'll have problems - you may comment ' ....wordpress_params.super_cache' line out, disable wordpress WP Super Cache plugin via Wordpress admin panel and uncomment '...wordpress_params.regular' settings (+restart Nginx). From my own test - they both works with or without WP Super Cache enabled and I'd definitely prefer WP Super Cache to be up and running.
  • Enable site:
    sudo ln -s /usr/local/nginx/sites-available/mydomain.com /usr/local/nginx/sites-enabled/mydomain.com
  • Making NGinx to serve PHP and make it all start automatically after system restart (Credits):
    sudo aptitude -y install libfcgi0
    cd /etc/default/
    sudo wget -O php-fastcgi http://www.mensk.com/uploads/php-fastcgi.txt
    cd /etc/init.d/
    sudo wget -O php-fastcgi http://www.mensk.com/uploads/php-fastcgi.rc.txt
    sudo chmod +x php-fastcgi
    sudo /usr/sbin/update-rc.d -f php-fastcgi defaults
    sudo /etc/init.d/php-fastcgi start
    Restart NGINX:
    n2r (or sudo /etc/init.d/nginx stop, sudo /etc/init.d/nginx start)

  • Navigate to your website: http://mydomain.com you should be redirected to http://www.mydomain.com and then see phpinfo() screen...
  • Reboot your slice and make sure that after restart everything still works (NGINX & Co restarts properly)
    sudo reboot
Install and configure Wordpress + configure WP Super Cache Wordpress plugin to work with NGINX
  • Install Wordpress. Login to mysql console as mysql's root user: mysql -u root -p
  • Issue this command to create new username for Wordpress database (replace username, password and database name with your values):
    mysql> grant all privileges on *.* to wp_user@localhost identified by "wp_pa55w0rd";
    mysql> create database wp_dbase;
    mysql> quit
  • Get Wordpress files directly from SVN repository. See this great article about using subversion to install and update Wordpress.
    cd /home/public_html/mydomain.com/public
    sudo rm index.php
    svn co http://svn.automattic.com/wordpress/tags/2.6 .
    mv wp-config-sample.php wp-config.php
    sudo nano wp-config.php
    Set database name, DB user name and password, Change DB prefix to something different (good security measure), save and exit.

  • Adjust permissions:
    sudo chmod -R 777 /home/public_html/mydomain.com/public/wp-content
    sudo chmod 666 /home/public_html/mydomain.com/public/wp-config.php
  • Access your site: http://www.mydomain.com/
    - Enter blog name, remember the password that wordpress gave you.
    - Login as admin/password
    - Click Users tab at upper right in admin panel
    - Click on 'admin' user
    - Change password to something secure and you'd remember.
    - Logoff, Logon again with your new password.
    - Goto Settings->Permalinks
    - Set (x) "Custom Structure" -> /%category%/%postname%/, [Save Changes], ignore Wordpress warning: "You should update your .htaccess now." - it cannot find .htaccess - we are not running apache.
    - Access your blog's "About" page - and voila - it should work just fine as this: http://www.mydomain.com/about/ (instead of default ugly: http://www.mydomain.com/?p=123)
  • Download and unzip WP Super Cache plugin into '/home/public_html/mydomain.com/public/wp-content/plugins' directory. Activate it via Admin panel.
    For FTP-ing purposes I use FileZilla configured to use SFTP. (I don't elaborate on specifics of installing and activating Wordpress plugins in this document).
    - Goto Plugins, activate "WP Super Cache".
    - Goto Settings->WP Super Cache and set (x) WP Super Cache Status to "ON". [Update Status].
    You'll see bunch of warnings on this page regarding "mod rewrite" rules and ".htaccess" file. Just ignore these - we are not using Apache so WP Super Cache cannot find apache specific places to write settings. We did it for WP Super Cache already inside of 'wordpress_params.super_cache' - which contains "translation" of caching rules from Apache to Nginx.
    Your WP Super Cache-ed blog should be up and running now at fullest speed.
  • Make 'wp-content' directory a bit more secure: sudo chmod -R 755 /home/public_html/mydomain.com/public/wp-content - Goto Manage->Categories. Create few categories with subcategories.
    - Goto Write->Post - create few posts and assign them to subcategory, publish, save.
    - Access your posts - and see that they all have nice SEO-friendly URLs, thanks to custom wordpress-specific setups we included in our '/usr/local/nginx/sites-available/mydomain.com' file.
    - This also works just fine with John Godley's excellent redirection plugin that supports flexible custom redirects with regular expressions.
  • Customize your theme and go wild!
Done!

Comments

48 Responses to “Perfect Setup: Ubuntu Hardy+Nginx+MySQL5+PHP5+Wordress”

  1. Tony on August 14th, 2008 12:07 pm

    How does one go about setting up the iptables to allow postfix to work for email?

  2. admin on August 14th, 2008 12:16 pm

    Here’s the SliceHost’s article on exactly this subject:
    http://articles.slicehost.com/2008/8/1/postfix-mx-records-and-receiving-emails
    I think I might add this info to this article as well eventually.

    Gleb

  3. Tony on August 14th, 2008 1:07 pm

    When you have this line:

    - Replace: myorigin = /etc/mailname
    - with this: myorigin = $mydomain

    Do you actually mean replace it with the variable “$mydomain” or to actually put “$yahoo.com” or even just “yahoo.com” without the $ if my domain is yahoo.com

  4. admin on August 14th, 2008 1:46 pm

    Good question - actually in this case it has to be used as is, no substitution needed. Regardless of your actual domain - this text line will have “$mydomain”.
    I guess i should of come up with more clear “generic” domain, like: ‘myhotsite.com’ or something.

    Here is the source for these detailed postfix configurations:
    http://articles.slicehost.com/2008/7/31/postfix-basic-settings-in-main-cf

    Gleb

  5. SliceHost « So be IT on August 16th, 2008 11:56 am

    [...] hecho, he encontrado este manual sobre como instalar WordPress (usando nginx, una versión ligera de Apache muy eficiente) en Slicehost, incluyendo los pasos para [...]

  6. Scott Motte » Blog Archive » Slicehost, nginx, mysql, php, wordpress setup on August 17th, 2008 1:52 pm

    [...] Detailed tutorial on nginx, mysql, php, wordpress setup. [...]

  7. windexh8er on August 23rd, 2008 1:52 pm

    So… I’m confused. Why do you do this:

    sudo ln -s /usr/local/nginx/sites-available/mydomain.com /usr/local/nginx/sites-enabled/mydomain.com

    When you’re not linking to anything at this point? Since there’s nothing in /usr/local/nginx/sites-available at that point in time you just end up with a broken symlink?!?!

    Thx…

  8. admin on August 23rd, 2008 2:47 pm

    I guess I have 2 places where I do that - first one is not necessary - second is done after mydomain.com files are created. So I guess you’re right - first one could be eliminated…

    Gleb

  9. windexh8er on August 23rd, 2008 2:50 pm

    Also, can you post the actual files for the FastCGI? The host that you are referencing in the doc is not valid anymore…

    Thanks!

    ( i.e. http://zhware.net/files/nginx/* )

  10. admin on August 23rd, 2008 3:01 pm

    …that’s why I never liked referring to too many other sites. It’s prone to get broken. I love having everything in one place.
    Thanks for catch - fixed - files now at mensk.com - reload the page and check for new urls:
    http://www.mensk.com/uploads/php-fastcgi.rc.txt
    http://www.mensk.com/uploads/php-fastcgi.txt

    Gleb

  11. windexh8er on August 23rd, 2008 4:12 pm

    Thanks for the fast update! :)

    Another question for you… I thought it might be due to because of the locale stuff at the beginning, because I’ve never seen this before, but whenever I paste anything into vi / nano during following the instructions a quote (”) will appear as ( ?~@~\ ) in VI and as something else in nano. Very odd.. Even if I create the file locally on my Mac in something like TextMate (file encoding is UTF8 and LF for line endings) and SCP it over… I have never seen that and have no idea why it would be doing it.

    I’m using SliceHost as well with the 8.04.1 fresh build.

    Thoughts?
    TIA!
    –windexh8er

  12. windexh8er on August 23rd, 2008 5:12 pm

    And one more thing you might want to update to the 2.6.1 trunk since it’s stable:

    http://svn.automattic.com/wordpress/tags/2.6.1/

  13. Bob on August 25th, 2008 1:15 am

    Mersi boku. Good idea. I’ll become your regular visitor and RSS subscriber.

  14. clidiot on August 25th, 2008 3:50 am

    Thank you for putting this together. When I get a few hours to try it out, I’m going to grab a new 256 slice and give it a shot.

  15. boni on September 2nd, 2008 2:27 am

    Hi,
    Great tutorial. Followed your instruction and everythings worked fine for line 20 minutes and then php-cgi died. Tried reboot, but no success and when I restart it on the command line, still nginx does not pick it up. The only way am able to run it is more like in a debug mode. First kill all the php-cgi and then run

    /usr/bin/php-cgi -q -b localhost:9000

    on the consoles. The site comes up, but again dies traffic start building up?

    What could I have missed?

    Thanks

  16. boni on September 2nd, 2008 5:41 am

    Hi again,

    Finally solved my problem. The problem pointed http://www.mensk.com/uploads/php-fastcgi.rc.txt.. Right at the end there is a : after last esac. I think this was causing the script not to execute properly. Removed it and now everything works fine. This could explain why my site would be up after manual start of php-cgi and then die. My theory is that php-cgi would shut down when there are no requests and then when a request comes it would try to be started using the script but fail. That is what I suspected happened. Hope that helps somebody. Great thanks to the guys in slicehost chat rooms who helped me walk through all these scripts. Its nice that you get real tech people there who can help when it really matters

  17. revelnick on September 3rd, 2008 2:59 pm

    good tutorial, its like having a lot of great tutorials on a single page.

    where you have this {
    Enable vhost by creating symlink:
    sudo ln -s /usr/local/nginx/sites-available/mydomain.com /usr/local/nginx/sites-enabled/mydomain.com
    }

    it should probably be {
    Enable vhost by creating symlink:
    sudo ln -s /usr/local/nginx/sites-available/default /usr/local/nginx/sites-enabled/default
    }

    Then in the next step when you restart nginx, it will use the default configuration created in the previous step.

    @windexh8er - that’s the source of confusion

  18. windexh8er on September 9th, 2008 11:16 am

    @revelnick — yeah, it just didn’t make any sense to me at the time because I didn’t go further down in the instructions.

    @admin — another question for you. With this setup if you enable:

    define(’FORCE_SSL_ADMIN’, true);

    …and then try to go to the wp-admin page you end up with an endless loop. Any thoughts on why this is? I tried a variety of changes to nginx to no avail. :(

  19. friebly on September 23rd, 2008 6:52 pm

    Could you use a similar method to install Wordpress MU?

  20. admin on September 24th, 2008 1:01 am

    Not sure about MU. The main “issue” with using NGinx + Wordpress in general is that some plugins that use redirection, rewriting or otherwise based on Apache functionality will stop working. This is something to consider before migrating business to Nginx-based setup.

    Gleb

  21. friebly on September 24th, 2008 1:59 pm

    I found a tutorial here http://wpmu.org/nginx-wordpress-26/ that has a different nginx.conf file. Would I use it together with yours, or do you think I would put that into my websites vhost? It looks closer to what you said to put into the vhost but it says to put it in the nginx.conf.

  22. builder2 » Slicehost VPS Hosting on October 16th, 2008 1:39 pm

    [...] got my VPS running in just a few hours or so by using this excellent guide from MENSK Technologies Corporation, it was good enough for my needs with just the bare essentials: PHP, MySQL, Nginx. Yes, I opted to [...]

  23. Nahum Wild on October 22nd, 2008 6:39 pm

    Great post thanks, saved me heaps of time. One thing I did different was update the ngnix site conf to add expire headers to static assets, like what they are doing at the site that friebly has posted about - but I didn’t see that until just now!

    I’ve posted the whole conf to my blog - http://www.motionstandingstill.com, but all I really did was add the following location section and made sure that the ‘root’ clause specified before this.

    location ~* i.+\.(css|js|jpg|jpeg|gif|png)$
    {
    expires 7d;
    }

  24. Andrew Dedman on October 23rd, 2008 7:54 am

    Thanks very much, worked perfectly : )

  25. clidiot on November 2nd, 2008 9:59 pm

    PHEW!

    After hours and hours of running this around and around, I tracked down a problem that was driving me insane. The config file posted has a redirect to add the www to every incoming request. My existing blog database, however, has the blog home URL listed without the http://www. When I got everything up and running, every incoming request would head into an infinite redirect loop between domain.com and http://www.domain.com.

    Thank you for dropping this all together in one place. Very useful.

  26. grradmin on November 5th, 2008 4:02 pm

    I’m having possibly the same issue as clidiot above me was talking about. Everything is fine as long as I have Apache + Wordpress on the same slice. But as soon as I use the config on this page and through nginx into the mix it results in a redirect loop. Firefox says “Redirect Loop - Firefox has detected that the server is redirecting the request for this address in a way that will never complete”. I don’t use http://www.domain.com as my blog’s URL, it is http://domain.com instead. I’ve gone through the redirect rules and I don’t see where it’s adding that http://www. though :(

  27. philwilson.org » Blog Archive » Mai blog! It is back! on November 18th, 2008 6:49 pm

    [...] being served from Apache+mod_php to Nginx+fastcgi (in particular I followed these instructions: Perfect Setup: Ubuntu Hardy+Nginx+MySQL5+PHP5+Wordress). I learnt a few things, although I’m sure most lessons will become apparent over the coming [...]

  28. Mikhailov Anatoly on December 6th, 2008 12:28 pm

    It’s wonderful article.! Great Thanks

  29. Handy guide for getting PHP working unde … « Paul M. Watson on January 16th, 2009 3:38 pm

    [...] pm on January 16, 2009 | # | Tags: dev Handy guide for getting PHP working under NGINX. Needed this page though to get the fastcgi_params file. [...]

  30. SliceHost 迁移完毕 « 刀枪Blue on January 17th, 2009 5:07 am

    [...] 经历了点波折,不过总算完成。绝大部分 setup 可以参考 Ubuntu Hardy+Nginx+MySQL5+PHP5+Wordress。 [...]

  31. John Agan on January 30th, 2009 11:32 pm

    I love you man!!

    Thank you so much for this!

  32. Chris on February 3rd, 2009 9:14 pm

    THANKS!!!!!!!

    Although for some reason I couldn’t get the same configuration to work with php-fpm, and for the life of me didn’t know why. This works just as well though so am stoked. Thanks for taking the time to document it all.

  33. Chris on February 3rd, 2009 11:17 pm

    You could also add xcache to speed things up even more:

    cd ~/sources
    wget http://xcache.lighttpd.net/pub/Releases/1.2.2/xcache-1.2.2.tar.gz
    tar xzvf xcache-1.2.2.tar.gz
    cd xcache-1.2.2
    phpize
    ./configure –with-php-config=/usr/local/bin/php-config –enable-xcache
    make install

    sudo nano /etc/php5/cgi/php.ini

    Add line

    extension=xcache.so

    to the end of the file.

    You can also edit /etc/php5/cli/php.ini as well.

  34. Chris on February 3rd, 2009 11:32 pm

    Last comment -

    php.ini edits possibly more like this:

    [xcache-common]
    zend_extension = /usr/lib/php5/20060613+lfs/xcache.so
    [xcache]
    xcache.shm_scheme = “mmap”
    xcache.size = 64M

    The directory to xcache.so is output when you run make install above.

    You can check it is running using phpinfo() in a script or “php -v” from command line (you need to edit the cli php.ini also) if you run php -v you should see:

    Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies
    with XCache v1.2.2, Copyright (c) 2005-2007, by mOo

  35. Setting Up The Blog On SliceHost | Agan on February 3rd, 2009 11:43 pm

    [...] so you can setup anything you want. Me personally, I needed a WordPress / Rails slice. I found this article by MENSK Technologies a very useful starting [...]

  36. Wordpress / NGINX / XCACHE / PHP5 / MYSQL on Ubuntu Hardy 8.04LTS - happybelly on February 5th, 2009 2:28 am

    [...] Great documentation for nginx setup suitable for small VPS. See my comments at bottom to add xcache as well. Added by happybelly, on February 3, 2009.Sections: Uncategorized. Post a comment or leave a trackback: Trackback URL. « NGINX + PHP-FPM + XCACHE on Ubuntu 8.04 LTS [...]

  37. Nielsvz.com » Blog Archive » Nginx awesomeness on February 5th, 2009 7:17 am

    [...] Perfect Setup: Ubuntu Hardy+Nginx+MySQL5+Wordpress [...]

  38. Gunnar on February 21st, 2009 1:17 pm

    Btw, if you just want to use postfix to send mail from PHP, there’s no need to install it, just use gmail :P

  39. Setting up Wordpress on Slicehost | Abstrakce on February 23rd, 2009 3:44 pm

    [...] And I would not have succeded without this extremely helpful article : http://www.mensk.com/webmaster-toolbox/perfect-ubuntu-hardy-nginx-mysql5-php5-wordpress/ [...]

  40. MarcRue on February 25th, 2009 11:28 am

    I’m curious about how many connections or petitions/second can handle your setup in slicehost, did anyone try how well it performances?

  41. the_guv on March 11th, 2009 7:41 pm

    @MarcRue - “50,000 simultaneous connections have been reported,” according to the nginx wiki, http://wiki.codemongers.com/NginxGettingStarted.

    Admin - why hide behind a title? You’re a ruddy hero! And a big cheers to PickedOnion too, John, Matt, the blessed Russian and everyone who made my week so much fun doing this.

    Wow - can’t wait to get off the shared host…just the email to go…

  42. Cal on March 21st, 2009 11:00 am

    amazing!!
    thanks for this intro!! i would never every have figured out how to do this by myself!”!

  43. Sonny on March 23rd, 2009 10:10 am

    When you do -

    sudo ln -s /usr/local/nginx/sites-available/mydomain.com /usr/local/nginx/sites-enabled/mydomain.com

    the first time, did you instead mean to create a symlink to /usr/local/nginx/sites-available/default ?

    Because, otherwise navigating to the slice IP after that point results in a connection refused error.

    I can’t thank you enough for writing this guide. It made my day. Getting the Nginx up and running the very first time was a beautiful feeling :)

    Cheers.

  44. Wordpress @ Slicehost - Sudarshan Acharya on March 25th, 2009 11:47 pm

    [...] get it up and running in about an hour with all the content migrated. When there are documents like Mensk.com and Slicehost Articles, you really don’t have anything left to [...]

  45. Linux tips | builder2 on March 26th, 2009 12:49 pm

    [...] Perfect Setup: Ubuntu Hardy+Nginx+MySQL5+PHP5+WordPress [...]

  46. Perfect Setup: Ubuntu Hardy+Nginx+MySQL5+PHP5+Wordress | MENSK Technologies Corporation on April 28th, 2009 9:25 am

    [...] More: Perfect Setup: Ubuntu Hardy+Nginx+MySQL5+PHP5+Wordress | MENSK Technologies Corporation [...]

  47. Vinod on May 26th, 2009 9:23 am

    Thank you very much for the detailed instructions. I could move my blog faster to slicehost with your instructions.
    Cheers.

  48. Nginx awesomeness - Flapdrol.com on June 30th, 2009 5:37 pm

    [...] up Nginx, PHP5, MySQL5 and WordPress was pretty easy after reading these articles:Perfect Setup: Ubuntu Hardy+Nginx+MySQL5+WordpressInstalling Nginx with PHP5 and MySQL support on Ubuntu 8.10ApacheBenchUsing ApacheBench i’ve tested [...]

Feel free to leave a comment...
and oh, if you want a pic to show with your comment, go get a gravatar!





Bottom