I upgraded the Apache to 2.2.27 on my FreeBSD box via portmaster. The upgrade went very smooth. After the upgrade, I decide to test the Apache by restarting the server. Oh well, I got the following error message:

[FreeBSD]Shared object "libaprutil-1.so.5" not found, required by "httpd"

Oh well, looks like libaprutil-1.so.5 is missing. How about I create this file by soft-linking from the newer version, such as libaprutil-1.so.6, libaprutil-1.so.7 etc. However, when I check the lib directory, I don’t see anything like that.

#/usr/local/lib
-rw-r--r--  1 root  wheel   251k Jun 11 10:58 libaprutil-1.a
-rwxr-xr-x  1 root  wheel   961B Jun 11 10:58 libaprutil-1.la
lrwxr-xr-x  1 root  wheel    21B Jun 11 10:58 libaprutil-1.so -> libaprutil-1.so.0.5.3
lrwxr-xr-x  1 root  wheel    21B Jun 11 10:58 libaprutil-1.so.0 -> libaprutil-1.so.0.5.3
-rwxr-xr-x  1 root  wheel   148k Jun 11 10:58 libaprutil-1.so.0.5.3

Looks like it is not that simple to solve the problem. After couple trials and errors, I came up a solution. First, I need to reinstall the Apache, and then I need to reinstall Apr1.

cd /usr/local/www/apache22
make

Notice that I compile the file without installing it. That’s because I want to check the library dependence.

cd /usr/ports/www/apache22/work/httpd-2.2.27
ldd ./httpd
./httpd:
        libm.so.5 => /lib/libm.so.5 (0x80087d000)
        libpcre.so.3 => /usr/local/lib/libpcre.so.3 (0x800a9e000)
        libaprutil-1.so.0 => /usr/local/lib/libaprutil-1.so.0 (0x800d02000)
        libdb-4.8.so.0 => /usr/local/lib/libdb-4.8.so.0 (0x800f27000)
        libgdbm.so.4 => /usr/local/lib/libgdbm.so.4 (0x801299000)
        libexpat.so.6 => /usr/local/lib/libexpat.so.6 (0x8014a4000)
        libiconv.so.3 => /usr/local/lib/libiconv.so.3 (0x8016c8000)
        libapr-1.so.0 => /usr/local/lib/libapr-1.so.0 (0x8019c4000)
        libcrypt.so.5 => /lib/libcrypt.so.5 (0x801bf5000)
        libthr.so.3 => /lib/libthr.so.3 (0x801e14000)
        libc.so.7 => /lib/libc.so.7 (0x802037000)
        libapr-1.so.5 => not found (0)
        libintl.so.9 => /usr/local/lib/libintl.so.9 (0x802392000)

So it is libaprutil-1.so.0, which is what we have in /usr/local/lib/. That’s good. Now we can hit the install button.

cd /usr/ports/www/apache22/
make reinstall

So let’s try to run Apache again. Looks like we got a different error message:

/usr/local/etc/rc.d/apache22 restart
Performing sanity check on apache22 configuration:
Shared object "libapr-1.so.5" not found, required by "libaprutil-1.so.0"

It’s okay. Let’s do something similar to the apr1:

cd /usr/ports/devel/apr1/
make reinstall

Try to restart Apache again. The problem should be gone:

/usr/local/etc/rc.d/apache22 restart
Performing sanity check on apache22 configuration:
Syntax OK
Stopping apache22.
Waiting for PIDS: 1022.
Performing sanity check on apache22 configuration:
Syntax OK
Starting apache22.

Hope my solutions help!

–Derrick

Our sponsors:

I upgraded the Apache to 2.2.27 on my FreeBSD box via portmaster. The upgrade went very smooth. After the upgrade, I found that Apache no longer rendered the PHP page correctly. In the other words, it displayed the source code of the PHP files instead of executing the code.

Before you start doing anything, please make sure that your website is not accessible from public. For example, most web applications like to include the password information in the source code, which is accessible by public if the PHP engine is failed. You may want to restrict the public access during the fix. The easiest way is to set up a .htaccess file and restrict the access by IP address.

Let’s come back to the fix. For some reasons, Apache/PHP team decide to make something fun to the FreeBSD sysadmin, because they think FreeBSD sysadmin have plenty of spare time. Here is what they decide to do:

