How I Migrated From Apache to NGINX

Steps to Migrating from Apache2 to NGINX

First, we will install NGINX and PHP-FPM:

sudo apt-get install nginx php5-fpm

Next, we will need to update the PHP-FPM config at /etc/php5/fpm/pool.d/www.conf

sudo nano /etc/php5/fpm/pool.d/www.conf

My server has 4 cores, so this is what my www.conf file looks like:

user              www-data;
worker_processes  4;
worker_cpu_affinity 0001 0010 0100 1000;
error_log         /var/log/nginx/error.log;
pid               /var/run/nginx.pid;

events {
    worker_connections  2048;
}

http {
    include     /etc/nginx/mime.types;
    access_log  /var/log/nginx/access.log;

    sendfile            on;
    tcp_nopush          on;
    keepalive_timeout   5;
    tcp_nodelay         on;
    server_tokens       off;

    gzip          on;
    gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;
    gzip_disable  "MSIE [1-6]\.(?!.*SV1)";

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

After making the changes to PHP-FPM we will need to restart the service:

sudo /etc/init.d/php5-fpm restart

Now we can setup our NGINX config at /etc/nginx/nginx.conf

sudo nano /etc/nginx/nginx.conf

Configurations will vary based on your server and web site, but these setting worked for me, find and change these values in the nginx.conf file:

pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
pm.max_requests = 100
php_admin_value[memory_limit] = 128M

Note: Be sure and remove any leading semicolons (;)

After NGINX is configured, restart the service:

sudo /etc/init.d/nginx restart

Creating the Domain Configuration Files in NGINX

In Apache, any domains that are hosted on the server are configured in “/etc/apache2/sites-available/“, and NGINX has its equivalent configuration files in “/etc/nginx/sites-available/“, so the next step is to create those new files in the NGINX directory. I am running WordPress websites on my server, so this is what works best for me:

server {
    listen       80;
    server_name  [domain.com] *.[domain.com];
    root         /var/www/[domain.com]/public;
 
    access_log   /var/www/[domain.com]/log/access.log;
    error_log    /var/www/[domain.com]/log/error.log;
 
    location / {
        index index.php;
        try_files $uri $uri/ /index.php?q=$uri&$args;
    }
 
    # Add trailing slash to */wp-admin requests.
    rewrite /wp-admin$ $scheme://$host$uri/ permanent;
 
    # Directives to send expires headers and turn off 404 error logging.
    location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
        expires 24h;
        log_not_found off;
    }
 
    # this prevents hidden files (beginning with a period) from being served
    location ~ /\.          { access_log off; log_not_found off; deny all; }
 
    location ~ \.php$ {
        client_max_body_size 25M;
        try_files      $uri =404;
        fastcgi_pass   unix:/var/run/php5-fpm.sock;
        fastcgi_index  index.php;
        include        /etc/nginx/fastcgi_params;
    }
    
    #Once the w3-total.conf file is ready uncomment out the line below
    #include w3-total.conf;
}

Once the config files in the sites-available directory are ready, we just need to “publish” the sites to the web by creating a symlink to the file from the “sites-enabled” directory:

sudo ln -s /etc/nginx/sites-available/[domain.com] /etc/nginx/sites-enabled/[domain.com]

After we have updated our site configurations, we will stop Apache and restart NGINX:

service apache2 stop
sudo /etc/init.d/nginx restart

Removing Apache

Once we are confidant that NGINX is running and apache is no longer needed, we will simply remove Apache from our web server.

sudo apt-get remove apache2*

References
http://articles.slicehost.com/2008/5/16/ubuntu-hardy-nginx-virtual-hosts/
http://evansolomon.me/notes/faster-wordpress-multisite-nginx-batcache/

Creating a Dedicated Memcached Server on Rackspace Cloud Servers

This tutorial will step us through the creation of a Memcached server on Rackspace cloud servers.  The ultimate goal will be to have a dedicated Memcached server which will be accessed by multiple web servers that are load balanced in a Rackspace cloud hosting environment.

There are a few reasons to set up a dedicated Memcached server:

  • Performance: We will custom-prepare the server for running Memcached, not web pages, this server will serve as a shared caching environment across all of our web servers
  • Scale: We will be able to scale our web site or web application quickly by adding additional web servers behind a load balancer, without having to worry about our caching server

