Taking Advantage of Environment Variables in OpenShift PHP Apps

Environment variables (ENV) are an important aspect of OpenShift PaaS. PHP is one of the most prominent languages on OpenShift. In my blog post I do want to show you how you can/should use ENV to consume information from OpenShift.

Cartridges

OpenShift's concept of cartridges gives you full control of the application servers, databases, and similar functionality you want to run on the platform. Any user can deploy any cartridge from any possible place (in Online it needs to be a publically accessible location) . Cartridges may need to expose some information to the user's application and setting environment variables (ENV) is the OpenShift solution. For sure, there are different possible approaches, but ENV provides a solid base that is simple to extend and relatively secure in your application.

Environment variables help you to separate concerns of you application regarding configuration. If your application uses environment variables as a way to consume configuration, it is independent on the runtime environment. Then if you decide to move the application somewhere else, you just need to provide new environment variables and you are not forced to change the code.

Also environment variables play important role with scaling. Because when you do scale your storage system, you may have different endpoints to access it. By consuming the configuration from environment variables, the platform can inject the information based on the current state of the cluster.

ENV

In every operating system there is this concept of ENV. In some it's easy to hook up, in some it is a bit more difficult. However, in the end you end up with the same result. The operating system or the process that is starting your application can expose information to that application.

Linux way

What we do in Linux is to export the environment variables and the process that is being started will inherit all these information.

export MY_ENV_VAR="some information"

OpenShift

In OpenShift we have several ways to provide env variables.

A legacy way is to edit the .openshift/action_hooks/pre_start_php-5.3 script and use the command mentioned before to export your information. OpenShift by itself and also through cartridges exports some information. You can get a list of OpenShift based ENV here.

The new way is to use command line tool rhc to set the values of environment variables. This has one big advantage, as the configuration is completely independent from your source-code. How to do that?

rhc set-env VARIABLE1=VALUE1 VARIABLE2=VALUE2 -a myapp

this way you set up 2 environment variables. If you have more information to set, this may be cumbersome. In such a case you can load the information from a file. Create a simple text file

VARIABLE1=VALUE1
VARIABLE2=VALUE2

and load it using the command-line tool

rhc set-env /path/to/file -a myapp

OpenShift will inject all the information into your gears and you do not need to save it in your git repository. Cool, isn't it?

PHP

In PHP, there is special global variable called $_ENV that is an associative array that contains all the environment variables that are available through the OS and the PHP server. With the example from the previous code, I can access the variable by

<?php
echo($_ENV["MY_ENV_VAR"]);
?>

The same way you would access the environment variables exposed by OpenShift

<?php
echo($_ENV["OPENSHIFT_APP_NAME"]);
?>

Environment variables are preferred way to expose configuration parameters to applications.

Example with MySQL

Let's say you create a php based application with MySQL

rhc app create myapp php-5.3 mysql-5.1

Now, if you want to connect to MySQL from your PHP code, you would use something like with PDO

define('DB_HOST', getenv('OPENSHIFT_MYSQL_DB_HOST'));
define('DB_PORT',getenv('OPENSHIFT_MYSQL_DB_PORT')); 
define('DB_USER',getenv('OPENSHIFT_MYSQL_DB_USERNAME'));
define('DB_PASS',getenv('OPENSHIFT_MYSQL_DB_PASSWORD'));
define('DB_NAME',getenv('OPENSHIFT_GEAR_NAME'));
 
$dsn = 'mysql:dbname='.DB_NAME.';host='.DB_HOST.';port='.DB_PORT;
$dbh = new PDO($dsn, DB_USER, DB_PASS);

Conclusion

That's how easy it can be. Using environment variables is easy and it's a good way to help you to decouple configuration from your application. It is also a good way to keep your code the same even when you move between machines.

What's Next?