cloudfoundry-samples/cf-ex-wordpress

Name: cf-ex-wordpress

Owner: Cloud Foundry Sample Applications

Description: CloudFoundry PHP example application: Wordpress

Created: 2013-06-25 15:34:42.0

Updated: 2017-10-25 20:15:32.0

Pushed: 2016-08-23 12:33:26.0

Homepage: null

Size: 6496

Language: Python

GitHub Committers

UserMost Recent Commit# Commits

Other Committers

UserEmailMost Recent Commit# Commits

README

CloudFoundry PHP Example Application: Wordpress

This is an example application which can be run on CloudFoundry using the PHP Build Pack.

This is an out-of-the-box implementation of Wordpress 4.0. It's an example of how common PHP applications can easily be run on CloudFoundry.

Usage
  1. Clone the app (i.e. this repo).

    clone https://github.com/dmikusa-pivotal/cf-ex-wordpress.git cf-ex-wordpress
    f-ex-wordpress
    
  2. If you don't have one already, create a MySQL service. With Pivotal Web Services, the following command will create a free MySQL database through ClearDb.

    reate-service cleardb spark my-test-mysql-db
    
  3. Edit the manifest.yml file. Change the 'host' attribute to something unique. Then under “services:” change “mysql-db” to the name of your MySQL service. This is the name of the service that will be bound to your application and thus used by Wordpress.

  4. Like every normal Wordpress install, edit htdocs/wp-config.php and change the secret keys. These should be uniqe for every installation. You can generate these using the WordPress.org secret-key service.

  5. Push it to CloudFoundry.

    ush
    

    Access your application URL in the browser. You'll see the familiar Wordpress install screen. Setup your password and your all set.

How It Works

When you push the application here's what happens.

  1. The local bits are pushed to your target. This is small, five files around 25k. It includes the changes we made and a build pack extension for Wordpress.
  2. The server downloads the PHP Build Pack and runs it. This installs HTTPD and PHP.
  3. The build pack sees the extension that we pushed and runs it. The extension downloads the stock Wordpress file from their server, unzips it and installs it into the htdocs directory. It then copies the rest of the files that we pushed and replaces the default Wordpress files with them. In this case, it's just the wp-config.php file.
  4. At this point, the build pack is done and CF runs our droplet.
Persistent Storage

If you've ever used Wordpress before, you're probably familiar with the way that you can install new themes and plugins through the WebUI. This and other actions like uploading media files work by allowing the Wordpress application itself to modify files on your local disk. Unfortunatley, this is going to cause a problem when you deploy to CloudFoundry.

A naive approach to solving this problem is to simply bundle these files, themes, plugins and media, with your application. That way when you cf push, the files will continue to exist. There are multiple problems with this approach, like large and possibly slow uploads, tracking what's changed by actions in Wordpress and the fact that you probably don't want to push every time you need to upload media. Given this, it's likely that for any serious installation of Wordpress you want a better solution.

One possible better solution is to use one of the third party plugins for Wordpress which allow you to upload media files to a storage system like Amazon's S3. While this works great for media files, the plugins that I've seen do not address the issue of installing themes or plugins. Doing this looks like it would still require you to push all the files up with your application, which can be tricky cause there isn't a good way to manually install a Wordpress plugin or theme.

Enter the latest solution. As of CF release v183, CF now has support for FUSE enabled. Given this, it's possible to use FUSE to mount a remote file system that Wordpress can use to store your files. This solution works by mapping the wp-content directory to your persistent, remote file system. Because this is the directory where Wordpress installs themes, plugins and uploads media; the normal functionality of Wordpress simply works as you would expect.

To enable this support in this sample application, simply set the following environment variables in the manifest.yml file of this example.

| Variable | Explanation | ——————- | —————————————————–| | SSH_HOST | The user, host name or IP address and port of your SSH server. Ex: user@my.host.name:2222. Required. | | SSH_PATH | The full remote path of the directory to mount into the application file system. Required. | | SSH_KEY_NAME | The name of your SSH key. The public and private key need to be bundled with your application under the .ssh directory. These are used to authenticate with the remote SSH server. Required. | | SSH_OPTS | List of options passed through to sshfs. Defaults to none. Optional. |

Example:


ications:
me: <app-name>
mory: 128M
th: .
ildpack: https://github.com/dmikusa-pivotal/cf-php-build-pack.git
rvices:
mysql-db
v:
SSH_HOST: user@my-ssh-server.name
SSH_PATH: /home/sshfs/remote
SSH_KEY_NAME: sshfs
SSH_OPTS: '["cache=yes", "kernel_cache", "compression=no", "large_read", "Ciphers=arcfour"]'

When the above configuration is specified, the example application will take the information and mount the SSH_PATH to the wp-content directory of your Wordpress application. This means that anything in Wordpress that would normally be written to the local file system is actually written to the remote path on the SSH_HOST specified.

As with the other solutions, this one is not perfect either. Here are some things to be aware of with this solution.

Changes

These changes were made to prepare Wordpress to run on CloudFoundry.

  1. Edit wp-config.php, configure to use CloudFoundry database.
wp-config-sample.php    2013-10-24 18:58:23.000000000 -0400
wp-config.php   2014-03-05 15:44:23.000000000 -0500
14,18 +14,22 @@
@package WordPress


** Read MySQL service properties from _ENV['VCAP_SERVICES']
rvices = json_decode($_ENV['VCAP_SERVICES'], true);
rvice = $services['cleardb'][0];  // pick the first MySQL service

** MySQL settings - You can get this info from your web host ** //
 The name of the database for WordPress */
ine('DB_NAME', 'database_name_here');
ine('DB_NAME', $service['credentials']['name']);

 MySQL database username */
ine('DB_USER', 'username_here');
ine('DB_USER', $service['credentials']['username']);

 MySQL database password */
ine('DB_PASSWORD', 'password_here');
ine('DB_PASSWORD', $service['credentials']['password']);

 MySQL hostname */
ine('DB_HOST', 'localhost');
ine('DB_HOST', $service['credentials']['hostname'] . ':' . $service['credentials']['port']);

 Database Charset to use in creating database tables. */
ine('DB_CHARSET', 'utf8');
Caution

Please read the following before using Wordpress in production on CloudFoundry.

  1. Wordpress is designed to write to the local file system. This does not work well with CloudFoundry, as an application's local storage on CloudFoundry is ephemeral. In other words, Wordpress will write things to the local disk and they will eventually disappear. See the Persistent Storage above for ways to work around this.

  2. This is not an issue with Wordpress specifically, but PHP stores session information to the local disk. As mentioned previously, the local disk for an application on CloudFoundry is ephemeral, so it is possible for you to lose session and session data. If you need reliable session storage, look at storing session data in an SQL database or with a NoSQL service.

License

This project is licensed under the Apache v2 license.


This work is supported by the National Institutes of Health's National Center for Advancing Translational Sciences, Grant Number U24TR002306. This work is solely the responsibility of the creators and does not necessarily represent the official views of the National Institutes of Health.