Showing posts with label apache. Show all posts
Showing posts with label apache. Show all posts

Friday, October 21, 2011

Installing and Configuring ZendServer Community Edition (CE) on CentOS 5 / 6

The quick and the dirty:
Download the Zend Server (DEB/RPM Installer Script) from zend.com. (An account is required).
un-pack the the tarball (tar -xzfv ZendServer-5.5.0-RepositoryInstaller-linux.tar.gz)
Run ./install_zs.sh 5.3 ce or ./install_zs.sh 5.2 ce depending on which version of PHP you want to run.
Edit your iptables (you are running iptables right?) vi /etc/sysconfig/iptables
Add in a line for the ZendServer lighthttpd server (-A INPUT -m state --state NEW -m tcp -p tcp --dport 10081 -j ACCEPT)
Restart iptables (/sbin/service iptables restart)
Visit (http://YOURSERVERHERE.com:10081/ZendServer/) in a web browser to accept the EULA and set a password.

Alternatively run (/usr/local/zend/bin/zs-setup accept-eula) and (/usr/local/zend/bin/zs-setup set-password YOURSECUREPASSWORD )

If you need to restart Zend Server run /sbin/service zend-server restart.  This will restart both apache (httpd) and the LightHTTPD Zend Server gui.

Some important notes before heading off into the wonderful world of Zend Server:
Be sure that your distribution's PHP isn't installed as well as the Zend Server, including the CLI, as it will mess with running php from the command line and who knows what else.

The php binary is located at /usr/local/zend/bin/php, which can be verified by running which php.  As such if you need to run php from cron be sure to add this to your path. (I have PATH=$PATH:$HOME/bin:/usr/local/zend/bin in my ~/.bash_profile).

If you need to modify a setting in php.ini you will find it at /usr/local/zend/etc/php.ini.  Remember to restart zend server for any changes to take effect.

Beyond those things there isn't too much difference between running zend server and running php from your distribution.

Monday, October 19, 2009

Nagios: check_http, using the --invert-regex option

Some times you want to check that something is running or working correctly and you work out tests for that. Other times you want to know when something is broken and throwing error messages. This is about the latter, a proper HTTP 200 code is great and all, but what if the page is just showing "Too Many Connections" instead of your home page? My old check_http command for this server used to look like, well, check_http. I didn't check anything about it specifically, just that it was returning a 200 code.

Today however I knew I needed something more in depth. Our database server lost its local network connection, but still was available over the public IP, which is what I test against. Once we re-directed the SQL requests to the public IP address of the server everything started working again, until we ran across "Too Many Connections". The database server kept all of the "local" connections open and thus we ate up the rest.

So, how to test for this scenario? After reading through the man pages of check_http I saw this little gem "--invert-regex Return CRITICAL if found, OK if not". This I knew was exactly what I was looking for! If it sees our error codes it will go Critical! Now to put this gem into practice. Here is where the man pages fall short. There is no explanation on HOW to use this, just that it exists. I tried the obvious to me "check_http -H hostname.com -w 3 -c 5 --invert-regex 'Some string'", but that didn't work. OK, lets try "check_http -H hostname.com -w 3 -c 5 --invert-regex='Some string'" nope that errored out with " option `--invert-regex' doesn't allow an argument".

Third times the charm right?
"check_http -H hostname.com -w 3 -c 5 -r 'Some string' --invert-regex '"
# HTTP OK HTTP/1.1 200 OK - 0.355 second response time |time=0.354966s;3.000000;5.000000;0.000000 size=12975B;;;0

Yes, as it turns out third time is the charm. So that got me thinking some more. How can I ensure that the page is rendering correctly, and if it isn't fail but in a specific way?

"check_http -H hostname.com -w 3 -c 5 -r 'Some string I want in my page' -r 'Some string I don't want to see' --invert-regex '"

You can add more than one -r to the check_http command and it will require all of them to be present for the test to pass, and if one of them fails then it will go critical! Perfect!

If you have any more insight into using the check_http command in Nagios I want to hear about it. We are always running into new failure scenarios that we didn't anticipate and I want to know about them before one of my users tells me about it.

Tuesday, February 17, 2009

Please check your autoconf installation and the $PHP_AUTOCONFenvironment variable is set correctly and then rerun this script.

This is a very simple fix if you are running Redhat Enterprise / CentOS 5.2.  

yum install autoconf

I came across this while setting up memcache / memcached.  I had tried running phpize from the memcach-2.2.4 directory but was getting the error "Please check your autoconf installation and the $PHP_AUTOCONFenvironment variable is set correctly and then rerun this script."

Once I had autoconf installed I was able to finish the install process
./configure
make
make install

I know there are easier ways to do all of this on CentOS, but we are using a newer version of PHP (5.2.6) than came with CentOS (5.1.6), so using yum to install this would not have worked.

Tuesday, February 10, 2009

How to: mod_expires & mod_deflate in Apache running on CentOS 5

While trying to improve the performance of our internal workflow I was tasked with setting up mod_deflate and mod_expires, based off of Yahoo's! Best Practices for Speeding Up Your Website.

The nitty gritty of these two is to make sure they are both listed in your httpd.conf file:
LoadModule expires_module modules/mod_expires.so
LoadModule deflate_module modules/mod_deflate.so

Since this server is running the default CentOS 5 apache I already had the support I needed.  I then continued on to find the documentation online. Both modules support vhost context so that is the route I went with. I added the lines below to each vhost that I wanted the settings to take place for.

ExpiresActive On
                ExpiresByType image/gif A2592000
                ExpiresByType image/jpeg A2592000
                ExpiresByType image/png A2592000
                ExpiresByType text/css A2592000
                ExpiresByType application/x-javascript A2592000
                ExpiresByType application/pdf A2592000
        

The syntax for the ExpiresByType directive is:
ExpiresByType mime/type TimeInSeconds. 

The A2592000 is Access time + one month.  If I wanted the file to be cached for one month from modification date I would have done M2592000 instead.

Other handy numbers in seconds:
86400 = One Day
604800 = One Week
2592000 = One Month
31536000 = One Year (365 Days)
157680000 = Five Years
3153600000 = Ten Years

Why might these large numbers come in handy?  Well you want to set far future expiration dates for things that don't change often.  The catch is if you need to update one of these items with a far future expiration date.  You have to change the file name.  Modify the case of the filename will work in the short term but really you want to start adding version strings to all of your static files like CSS and JavaScript.  

mod_deflate is much easier to setup.  Simply add the line:
AddOutputFilterByType DEFLATE text/html text/plain text/xml application/x-javascript text/css

Again based on the mod_deflate documentation you can add this directive to the vhost directives.  Please note that this directive can be placed on just about any context level and as such is very powerful.  Also note that you should not try to compress image file because they are already compress and it really is just a waste of CPU and time.

Using these two methods we where able to reduce our website on a first visit from 190.7Kb total to 157.3Kb total.
Before:
9.4K HTML/Text
32.1K Javascript
12.9K Stylesheets
0.4K CSS Images
135.9K Images
190.7K Total

After:
3.1K HTML/Text
15.0K Javascript
2.9K Sytlesheets
0.4K CSS Images
135.9K Images
157.3K Total

I also used the yuicompressor to minify our main Javascript and our CSS file.
After:
3.1K HTML/Text
12.3K Javascript
2.2K Sytlesheets
0.4K CSS Images
135.9K Images
154.0K Total

As you can see using mod_deflate to compress the Javascript and CSS is a more substantial savings in terms of bandwidth than trying to minify.

Granted based on my observations if we really wanted to save on bandwidth and make our pages load faster we would reduce the substantial image footprint.

In case anyone is wondering where I culled all of these numbers from I used Y! Slow for Firebug in Firefox. 

Thursday, January 22, 2009

301 Permenant Redirects in Apache on CentOS

Hello and welcome back to 301 Redirects and you.  You might remember that I did a post on 301 Redirects on IIS a few years ago, way back in 2007 actually.

Today we are concerned with the Apache web server and doing SEO / SSL friendly 301 redirects for host.com to www.host.com.

If you are just running host.com and not using any named virtual hosts you can do:
ServerName www.host.com
RewriteEngine on
RewriteRule ^/(.*) http://www.host.com/$1 [L,R=301]

If you are running named virtual hosts you can then add the directives below to your virtual hosts.

<VirtualHost *:80>
       ServerName somehost.com
       Redirect 301 / http://host.com
</VirtualHost>

Thursday, January 15, 2009

How to: Use chkconfig, or keeping your services running on a new run level

OK, so I didn't take my own advice and made sure that all of my services where set to the run on the correct run levels before I switched run levels and rebooted the servers.

chkconfig is a command-line tool for updating the /etc/rc[0-6].d directories.

So I ran chkconfig --list | more to see what was running and in what run levels. Next I ran chkconfig --levels 235 service on to tell the service to start when it enters that run level. For example:

chkconfig --levels 235 named on

Now since I have already rebooted the server, and I know this service didn't start on it's own I had to:

service named start

If I had been smarter and done all of this before hand but wanted to see if named was running or not I would have run:

service named status

I understand that all of this is basics, but some people learn from others mistakes, so hopefully I can save one person from doing the same thing.

Other useful chkconfig switches:
chkconfig --help (Used to display the help dialog)
chkconfig --add [Service Name] (chkconfig --add mysqld) (Adds a service to the chkconfig list)
chkconfig --del [Service Name] (chkconfig --del mysqld) (Deletes a service from the chkconfig list)
chkconfig --level [2,3,4,5][Service Name][on, off, reset] (chkconfig --levels 235 httpd on)(Sets the run levels a service should start in.)

chkconfig can also manage xinetd scripts via /etc/xinetd.d.

Oh, and while you are at it run chkconfig --list | more to review what services are running on your server, you might be suprised. For instance I had bluetooth support running, but not one computer in my company has bluetooth support, so I disabled it (chkconfig --levels 2345 off) and (service bluetooth stop).



Monday, January 05, 2009

How-To: Install, Configure, and Import your first SVN (Subversion) repo on CentOS 5

This might only be useful to me, I don't know but at least I will know its out there and when I have to do this again I will know what to do.

Use wget to pull down the latest source.
tar xzfv subversion.1.2.3.4.tar.gz
cd subversion.1.2.3.4/
./configure
make && make install
svnadmin create --fs-type fsfs /path/to/repo
touch /path/to/repo/.htpasswd
htpasswd /path/to/repo username
svn import -m "First Import" --username=username /source/path/ file:///path/to/repo
Setup the apache config file. Since I use named virtual hosts and typically have multple repos here is a sample.

<VirtualHost *:80>
        ServerName svn.yourhost.com
        DocumentRoot "/var/www/html"
        ServerPath /html/
        DirectoryIndex index.php index.htm
        <Location /svn/repo1>
                DAV svn
                SVNPath /path/to/repo/repo1
                AuthType Basic
                AuthName "repo1 Repository"
                AuthzSVNAccessFile /path/to/svn-acl-conf
                AuthUserFile /path/to/repo/repo1/.htpasswd
                Require valid-user
        </Location>
        <Location /svn/repo2>
                DAV svn
                SVNPath /path/to/repo/repo2
                AuthType Basic
                AuthName "repo2 Repository"
                AuthzSVNAccessFile /path/to/svn-acl-conf
                AuthUserFile /path/to/repo/repo1/.htpasswd
                Require valid-user
        </Location>
        <Location /svn/repo3>
                DAV svn
                SVNPath /path/to/repo/repo3
                AuthType Basic
                AuthName "repo3 Repository"
                AuthzSVNAccessFile /path/to/svn-acl-conf
                AuthUserFile /path/to/repo/repo3/.htpasswd
                Require valid-user
        </Location>
</VirtualHost>


The /path/to/svn-acl-conf file contains
[repo1:/]
username = rw
[repo2:/]
username = rw
[repo3:/]
username =rw

This file needs to be updated everytime a new repository is added with the appropriate username and permissions.

I am sure I have missed some steps with this, but it's a decent starting point.

Friday, December 26, 2008

Adding a Virtual Host to Apache2 based on Name in CentOS 5

Well today I was setting up our new web development server and I wanted to use Host / Name based virtual hosts in apache, instead of the previous use of ports.

Much to my amazment this one is really simple.

Make sure to uncomment or add in:
NameVirtualHost *:80
Since I don't want to add multple IP's to the server and I always want to use port 80 (The default for http). 

Then I added 

<VirtualHost *:80>
        ServerName scorpio.mydomain.local
        ServerAlias scorpio
        DocumentRoot "/var/www/html"
        ServerPath /html/
        DirectoryIndex index.php index.htm
</VirtualHost>
<VirtualHost *:80>
        ServerName dev.mydomain.local
ServerAlias www.mydowmain.local mydomain.local
        DocumentRoot "/var/www/html"
        ServerPath /html/
        DirectoryIndex index.php index.htm
</VirtualHost>
<VirtualHost *:80>
        ServerName dev.myotherdomain.local
ServerAlias www.myotherdowmain.local myotherdomain.local
        DocumentRoot "/var/www/html"
        ServerPath /html/
        DirectoryIndex index.php index.htm
</VirtualHost>
<VirtualHost *:80>
        ServerName dev.mythirddomain.local
ServerAlias www.mythirddowmain.local mythirddomain.local
        DocumentRoot "/var/www/html"
        ServerPath /html/
        DirectoryIndex index.php index.htm
</VirtualHost>

When it was all said and done this was pretty easy.  Not as easy as doing the same thing in IIS in my opinion but still very easy.  I could have tried this with Webmin but I did this all using vi from the CLI.

Friday, November 14, 2008

Adding a Virtual Host to Apache2 based on Port

Today I had to setup an internal testbed server for one of our websites.  I didn't want to create a new host name for the site on our Apache server so I went with port based virtual hosts.

There are a few things you need to add for this to work.  My first attempt to make this happed in Webmin didn't produce the results I wanted, so I turned to my trusty text editor vi.

vi /etc/httpd/conf/httpd.conf

Now I had to add in a line similar to:
Listen 8080

Also you have to tell apache to use name based virtual hosting. So add in the line:
NameVirtualHost *:8080

Then finally you can create the directives for your virtual host.
DocumentRoot /your/path/here
ServerName 1.2.3.4:8080