Chapter 5. Environment and Application Management

Once you have added the application cartridges you need and pushed your code to the cloud, you will hopefully hit the OpenShift URL and find your app just works. Now is the time to throw your hands in the air and do a happy dance; this is the awesomesauce of Platform as a Service. Once you are all danced out, you might realize there are some aspects of your application you would like to explore further or tweak; the next few pages will help with that.

In this chapter, you will learn how to access your application’s container, view its log output, and fiddle with its configuration should the need arise. We will explain how to connect to your application’s gear via SSH, how to view and set OpenShift environment variables, and how to access application logs. We will also show how to make configuration changes to your application server or database and how to use marker files to set options such as hot deployment.

SSH Access

Your application’s remote container, called a gear, can be accessed using the Secure Shell (SSH) protocol in the same way as you access regular machines. To communicate with OpenShift securely, your OpenShift account must first contain an SSH public key belonging to the machine from which you wish to connect. This key is uploaded to OpenShift when you first run the terminal command rhc setup (see Chapter 2 for more on this); you can also add keys manually via the OpenShift Web Console’s Settings section.

The simplest way to connect to an application gear is to go to the command line, change into the directory where your app was cloned locally, and enter the command rhc ssh. This will start an SSH session with your main application gear. If the local clone of your application repository is not linked to your OpenShift app in RHC (in which case you will receive an error message), or you wish to SSH from another directory, you should add the -a appname option, replacing appname with the name of your app.

If you would prefer to use an alternative tool for creating an SSH connection, you can view the SSH URL you will need for your main application gear with the command rhc app show -a appname.

If your app is scalable and you would like to SSH into the other gears, you can use the command rhc app show --gears -a appname to view their SSH URLs and the ssh command-line tool to connect (e.g., ssh user@host).

Once you have connected to the gear via SSH, you will see a “Welcome to OpenShift console” message and a warning about making destructive modifications to your application; you should always take care when making changes on the gear directly as it is possible to make persistent, unversioned changes to your app and its environment. By default, you will find yourself in the home directory of the OpenShift user for your application, which will have a UUID username that doesn’t quite roll off the tongue. If you list the contents of the directory, you will see subdirectories for the cartridges on your gear, as well as Git, your app’s deployment history, and the app itself.

Here is the output from a sample SSH session with our Python demo application. We connect to the application gear, then use the ls command to list the contents of some of the key directories, starting with our OpenShift application user’s home directory:

[me@localhost ~/insultapp]$ rhc ssh
Connecting to 6e7672676e61676976757570@insultapp-osbeginnerbook.rhcloud.com ...

    *********************************************************************

    You are accessing a service that is for use only by authorized users.
    If you do not have authorization, discontinue use at once.
    Any use of the services is subject to the applicable terms of the
    agreement which can be found at:
    https://www.openshift.com/legal

    *********************************************************************

    Welcome to OpenShift console

    This console will assist you in managing OpenShift applications.

    !!! IMPORTANT !!! IMPORTANT !!! IMPORTANT !!!
    Shell access is quite powerful and it is possible for you to
    accidentally damage your application.  Proceed with care!
    If worse comes to worst, destroy your application with "rhc app delete"
    and recreate it
    !!! IMPORTANT !!! IMPORTANT !!! IMPORTANT !!!

    Type "help" for more info.


[insultapp-osbeginnerbook.rhcloud.com 6e7672676e61676976757570]\> ls
app-deployments  app-root  cron  git  postgresql  python
[insultapp-osbeginnerbook.rhcloud.com 6e7672676e61676976757570]\> ls app-root
build-dependencies  data  dependencies  repo  runtime
[insultapp-osbeginnerbook.rhcloud.com 6e7672676e61676976757570]\> ls app-root
/repo
app.py.disabled  data  Insult_App.egg-info  libs  README.md  setup.py  setup.pyc
setup.pyo  wsgi

The demo application uses a Python cartridge, so there is a Python directory in the application’s home directory. The app-root directory contains several important application subdirectories, notably repo, containing the current clone of the application’s Git repository, and data, which is a persistent directory you will read more about later in the book (see Chapter 8).

When accessing an application gear via SSH, you can run the usual Linux commands you might execute on a local machine. However, there are some restrictions. Your app runs within a container secured with SELinux, and you do not have root access. As you would expect, you cannot access other applications running on the same remote machine. If you receive “Permission Denied” errors, it is likely because you have attempted to overstep your bounds. Remember, you are a developer, not an administrator on your gear.

Using SSH to Interact with a Database

One set of useful commands you can run when connected to an application gear via SSH are those associated with your database cartridge. If you are using PostgreSQL, as we are in our demo application, you can access your application database from your SSH session with the psql command. In the following example, we connect to the database, issue the help command to see what options are available, and then use \q to quit:

[insultapp-osbeginnerbook.rhcloud.com 6e7672676e61676976757570]\> psql
psql (9.2.4)
Type "help" for help.

insultapp=# help
You are using psql, the command-line interface to PostgreSQL.
Type:  \copyright for distribution terms
       \h for help with SQL commands
       \? for help with psql commands
       \g or terminate with semicolon to execute query
       \q to quit
insultapp=# \q
[insultapp-osbeginnerbook.rhcloud.com 6e7672676e61676976757570]\>

The OpenShift environment has been configured so that psql connects using the admin username and password to the default database. You can always override these options using the normal methods you use with psql. You may also like to use other PostgreSQL commands such as pg_dump or pg_restore. If you are using MySQL, you may wish to run commands, such as mysql and mysqldump, or, for MongoDB, mongo and mongodump.

Importing SQL in an SSH Session

The ability to issue database commands in an SSH session provides one method of importing data into your OpenShift database. You can connect to the database and enter SQL manually if you want to test it out or edit something specific. Most times, though, you will want to import your data from a file.

One way you can transfer a SQL file to your database gear is to use the scp (secure copy) command. Here is an example of sending a file called import.sql to the persistent data directory on our example application gear. You can use the command rhc app show --gears to obtain the SSH URL of the gear:

[me@localhost ~/insultapp]$ scp import.sql 6e7672676e61676976757570@insultapp
-osbeginnerbook.rhcloud.com:~/app-root/data
import.sql                                      100% 5360     8.2KB/s   00:00

If your database cartridge shares a gear with your application cartridge, which it will if your app is not scalable, another way of copying your SQL file to your gear is to check it in to your Git repository. For our Insult App, we have added, committed, and pushed an import.sql file at the root level of the repository. It contains the full list of Shakespearean insults, split into nouns and adjectives. You can view the full contents of this file in the book’s Git repository (see Using Code Examples). Here is an excerpt:

DROP TABLE IF EXISTS short_adjective;
DROP TABLE IF EXISTS long_adjective;
DROP TABLE IF EXISTS noun;

BEGIN;

CREATE TABLE short_adjective (id serial PRIMARY KEY, string varchar);
CREATE TABLE long_adjective (id serial PRIMARY KEY, string varchar);
CREATE TABLE noun (id serial PRIMARY KEY, string varchar);

INSERT INTO short_adjective (string) VALUES ('artless');
INSERT INTO short_adjective (string) VALUES ('bawdy');
INSERT INTO short_adjective (string) VALUES ('beslubbering');

INSERT INTO long_adjective (string) VALUES ('base-court');
INSERT INTO long_adjective (string) VALUES ('bat-fowling');
INSERT INTO long_adjective (string) VALUES ('beef-witted');

INSERT INTO noun (string) VALUES ('apple-john');
INSERT INTO noun (string) VALUES ('baggage');
INSERT INTO noun (string) VALUES ('barnacle');

To import this data into our PostgreSQL database, we issue the following commands within an SSH session:

[insultapp-osbeginnerbook.rhcloud.com 6e7672676e61676976757570]\> cd app-root
/repo/
[insultapp-osbeginnerbook.rhcloud.com repo]\> psql -f import.sql

Our example application database is now populated and ready to help produce a bundle of new insults; we will alter our code to make use of this in the next chapter.

Tip

Executing database commands in an SSH session is not the only method of connecting to your app database; we will demonstrate how to connect via your app code in Chapter 6 and how to use port forwarding to facilitate access in Chapter 7.

Environment Variables

Only masochistic developers hardcode database connection strings or server ports; we have environment variables to save us from the pain of marrying code to a particular environment. OpenShift and its standard cartridges have a bunch of useful environment variables available out of the box that you can reference in your applications. It is also possible to set custom environment variables.

Warning

Due to some maintenance that the operations team may need to do, your application’s IP address can change. Hardcoding the values pointed to by the environment variables in your OpenShift application can cause it to break. So, in case you didn’t get the message, don’t hardcode the values of the environment variables.

You can view the values of some of the essential environment variables, such as your database details, in the output of the command rhc app show -a appname. To view all of the environment variables and their values, SSH into your application gear and execute the command env. To view only the environment variables with names including the word “OPENSHIFT,” use the command env | grep OPENSHIFT.

Preconfigured Environment Variables

Table 5-1 outlines some of the key preconfigured environment variables for our demo application. Other cartridges have similar variables: just replace PYTHON or POSTGRESQL with the relevant cartridge or database name.

Table 5-1. Useful environment variables
Environment variableValuePurpose

OPENSHIFT_APP_NAME

insultapp

Application name

OPENSHIFT_APP_DNS

insultapp-osbeginnerbook.rhcloud.com

Application domain name

OPENSHIFT_PYTHON_IP

19.66.2.6

IP address the app listens on

OPENSHIFT_PYTHON_PORT

8080

Port the app receives external requests on

OPENSHIFT_SECRET_TOKEN

Not shown for brevity

128-character string unique to the application and synced across all gears

OPENSHIFT_DATA_DIR

$OPENSHIFT_HOMEDIR/app-root/data/

Persistent data directory

OPENSHIFT_REPO_DIR

$OPENSHIFT_HOMEDIR/app-root/runtime/repo/

Currently deployed copy of the app

OPENSHIFT_TMP_DIR

/tmp/

Temporary directory; SELinux and PAM namespaces protect data from other users

OPENSHIFT_PYTHON_LOG_DIR

$OPENSHIFT_HOMEDIR/python/logs/

Cartridge-specific log directory

OPENSHIFT_POSTGRESQL_DB_LOG_DIR

$OPENSHIFT_HOMEDIR/postgresql/log/

Database log directory

OPENSHIFT_POSTGRESQL_DB_HOST

19.66.2.7

Database hostname or IP

OPENSHIFT_POSTGRESQL_DB_PORT

5432

Database port

OPENSHIFT_POSTGRESQL_DB_USERNAME

adminm4rvN42

Database username

OPENSHIFT_POSTGRESQL_DB_PASSWORD

SLat4aTfsSt1

Database password

Custom Environment Variables

Developers can extend the array of built-in environment variables by adding their own. One way to achieve this is to export the custom variables in one of the action hook scripts that runs before your application starts. For example, you could add the line export FOO=bar to .openshift/action_hooks/pre_start_python. Alternatively, you can create and set custom environment variables with RHC. This is the preferred solution if the values of your environment variables are sensitive and hence you would rather not check them in to your Git repository.

Custom environment variables can be managed with the RHC commands env set, env list, env show, and env unset. Here is an example of each command:

[me@localhost ~]$ rhc env set API_USERNAME=admin API_PASSWORD=secret -a
insultapp
Setting environment variable(s) ... done
[me@localhost ~]$ rhc env list -a insultapp
API_PASSWORD=secret
API_USERNAME=admin
[me@localhost ~]$ rhc unset API_PASSWORD -a insultapp
Removing environment variables is a destructive operation that may result in
loss of data.
API_PASSWORD

Are you sure you wish to remove the environment variable(s) above from
application 'insultapp'? (yes|no): yes

Removing environment variable(s) ... removed
[me@localhost ~]$ rhc env show API_USERNAME API_PASSWORD -a insultapp
API_USERNAME=admin

Overriding Preconfigured Environment Variables

Some preconfigured environment variables can be overridden: for example, OPENSHIFT_SECRET_TOKEN. This environment variable provides a random token string that is synchronized across gears. Example uses for this include cookie encryption, forming JBoss clusters, and seeding a Rails secret token. The OPENSHIFT_SECRET_TOKEN variable is set by default with a random value generated when the application is created. However, it can be overridden with RHC if you wish to replace it with a secret string you have generated yourself:

[me@localhost ~/insultapp]$ rhc env set OPENSHIFT_SECRET_TOKEN=new_token
Setting environment variable(s) ... done

You can override other preconfigured environment variables in the same fashion. These will then be listed alongside your custom variables when you run the command rhc env list. Some preconfigured environment variables are protected and cannot be overridden; you will receive an error message if you attempt to override one of these with RHC.

Log Access

To ensure your application is working correctly, or troubleshoot when it is not, you may want to view the log files. You can do this by connecting to the application gear via SSH and navigating to the relevant locations, which you can find by checking the environment variables as described in the previous section. In general, you will find the log directories for web cartridges can be referenced with $OPENSHIFT_<cartridge>_LOG_DIR and databases with $OPENSHIFT_<database>_DB_LOG_DIR. For example, our demo application’s logs are directed to $OPENSHIFT_PYTHON_LOG_DIR and $OPENSHIFT_POSTGRESQL_DB_LOG_DIR.

A simpler method for checking the logs is to use RHC’s tail command. By default, rhc tail -a appname will tail the log files within the cartridges’ log directories; in the case of our Python application, this means the files stored in $OPENSHIFT_HOMEDIR/python/logs and $OPENSHIFT_HOMEDIR_postgresql/log. However, you can specify a different or more specific set of files, relative to $OPENSHIFT_HOMEDIR, with the -f option. You can also set various Linux tail command options by adding -o.