Creating the New Server

  1. Log into our Rackspace cloud account at https://mycloud.rackspace.com/, and click on the “Servers” tab in the primary navigation menu
  2. Once the “Servers” page has loaded, click on the “Create Server” button
  3. Once the form loads, start by naming our new server “Memcached
  4. Under the “Regions” drop-down, Look for the “First Generation Servers” and select the “Dallas (DFW)” option
  5. Under the “Image” heading, select the “Ubuntu 12.04 LTS” operating system
  6. Under the “Flavor” heading, select top option, which is “512 MB RAM / 20 GB Storage” (If at some point our websites require additional caching resources, we can scale up the RAM and disk space)
  7. Finally, click on the “Create Server” button at the bottom of the form
  8. Save the password that Rackspace issues, we will use it to login and configure our server in the next section of this tutorial

When the server is done being built, we will be able to access the new server from the “Servers” tab in our Rackspace Cloud account.  Rackspace will assign two IP address to our server.  One is called the “PublicNet” IP address, that is the external IP address used accessing our server from the Internet.  The other is the “ServiceNet” IP address, this is the internal Rackspace IP address that our web servers will be accessing.

Configuring the Memcached Server

We are now ready to access our new server.  To log in to our server, we will need to use the secure shell (SSH) protocol. Open a SSH terminal window and enter the following command, inserting the PublicNet IP corresponding to the server.  When prompted, use the password Rackspace issued for our server in the previous step.

ssh root@[PublicNet IP Address]

Type yes to verify the identity of our Cloud Server. This will prompt an RSA key to be stored in our computer’s list of known hosts. This message will not be presented upon subsequent logins.

We need to check for the latest versions of Ubuntu’s installed packages, so we need to make a list of what is already installed. To do this we will run the following command:

sudo apt-get update

This command will update the package listing for the operating system to interact with and the information is cached for the Aptitude package manager to use in operating system upgrade.

We can now check for the latest version of the items in the installed packages list, enter this command:

sudo apt-get upgrade

Apt-get will prompt to review the packages. When prompted to continue, enter a capital ‘Y’. This step will take several minutes.

During the update process the OS will appear and prompt with some options, make sure to choose “Install the package maintainers version” to ensure use of the latest version of GRUB.

Once the upgrades are finished running we will reboot the server to ensure that it is running the latest and greatest version with all current packages.

sudo reboot

Next we can configure Ubuntu’s “uncomplicated firewall” (UFW).

First we’ll will turn off all ports on the server except for the specific ones we’ll need for security reasons.  We can do this by simply enabling UFW with the following command:

sudo ufw enable

We will receive a note this may disrupt SSH connections. No worries since we will open the SSH (22) port next. When prompted “Proceed with operation (y|n)”, press “y” to continue.

Now we will open the ports required for Memcached (11211) and SSH (22) with the following commands:

sudo ufw allow 11211
sudo ufw allow 22

Now the firewall will only listen for connections on the ports we have specified. These ports apply to the Memcached and SSH protocols.

Installing and Configuring Memcached

Now that the Operating System has been updated and secured, we are ready to install and configure all of the software needed for running Memcached on your server. The process will not take long but it does involve several steps, start by running the following command:

sudo apt-get install mysql-server php5-mysql php5 php5-memcache php-pear memcached

Next, if you do not have a compiler on your server, you can download build-essential in order to install memcache:

sudo apt-get install build-essential

Finally use PECL (PHP Extension Community Library) to install memcache:

sudo pecl install memcache

We will say “yes” when prompted by pressing enter during the installation when asked if we would like to “Enable memcache session handler support? [yes] :”

Once we have completed the installation of memcache with PECL on the VPS, we will add memcached to memcache.ini:

echo "extension=memcache.so" | sudo tee /etc/php5/conf.d/memcache.ini

Adding Memcached to Web Servers

We are now ready to add Memcached to the web servers in our hosting environment by repeating the Memcached installation process on our web servers.

We will also need to make sure and update the IP Tables on our web servers to allow for Memcached traffic on port 11211.

