Running WordPress on App Engine flexible environment

This is the fifth post of “Running WordPress on App Engine flexible environment” series. In this series, I have been doing some experiments to run WordPress on App Engine flexible environment. I think this is a good time to summarize them and show you how to configure WordPress from scratch for running on App Engine flexible environment. This is a long post, and also there are some redundant parts in it, but I’d like to make this post a complete standalone guide for running WordPress on App Engine flexible environment and I’ll update this guide and try to make it shorter overtime, so please bare with me.

In this post, we’ll configure WordPress as follows:

  • Leverage App Engine’s autoscaler
  • Use Cloud SQL 2nd generation
  • Use read-only file system for better security
  • Use Google Cloud Storage for media upload
  • Use Memcached service for caching pages


Configure Google Cloud SDK

Configure Google Cloud SDK with your account and the project.

$ gcloud auth login
$ gcloud config set project YOUR_PROJECT_ID

Let’s configure the GCS bucket for later use. The default App Engine bucket looks like YOUR_PROJECT_ID.appspot.com. Change the default acl of that bucket as follows:

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

Create and configure a Cloud SQL second generation instance

Let’s say we will use wp for various resource names; in particular for the instance name, the database name, and the user name.

You can create a new Cloud SQL second generation instance with the following command:

$ gcloud sql instances create wp \
  --activation-policy=ALWAYS \

Then change the root password for your instance:

$ gcloud sql instances set-root-password wp \
  --password YOUR_INSTANCE_ROOT_PASSWORD # Don't use this password!

To access this MySQL instance, we’ll use Cloud SQL Proxy. Please download an appropriate binary from the download page, make it executable.

If you haven’t created a service account for the project, please create it(Choose a new service account). Download the JSON key file and save it in a secure place.

Run the proxy by the following command:

$ cloud_sql_proxy \
  -dir /tmp/cloudsql \
  -instances=YOUR_PROJECT_ID:us-central1:wp=tcp:3306 \

Now you can access to the Cloud SQL instance with the normal MySQL client. Please create a new database and a user as follows (don’t use the example password below):

$ mysql -h -u root -p
mysql> create database wp;
mysql> create user 'wp'@'%' identified by 'PASSWORD';
mysql> grant all on wp.* to 'wp'@'%';
mysql> exit

In the above example, I created a new database wp and a new user wp.

Download and configure WordPress

We provide a convenient tool for downloading and configuring WordPress. Let’s use this tool here. First, clone one of our git repos:

$ git clone https://github.com/GoogleCloudPlatform/php-docs-samples.git

Then cd into the `php-docs-samples/appengine/wordpress` directory and run `composer install`.

$ cd php-docs-samples/appengine/wordpress
$ composer install

Then run the `wordpress-helper.php` as follows:

$ php wordpress-helper.php setup -d ~/my-wordpress-project

After answering few questions, you’ll have fully working WordPress installation at `~/my-wordpress-project` directory.

Run WordPress locally

Chdir to the project directory and run the following command to run WordPress locally:

$ cd ~/my-wordpress-project
$ vendor/bin/wp server --path=wordpress

If you’re on Windows, use wp.bat:

> cd C:\my-wordpress-project
> vendor/bin/wp.bat server --path=wordpress

Then access http://localhost:8080/. Finish the installation step. Login to the Dashboard and update if any of the plugins have update.

Now it’s ready for the first deployment.


Deploy your WordPress as follows:

$ gcloud app deploy --promote --stop-previous-version app.yaml cron.yaml

Then access your site, use the username and the password you created locally.

Go to the Dashboard, and in the Plugins page, activate the GCS media plugin and Batcache Manager plugin. Try uploading a media and confirm the image is uploaded to the GCS bucket.

Check if Batcache is working

In the plugin page, you should see these 2 drop-ins are activated as follows:


To make sure itโ€™s really working, you can open an incognito window and visit the site because the cache plugin only serves from cache to anonymous users. Then go to the memcache dashboard in the Cloud Console and check the hit ratio and number of items in cache.

Various workflows

Install/Update plugins/themes

Because the wp-content directory on the server is read-only, you have to do this locally. Run WordPress locally (`vendor/bin/wp server –path=wordpress`) and update plugins/themes in the local Dashboard, then deploy, then activate them in the production Dashboard. You can also use the wp-cli utility in the project’s vendor directory as follows (you have to run Cloud SQL Proxy or local mysql server for this tool to work):

# To update all the plugins
$ vendor/bin/wp plugin update --all --path=wordpress
# To update all the themes
$ vendor/bin/wp theme update --all --path=wordpress

Remove plugins/themes

First Deactivate them in the production Dashboard, then remove them completely locally. The next deployment will remove those files from the production environment.

Update WordPress itself

Most of the case, just download the newest WordPress and overwrite the existing wordpress directory. It is still possible that the existing config files are not compatible with the newest WordPress, so please update the config file manually in that case.

Update the image

We sometimes release the security update for the php-docker image. Then you’ll have to re-deploy your WordPress instance to get the security update.


We walked though how to run WordPress on App Engine flexible environment. Because the flexible environment is securely configured and we’re using Cloud SQL proxy for SQL access, so you can run your WordPress site in a secure manner. It performs well because we’re leveraging Memcached service provided by App Engine. Also thanks to the App Engine autoscaler, Google will automatically spin up new instances when your site is getting lots of traffic.

If you need to run new WordPress site, please give this guide a try and let us know what you think.

12 comments on “Running WordPress on App Engine flexible environment

  1. Thanks so much for the step by step guide, it was very helpful. Just a small piece of advice I would make a small recommendation / update for the guide. Some users may unknowingly open up their projects default cloud storage bucket unknowingly to the public with the above. A wordpress media-specific bucket may be a better choice.

    1. Jesse: Thanks for the suggestion. I think most of the cases, people only use the project for hosting the WordPress site, and then, in my opinion, it’s ok to make the default bucket with public access. It also comes for free.

      However, I may miss something. Are there any specific concerns about making the default bucket publicly accessible?

      Anyways, I think the script should ask you which bucket to use, defaulting to the cloud default bucket. Maybe I will make a change.

      Thanks again ๐Ÿ™‚

  2. Thanks for this tmatsuo! Works like a charm! There is only one exception though. By default GD is not enabled on the flexible PHP environment. As a result you are not able to crop images, neither play with it. Editing through media editor gives you a broken image.

    I’ve spent one day on this issue. Please change your template “php.ini” file to include the line “extension=gd.so”. That fixes the problem!

    Once again, thanks for this tutorial!

    1. @Bruno
      I tried enabling `gd.so`, but the media editor doesn’t work for me yet. Did you anything else to make it work?

      1. @Bruno

        It turned out that the “gd” extention in the PHP docker image doesn’t support JPEG, so that the image editor didn’t work for me! I will turn the JPEG support on and definitely add the “gd” extension to the script.


  3. Forget to ask:

    Is it an easy way to see how google can scale this up? Will the Cloud SQL scale accordingly?

    Can you also compare this method (APP Engine Flex) to using Container Engine regarding to maintenance, performance, and availability/scale? It seems that this solution will be cheaper, right?


Leave a Reply

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

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