Originally, we install Apache first, then we install PHP. When we install the PHP, we pick an option such that the PHP will install a PHP engine used by Apache. In the recent release, they decide to remove the engine from the standard PHP package. For example, if you simply use the portmaster to upgrade your PHP (In my case, PHP 5.4 and 5.5), the engine will be missing. That’s why Apache fails to render the PHP files.

Here is what you will need to do. I suggest you to finish reading the following before doing the fix. Trust me. It may save you couple hours.

First, make sure that Apache is working fine.

If you are using PHP 5.4, make sure that you install this port: /usr/ports/www/mod_php5. If you are using PHP 5.5, install this one instead: /usr/ports/www/mod_php55. Make sure that you select the ZTS option. You can do it by running:

sudo make config

Notice that installing this port will reinstall the PHP package (/usr/ports/lang/php5 or /usr/ports/lang/php55). Make sure that the ZTS option is selected in PHP package as well.

Now try to restart the Apache server. That should make the Apache to render the PHP files instead of dumping it.

#sudo /usr/local/etc/rc.d/apache stop
#sudo /usr/local/etc/rc.d/apache start

Test the PHP files again. If you see the PHP result instead of PHP source code, congratulations! You are 20% done.

Now go back to the command line and run the following:

#List the PHP extensions installed by PHP 
php -m

#Check whether the PHP extensions are loaded properly by PHP
php -v

For some reasons, I noticed that many extensions were missing during the reinstallation, such as sessions, json etc. Let’s install them back:

#For PHP 5.4
cd /usr/ports/lang/php5-extensions

#For PHP 5.5
cd /usr/ports/lang/php55-extensions


sudo make reinstall clean

Don’t forget the pecl and related packages as well. After that, try to restart your Apache server and clean up the php extension configuration:

nano /usr/local/etc/php/extensions.ini

You will see a mess. Try to clean up the duplicated extensions and run the php -m and php -v again.

During the fix, I notice that everything works fine except for MySQL package. Interestingly, when I ran php -m, the mysql was available. However when I ran phpinfo(), it was missing. I found that this problem only happens with PHP 5.4, but not PHP 5.5. Therefore, I decided to remove the PHP 5.4 and loaded PHP 5.5 instead.

Simply repeat the installation and restart the server. If possible, try to reboot the machine.

So here is the summary:

  1. Remove PHP, Extensions and PECL packages (sudo make deinstall).
  2. Restart Apache (sudo /usr/local/etc/rc.d/apache stop; sudo /usr/local/etc/rc.d/apache start).
  3. Verify installed extensions with php -m; php -v; and phpinfo().
  4. Verify the result by loading the pages on the web.
  5. If your page is failed, try to find out which extension is missing by checking the error log, which is typically available in in /var/log/

Hope my solutions help!

–Derrick

Our sponsors:

After I updated the Apache to 2.2.22 for my FreeBSD box today, I got a problem:

#apachectl stop
#apachectl start

[warn] (2)No such file or directory: Failed to enable the 'dataready' Accept Filter

If you search for Failed to enable the ‘dataready’ Accept Filter on Google, you probably will find a lot of posts about this solution, like the following:

#kldload accf_http

Or include the following in the boot loader (/boot/loader.conf):

accf_http_load="YES"

However, even you already done these two things, this problem still exists.

#kldload accf_http
kldload: can't load accf_http: File exists

Why? That’s because the problem is not coming from accf_http. Instead, the problem is the missing dataready filter, which is accf_data. To solve this problem, simply do the following. First, update the /boot/loader.conf and add the following into the file:

accf_data_load="YES"

Of course, any changes to the boot loader requires a reboot. If you don’t want to reboot the machine, simple load the module manually and restart the Apache, i.e.,

#kldload accf_data
#apachectl stop
#apachectl start

That’s it! Apache will stop complaining the dataready filter and will work happily.

–Derrick

Our sponsors:

Apache 2.2.21 was rolled out today. Since it has some security fixes, I decide to put a new version on my server farm. I didn’t know that it becomes a small headache today morning.

The upgrade was running smooth, no error messages, no complaints, until I restart the Apache server manually

sudo apachectl restart

And guess what, my website didn’t show up on the browser. Instead, I saw the following picture on my browser:

