Posts Tagged ‘linux’

Running Tomcat as a service on Linux

Running Tomcat as a service is as easy as getting jsvc to run and it’s all documented in … hmmm well anyways this is how I do it…

Compiling JSVC

[root ~]# cd $TOMCAT_HOME/bin && tar -zxf jsvc.tar.gz
[root ~]# cd jsvc-src && chmod +x configure
[root ~]# ./configure
[root ~]# make

Now there whould be a file called jsvc in $TOMCAT_HOME/bin/jsvc-src/native/ please move this file to $TOMCAT_HOME/bin/jsvc this is the Java service executable that will execute your Tomcat server. The next step is to setup your init file, lets create the file /etc/init.d/tomcat that will be used to start Tomcat with jsvc.

#!/bin/sh
##############################################################
# chkconfig: 345 98 98
### BEGIN INIT INFO
# Provides: Tomcat
# Required-Start: $local_fs $network $remote_fs
# Required-Stop: $local_fs $network $remote_fs
# Default-Start:  3 4 5
# Default-Stop: 0 1 6
# Short-Description: start and stop Tomcat
# Description: Tomcat is a J2EE Application server
### END INIT INFO

CATALINA_HOME=/usr/local/tomcat
DAEMON_HOME=/usr/local/tomcat
TOMCAT_USER=tomcat

# Make sure we load the setenv.sh file 
# since we don't use the startup.sh script
. $CATALINA_HOME/bin/setenv.sh

# for multi instances adapt these lines.
TMP_DIR=/var/tmp
PID_FILE=/var/run/jsvc.pid
CATALINA_BASE=/usr/local/tomcat

CLASSPATH=\
$JAVA_HOME/lib/tools.jar:\
$CATALINA_HOME/bin/commons-daemon.jar:\
$CATALINA_HOME/bin/bootstrap.jar

case "$1" in
  start)
    #
    # Start Tomcat
    #
    #-user $TOMCAT_USER \
    echo $"Starting Tomcat..."
    cd $CATALINA_HOME && \
    $DAEMON_HOME/bin/jsvc \
    -home $JAVA_HOME \
    -Dcatalina.home=$CATALINA_HOME \
    -Dcatalina.base=$CATALINA_BASE \
    -Djava.io.tmpdir=$TMP_DIR \
    -wait 10 \
    -pidfile $PID_FILE \
    -outfile $CATALINA_HOME/logs/catalina.out \
    -errfile '&1' \
    $CATALINA_OPTS \
    -cp $CLASSPATH \
    org.apache.catalina.startup.Bootstrap
    #
    # To get a verbose JVM
    #-verbose \
    # To get a debug of jsvc.
    #-debug \
    exit $?
  ;;

  stop)
  #
  # Stop Tomcat
  #
  echo $"Stoping Tomcat..."
    $DAEMON_HOME/bin/jsvc \
    -stop \
    -pidfile $PID_FILE \
    org.apache.catalina.startup.Bootstrap
    exit $?
  ;;

  restart)
    $0 stop
    $0 start
    exit $?
  ;;

  *)
    echo "Usage: tomcat {start|stop}"
    exit 1;;
esac

Now you can start tomcat using /etc/init.d/tomcat start. You will see TWO java processes running on your computer when Tomcat is started in this way. There is one control process and then there is the wrapper for your java process (Tomcat).

where does the php.ini file go?

The Problem

I needed to add more memory to php but by default php installed from source (configure && make && make install) does NOT install the php.ini file. So where is waldo?

The Fix

Here is a code snip that shows what configuration file IS loaded when php is executed:

[root@mybox php-5.2.10]# php -r "phpinfo();" | grep Configuration
Configuration File (php.ini) Path => /usr/local/lib
Loaded Configuration File => (none)
Configuration

This shows that the php.ini path is in /usr/local/lib. So I grabbed the php.ini-recommended, copied that file to /usr/local/lib/php.ini and this file has the memory_limit set to 128MB which should be enough for now….

[root@mybox php-5.2.10]# php -r "phpinfo();" | grep Configuration
Configuration File (php.ini) Path => /usr/local/lib
Loaded Configuration File => /usr/local/lib/php.ini
Configuration

Done!

mysql gem and mysql NOT from RPM

Have you ever seen this:

>> require ‘mysql’
LoadError: libmysqlclient.so.15: cannot open shared object file: No such file or directory – /usr/local/lib/ruby/gems/1.8/gems/mysql-2.7/lib/mysql.so
from /usr/local/lib/ruby/gems/1.8/gems/mysql-2.7/lib/mysql.so
from /usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:32:in `require’
from /usr/local/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:509:in `require’
from /usr/local/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:354:in `new_constants_in’
from /usr/local/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:509:in `require’
from (irb):2

I found this happens when your environment for mysql is not setup correctly. The fix is easy. All you need is to add a file in the /etc/profile.d directory called mysql.sh with the correct exports and re-login…

[root@heimdull log]# cat /etc/profile.d/mysql.sh
export LD_LIBRARY_PATH=/usr/local/mysql/lib:$LD_LIBRARY_PATH
export PATH=/usr/local/mysql/bin:${PATH}

That fixes the binary and library paths… MAKE SURE THERE ARE NO MYSQL RPMS INSTALLED…

rpm -qa | grep mysql should give no mysql-[version] or mysql-server-[version] or mysql-devel-[version]

