Latest Entries

Nginx Error: Increase server_names_hash_bucket_size

Posted: February 5, 2010 | By: TJ | In Technology | No comments yet

During an initial server build with Nginx, I was having trouble starting the web server. Testing the Nginx configuration, the reported error was:

$ nginx -t
2010/02/05 17:18:23 [emerg] 12299#0: could not build the server_names_hash, you should increase server_names_hash_bucket_size: 32
2010/02/05 17:18:23 [emerg] 12299#0: the configuration file /etc/nginx/nginx.conf test failed

The server_names_hash_bucket_size is one of the directives in the core HTTP module for Nginx. This directive assigns the size of basket in the hash-tables of the names of servers. The hash bucket size is always equal to, or in multiples of, the size of the line of processor cache. As you can see from the error, the default on my Debian Lenny virtual machine was 32. After checking out the official documentation, I found that I simply had to increase the default bucket size from 32 to 128 in the nginx.conf. Test the configuration again and make sure the output is clean:

$ nginx -t
2010/02/05 17:22:57 [info] 21732#0: the configuration file /etc/nginx/nginx.conf syntax is ok
2010/02/05 17:22:57 [info] 21732#0: the configuration file /etc/nginx/nginx.conf was tested successfully

Fix PECL Error: ‘/bin/sh: bad interpreter: Permission denied’

Posted: January 27, 2010 | By: TJ | In Technology | No comments yet

Continuing off my last post on PECL issues, I’ve run into additional problems installing PECL extensions on my CentOS 5.4 server. Now that PECL is able to at least run, I was seeing permission issues as it finished compling:

$ pecl install apc

downloading APC-3.0.19.tgz …
Starting to download APC-3.0.19.tgz (115,735 bytes)
…………………….done: 115,735 bytes
47 source files, building
running: phpize
Configuring for:
PHP Api Version: 20041225
Zend Module Api No: 20060613
Zend Extension Api No: 220060519
/usr/local/bin/phpize: /tmp/pear/temp/APC/build/shtool: /bin/sh: bad interpreter: Permission denied
Cannot find autoconf. Please check your autoconf installation and the $PHP_AUTOCONF environment variable. Then, rerun this script.

ERROR: ‘phpize’ failed

The problem is that for security reasons, the /tmp filesystem is mounted with the noexec flag. You can check this by executing the following command:

$ mount | grep \/tmp
simfs on /tmp type simfs (rw,noexec)
simfs on /var/tmp type simfs (rw,noexec)

To fix this, you can temporary remount the directory to make it executable. To do this, issue the following command:

$ mount -o remount,exec /tmp

Once you’ve installed the extension, remount the directory again to set it back to noexec:

$ mount -o remount,noexec /tmp

Fixing ‘Unsupported Protocol’ Error with PECL

Posted: January 26, 2010 | By: TJ | In Technology | One comment

After installing PHP 5.2.10, I wanted to setup a few additional modules using PECL. I found soon after that I was unable to do so because of the following error:

pear.php.net is using a unsupported protocal – This should never happen. install failed

The problem seems to exhibit itself in corrupted PEAR installations with PHP 5.2.9 and 5.2.10. To fix this, we’ll update the channels:

$ mv /usr/local/lib/php/.channels /usr/local/lib/php/.channels.bak
$ pear update-channels

After that, you should be good to go.

WordPress Permalinks in Nginx

Posted: January 22, 2010 | By: TJ | In Technology | No comments yet

Setting up permalinks in WordPress is very easy in Apache. A few lines of mod_rewrite in the .htaccess and you’ve got pretty URLs. If you plan on using Nginx, the process is a bit different however the idea is the same. Essentially, you’ll want to add rewrite request directive in the virtual host configuration. This may vary depending on how you set up Nginx but this is the code you’ll need:

if (!-e $request_filename) {
rewrite ^/(.*)$ /index.php?q=$1 last;
break; }

You can place the rewrite directive in the location section. Here is what I am using with this blog:

location / {
root   /var/www/constantshift.com/public/;
index  index.php;
if (!-e $request_filename) {
rewrite ^/(.*)$ /index.php?q=$1 last;
break; }
}