That was not fun at all. So I decided to investigate what was wrong to the upgrade.

sudo tail /var/log/httpd-error.log

And I found something interesting:

httpd: Syntax error on line 100 of /usr/local/etc/apache22/httpd.conf:
Cannot load /usr/local/libexec/apache22/mod_negotiation.so into server:
/usr/local/libexec/apache22/mod_negotiation.so: Undefined symbol "ap_set_accept_ranges"

Therefore, I edited my Apache configuration and commented out that module:

#LoadModule negotiation_module libexec/apache22/mod_negotiation.so

Saved the file and restarted the server again. Now the problem is gone!

sudo apachectl stop
sudo apachectl start

When I tried to visited the website again, I found that the speed is bit slow. I think it has something to do with the mod_negotiation.so. I decided to rebuild the Apache.

cd /usr/ports/www/apache22
sudo make config

Make sure that the Negotiation: Enable mod_negotiation is checked.

sudo make

Running sudo make is enough. You don’t need to re-run sudo make install or sudo make reinstall.

This will rebuild the necessary libraries including the missing mod_negotiation.so.

Go back to the configuration file and enable the module again:

LoadModule negotiation_module libexec/apache22/mod_negotiation.so

Restart the server:

sudo apachectl restart

That’s it! Happy Apaching!

–Derrick

Our sponsors:

I like to experiment all kind of computer technologies especially server applications. I am not one of those who is satisfied with just making a website and putting it in somewhere. I like the full control of the server because I like to try different combination of applications for performance tuning. For example, I doubt regular web hosting company allows you to host the entire system on a ram disk with a reasonable price tag. That’s why I choose to host a server at home. That’s a lot cheaper, plus I have the full control. However, running server application may generate lots of upstream traffic. That’s why most internet server providers (such as Charter) do not allow their customers to run any server related applications using their internet connection service. They do it by blocking most service related common ports, e.g., 80 (HTTP), 21 (FTP), 22 (SSH) etc. So there is really nothing you can do other than hosting your applications on different ports.

Two years ago, I started hosting all of my websites using my own computers. I found a number of benefits.

Benefits of hosting websites at home

1. It saves me tons of money.

I was paying $72/year per domain for web hosting. Since I have more than ten domains, the total running costs per year is pretty high. This amount is really nothing comparing to the cost of the electricity.

Monthly cost for web hosting:

$72 per domain/yr * 10 domains / 12 months
= $60 per domain / month

My monthly electricity cost at home, which includes everything such as running 10 non-gaming computers, washer, dryer, lighting etc:

$80 / month

I haven’t tried measuring the exact energy but you can imagine the electricity used by computers should be under $10 / month.

2. It is fun (and environmental friendly too).

I have few stone-age computers including a Pentium II laptop, a Mac G3 (speed wise similar to Pentium II), a Pentium M Celeron laptop etc. I integrated them to a web server farm (web clusters). Since running a web server does not require a lot of CPU power, they are doing okay for hosting low-traffic websites. Also, it is cool to show off my friends the global data center that I build for my websites.

3. Your data is secured!

Have you ever heard of any bank host their web sites on web hosting? No matter what type of encryption you use for your web applications, you still need to process the raw, original, and unencrypted data on the server side at one point. Processing confidential information on a shared server is like talking your secrets in a study room in a public library. You think you are in an isolated environment, but you can be surveillanced, it’s very simple and easy.

Here is an example:
Supposes I have a web application which accepts the confidential information from my users, and all traffics are encrypted. After the confidential information is decrypted on the server-side, my web application processes the raw information and do further things.

Let’s say the server environment is Apache + PHP + MySQL, the most popular combination of web application environment. Since they are all open-source, it is very easy to modify the source codes and log every single thing into a file, including the raw, original, unencrypted data processed by my web application.

You may think this may require lots of work and it will never happen on you. What if your competitor wants your confidential information? It doesn’t cost much to hire someone to do it.

Sounds scary?

More scary things come along. Shared web hosting (hosting multiple domains on one single server) always come with lots of trouble that many people are ignored. In theory, every website on a shared hosting lives in a virtual, independent environment, think about it as a virtual machine like VMWare or Hyper-V. Practically, it is not easy to set up such environment (e.g., FreeBSD Jail) and many web hosting companies choose to go with a less difficult path, because customers will not realize it anyway. Now here is the interesting part, supposes my domain and your domain are hosted on the same server. I can access the resource at the operating system level first (which will required some hacking), then access your file after that. Now I have access your source code and I can do whatever I want.