log-in and out…

install the gem

[root@heimdull ~]# gem install mysql — –with-mysql-config=`which mysql_config`
Building native extensions. This could take a while…
Successfully installed mysql-2.7
1 gem installed

test the new gem:

[root@heimdull current]# RAILS_ENV=production ruby script/console
Loading production environment (Rails 2.1.0)
>> require ‘mysql.so’
=> []
>> puts Mysql::VERSION
20700
=> nil
>> exit

Using awk to sum all entries in one column

Had to search this one for a while… here is the source file:

360109368 15004557 java.lang.String
310090432 7692644 char[]
179389488 7474562 java.util.HashMap$Entry
71350968 70689 java.util.HashMap$Entry[]
14298360 109019 * ConstMethodKlass
7853616 109019 * MethodKlass
7409816 119136 java.lang.Object[]
7302080 17556 int[]
7094864 11288 byte[]
I wanted the sum of all the numbers in the first column and heres the awk line I used:
cat sourcefile | awk ‘{print $1}’ | awk ‘BEGIN{sum=0}{sum+=$1}END{print “Total: ” sum}’

Mysql driver for rails

When installing the mysql gem you might get this:
Building native extensions.  This could take a while… ERROR:  Error installing mysql: ERROR: Failed to build gem native extension.
the fix is easy but you are going to need the mysql-devel package if you are on redhat then do this:
yum install mysql-devel
Now you can install the mysql driver like this:
gem install mysql — –with-mysql-config=`which mysql_config`
To test the driver us the rails console:
# ruby script/console
>> require ‘mysql’
>> puts Mysql::VERSION
This should give you the 20700 version. (As of Jan 2007 thats the latest version.)Now enjoy the speed.

Working with Linux LVM

Growing your lvm partition.
  • Find free space:
  • lvm vgs (VFree is amount of free space)
  • Find the the logical volum:
  • lvdisplay (LV Name is what you want)
  • Extend the drive (Add 50GB to current size) : 
  • lvextend –size +50G /dev/drive
  • unmount the drive (If drive is busy use lsof | grep /mountpoint to find the process that is using the mountpoint)
  • e2fsck -f /dev/drive
  • resize2fs /dev/drivemount
  • done
Its best if the drive is umounted before the lvextend command runs. (I have never had issues with this but you never know. ) 

Deploying with capistrano to servers behind a firewall

First lets install the rsync_with_remote_cache gem:
Check-out from source
Add patch so we will deploy to all roles not just the :app role(this will ensure that migration will work)
vi lib/capistrano/recipes/deploy/strategy/rsync_with_remote_cache.rb
change this:
# Step 2: Update the remote cache.
logger.trace “copying local cache to remote”
find_servers(:roles => :app, :except => { :no_release => true }).each do |server|
system(”rsync -az –delete #{local_cache}/ #{user}@#{server.host}:#{repository_cache}/”)
# TODO: an alternate version that excludes SVN, if we wanted to use an export-like strategy,
# from Andrew Kreiling – however, if we do an svn export locally and then sync it up, it wouldn’t
# include .svn anyway so this may be moot
# system(”rsync -az –delete –exclude=.svn –delete-excluded #{local_cache}/ #{user}@#{server.host}:#{repository_cache}/”)
end
to this:
# Step 2: Update the remote cache.
logger.trace “copying local cache to remote”
find_servers(:except => { :no_release => true }).each do |server|
system(”rsync -az –delete #{local_cache}/ #{user}@#{server.host}:#{repository_cache}/”)
# TODO: an alternate version that excludes SVN, if we wanted to use an export-like strategy,
# from Andrew Kreiling – however, if we do an svn export locally and then sync it up, it wouldn’t
# include .svn anyway so this may be moot
# system(”rsync -az –delete –exclude=.svn –delete-excluded #{local_cache}/ #{user}@#{server.host}:#{repository_cache}/”)
end
Create the gem
rake package
Install the gem
gem install pkg/capistrano_rsync_with_remote_cache-2.1.gem
Verify
gem list capistrano_rsync_with_remote_cache
Now inside of the capistranos deploy.rb file add this
set :deploy_via, :rsync_with_remote_cache
This strategy maintains two cache directories:
    * The local cache directory is a checkout from the Subversion repository. The local cache directory is specified with the local_cache variable in the configuration. If not specified, it will default to “.rsync_cache” in the same directory as the Capfile.
    * The remote cache directory is an rsync copy of the local cache directory. The remote cache directory is specified with the repository_cache variable in the configuration (this name comes from the remote_cache strategy that ships with Capistrano, and has been maintained for compatibility.) If not specified, it will default to “shared/cached-copy” (again, for compatibility with remote_cache.)
Deployment happens in three major steps. First, the local cache directory is processed. If it does not exist, it is created with a checkout of the revision to be deployed. If it exists, but is not a checkout from the repository specified in the configuration, the cache directory is removed, then recreated as if it did not exist. If it exists, and is a checkout from the repository specified, it is updated to the revision to be deployed.
Second, rsync runs on the local side to sync the remote cache to the local cache. When the rsync is complete, the remote cache should be an exact replica of the local cache.
Finally, a copy of the remote cache is made in the appropriate release directory. The end result is the same as if the code had been checked out directly on the remote server, as in the default strategy.