The following command tails the insultapp application’s database logs only, outputting the last 50 lines rather than the default of the last 10:

[me@localhost ~]$ rhc tail -f postgresql/log/* -o '-n 50' -a insultapp

Application and database cartridges will be configured to output their logs to the directories referenced by the aforementioned environment variables by default. If you produce application-specific logs, you should direct these to your web cartridge’s log directory as well, e.g., $OPENSHIFT_PYTHON_LOG_DIR. Files in this directory will automatically be included in the output of the rhc tail command.

To learn how to manage disk usage and back up your remote files, including log files, see Chapters 8 and 9.

Changing Application Server or Database Settings

One of the advantages of using a Platform as a Service is that you do not have to tinker with dozens of configuration files just to get an app running in the cloud. That said, you may well want to alter the out-of-the-box config, and many cartridges facilitate that.

Application Server Configuration Changes

If you are coding in Java and using an application server such as Tomcat, JBoss, or WildFly, you can override server config files within your OpenShift Git repository. This is where you could change, for example, the application server’s log levels or settings for your data source. Look inside the .openshift/config directory to see which files have been cloned ready for modification. These configuration files will already include the relevant OpenShift environment variables, so you will want to use them as a starting point when making changes.

Many of the other application cartridges are Apache-based. You cannot edit the main httpd.conf file, but some cartridges do offer configuration options. One way to make Apache configuration changes to individual directories is by using .htaccess files. A common use case for this is adding an .htaccess file containing mod_rewrite directives to the /php directory in a WordPress application, so requests to the default OpenShift URL are redirected to a custom domain. For specific configuration options for your cartridge of interest, please refer to its documentation.

Database Configuration Changes

Another set of cartridges users may wish to reconfigure are the database cartridges. For example, you may want to change the log rotation frequency or tweak settings for resource usage or caching. If you need to change PostgreSQL’s configuration, you can edit the postgresql.conf file. If your application is not scalable, you can do this by using SSH to connect to your app gear, navigating to $OPENSHIFT_HOMEDIR/postgresql/conf, and opening the file with Vim, Nano, or some other editor. If your application is scalable, the PostgreSQL instance will have its own gear; use the command rhc app show --gears -a appname to view its SSH URL, then connect to the database gear with the ssh command (or your preferred SSH tool). The postgresql.conf file will be in the same location as on an application gear with an embedded PostgreSQL cartridge. Once you have made your changes, you can restart the PostgreSQL cartridge so that they take effect with the command rhc cartridge restart postgresql -a appname.

The general process for making config changes to other database cartridges is the same as described for PostgreSQL. In the case of MySQL, the relevant config file can be found at $OPENSHIFT_HOMEDIR/mysql/conf/my.cnf. The MongoDB config file is available at $OPENSHIFT_HOMEDIR/mongodb/conf/mongodb.conf.

Using Marker Files

Many basic OpenShift cartridge configuration options are controlled with marker files. If a particular marker file is present, the option is enabled; otherwise, the default behavior prevails. Marker files are added in an OpenShift application’s Git repository, in the .openshift/markers directory. The contents of marker files are irrelevant; they are empty files. They do not have any file extension.

One of the most common marker files used is hot_deploy—as mentioned in Hot-Deploying Code—which tells OpenShift to deploy new builds without restarting the cartridge server. Other marker files you may be interested in include force_clean_build (instructs OpenShift to remove previously built artifacts before building the app), disable_auto_scaling (prevents scalable applications from scaling according to load), and java7 (if this is removed, Java cartridges will use Java 6).

The marker files must be committed and pushed with Git. Here is an example of adding the force_clean_build marker to our example app:

[me@localhost ~/insultapp]$ touch .openshift/markers/force_clean_build
[me@localhost ~/insultapp]$ git add .openshift/markers/force_clean_build
[me@localhost ~/insultapp]$ git commit -m "Adding marker to force clean build"
[me@localhost ~/insultapp]$ git push

This will cause OpenShift to re-create the app’s virtual environment and reinstall the required Python eggs (these are code bundles, like JARs in Java). We do not want this to happen on every build as it takes time to download those dependencies, so once we are satisfied that the environment is clean we would remove the marker file.

It’s time to take a deep breath; we have learned a lot in this chapter. We showed how to use SSH to connect to your application’s gears and interact with databases hosted on OpenShift. We know that application configuration is easier to maintain when we use environment variables rather than hardcoded values; in this chapter we learned how to access the values of OpenShift’s environment vars and how to define our own. We discussed OpenShift application log access with rhc tail and where to direct app log output. Finally, we explained how to make application server and database configuration changes and how to control app config switches with marker files.

In the next chapter, we will dive into application dependencies and show how to connect to a database from your OpenShift app code.