The most secure place in the world is the place that can be accessed by you, and no body else, i.e., your home, or any place you have full control

Our sponsors:

I was installing XAMPP on Fedora 11 64-bit today, and I saw this famous message:

sudo /opt/lampp/lampp startapache
XAMPP is currently only availably as 32 bit application. Please use a 32 bit compatibility library for your system.

The message is very clear that XAMPP doesn’t like 32-bit system. So, we will need to cheat XAMPP that the system is 32-bit. First, we will need to install some libraries:

sudo yum -y install glibc.i686 libgcc.i686 libstdc++.i686

and now, we need to skip the 32-bit annoying check. Use Nano or your favorite editor to open this file: /opt/lampp/lampp

sudo nano /opt/lampp/lampp

Replace the following from:

# XAMPP is currently 32 bit only
case `uname -m` in
       *_64)
       if /opt/lampp/bin/php -v > /dev/null 2>&1
       then
               :
       else
               $de && echo "XAMPP gibt es zur Zeit nur als 32-Bit Applikation. Bitte verwende eine 32-Bit Kompatibilitaetsbibliothek fuer Dein System."
               $de || echo "XAMPP is currently only availably as 32 bit application. Please use a 32 bit compatibility library for your system."
               exit
       fi
       ;;
esac

To:

# XAMPP is currently 32 bit only
#case `uname -m` in
#       *_64)
#       if /opt/lampp/bin/php -v > /dev/null 2>&1
#       then
#               :
#       else
#               $de && echo "XAMPP gibt es zur Zeit nur als 32-Bit Applikation. Bitte verwende eine 32-Bit Kompatibilitaetsbibliothek fuer Dein System."
#               $de || echo "XAMPP is currently only availably as 32 bit application. Please use a 32 bit compatibility library for your system."
#               exit
#       fi
#       ;;
#esac

Now run the following the start XAMPP:

sudo /opt/lampp/lampp startapache

Wow! Everything is working great!

–Derrick

Our sponsors:

Let’s put the nginx, Tornado and Apache and see who is the winner.

What to test:

A simple Hello World webpage.

How:

ab -n 10000 -c 300 http://myserver.ip

Test Environment:

OS: Ubuntu 9.10 (32-bit) / Linux 2.6.31
CPU: Pentium Celeron M 1.5 GHz
Ram: 512 MB
Apache: 2.2.12
PHP: 5.2.10
Python: 2.6
Tornado: 0.2
nginx: 0.6.13

Result:

Apache

Server Software:        Apache/2.2.12
Server Port:            80

Document Path:          /
Document Length:        13 bytes

