Using Google Cloud Storage for media upload

This is the third post of “Running WordPress on Managed VMs” series. Originally App Engine PHP Runtime provides a very handy stream wrapper for accessing Google Cloud Storage. In this post, I will show you how to utilize this stream wrapper on Managed VMs and use GCS as the media storage for your WordPress blog.

Create a Google Cloud Storage bucket

Let’s create a bucket. You can create a default App Engine bucket at: https://console.developers.google.com/appengine/settings. The default App Engine bucket looks like YOUR_PROJECT_ID.appspot.com. Then change the default acl of that bucket as follows:

 $ gsutil defacl ch -u AllUsers:R gs://YOUR_PROJECT_ID.appspot.com

By this command, all of the new files in this bucket is publicly readable by default. This is appropriate for using it as a Media storage for WordPress.

Install App Engine PHP SDK and activate the stream wrapper

Install App Engine PHP SDK with composer.

$ composer require google/appengine-php-sdk

Add a required extension in php.ini:


Then add the following lines to wordpress/wp-config.php:

set_include_path(__DIR__ . '/../vendor/google/appengine-php-sdk');

require_once(__DIR__ . '/../vendor/autoload.php');

define('MY_BUCKET', 'YOUR_PROJECT_ID.appspot.com');

Then now you can use “gs://” stream wrapper on production environment. Unfortunately this stream wrapper doesn’t work locally.

Create a simple plugin for tweaking upload_dir

Create a new file `wordpress/wp-content/plugins/gcs-media.php` with the following:

 * @package GCS media
 * @version 0.1
Plugin Name: GCS media
Plugin URI: https://wp.gaeflex.ninja/
Description: Use Google Cloud Storage for media upload.
Author: Takashi Matsuo
Version: 0.1
Author URI: https://wp.gaeflex.ninja/
License: Apache 2.0

namespace GCS\Media;

defined( 'ABSPATH' ) or die('No direct access!');

add_filter('upload_dir', 'GCS\Media\filter_upload_dir');
function filter_upload_dir( $values ) {
    $basedir = 'gs://' . MY_BUCKET;
    $baseurl = 'https://storage.googleapis.com/' . MY_BUCKET;
    $values = array(
        'path' => $basedir . $values['subdir'],
        'subdir' => $values['subdir'],
        'error' => false,
    $values['url'] = rtrim($baseurl . $values['subdir'], '/');
    $values['basedir'] = $basedir;
    $values['baseurl'] = $baseurl;
    return $values;

Then deploy the app and activate the plugin by `activate` the GCS Media plugin:

Screenshot 2016-03-05 at 11.15.18 PM

Upload any images, then you’ll see the images are uploaded to the Google Cloud Storage bucket! The image editor still doesn’t work, but this is not a big problem for me. Also, I don’t think this stream wrapper will work any environments other than Managed VMs. When there is a more portable stream wrapper implementation is available, I will migrate to it and update this post.


By using App Engine PHP SDK, you can use some nice features of App Engine on Managed VMs too. In this post, we activated the Google Cloud Storage stream wrapper in the SDK and did a quick hack for changing the upload directory by writing a simple WordPress filter. Now my blog can have images 🙂 In the next post, I will activate batcache backed with memcached object cache for better performance.

Leave a Reply

Your email address will not be published. Required fields are marked *

By submitting this form, you accept the Mollom privacy policy.