Configuring Munin Plugins for Varnish with Git

Posted: December 26, 2009 | By: TJ | In Technology | No comments yet

I’ve been using Varnish as a proxy to Nginx for some time and have really been impressed with some of the performance benefits I’ve seen. Although this site doesn’t generate enough traffic to warrant this type of setup, I’ve wanted to at least monitor and track cache hits and misses for Varnish. Enter Munin.

Munin is a networked resource monitoring tool that can help analyze resource trends and “what just happened to kill our performance?” problems. It is designed to be very plug and play. A default installation provides a lot of graphs with almost no work. For my setup, I’ve got Munin, the grapher/gatherer, running on another (dv) Dedicated Virtual Server from (mt) Media Temple that does all the leg work. Then I’ve got Munin nodes running on a few different servers. The default resources monitored are network throughput, disk usage, MySQL, load, ram, entropy, etc.

To start monitoring Varnish, we’ll need to setup a Munin plugin that is available on GitHub. For this, you’ll need Git:

$ aptitude install git-core

Navigate to your Munin’s plugin directory, usually /usr/share/munin/plugins:

$ cd /usr/share/munin/plugins

Now clone the repository with Git:

$ git clone git://github.com/basiszwo/munin-varnish.git

Now, let’s make things executable:

$ chmod a+x /usr/share/munin/plugins/munin-varnish/varnish_*

Then symlink the new plugins to the configuration directory, usually in /etc/munin:

$ ln -s /usr/share/munin/plugins/munin-varnish/varnish_* /etc/munin/plugins/

For most, this should be your final step. Change your Munin node configuration by adding the following to /etc/munin/plugin-conf.d/munin-node:

[varnish*]
user root

Restart the Munin node daemon and check the munin-node.log for errors:

$ /etc/init.d/munin-node restart
$ tail -f /var/log/munin/munin-node.log

Not so fast. You’re missing a Perl module:

Can't locate Net/Telnet.pm in @INC (@INC contains: /etc/perl /usr/local/lib/perl/5.10.0 /usr/local/share/perl/5.10.0 /usr/lib/perl5 /usr/share/perl5 /usr/lib/perl/5.10 /usr/share/perl/5.10 /usr/local/lib/site_perl .) at /etc/munin/plugins/varnish_varnishstat_ line 2.

No problem. Let’s install the Net::Telnet Perl module:

$ wget http://search.cpan.org/CPAN/authors/id/J/JR/JROGERS/Net-Telnet-3.03.tar.gz
$ tar -zxvf Net-Telnet-3.03.tar.gz
$ cd Net-Telnet-3.03
$ perl Makefile.PL
$ make
$ make test
$ make install

If the module is installed successfully, you should restart Munin node again and check for pretty graphs:

Varnish Graph

Varnish Graph

Media Temple (gs) Grid Service Domain & MySQL Backups

Posted: October 25, 2009 | By: TJ | In Technology | No comments yet

Having been on many shared hosting platforms before, I am fortunate enough to have a few (gs) Grid Services with (mt) Media Temple. Although no native backup tool currently exists for the (gs), I’ve created some simple backup scripts to backup the domain directories and MySQL databases. Both are very simple bash scripts that can be set up as cron jobs from with the AccountCenter. The first backup we’ll create is for domain backups:

1. If you haven’t done so already, enable SSH from the (mt) Media Temple AccountCenter.

2. Once you’ve logged in via SSH, navigate to the /data directory. Keep in mind you’ll need to add your site number in the ##### for this to work. You can find your site number in the Server Guide > Access Domain section of the AccountCenter.

cd /home/#####/data

3. Run the following commands to create and set permissions of the backup directory:

$ mkdir backup
$ chmod 777 backup

4. Create a file called backup.sh and make it executable:

$ touch backup.sh
$ chmod +x backup.sh

5. Open the file in a text editor or vim and paste in the following:

#!/bin/bash
today=$(date '+%d_%m_%y')
echo "* Performing domain backup..."
tar czf /home/#####/data/backup/example.com_"$today".tar.gz -C / home/#####/domains/example.com
# Remove backups older than 7 days:
MaxFileAge=7
find /home/#####/data/backup/ -name '*.gz' -type f -mtime +$MaxFileAge -exec rm -f {} \;
echo "* Backed up..."

This really simple script creates a tar.gz backup of the example.com directory, stamps it with the current date and places it in the the backup folder we just created. It will also prune any backup older than 7 days old. Before saving the file, be sure to make the necessary adjustments for your site number after the /home directory. You’ll also need to modify example.com for the actual domain you’ll be backing up. Before adding it as a cron, run the script via SSH — the output should look like this:

example.com@n10:/home/#####/data$ ./backup.sh
* Performing domain backup...
* Backed up...

Depending on the size, the backup may hesitate after the initialization while the domain directory is being compressed. You can now verify that the new backup is in the /home/#####/data/backup/ directory with the today’s date: example.com_25_10_09.tar.gz. Once you’ve confirmed the backup works, add the backup.sh file as a cron within the AccountCenter following this KnowledgeBase article. You can schedule the cron as frequent as you would like however the General Settings should look like this:

Cron Settings

Click to enlarge

Now, you’ve probably got at least 1 MySQL database that should be backed up as well. This can be accomplished just as easily.

1. SSH back into the /data directory and create a new bash script file:

$ touch db-backup.sh
$ chmod +x db-backup.sh

2. Now, open the file in a text editor or vim and paste in the following:

#!/bin/sh
#############################
SQLHOST="internal-db.s#####.gridserver.com"
SQLDB="db#####_dbname"
SQLUSER="db#####"
SQLPASS="db_user_password"
SQLFILE="db#####_example.com_$(date '+%d_%m_%y').sql"
LOCALBACKUPDIR="/home/#####/data/backup"
#############################
echo "* Performing SQL dump..."
cd $LOCALBACKUPDIR
mysqldump -h $SQLHOST --add-drop-table --user="$SQLUSER" --password="$SQLPASS" $SQLDB > $SQLFILE
# Remove backups older than 7 days:
MaxFileAge=7
find /home/#####/data/backup/ -name '*.sql' -type f -mtime +$MaxFileAge -exec rm -f {} \;
echo "* Backed up..."
exit

This bash script uses mysqldump to dump a MySQL database which stamps it with the current date and places it in the the backup folder we created before. This will also prune any database backups that are older than 7 days. Before saving the file, be sure to make the necessary adjustments for your site number and database credentials — all of this can be found under the Manage Databases section of the AccountCenter. Before adding it as a cron, run the script via SSH — the output should look like this:

example.com@n10:/home/#####/data$ ./db-backup.sh
* Performing SQL dump...
* Backed up...

Once you’ve confirmed the script completes without errors, add it as a cron job so you’ll never have to worry about losing your MySQL data again!

Installing APC for PHP 5.3

Posted: September 2, 2009 | By: TJ | In Technology | No comments yet

After attempting to install APC, an opcode cacher on my Lenny server, I found that the version included in the Lenny package isn’t compatible with PHP 5.3. APC has released a version that is compatible so you’ll need install the PHP extension from source. The pecl error with version 3.0.19 was:

/tmp/pear/temp/APC/php_apc.c:959: error: duplicate 'static'
make: *** [php_apc.lo] Error 1
ERROR: 'make' failed

Luckily, installing from source is pretty easy:

$ cd /usr/local/src
$ wget http://pecl.php.net/get/APC-3.1.3p1.tgz
$ tar xzvf APC-3.1.3p1.tgz
$ cd APC-3.1.3p1
$ phpize
$ ./configure --enable-apc --enable-mmap
$ make
$ make install

After the extension successfully compiles, you’ll need to move the apc.so into your extension directory — this may differ depending on your system:

$ cp /usr/local/src/APC-3.1.3p1/modules/apc.so /usr/local/lib/php/extensions/no-debug-non-zts-20090626/

Copy the following into the php.ini:

extension = apc.so
apc.enabled=1
apc.shm_size=30

Restart the web server and if applicable, the php daemon:

$ /etc/init.d/nginx restart && php-fpm restart

To verify that everything has been set up properly, load a phpinfo page in the document root. You should have the APC PHP module displayed:

APC Module

Click to enlarge

Nginx Error: 413 Request Entity Too Large

Posted: August 14, 2009 | By: TJ | In Technology | No comments yet

While working in phpMyAdmin, I found that making a very simple table change was causing the following error:

413 Request Entity Too Large

The problem was that the client_max_body_size was not set properly in the nginx.conf. The directive is part of the Nginx core HTTP module and is set to 1MB by default. I set the value to 4MB and restarting fixed the issue. Essentially, the client_max_body_size is the maximum accepted body size of client request, indicated by the line “Content-Length” in the header of request. If size exceeds this value, the client gets sent the error “Request Entity Too Large” (413). If you expect to receive files uploaded to your server through the POST request method you’ll need to increase this value.

Compiling PHP 5.3.0 with FPM

Posted: July 21, 2009 | By: TJ | In Technology | No comments yet

PHP-FPM (PHP FastCGI Process Management) is a patch for PHP to improve PHP’s FastCGI capabilities and administration. Prior to FPM, I was using the spawn-fcgi library from Lighttpd to manage PHP processes for Nginx. Although this works as it should, I was curious to try FPM given some of the configuration options. Some of the key features over using FastCGI are:

1. Process Management. Using PHP-FPM provides the ability to gracefully stop and start PHP workers without losing any queries. You also have a log and pid file as well.

2. Restrict IP addresses from which requests can come from.

3. Start the workers with different uid/gid/chroot/environment and different php.ini option. You do not need a safe mode.

4. Just like MySQL, PHP-FPM provides the ability to track the slow execution of scripts and record them in a log file along with the backtrace.

The most recent patch provided is for PHP 5.3.0. The following will outline how to install and patch PHP 5.3.0 with FPM:

$ cd /usr/local/src/
$ wget http://us.php.net/get/php-5.3.0.tar.bz2/from/this/mirror
$ tar -jxvpf php-5.3.0.tar.bz2
$ wget http://php-fpm.org/downloads/php-5.3.0-fpm-0.5.12.diff.gz
$ gzip -cd php-5.3.0-fpm-0.5.12.diff.gz | patch -d php-5.3.0  -p1
$ cd php-5.3.0

Now, this part is really up to you. I’ve set this up on a development VM with VirtualBox so if you want to compile PHP with different extensions, check php.net for availability:

$ ./configure --enable-fastcgi --enable-fpm --with-mcrypt --with-zlib --enable-mbstring --with-openssl --with-mysql --with-mysql-sock --with-curl --with-gd --enable-gd-native-ttf --without-sqlite --disable-pdo --disable-reflection

Now, make and install:

$ make all install
$ strip /usr/local/bin/php-cgi

Edit the php-fpm.conf so that PHP runs as www-data instead of nobody. You’ll need to uncomment lines 63 and 66 as well:

$ vim /usr/local/etc/php-fpm.conf
:63
www-data
:66
www-data

To create the init script, we’ll symlink the one provided and update the rc.d:

$ cd /etc/init.d/
$ ln -s /usr/local/sbin/php-fpm php-fpm
$ /usr/sbin/update-rc.d -f php-fpm defaults

Start it up:

$ /etc/init.d/php-fpm start

WordPress + Memcached = Awesome

Posted: July 19, 2009 | By: TJ | In Technology | No comments yet

If you’re already running memcached and using WordPress, you can provide an object cache directive to help speed things up. All you need to do is place this object-cache.php script in the /wp-content directory (not the plugins folder). Then add the following to the wp-config.php:

/** Memcached Support */
global $memcached_servers;
$memcached_servers = array('default' => array('127.0.0.1:11211'));

If memcached is running on another port besides 11211, make sure to change the port value in the memcached_servers line. You can verify that caching is taking place by tailing the memcached log:

$ tail -f /var/log/memcached.log

You should see some pretty verbose output in the log. For the more documentation, check out the SVN branch.



Copyright © 2010. All rights reserved.

This blog is powered by WordPress and proudly hosted by (mt) Media Temple.