Concurrency Level:      300
Time taken for tests:   5.295 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      2863146 bytes
HTML transferred:       130143 bytes
Requests per second:    1888.58 [#/sec] (mean)
Time per request:       158.850 [ms] (mean)
Time per request:       0.529 [ms] (mean, across all concurrent requests)
Transfer rate:          528.05 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    8 151.0      0    3028
Processing:     0  122 602.0     48    5289
Waiting:        0  122 600.8     48    5284
Total:         10  130 622.1     49    5292

Percentage of the requests served within a certain time (ms)
  50%     49
  66%     50
  75%     50
  80%     51
  90%     53
  95%     63
  98%     68
  99%   5271
 100%   5292 (longest request)

nginx

Server Software:        nginx/0.6.13
Server Port:            8000

Document Path:          /
Document Length:        13 bytes

Concurrency Level:      300
Time taken for tests:   3.172 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      2230000 bytes
HTML transferred:       130000 bytes
Requests per second:    3152.12 [#/sec] (mean)
Time per request:       95.174 [ms] (mean)
Time per request:       0.317 [ms] (mean, across all concurrent requests)
Transfer rate:          686.45 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    2  68.3      0    3057
Processing:     0   70 359.1     27    3164
Waiting:        0   70 359.1     26    3164
Total:         10   72 365.6     27    3169

Percentage of the requests served within a certain time (ms)
  50%     27
  66%     27
  75%     27
  80%     27
  90%     28
  95%     29
  98%     32
  99%   3157
 100%   3169 (longest request)

Tornado Web:

Server Software:        TornadoServer/0.1
Server Port:            8888

Document Path:          /
Document Length:        12 bytes

Concurrency Level:      300
Time taken for tests:   5.109 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      1680000 bytes
HTML transferred:       120000 bytes
Requests per second:    1957.33 [#/sec] (mean)
Time per request:       153.270 [ms] (mean)
Time per request:       0.511 [ms] (mean, across all concurrent requests)
Transfer rate:          321.12 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0   32 309.3      0    3035
Processing:    33  103  28.5    103     375
Waiting:       33  102  28.5    103     375
Total:         36  135 311.3    103    3154

Percentage of the requests served within a certain time (ms)
  50%    103
  66%    105
  75%    108
  80%    112
  90%    116
  95%    126
  98%    313
  99%   3121
 100%   3154 (longest request)

What do these numbers mean?

In a given time, if nginx and Tornado Web can handle 1.66 and 1.036 times more requests than Apache, respectively! In the other words, the server is more efficient and it can use the saved resource to do something else!

–Derrick

Our sponsors:

I just did a benchmark comparison on Tornado Web Server and Apache + PHP server. The result is pretty amazing.

What to test:

A simple Hello World application.

How:

ab -n 1000 -c 300 http://myserver.ip

Test Environment

OS: FreeBSD 7.1
CPU: Pentium III 933 MHz
Ram: 256 MB
PHP: 5.2.9
Python: 2.5.4
Tornado: 0.2

Result:

Apache + PHP:

Concurrency Level:      300
Time taken for tests:   3.515 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      255000 bytes
HTML transferred:       12000 bytes
Requests per second:    284.50 [#/sec] (mean)
Time per request:       1054.499 [ms] (mean)
Time per request:       3.515 [ms] (mean, across all concurrent requests)
Transfer rate:          70.85 [Kbytes/sec] received

Tornado Web Server:

Concurrency Level:      300
Time taken for tests:   1.907 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      168000 bytes
HTML transferred:       12000 bytes
Requests per second:    524.48 [#/sec] (mean)
Time per request:       571.993 [ms] (mean)
Time per request:       1.907 [ms] (mean, across all concurrent requests)
Transfer rate:          86.05 [Kbytes/sec] received

What do these numbers mean?

Tornado Web Server can handle 1.84 times more requests than Apache + PHP server in a given time!

–Derrick

Our sponsors:

Recently I am playing the following technologies (toys):

  1. Tornado Web – Not sure how long will Apache + PHP last. Time to learn Python.
  2. Tokyo Cabinet & Tyrant – Another one of my long term plans to step away from SQL.
  3. PHP API for Tokyo Tyrant — I decide to write my own because I cannot find a good one.
  4. Moving my development platform from Windows to FreeBSD. My servers have been already on FreeBSD for many years. I think now is a good time to move my desktop systems to FreeBSD as well. Why not Linux? Oh Well…
  5. LUA – I may pick up Lua if time is permitted.

Looks like I will have a busy time other than shoveling the snow this Winter.

–Derrick

Our sponsors:

The Apache web server comes with the OS X is a bit out dated. So I decided to install a new one. After I tried installing it using mac port, it kept giving error.

Finally, I built the Apache from source, and it worked!

Grep Apache from here.

Download the file, where the link should look something like:

Unix Source: httpd-2.2.14.tar.gz

Run the following command in terminal:

tar -zxvf httpd-2.2.14.tar.gz

cd httpd-2.2.14

./configure

make

sudo make install

That’s it! Now, let’s test the webserver.

First, let’s disable the Apache that shipped with the OS X (Not the one you just install!). You can simply do it by going to:

System Preferences -> Sharing -> Web Sharing

Go back to Terminal. Make sure the default web server is not running:

sudo apachectl stop

Now, let’s verify the installations:

/usr/local/apache2/bin/apachectl -v

You should see something like this:

Server version: Apache/2.2.14 (Unix)
Server built:   Oct 24 2009 20:53:45

Now, let’s start the web server:

sudo /usr/local/apache2/bin/apachectl start

Open your browsers and access to http://localhost/.
You should see something like:

It works!

Have fun!

–Derrick

Our sponsors: