Install web server
h1. Create servers
- GO THROUGH ALL THIS IF YOU REINSTALL YOUR SYSTEM*
We used Debian Lenny virtual servers. We need at least 512 MB RAM.
h1. Install packages
<pre>
apt-get update
apt-get install apache2 php5 libapache2-mod-php5 php5-cli php5-ldap
apt-get install mysql-server mysql-client php5-mysql phpmyadmin php5-memcache php-apc
apt-get install ssh subversion expect lynx imagemagick
</pre>
h1. Apache configuration
h2. .htaccess
vi /etc/apache2/sites-enabled/000-default
- Change to Allow Override? all in /var/www/*
apache2ctl restart
h2. rewriteEngine
<pre>
ln -s /etc/apache2/mods-available/rewrite.load /etc/apache2/mods-enabled/
</pre>
The Agilo server can trigger the tests by calling the php script only with the following trick:
mail.toltech.nl:81 redirects to azavista-test:80
You have to ask the system administrators to do that for you in any case. Just tell them: "Please Bas, make mail.toltech.nl:81 route to azavista-test:80 (and include azavista-test in the DNS)".
If you point to azavista-test:81 instead (a cross-port redirection doesn't work always), you also need to open port 81 (and not only *:80 in the virtual name) so that we can also Listen to it:
<pre>
sudo vi /etc/apache2/ports.conf
...
[Name Virtual Host?]] *:80
Listen 80
Listen 81
</pre>
<pre>
sudo vi /etc/apache2/sites-enabled/000-default
...
<Virtual Host? *:80 *:81>
...
</pre>
h2. SSL server
SSL is needed for https secure transactions. Configure your server like this.
Enable ssl in Apache:
<pre>
sudo a2enmod ssl
</pre>
Copy the key and the certificate in a directory /etc/apache2/ssl/ (developers can find a key and certificate at /working_files in the repository).
Install a virtual server in /etc/apache2/sites-enabled/001-ssl
<pre>
Name Virtual Host? *:443
<Virtual Host? *:443>
Server Admin? webmaster@localhost
# Server Name? ws11
# Server Alias? localhost
# Uncomment to disable SSL:
# Redirect Match? 302 (.*) http://azavista.com$1
SSLEngine On
SSLCertificateFile /etc/apache2/ssl/private_ssl_certificate.crt
SSLCertificateKeyFile /etc/apache2/ssl/private_ssl_certificate.key
Document Root? /var/www/
<Directory />
Options Follow Sym Links?
Allow Override? None
</Directory>
<Directory /var/www/>
Options Indexes Follow Sym Links? Multi Views?
Allow Override? all
Order allow,deny
allow from all
</Directory>
Script Alias? /cgi-bin/ /usr/lib/cgi-bin/
<Directory "/usr/lib/cgi-bin">
Allow Override? None
Options +ExecCGI -Multi Views? +Sym Links If Owner Match?
Order deny,allow
Allow from 83.160.103.186
Allow from 95.97.75.122
</Directory>
Error Log? /var/log/apache2/ssl-azavista.com_error.log
Error Log? /var/log/apache2/ssl_error.log
- Possible values include: debug, info, notice, warn, error, crit,
- alert, emerg.
Log Level? warn
Custom Log? /var/log/apache2/access_ssl.log combined
</VirtualHost>
</pre>
Make sure [Suhosin Php?]] is configured correctly, not to mess with your sessions.
h1. Suhosin Php?
This is a security extension for php, that makes settings more strict.
Documentation: http://www.hardened-php.net/suhosin/configuration.html
h2. Memory limit
Suhosin by default removes the ability of the php script to change the memory limit settings. To override this you need to edit /etc/php5/conf.d/suhosin.ini:
<pre>
suhosin.memory_limit=256M
</pre>
We increased it a lot, because od the CIC sync and the email campaigns:
suhosin.memory_limit=6G
This means that the script can set the memory limit up to 256Megs, but not more.
h2. Session cookies
This is required to keep cookies between http and https sessions, apart from the CakePHP configurations in azavista_session.php
<pre>
suhosin.session.cryptdocroot = Off
</pre>
See http://stackoverflow.com/a/11657470/653201
h2. other defaults
It also limits the max number of posted variables!
We tuned it to this:
<pre>
; configuration for php suhosin module
; /etc/php5/conf.d/suhosin.ini
extension=suhosin.so
suhosin.executor.include.whitelist="phar"
suhosin.memory_limit=6G
suhosin.post.max_vars = 2048
suhosin.request.max_vars = 2048
</pre>
Restart Apache
<pre>
sudo /etc/init.d/apache2 restart
</pre>
h2. php.ini
Edit /etc/php5/apache2/php.ini.
Increase execution time, at least when importing the CSV files. Make it about five minutes. You can later reduce it for production.
<pre>
max_execution_time = 30
</pre>
Keep an eye on the memory limit, maybe this default is too high for production:
<pre>
memory_limit = 128M
</pre>
Increase the garbage collection time, so that it is not below the time you expect your sessions to last (see http://www.lextech.com/blog/cakephp-and-session-garbage-collection)
<pre>
; six hours
session.gc_maxlifetime = 21600
</pre>
Check also
<pre>
; Maximum size of POST data that PHP will accept.
post_max_size = 8M
; Maximum allowed size for uploaded files.
upload_max_filesize = 8M
</pre>
Make sure you have the correct time zone set (both for apache and cli):
<pre>
date.timezone = 'Europe/Amsterdam'
</pre>
Make sure you configure Suhosin [Suhosin Php?]]
h1. APC
<pre>
sudo apt-get install php-apc
</pre>
And add extension=apc.so to your php.ini
h1. APC
h3. This is how you can install APC and it works out of box
First, we need the pecl command so we can download and install APC from the repositories.
Do to so, we execute the following command:
<pre>
aptitude install php-pear
</pre>
But, this will not run on its own, we need the following package for the phpize command:
<pre>
aptitude install php5-dev
</pre>
We also need the apxs command, which is installed via the following package:
<pre>
aptitude install apache2-dev
</pre>
Now we have all the software we need, so we install apc via the pecl command:
<pre>
pecl install apc
</pre>
Once that finishes, we need to enable apc in Apache's configuration. the following command should do this for us.
<pre>
echo "extension=apc.so" > /etc/php5/apache2/conf.d/apc.ini
</pre>
- > That didn't work for me, my PHP doesn't include files in that directory. I added that line directly to php.ini.
Then we restart Apache:
<pre>
/etc/init.d/apache2 restart
</pre>
h3. Production / beta servers
we cannot run make on those so instead of pecl we use:
<pre>
sudo apt-get install php-apc
</pre>
http://azavista.com/site/apc.php login apc, password azavista
h1. Memcache
We use both APC and Memcache, in production.
Memcache in production runs with two instances: one for storing PHP sesions (port 11211) a another one for caching our aplication data (port 11212)
h1. Mem Cache?
h1. restart
echo -e "flush_all\n\quit\n" | telnet localhost 11211
. command line
telnet localhost 11211
stats
stats slabs
stats items
stats cachedump 1 0
get testkey
delete testkey
quit
h1. Use memcache to store sessions
http://www.dotdeb.org/2008/08/25/storing-your-php-sessions-using-memcached/
Installation
The first thing is to install the memcached server on your Debian server :
apt-get install memcached
Then, since the memcache PECL extension now provides its own session handler, it’s easy to plug PHP and memcached servers. Just install the appropriate extension (from Dotdeb) :
apt-get install php5-memcache
and change some of your PHP settings :
session.save_handler = files
; session.save_path = "N;/path"
to :
session.save_handler = memcache
- change server
- port to fit your needs...
session.save_path="tcp://127.0.0.1:11211?persistent=1&weight=1&timeout=1&retry_interval=15"
That’s all! After relaunching your Apache2 server, your PHP sessions will be stored on the memcached server.
h2. Use multiple memcached instances to separate 'namespaces'
Memcache doesn't use namespaces, so you cannot flush just a part ot it. But running multiple instances of memcached listening to different ports is very easy, and you can use them for different purposes. One for sessions, and one for the application data, for example.
There are three files that need to be replicated and slightly edited:
<pre>
/etc/init.d/memcached
/usr/share/memcached/scripts/start-memcached
/etc/memcached.conf
</pre>
Make copies of all of them, append a number to the file names, and edit their contents to refer to each other correctly:
<pre>
- editions for /etc/init.d/memcached2
- Provides: memcached2
DAEMONBOOTSTRAP=/usr/share/memcached/scripts/start-memcached2
NAME=memcached2
DESC=memcached2
- editions for /usr/share/memcached/scripts/start-memcached2
my $etcfile = "/etc/memcached2.conf";
my $pidfile = "/var/run/memcached2.pid"
</pre>
Moreover, edit /etc/memcached2.conf to set the instance options:
<pre>
- editions for /etc/memcached2.conf
logfile /var/log/memcached2.log
- Default connection port is 11211
-p 11212
- This is a new line, required only by newer versions that also listen to udp: default udp port is 11211
-U 11212
- Sometimes this option -l is set to 127.0.0.1, preventing listening from other servers. Open it:
-l 0.0.0.0
</pre>
Start the new instance, and confirm they are at different ports:
<pre>
/etc/init.d/memcached2 start
netstat -lnp | grep memcached
</pre>
Set it up so that it starts up automatically on boot:
<pre>
update-rc.d memcached2 defaults
</pre>
See http://code.google.com/p/memcached/wiki/NewConfiguringServer#Multiple_Instances
h1. Memcached pool of servers
Memcached just receives requests, doesn't distribute anything. It is the client library that hashes the query and asks to the right server in the pool. Therefore, all servers must have the same identification in all client instances, so that they get the same hash!
We cannot use 'localhost' in one application instance and a full IP address in another, to refer to the same Memcached server, for example.
Also notice that the CakePHP 'prefix' for the cache configuration must be the same in all instances. Beware of using smart prefixes based on the application path!
h1. Memcached and CakePHP
Cake uses a restricted configuration parameter set for Memcached's addServer(), see cake/libs/cache/memcache.php
I'm not use if it uses failure or failover! See http://code.google.com/p/memcached/wiki/NewConfiguringClient#Failure,_or_Failover
h1. How to make web sites fast ?
You can use a cache to store the results of frequent database queries. Memcache is a tool to store this in memory, so that from cakePHP you can simply use things like
<pre>
Cache::write('recentFive', $recentFive, 86400);
</pre>
to store a DB result array $recentFive, and a structure like
<pre>
if(!$recentFive = Cache::read('recentFive')) {
// Do the DB query here it not cached
}
</pre>
to read it back.
Basic memcache installation steps, summarized:
- You need to download, install and have memecached server (daemon) up and running.
- Ensure that your PHP installation has the memcached lib enabled. The easiest way to do so is to check the phpinfo() and look for the “memcache” section.
- You need to switch [CakePHP]] caching engine from the “? (default) to “Memcache”.
Details below.
h2. Caching
Visit ibm tutorial about memcache
http://www.ibm.com/developerworks/opensource/library/os-php-cake5/
h1. What do you need for memcache ?
apt-get install memcached
This is a manual installation, maybe outdated:
Prerequisite Install
<pre>
- Download & install libevent (memcached dependency)
wget http://www.monkey.org/~provos/libevent-1.4.8-stable.tar.gz
tar xfz libevent-1.4.8-stable.tar.gz
cd libevent-1.4.8-stable
./configure && make && sudo make install
- Create a symlink to libevent
sudo ln -s /usr/local/lib/libevent-1.4.so.2 /usr/lib
- Download & install memcached
wget http://danga.com/memcached/dist/memcached-1.2.6.tar.gz
tar xfz memcached-1.2.6.tar.gz
cd memcached-1.2.6
./configure && make && sudo make install
- Run memcached as a daemon (d = daemon, m = memory, u = user, l = IP to listen to, p = port)
memcached -d -m 1024 -u root -l 127.0.0.1 -p 11211
</pre>
PHP5-Memcache Install
<pre>
- Download the extension module
apt-get install php5-memcache
- Edit /etc/php5/conf.d/memcache.ini and uncomment the following line by removing the semi-colon
extension=memcache.so
- Restart apache
/etc/init.d/apache2 restart
</pre>
Test Installation
Create a file 'memcache_test.php' in your webroot and paste the following:
<pre>
<?php
$memcache = new Memcache;
$memcache->connect('localhost', 11211) or die ("Could not connect");
$version = $memcache->getVersion();
echo "Server's version: ".$version."<br/>\n";
$tmp_object = new stdClass;
$tmp_object->str_attr = 'test';
$tmp_object->int_attr = 123;
$memcache->set('key', $tmp_object, false, 10) or die ("Failed to save data at the server");
echo "Store data in the cache (data will expire in 10 seconds)<br/>\n";
$get_result = $memcache->get('key');
echo "Data from the cache:<br/>\n";
var_dump($get_result);
?>
</pre>
That is how to install memcahe in our system.
Caching is disabled by default so we need to enable it before using it so
we need to configure it for cakephp.
You can do that by uncommenting the following
<pre>
Configure::write('Cache.check',true)
</pre>
line in app/config/core.php.
and make sure the value is true. That is for making cache works.
-to make memcache work we need to uncomment the following lines
<pre>
- Memcache (http://www.danga.com/memcached/)
- Memcache (http://www.danga.com/memcached/)
Cache::config('default', array(
'engine' => 'Memcache', //required?
'duration'=> 3600, //optional?
'probability'=> 100, //optional?
'prefix' => Inflector::slug(APP_DIR) . '_', //optional? prefix every cache file with this string
'servers' => array(
'127.0.0.1:11211' // localhost, default port 11211
), //optional?
'compress' => false, // optional? compress data in Memcache (slower, but uses less memory)
));
</pre>
and comment out
<pre>
// Cache::config('default', array('engine' => 'File'));
</pre>
in app/config/core.php
http://www.dirnonline.com/release/memcached-for-cakephp/
http://teknoid.wordpress.com/tag/cakephp-memcached/
http://amiworks.co.in/talk/step-by-step-guide-to-install-memcache-on-linux/
http://www.linuxsa.org.au/pipermail/linuxsa/1999-August/008869.html
http://www.php.net/manual/en/memcache.installation.php
http://code.google.com/p/memcached/wiki/NewConfiguringServer
use memcache also for views: http://andy-gale.com/cakephp-view-memcache.html
h1. email
apt-get install postfix
Configure for 'Satellite system':
- System mail name: azavista-production.toltech
- SMTP relay host: 213.222.2.6 (mailscanner.toltech.nl, mail.azavista.com)
- Root and postmaster mail recipient: (empty)
- Other destinations to accept mail for (blank for none): azavista-production, localhost.localdomain, localhost
- Force synchronous updates on mail queue\
- Local networks: 127.0.0.0/8
- Mailbox size limit: 0
- Local address extension character: +
- Internet protocol: ipv4
<pre>
- Contents of /etc/postfix/main.cf
- Debian specific: Specifying a file name will cause the first
- line of that file to be used as the name. The Debian default
- is /etc/mailname.
- myorigin = /etc/mailname
smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)
biff = no
- appending .domain is the MUA's job.
append_dot_mydomain = no
- Uncomment the next line to generate "delayed mail" warnings
- delay_warning_time = 4h
readme_directory = no
- TLS parameters
smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
smtpd_use_tls=yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
- See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for
- information on enabling SSL in the smtp client.
myhostname = www.azavista.com
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
mydestination = azavista-production, localhost, localhost.localdomain, localhost
relayhost = 213.222.2.6
mynetworks = 127.0.0.0/8 ::ffff:127.0.0.0?/104 ::1?/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
</pre>
After modifying main.cf, be sure to run '/etc/init.d/postfix reload'.
Test it:
<pre>
mail jose@toltech.nl
Subject: test azavista-test
hi there!
.
Cc:
</pre>
h1. Configure azavista base url
This goes for cron jobs only, to determine which base url it is using for creating links in emails. To configure it you need to add an entry in the config_app/azavista.php with the name of the server as key:
<pre>
$base_url'www.azavista.com'? = "http://azavista.com";
</pre>
h1. Configure database
If you have two servers, one for the website and another to process the queue, you'll need to let one mysql to listen to the other. Edit configuration in web server, where the database is:
/etc/mysql/my.cnf
comment out
# bind-address = 127.0.0.1
and restart
/etc/init.d/mysql restart
h1. Create database user
http://azavista-test/phpmyadmin/ (http://10.1.0.188/phpmyadmin/)
Go to Home -> Privileges -> Add a new User
Create this user:
<pre>
user: comodo
host: localhost
password: c0m0d0
no database
</pre>
All data and structure privileges
h1. Create databases
- azavista
- azavista_interactions
- azavista_unit_tests
All of type uft8_general_ci. Leave emtpy, let the schema populate them.
h1. GPG
Azavista uses GnuPG to encrypt some things. It must be installed in the server. Moreover, a public key for support@azavista.com must be in Apache's keyring for the application to be able to encrypt.
h1. InstallingGPGpublicKey
Azavista uses GnuPG (gpg) to encrypt some things. It must be installed in the server. Moreover, a public key for support@azavista.com must be in Apache's keyring for the application to be able to encrypt.
For Apache, I'm putting the gpg keyring directory at /mnt/data/azavista/.gnupg/, for user www-data. Change this path in the scripts below.
On my dev machine, I put it in /var/www/.gnupg/.
You can find the public key in the svn repository: just update your code and copy it from app/webroot/azavista-pub.gpg to /tmp, for the following instructions to work.
Create Apache's gpg homedir, and import public key:
<pre>
cp azavista-pub.gpg /tmp/
cd /www/var/
sudo mkdir .gnupg
sudo chown www-data:www-data .gnupg
sudo chmod o-rx .gnupg
sudo chmod g-rx .gnupg
sudo su www-data -c "gpg --homedir /var/www/.gnupg/ --import /tmp/azavista-pub.gpg"
</pre>
(This implies that all gpg commands must have the option --homedir /mnt/data/azavista/.gnupg/)
Trust this key, to prevent warning messages when encrypting later (message: "It is NOT certain that the key belongs to the person named in the user ID.")
<pre>
sudo su www-data -c "gpg --homedir /var/www/.gnupg/ --edit-key support"
Command> trust
5 = I trust ultimately
Your decision? 5
Do you really want to set this key to ultimate trust? (y/N) y
</pre>
Test it:
<pre>
echo "Hello World" > /tmp/test.txt
sudo su www-data -c "gpg --homedir /var/www/.gnupg/ --recipient support --encrypt /tmp/test.txt"
</pre>
Now, acting as support (with my private key installed locally), I can try to decrypt that:
<pre>
gpg --decrypt /tmp/test.txt.gpg
</pre>
Our private key must be installed for that, BUT NEVER ON THE PRODUCTION SERVER!
The command for importing our private key on your local machine is just
<pre>
gpg --allow-secret-key-import --import secret.key
</pre>
I can also put multiple GPG encrypted files named pay*.asc in a directory /tmp/, and decrypt them all with this:
<pre>
find /tmp/ -name pay\*.asc -exec gpg --batch --passphrase MY_PASSPHRASE_HERE --decrypt {} >> /tmp/decoded.out \;
</pre>
h1. Install Azavista
When checking out from SVN, you'll be asked for user and password. Use for example "jose" and "sinabmtdA".
<pre>
cd /var/www
mkdir azavista_app
cd azavista_app
svn co http://agilo.toltech.nl/svn/azavista/trunk/
svn co http://agilo.toltech.nl/svn/azavista/build/
cp -R trunk azatest
cd /var/www
ln -s azavista_app/trunk azavista
cd /var/www/azavista_app/build
./test_build.sh
</pre>
In a test server, allow apache to serve files in /var/www/build by editing the file .htaccess there, and commenting out the denial. Otherwise Automatic Build And Test? can't run the build.php script in there.
Let apache own the azavista/app/tmp and azavista/archive directories (also in the test installations) so that apache can write on them. Use
<pre>
chown -R www-data:www-data /var/www/azavista/archive
chown -R www-data:www-data /var/www/azavista/app/tmp
</pre>
Changing that ownership for the whole tree is necessary if YOU (and not SVN, which does it indirectly) intend to upgrade azavista using the build.php script from your browser, something that is not done some much recommended anyway.
Notice that the test server installation gets fully installed (including the database schema) when you run the automatic upgrade, but not so the live installation. For that, use the script at /var/www/azavista_app/build/LAUNCH_ME... . Make a copy of it and call it 'azavista_update_db.sh' or so, edit it to adapt it to the database configuration, and run it with the following option (that installs basic user data, including the sysadmin account):
./azavista_update_db.sh --drop 1
With an incomplete database, you'll get the following misleading [Cake Php?]] error:
Error: The requested address '/users/login' was not found on this server.
See [Upgrade Azavista?]] for more details.
h1. Configure Azavista
The installation scripts copy the config_sql, config_test, or confing_andersen to the right places in app/config. If your installation doesn't use that, or changes something, you'll have to review them.
Also review app/config_app/azavista.php, specially the part about the base_url that is passed to cron, for it to generate the correct direct access links.
h1. Root directory redirection
By using a .htaccess:
<pre>
Deny from all
Allow from 95.97.75.122
Allow from 80.101.102.24
Allow from 82.94.228.216
Allow from 82.169.179.97
Allow from 10.1
- Allow servers to see themselves
Allow from 10.1.0.70
Allow from 10.1.0.71
Allow from 127.0.0.1
<If Module? mod_rewrite.c>
Rewrite Engine? on
Rewrite Rule? ^$ azavista/app/webroot/ L?
Rewrite Rule? (.*) azavista/app/webroot/$1 L?
Rewrite Rule? users/(.*)$ azavista/users/$1 L?
Rewrite Rule? dl/(.*)$ azavista/dl/$1 L?
Rewrite Rule? App(.*)$ azavista/App$1 L?
Rewrite Cond? %{SCRIPT_FILENAME} !^.*\/azavista\/.*$
Rewrite Cond? %{SCRIPT_FILENAME} !^.*\/offline\/.*$
Rewrite Cond? %{SCRIPT_FILENAME} !^.*\/piwik\/.*$
Rewrite Rule? (.*) site/$1 L?
</IfModule>
</pre>
h1. Restrict access
Apart from the .htaccess above to limit access, you can also edit /etc/hosts.allow
<pre>
- mail.toltech.nl 80.101.102.24
- agilo 82.94.228.216
- jose 82.169.179.97
ALL: 80.101.102.24, 82.94.228.216, 82.169.179.97, 195.169.147.106, 82.94.228.211, 127.0.0.1, localhost
</pre>
and /etc/hosts.deny:
<pre>
ALL:ALL
</pre>
h2. Dispatcher
<pre>
- m h dom mon dow command
- * * * * /var/www/azavista/app/vendors/cakeshell negotiations_handler -cli /usr/bin -console /var/www/azavista/cake/console/ -app /var/www/azavista/app/ >> /var/www/azavista/log/cron.log
</pre>
These are the cronjobs run by root at queue.azavista.com:
<pre>
- restart office server at every hour and, inmediatelly after that, resume the queue.
0 * * * * sudo -E -H -u officeserver /var/www/azavista/app/libs/soffice/oooctl.sh restart >> /var/www/azavista/log/cron.log; /var/www/azavista/app/vendors/cakeshell negotiations_handler -cli /usr/bin -console /var/www/azavista/cake/console/ -app /var/www/azavista/app/ >> /var/www/azavista/log/cron.log
- do queue stuff - do not do it while the office server is restarting
1-59 * * * * /var/www/azavista/app/vendors/cakeshell negotiations_handler -cli /usr/bin -console /var/www/azavista/cake/console/ -app /var/www/azavista/app/ >> /var/www/azavista/log/cron.log
1-59 * * * * /var/www/azavista_demo/app/vendors/cakeshell negotiations_handler -cli /usr/bin -console /var/www/azavista_demo/cake/console/ -app /var/www/azavista_demo/app/ >> /var/www/azavista_demo/log/cron.log
</pre>
h2. Automatic test run
You have to connect the server with SVN to this one to update and run the tests. See
Root's crontab at the test server:
<pre>
- m h dom mon dow command
30 20 * * * /usr/share/salsa2/backup/dump_mysql
- See every few minutes if the test server needs an upgrade,
- due to a recent SVN commit:
- /5 * * * * /var/www/build/update_if_triggered.sh test
</pre>
If something goes wrong, see the /tmp/post-commit file both in the SVN server (Agilo) and in the test server.
h1. optional
apt-get install php5-dev
Xdebug: pecl install xdebug
h1. Troubleshooting
from Jose Viña <jose@toltech.nl>
to Marek Robert Lipinski <marek@toltech.nl>, Bas Tichelaar <btichelaar@toltech.nl>
date Wed, Jul 28, 2010 at 11:29 AM
subject mail problem
Hi!
FYI: I installed postfix at azavista-test as we used to. Mailing works
from the command line, no problem.
But when the user www-data via a shell script tries to use it, it gets
<pre>
r1024 => send-mail: fatal: /etc/mailname: cannot open file:
Permission denied
r1025 => Can't send mail: sendmail process failed with error code 75
</pre>
WARNING: before fixing this, run 'stat /etc/mailname' to see the date of last change.
Indeed, that /etc/mailname file has permissions 600 for root. Not
something I changed, I think it came like that.
I set it to 644, as it is in my toltech-11. I hope it is OK... Any
idea of why this is different now?
h1. Open Office Server?
h2. Installation
To run openoffice in server mode the following packages are needed:
<pre>
apt-get install openoffice.org xvfb
</pre>
Create a user (password: WsHzJRTp96):
adduser officeserver
<pre>
chmod -R g+w /var/www/azavista/app/tmp
usermod -G www-data officeserver
</pre>
(if officeuser doesn't have permission to write in the destination directory, the phyton script will cause the ERROR! ErrorCodeIOException 283 reported at #3681). (You still get the error despite granting permissions? Remember that it is openoffice, not phyton, the one that writes on that destination. Maybe you need to restart the openoffice server with the right user, with the command below for 'Run script').
To use it with azavista create a directory for conversion:
<pre>
mkdir /var/www/azavista/app/tmp/convert
chmod og+w /var/www/azavista/app/tmp/convert
</pre>
A directory from that user's home should point to azavista's fonts directory, for the PDF generator to use them:
<pre>
sudo su officeserver
cd
ln -s /var/www/azavista/vendors/fonts .fonts
</pre>
h2. Run script
The attached script can start/stop/restart the open office server (it is also in the azavista svn).
To do it as root you need to become officeserver user (cannot use the script as root):
<pre>
sudo -E -H -u officeserver /var/www/azavista/app/libs/soffice/oooctl.sh restart
</pre>
h1. Call Center
The call center application uses PAMI, included in the repository. This, in turn, requires log4php:
Apache log4php has it's own PEAR channel.
To install from the PEAR channel, execute the following commands:
<pre>
pear channel-discover pear.apache.org/log4php
pear install log4php/Apache_log4php
</pre>
h1. Install developers boxes
Apart from the generic ones at [Install Azavista Servers?]] and [Upgrade Azavista?]], these other instructions are interesting for developers:
h2. SVN configuration
Avoid storing unencrypted SVN passwords. To use gnome's keyring instead, edit your ~/.subversion/servers file and add:
<pre>
auth?
### Set password stores used by Subversion. They should be
### delimited by spaces or commas. The order of values determines
### the order in which password stores are used.
### Valid password stores:
### gnome-keyring (Unix-like systems)
### kwallet (Unix-like systems)
### keychain (Mac OS X)
### windows-cryptoapi (Windows)
password-stores = gnome-keyring , kwallet
</pre>
Then delete any already stored password you may have unencrypted at ~/.subversion/auth/svn.simple/.
After the next SVN operation you will be asked for a password again, but it should not be readable in files in that directory when stored.
h1. For vim users
h2. Exuberant-ctags
sudo apt-get install exuberant-ctags
This script creates the tags index in the parent directory of the one given as first argument:
<pre>
- !/bin/bash
cd $1
exec ctags-exuberant -f $1/../tags \
-h ".php" -R \
--exclude="\.svn" \
--totals=yes \
--tag-relative=yes \
--PHP-kinds=+cf \
--regex-PHP='/abstract class (^?*)/\1/c/' \
--regex-PHP='/interface (^?*)/\1/c/' \
--regex-PHP='/(public |static |abstract |protected |private )+function
(^ (?*)/\2/f/'
</pre>
It scans for PHP files recursively through the given tree, excluding any files found in a .svn directory. (I run this script every hour from cron).
Once the index file is generated (it takes less than a second), all you need to do in vim is tell it to load it in ~/.vimrc:
set tags=$PATH_TO_TAGS/tags
At this point, you can do all sorts of
fun stuff. Place the cursor on a class name or method name, anywhere
in it, and hit Ctrl-], and you'll jump to the file and line of its
declaration; Ctrl-T then takes you back. If you change the invocation
to Ctrl-W ], it will split the current window and open the declaration
in the new pane.
http://weierophinney.net/matthew/archives/134-exuberant-ctags-with-PHP-in-Vim.html
h1. X Debug
h1. Installing Xdebug in Ubuntu
Installing xdebug:
<pre>
sudo apt-get install php5-xdebug
</pre>
The config file:
<pre>
gedit /etc/php5/apache2/conf.d/xdebug.ini &
</pre>
h2. For profiling
In the config set the following:
<pre>
- profiler is enabled
xdebug.profiler_enable = 1
- the profiler will create files for each request in this directory
xdebug.profiler_output_dir = /var/www/profiler
- this is the filename for the profiling information: %R: reuquest_uri, %U server_id, %t timestamp, %r random number
xdebug.profiler_output_name = cachegrind.out.%R.%U.%t.%r
</pre>
Convenient: If you configure your php.ini with xdebug.profiler_enable = 0 and xdebug.profiler_enable_trigger = 1, you can enable the profiler temporarily by passing a variable like http://localhost/azavista/pages/plannerStart?XDEBUG_PROFILE=1
To process the profiler files, use cachegrind as explained at [Performance Analysis?]].
h2. For debugging
The config file (xdebug.ini or php.ini) file should be further configured as follows:
<pre>
xdebug.remote_enable = 1
xdebug.remote_port = 9000
xdebug.remote_host = localhost
</pre>
h2. Alternative installation
- Make sure you have phpize by installing php5-dev and PEAR: sudo apt-get install php5-dev php-pear
- Download Xdebug through PEAR/PECL: sudo pecl install xdebug
- The installation reports where the library was installed, at the end: copy that line (something like /usr/lib/php5/20060613+lfs/xdebug.so).
- Add a reference to that library in your php.ini config file (probably at /etc/php5/apache2/php.ini), like follows: zend_extension="/usr/lib/php5/20060613+lfs/xdebug.so". Use the correct path. Ignore the comment from the installer about adding a line extension=xdebug.so.
- Restart apache with sudo apache2ctl restart.
To confirm the installation, you can write a PHP page that calls @phpinfo()@, load it in a browser and look for the info on the Xdebug module.
Now you can test for example "code coverage":http://debuggable.com/posts/cakephp-code-coverage-for-group-tests:483b2b77-c420-47e3-b337-653c4834cda3 from the cake's simple test.
php.ini configuration should be in this section:
<pre>
Zend?
zend_extension = /full/path/to/xdebug.so
</pre>
h2. Debugging from vim
To setup vim to use Xdebug, please read http://tech.blog.box.net/2007/06/20/how-to-debug-php-with-vim-and-xdebug-on-linux/
With vim configured properly, go to http://localhost/azavista/?XDEBUG_SESSION_START=1. This will set a cookie in your browser which expires in one hour which tells the PHP XDebug module to try to make a connection every time a page loads to a debugging client which is listening on port 9000. The cool thing is that if it can’t make a connection, it just keeps loading the page, so there’s no issue just leaving the cookie on.
Now go back to vim and press F5. You should see a message like “waiting for a new connection on port 9000 for 5 seconds…” at the bottom of the screen. You have five seconds to now refresh the PHP page. This will create a connection between the debugger and client. Now you’re debugging. Follow the instructions in the Help window to step into, over and out of code. Press F5 to run the code until a breakpoint (which you can set using :Bp).
To get the value of the variable under the cursor, press F12. To go to next step (step into), use F2.
<pre>
In debugging mode (F5):
<F1> : resizing windows
<F2> : step into
<F3> : step over
<F4> : step out
<F6> : stop debugging
<F11> : shows all variables
<F12> : shows variable on current cursor
,e : evalute expression and display result. cursor is automatically move to watch window. type line and just press enter.
command mode (:)
:Bp : toggle breakpoint on current line
:Up : goto upper level of stack
:Dn : goto lower level of stack
</pre>
F6 exists debugging. Extra help is given in one of the debug panels.
For the differences between 'step into', 'step over' and 'step out' see e.g. http://www.developerfusion.com/article/33/debugging/4/.
To switch between panels, use the standard vim way to "change between windows":http://vimdoc.sourceforge.net/htmldoc/windows.html#window-move-cursor: Control+W and the an arrow key to go in certain direction.
h2. Debugging from Eclipse
To use it from within Eclipse, see e.g. http://devzone.zend.com/article/2930.
Please write your experiences here.
h1. Branches
svn co http://agilo.toltech.nl/svn/azavista/branches/BRANCH_NUMBER
svn copy http://agilo.toltech.nl/svn/azavista/trunk http://agilo.toltech.nl/svn/azavista/branches/BRANCH_NUMBER
To make a branch from a particular revision in the past, just specify it with the -r option:
svn copy -r REVISION_NUMBER http://agilo.toltech.nl/svn/azavista/trunk http://agilo.toltech.nl/svn/azavista/branches/BRANCH_NUMBER
h3. Merging
The "SVN book":http://svnbook.red-bean.com/en/1.5/svn.branchmerge.advanced.html says: "The term “merge” somehow denotes that branches are combined together, or that there's some sort of mysterious blending of data going on. That's not the case. A better name for the command might have been svn _diff-and-apply_, because that's all that happens: two repository trees are compared, and the differences are applied to a working copy."
So "merging" goes like this:
- you have a clean working copy of the trunk head.
- you apply the differences between two versions (of a file, or of the whole tree) to your working copy
- you review the changes in your working copy (svn diff), and solve possible conflicts
- you commit all this changes with a clear description message, like "MERGED r1976:1985 porting changes from branch 0.1".
h4. In practice: merging a branch back into the trunk
Subversion knows which branch changes you've already replicated to your trunk, so it carefully replicates only those changes you don't yet have. After merging, you'll have to test and svn commit the local modifications to your trunk.
Here's the merging procedure, then:
<pre>
- Your trunk working copy must be a clean trunk head, with no pending modifications:
$ cd azavista/trunk/app
$ svn update
At revision 1977.
- On the same trunk working copy, apply the branch changes:
$ svn merge http://agilo.toltech.nl/svn/azavista/branches/0.1/app
- ...examine the diffs, test, etc...
$ svn status
- Commit, with a clear description.
$ svn commit -m "Bring last branch 0.1 changes into the trunk."
...
Transmitting file data ...
Committed revision 1978.
</pre>
We put a script in the build directory in the Azavista repository to do the merge safely, that you can run from your trunk working copy root, just by providing the new branch number as argument:
<pre>
cd azavista/trunk/app
../build/svnmerge BRANCH_NUMBER
</pre>
After that, review the merge, and commit.
You can also manually apply the changes of one single changeset:
<pre>
cd azavista/trunk/app
svn merge -c 1971 http://agilo.toltech.nl/svn/azavista/branches/0.1/app
</pre>
The --dry-run option for merge doesn't actually apply any local changes to the working copy. It only shows status codes that would be printed in a real merge.
- Running SCP in batch mode
SCP (Secure Co Py?) and SSH in general can be used in batch mode without asking for passwords. That is very convenient for scripts.
Instructions to do so are a little ambiguous in different places . (See some references below). This worked in my case, using OpenSSH both in the server and the client.
Procedure
1. In these instructions, the user name is the same in both machines. Instructions for different user names could differ from these (but see note below!!!)
2. The user keys will be stored in ~/.ssh in both machines.
3. At the client, run:
ssh-keygen -t dsa
to generate a key pair. Accept default options by pressing return. Specially, do not enter any passphrase. (Option -d seems to be an alias of -t dsa in some platforms).
4. Change the permissions of the generated .pub file to 600 by commanding chmod 600 id_dsa.pub
5. Copy the public key to the server with
scp id_dsa.pub user@server:~/.ssh/authorized_keys
(Caution: if that destination file already exists on the server, copy first to a different file foo and then append the contents with cat foo >> authorized_keys executed on the server).
6. Done!!! Verify that now you can connect directly from the client with ssh user@server without being prompted for a password or username.
7. If it doesn't work, verify that in the server your home directory, the ~/.ssh subdirectory, and the authorized_keys file do not have writing permissions to others. If they do, they won't be considered to grant access. You can correct this with something like:
chmod 755 ~ 0
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
8. If it still doesn't work, try changing the authorized_keys file name to authorized_keys2, or ask your system administrator what file name is ssh actually using.
9. If it worked, you can now run SCP in batch mode with the -B option, as in
scp -B foofile user@server:~/foodir/
Notes
The name of the server must have been registered in the known_hosts. This can be done with a regular (with password) ssh connection, and accepting the host as known. Then, the host name should be the same as the one accepted!!! If you used user@server first, do not use user@server.domain.tk later on!!!
SSH protocol 2 is assumed in this procedure (it uses dsa keys). If your ssh configuration files (at /etc/ssh/) do not establish this as a default, you may have to force it with the -2 option of the ssh and scp. Moreover, if the default public key is not configured to be "id_dsa.pub" you can specify what key to use for identification with the -i option.
The same procedure worked fine when the username was different in both machines. I simply copied userA's public key at the end of userB's authorized_keys file, then I could login from my client as userA with ssh userB@server.
References
http://www.atmos.albany.edu/facstaff/rmctc/ssh2/brandenb-Ssh.html
OpenSSH manual