Tuesday, July 30, 2013

Machine Configs for Bash Php & Apache


System wide configs for Bash, Php, and Apache (Php).

 We are vitalizing our systems and want to get to a standard config that will allow our single code base to run on many servers that may be utilizing other servers for services such as MySQL, Memcached, NFS shares and so on. The idea is that the server itself could hold the config necessary for it to communicate with its sibling systems.

Example Diagram:


Notice how the top section is web, middle is database, and bottom is storage.
Now each set of web servers could communicate with one or more databases and storage servers. But how do you let your code know which ones it should be using?

Here is where I am breaking off into Environment Variables!

   

Environment Variables.

By creating a single set of OS based environment variables, we can share the same config across all code on a server and standardize the setup for a new server that looks at other service providers.

Step 1: Profile Configs.

All login shell connections have a profile with "configs" that are loaded via /etc/profile.d (CentOS) or something similar.  I created a file in profile.d that will auto load with most things like executing a Php CLI script via login shell. Then it just takes a few tweaks for Apache and others. ( Environment Variables 1 2 )

/etc/profile.d/custom.config.sh
export MYVAR=this custom var
export MYVAR2=another custom var
 Now, to load this into Apache you first need to add
. /etc/profile.d/custom.config.sh
to your /etc/sysconfig/httpd file. This tells apache to source that file when restarting.
Next you need to tell Apache what to include into its SERVER variables. It is inclusive only, so you need to specify the variable for them to be included. I did this in the main /etc/httpd/conf/httpd.conf file, but you should be able to do it an any of the /etc/httpd/conf.d/files.

Example:

PassEnv MYVAR MYVAR2
Now, this will allow these variables to be passed to Apache Php scripts for use. Here is a Php script to test your output.

test.php

 <?php
echo "<pre>SERVER\n";
print_r($_SERVER);
echo "ENV\n";
print_r($_ENV);
exit;
 This should show something like this..
SERVER
Array
(
    [HTTP_AUTHORIZATION] =>
    [MYVAR] => this custom var
    [MYVAR2] => another custom var

    [HTTP_HOST] => www.bla.com
    [HTTP_USER_AGENT] => Mozilla/5.0 (Windows NT 6.1; WOW64; rv:22.0) Gecko/20100101 Firefox/22.0
    [HTTP_ACCEPT] => text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    [HTTP_ACCEPT_LANGUAGE] => en-US,en;q=0.5
    [HTTP_ACCEPT_ENCODING] => gzip, deflate
    [HTTP_CONNECTION] => keep-alive
    [PATH] => /sbin:/usr/sbin:/bin:/usr/bin
    [SERVER_SIGNATURE] =>
Apache/2.2.15 (CentOS) Server at www.bla.com Port 80


    [SERVER_SOFTWARE] => Apache/2.2.15 (CentOS)
    [SERVER_NAME] => www.bla.com
    [SERVER_ADDR] => 10.128.1.100
    [SERVER_PORT] => 80
    [REMOTE_ADDR] => 10.128.1.58
    [DOCUMENT_ROOT] => /var/www/vhosts/bla/website/www/
    [SERVER_ADMIN] => admin@bla.com
    [SCRIPT_FILENAME] => /var/www/vhosts/bla/website/www/index.php
    [REMOTE_PORT] => 57829
    [GATEWAY_INTERFACE] => CGI/1.1
    [SERVER_PROTOCOL] => HTTP/1.1
    [REQUEST_METHOD] => GET
    [QUERY_STRING] =>
    [REQUEST_URI] => /
    [SCRIPT_NAME] => /index.php
    [PHP_SELF] => /index.php
    [REQUEST_TIME_FLOAT] => 1375211324.713
    [REQUEST_TIME] => 1375211324
)
ENV
Array
(
)
   

 Overriding the Variables per Virtual Host

Another awesome thing is that you may override the variables per virtual host on the machine. This will allow us to override the config for one V.H. using SetEnv which is part of Apache Module mod_env.

Example config:

# bla.com public
<VirtualHost *:80>
    DocumentRoot /var/www/vhosts/bla/website/www/
    ServerName www.bla.com
    ServerAlias bla.com
    ErrorLog logs/www.bla.com-error_log
#  CustomLog logs/www.bla.com-access_log combined
    <Directory /var/www/vhosts/bla/website/>
        AllowOverride All
    </Directory>
    SetEnv SITE_NAME bla.com
    SetEnv MYVAR 192.168.0.100
    SetEnv MYVAR 192.168.0.100

</VirtualHost>

BASH

Now some more details on how to get these variables into BASH and Crontab Php Scripts.
#!/bin/bash -l
This is how to use bash to act as a shell login (-l) which will load the profile configs and hence our custom environment variables.

Example BASH script to test variables

#!/bin/bash -l
set > test.sh.txt

CRONTAB

We are down to the end here, with slight wave of the hand we can pass the environment variable to php crontab scripts also. This is done by using the bash -l command to do a shell login call and using the -c with executes a command via bash.

Example CRONTAB

[root@web1 vhosts]# crontab -l
# *    *    *    *    *  command to execute
# .    .    .    .    .
# .    .    .    .    .
# .    .    .    .    .
# .    .    .    .    ...... day of week (0 - 6) (0 to 6 are Sunday to Saturday, or use names)
# .    .    .    ........... month (1 - 12)
# .    .    ................ day of month (1 - 31)
# .    ..................... hour (0 - 23)
# .......................... min (0 - 59)

* * * * * cd /var/www/vhosts/; bash -l -c ./test.php
* * * * * cd /var/www/vhosts/; ./test.sh

Example Php Script ./test.php

#!/usr/local/bin/php
<?php

file_put_contents('./test.php.txt',var_export($_SERVER,true));