How to Install WordPress in Google App Engine Standard Environment

WordPress and App Engine

Have you ever wondered about other alternative ways to install and run your WordPress website? In this article, I’m going to explain how you can install and run a WordPress inside Google App Engine.

Prerequisites

  1. Create a project in the Cloud Console.
    You need to have one project in Google Cloud to work with any of the google cloud services, In this project, we will make use of Cloud SQL API and Google App Engine which required us to have such a project before using them.
  2. Enable billing for your project.
    It is always a best practice to enable billing in a Cloud service project to avoid surprising cloud billings.
  3. Install the Cloud SDK.
    Cloud SDK is required to install into your local device, then it will allow us to access the Google Cloud Services through the command line easily.
  4. Enable the Cloud SQL API.
    Because WordPress required to access MySQL, we will make use of the Google MySQL service for that.
Select your project
API should be enabled as shown in the above picture.

5. Install Composer.
Composer is a Dependency Manager for PHP, we will use it to install a couple of supporting packages for this process as WordPress is written in PHP. [NOTE: Composer requires PHP 5.3.2+ to run. ]

php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"php -r "if (hash_file('sha384', 'composer-setup.php') === '756890a4488ce9024fc62c56153228907f1545c228516cbf63f885e036d37e9a59d27d63f46af1d4d07ee0f76181c7d3') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"php composer-setup.phpphp -r "unlink('composer-setup.php');"mv composer.phar /usr/local/bin/composer 
Installing Composes into Mac

Once you are ready with the above prerequisites, the next step is to Configure the Cloud SQL for the MySQL instance

Configure a Cloud SQL for MySQL instance

Note: In this guide, we use wordpress for the instance name and the database name. We use root for the database user name.

  1. Create a new Cloud SQL for MySQL Second Generation instance with the following command:
gcloud sql instances create wordpress \
--activation-policy=ALWAYS \
--tier=db-n1-standard-1 \
--region=us-central1 \
--project=myproject # Replace with project name created in step 1

NOTE: you can choose db-f1-micro or db-g1-small instead of db-n1-standard-1 for the Cloud SQL machine type, especially for development or testing purposes. However, those machine types are not recommended for production use and are not eligible for Cloud SQL SLA coverage. See the Cloud SQL SLA for more details.

Also, look at the instance types and pricing for more details:

Creating the Instance

This process will take a bit of time to complete. Once it completed, you will see an output similar to below:

Instance created successfully

Now we have created a Cloud SQL instance for us to use, next step is to create a database for the WordPress site that we are going to create.

2. Create the database you want your WordPress site to use:

gcloud sql databases create wordpress --instance wordpress
Database created successfully

Now we have created a MySQL database called “wordpress” inside the CloudSQL instance that we created above. Alright, Next we need to set up a root password for the instance we created above.

3. Change the root password for your instance:

NOTE: As a password, you can choose any password of your choice.

gcloud sql users set-password root \
--host=% \
--instance wordpress \
--password=YOUR_INSTANCE_ROOT_PASSWORD # Use your password!

Once you enter the above command with your password, You should see an output similar to below:

Password update success

Alright, we are now done with creating the Cloud SQL for MySQL instance, Next, we need to Create a WordPress project for App Engine.

Create a WordPress project for App Engine

In order to interact with WordPress with App Engine, there is a package given by google with cloud-tools, called wp-gae , It provides a convenient way for you to either create a new WordPress project or add the required configuration to an existing one. That’s why we need to have the PHP package managecomposer.

Setting up wp-gae :

  1. Download the google/cloud-tools package:
composer require google/cloud-tools

If you are successfully installed the google/cloud-tools you will see an output similar to below.

Successful google/cloud-tools install

Note: If you receive an error about extensions, install phar and zip PHP extensions and retry:

sudo apt-get install php7.2-zip php7.2-curl

2. Now you can run the wp-gae command which is included in that package:

php vendor/bin/wp-gae

If you are successful, then when you enter the above command you will see an output similar to below.

NOTE: You can also install google/cloud-tools globally, which will allow you to execute the command wp-gae anywhere.

The wp-gae command will ask you several questions in order to set up your Cloud SQL database connection, and then write the required configuration to your wp-config.php configuration file. It also copies the following files into your project directory to allow WordPress to run on App Engine:

  • app.yaml: The App Engine configuration file which specifies the runtime and static asset handlers.
  • cron.yaml: The App Engine configuration file that ensures wp-cron.php is run every 15 minutes.
  • php.ini: For setting PHP configuration in App Engine specific to WordPress.
  • gae-app.php: The Front Controller, which is required for all App Engine applications.

Now we are ready to Create our WordPress project in GCP. Let’s see how we can achieve it in the next section.

NOTE: As I’m writing this article in 2021, gae project defaults to PHP 7.2 version. https://github.com/GoogleCloudPlatform/php-tools/blob/master/src/Utils/WordPress/files/app.yaml

Create a new WordPress project

To download WordPress and set it up for GCP, run the create command:

php vendor/bin/wp-gae create

The command asks you several questions. After you answer them, you’ll have a new WordPress project. By default, it will create my-wordpress-project in the current directory. But if you need a different name you can specify when it asks for a directory name. In my case I chose service-wp. Also, you might need the following details to answer the questions;

To determine the region your database is in:

gcloud sql instances describe wordpress | grep region

To get the project id:

gcloud projects list # Look for your created project and find the id
Download WordPress and Setup for GCP

But if you are facing an error as follows :

Possible Error

This means your PHP version does not have the zip module installed, You can confirm this by executing the following command in your terminal

php -m | grep zip
Success output of the above command

If you don’t see any output you can use the following commands to resolve the issue for you if you are on macOS; If not you need to find a solution to install this zip module to PHP version to your OS version.

brew update
brew install php@7.3 # Check your PHP version
brew link php@7.3 # Check your PHP version

If everything is above successful, again try the above failed command and this should be successful this time. So then you should see a folder structure similar to below:

WordPress service folder structure

Then we have to deploy the created service Google Cloud and verify the steps we followed.

Deploy to Google Cloud

Go to the root of your WordPress project:

cd service-wp

Run the following command to deploy your project to App Engine:

gcloud app deploy app.yaml cron.yaml

Now you should be able to access your website in the following URL if everything has worked as expected.

https://YOUR_PROJECT_ID.appspot.com/

If you are successful, then you should see the default WordPress setup page as follows:

Successful Page Load

NOTE: If you receive any error in your application, such as “Error establishing a database connection”, set the WP_DEBUG constant to true in wp-config.php and redeploy:

define('WP_DEBUG', true);

Enable the Google Cloud Storage plugin

App Engine file system is read-only, so naturally, it is not possible to upload any files directly, but this problem is solved when you install the Google Cloud Storage plugin.

To use the Google Cloud Storage plugin for media uploads, follow these steps:

  1. Goto: Cloud Console Storage page and create a bucket with a name you like, in my case it is mp_wordpress;
  2. Update permission of that to enable the Access control permission to be fine-grained as follows.
Modify permission

3. Change the default Access Control List (ACL) of that bucket as follows:

gsutil defacl ch -u AllUsers:R gs://<your_bucket_name>
Update ACL of the Bucket

2. Go to the Dashboard at https://YOUR_PROJECT_ID.appspot.com/wp-admin. On the Plugins page, Activate the Google Cloud Storage plugin.

Enable Google Cloud Storage Plugin

Then you will see the Settings button and click on it.

Click on the Settings button

Then update your bucket name which you created in step 1.

Update bucket name

After activating the plugin, try uploading a media object in a new post and confirm the image is uploaded to the Cloud Storage bucket by visiting the Cloud Console Storage page.

Hope you successfully followed the steps above and able to see the uploaded images in the cloud storage bucket you created.

Local development

To access this MySQL instance, use Cloud SQL Proxy. Download it to your local computer and make it executable.

Install in Cloud Shell:

Find the correct distribution based on your OS here: Distributions

# Example: Download For Ubuntu
wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64 -O cloud_sql_proxy
# Make it executable
chmod +x cloud_sql_proxy

In my case it’s macOS:

# Example: Download For Ubuntu
wget https://dl.google.com/cloudsql/cloud_sql_proxy.darwin.amd64 -O cloud_sql_proxy
# Make it executable
chmod +x cloud_sql_proxy

If you don’t have wget in mac install using the following command:

brew install wget

Go to the Credentials section of your project in the Console. Click Create credentials and then click Service account key. For the Service account, select the App Engine app default service account. Then click Create to create and download the JSON service account key to your local machine. Save it to a safe place.

Run the proxy by the following command:

./cloud_sql_proxy \
-instances=YOUR_PROJECT_ID:us-central1:wordpress=tcp:3306 \
-credential_file=/path/to/YOUR_SERVICE_ACCOUNT_JSON_FILE.json &
Starting the Cloud SQL Proxy

If running within Cloud Shell:

./cloud_sql_proxy -instances <YOUR_PROJECT_ID>:us-central1:wordpress=tcp:3306 &

NOTE: See Connecting to Cloud SQL from External Applications for more options when running the Cloud SQL proxy.

Now you can access the Cloud SQL instance with the MySQL client in a separate command-line tab.

NOTE: Also if you see an error as follows, it means you have an active instance of MySQL running on your machine; So you need to find that service and stop it.

2021/06/16 14:19:32 listen tcp 127.0.0.1:3306: bind: address already in use

You can use the following command to check the running process on port 3306.

sudo lsof -i tcp:3306
Already running program on port 3306

Then you can kill the running process as follows;

sudo kill 2383

NOTE: For that, you need to have MySQL installed on your machine. If you don’t have MySQL installed, then follow this Install MYSQL article.

mysql --host=127.0.0.1 -u root -p

Then enter the password you used for the Google Cloud MySQL client DB above. If successful you will see the mysql prompt, and try following commands.

use wordpress;
show tables;
exit

If you are successful; You would see an output as follows for the above commands.

Install and update WordPress, plugins, and themes

Because the wp-content directory on the server is read-only, you have to perform all code updates locally. Run WordPress locally and update the plugins and themes in the local Dashboard, deploy the code to production, then activate them in the production Dashboard. You can also use the wp-cli utility as follows. Be sure to keep the Cloud SQL proxy running.

# Install the wp-cli utility
composer require wp-cli/wp-cli-bundle
# After that you can do any of the followings as you need.# You can install wordpress pulgins as follows
# Plugin slugs canbe found end of the URL (i.e: wordfence) :
# https://wordpress.org/plugins/wordfence/
Syntax: vendor/bin/wp plugin install <plugin-slug> --activate --path=<project-path>
vendor/bin/wp plugin install wordfence --activate --path=service-wp
# You can install wordpress themes as follows
# Theme slugs canbe found end of the URL (i.e: install) :
# https://wordpress.org/themes/twentytwenty/
Syntax: vendor/bin/wp theme install <theme-slug> --activate --path=<project-path>
vendor/bin/wp theme install twentytwenty --activate --path=service-wp
# You can run the "wp" command to update Wordpress itself as follows
Syntax: vendor/bin/wp core update --path=<project-path>
vendor/bin/wp core update --path=service-wp
# You can update all the plugins as follows
Syntax: vendor/bin/wp plugin update --all --path=<project-path>
vendor/bin/wp plugin update --all --path=service-wp
# You can update all the themes as follows
Syntax: vendor/bin/wp theme update --all --path=<project-path>
vendor/bin/wp theme update --all --path=service-wp

NOTE: Also note that after any of the above steps you need to deploy the project as follows to reflect the changes in the app engine deployed version.
gcloud app deploy app.yaml cron.yaml

The following errors might occur during the above process;

Error 1:

For example, when you try to install a new plugin you will see an error output as follows;

This happens when you have a mismatching version of guzzlehttp/guzzle module found inside the project vendor folder and inside the following folder;

your-project-folder/wp-content/plugins/gcs/vendor

In order to resolve this issue; you need to exact the same version of the guzzlehttp/guzzle in the above into your project vendor modules;

You can check the version of the module in each location by looking at the CHANGELOG.md file inside each module directory like below.

Inside the plugins directory
Inside the project vendor directory

In order to install the exact same version as the your-project-folder/wp-content/plugins/gcs/vendor ; Use the following command;

composer require guzzlehttp/guzzle:6.3.3
Installing guzzlehttp/guzzle module with version 6.3.3

Then if you try to install the above plugin or any of the above commands it should work as follows;

Installing wordfence Wordpress plugin

Error 2:

Failed opening required 'google/appengine/api/urlfetch_service_pb.php'

If you get this error, you can set a WP_CLI_PHP_ARGS environment variable to add include_path PHP configuration for wp-cli:

export WP_CLI_PHP_ARGS='-d include_path=vendor/google/appengine-php-sdk'

Then try the update commands again.

After everything is up to date, deploy the app again:

gcloud app deploy app.yaml cron.yaml

NOTE: This will deploy a new version of the app and set it as the default while keeping the previous versions available under versioned hostnames. Visit the App Engine, Versions area to see previous versions.

Alternately, you may deploy the new version and stop previous ones so they stop incurring charges:

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

I hope you were able to follow the tutorial successfully, let me know if this helped you. Thanks 😊

Versatile Full-stack Developer with 5+ years of experience designing, developing, and managing complex applications and internal frameworks.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store