Once Memchaced is installed, we will need to set the IP to local internal Rackspace IP address of Memcached server, to do that we will open the memcached.conf file and update the port from 127.0.0.1 to your new IP Address:

sudo nano /etc/memcached.conf

Now we will restart our Memcached service:

service memcached restart

Rinse and Repeat on All Web Servers

Install Memcached and update the config files on all the servers that are sharing the same cached files.

WordPress and W3TotalCache

If we are running a WordPress website, we can simply change the Memcached server location in the W3TotalCache config file by pointing to the internal Rackspace IP address of the Memcached server

[Path to WordPress install]/wp-content/w3tc-config/master.php

References (for more detailed information, be sure and follow these links)
https://www.digitalocean.com/community/articles/how-to-install-and-use-memcache-on-ubuntu-12-04
http://www.rackspace.com/blog/setting-up-memcached-on-cloud-servers/

cloud-db1

Creating a MySQL Database Server on Rackspace Cloud Servers

This tutorial will step us through the creation of a MySQL cloud database server on Rackspace cloud servers, we will not be using the “Rackspace Cloud Databases”.  The ultimate goal will be to have a dedicated database server which will be accessed by multiple web servers that are load balanced in a Rackspace cloud hosting environment.

There are a few reasons to set up a dedicated database server:

  • Performance: We will custom-prepare the server for running databases, not web pages
  • Security: We will keep the database off of the web server and made available to our web servers within the Rackspace private network
  • Scale: We will be able to scale our web site or web application quickly by adding additional web servers behind a load balancer, without having to worry about our database server

Creating a Rackspace Cloud Account

At this point, if you do not have an account on Rackspace, that will be your first step.  So go ahead and follow the following link and create your account.  For this tutorial, make sure and click on the box that does not include managed hosting services.
https://cart.rackspace.com/cloud/

We can now go ahead and log into our Rackspace cloud account:
https://mycloud.rackspace.com/

Creating the New Server

  1. After we have logged in, click on the “Servers” tab in the primary navigation menu
  2. Once the “Servers” page has loaded, click on the “Create Server” button
  3. Once the form loads, start by naming our new server “Database01
  4. Under the “Regions” drop-down, Look for the “First Generation Servers” and select the “Dallas (DFW)” option
  5. Under the “Image” heading, select the “Ubuntu 12.04 LTS” operating system
  6. Under the “Flavor” heading, select top option, which is “256 MB RAM / 10 GB Storage” (If at some point our database requires additional resources, we can scale up the RAM and disk space)
  7. Finally, click on the “Create Server” button at the bottom of the form
  8. Save the password that Rackspace issues, we will use it to login and configure our server in the next section of this tutorial

When the server is done being built, we will be able to access the new database server from the “Servers” tab in our Rackspace Cloud account.  Rackspace will assign two IP address to our database.  One is called the “PublicNet” IP address, that is the external IP address used accessing our server from the Internet.  The other is the “ServiceNet” IP address, this is the internal Rackspace IP address that our web servers will be accessing.

Configuring the Database Server

We are now ready to access our new server.  To log in to our server, we will need to use the secure shell (SSH) protocol. Open a SSH terminal window and enter the following command, inserting the PublicNet IP corresponding to the server.  When prompted, use the password Rackspace issued for our server in the previous step.

ssh root@[PublicNet IP Address]

Type yes to verify the identity of our Cloud Server. This will prompt an RSA key to be stored in our computer’s list of known hosts. This message will not be presented upon subsequent logins.

We need to check for the latest versions of Ubuntu’s installed packages, so we need to make a list of what is already installed. To do this we will run the following command:

sudo apt-get update

This command will update the package listing for the operating system to interact with and the information is cached for the Aptitude package manager to use in operating system upgrade.

We can now check for the latest version of the items in the installed packages list, enter this command:

sudo apt-get upgrade

Apt-get will prompt to review the packages. When prompted to continue, enter a capital ‘Y’. This step will take several minutes.

During the update process the OS will appear and prompt with some options, make sure to choose “Install the package maintainers version” to ensure use of the latest version of GRUB.

Once the upgrades are finished running we will reboot the server to ensure that it is running the latest and greatest version with all current packages.

sudo reboot

Next we can configure Ubuntu’s “uncomplicated firewall” (UFW).

First we’ll will turn off all ports on the server except for the specific ones we’ll need for security reasons.  We can do this by simply enabling UFW with the following command:

sudo ufw enable

We will receive a note this may disrupt SSH connections. No worries since we will open the SSH (22) port next. When prompted “Proceed with operation (y|n)”, press “y” to continue.

Now we will open the ports required for MySQL (3306) and SSH (22) with the following commands:

sudo ufw allow 3306
sudo ufw allow 22

Now the firewall will only listen for connections on the ports we have specified. These ports apply to the MySQL and SSH protocols.

Installing and Configuring MySQL

Now that the Operating System has been updated and secured, we are ready to install MySQL.

sudo apt-get install mysql-server mysql-client

The process will not take long but during the installation process we will be prompted to set a password for the MySQL ‘root user’. So choose a strong password and keep it in a safe place for future reference.

When the installation is complete, run the following command to secure our MySQL:

sudo mysql_secure_installation

Next we will update the MySQL config file to meet our needs (/etc/mysql/.my.cnf)

sudo nano /etc/mysql/my.cnf

We will change the following “bind-address” and “query_cache” settings:

bind-address = 127.0.0.1
...
query_cache_limit = 1M
query_cache_size = 16M

Change the above settings:

  • from “127.0.0.1” to “0.0.0.0
  • from “1M” to “2M
  • from “16M” to “32M
bind-address = 0.0.0.0
...
query_cache_limit = 2M
query_cache_size = 32M

We will now restart the MySQL service to apply all or our changes.

service mysql restart

Now we can log in to our MySQL environment and create our first database.

Log into MySQL, replace “[user]” with the database admin username.:

mysql -u [user] -p

Create the database, replace “[db_name]” with the new database name.

mysql> CREATE DATABASE [db_name];

Add a user to the database to access from any IP Address (‘%‘), this simple step ensures that any web server behind the load balancer will have access to the newly created database. Replace “[db_name]” with the name of our new database, “[user]” with the username that will be accessing this database, and “[password]” with the user’s password.  If our website has a configuration file for accessing the MySQL database, these values will need to be included in that file.

mysql> GRANT ALL on [db_name].* to '[user]'@'%' IDENTIFIED BY '[password]';

Flush Privileges:

mysql> FLUSH PRIVILEGES;

Log out of MySQL

mysql> exit;

It’s a Wrap

We now have a dedicated cloud database server that is custom-configured to run MySQL within our Rackspace cloud environment. All of our web servers will now be able to share a common database and to have direct access to that database from behind the firewall on the Rackspace network.

References:
http://www.sitepoint.com/ubuntu-12-04-lts-precise-pangolin-introducing-mysql-server/
https://launch.rackspace.com/build/wordpress/server/serversetup/

Minimal Viable Product (MVP) and The Lean Startup

I am one of those developers who does not want to launch a product until it is just right and all of the bugs are worked out. I have been challenged by a few of the presentations at SXSW 2012 to focus on launching with a Minimal Viable Product and to iterate and improve as feedback comes in from users. There has been a lot of emphasis just getting the product out into the user’s hands so that you aren’t just guessing what they want. There have been several examples of companies who have spent millions of dollars solving huge problems. They focused on product development and great features, but have failed because no one ever used their final product. If they could have figured that out before spending millions of dollars and a lot of time on product development, they could have “pivoted” at an early stage to meet real user needs.

Nice Scroll Bars

I have been working on a custom WordPress theme with my brother, @erictufts, that has at its very core the need for iOS styled scroll bars.  We had tried every custom scroll bar out there and just could not seem to find a solution that met all of our design criteria.

Our requirements were:

  • That the scroll bars use jQuery (since I am really not interested in having yet one more JavaScript library downloaded by the user just to replace the browsers default scroll bars)
  • That the scroll bars work consistently across desktop and mobile browsers
  • That the scroll bars would fade out as the scrollable pane lost focus
  • That the implementation would not require that we add a bunch of extra HTML and CSS to the page
  • That the solution be in active development
We finally found Nicescroll last week and have been very pleased with the results so far.
Check out the simple demo.

Nicescroll