WordPress

Using WordPress multisite with your own domains and Mailgun

In the real world, you probably want to use your own domain instead of a subdomain of appspot.com for your WordPres sites. Also often times you want to serve multiple blogs from one single WordPress installation. In this post, I will walk through how to map your own domain to your blog, how to configure WordPress multisite on App Engine flexible environment, and also how to configure mail capability with Mailgun. I started hiding the details of some of the steps by default (click to show details).

Prerequisites

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 \
  --tier=db-n1-standard-1

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 \
  -credential_file=PATH_TO_YOUR_SERVICE_ACCOUNT_JSON

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 127.0.0.1 -u root -p
mysql> create database wp;
mysql> create user 'wp'@'%' identified by 'PASSWORD';
mysql> grant all on wp.* to 'wp'@'%';
mysql> exit
Bye

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.

Create an SSL cert, configure App Engine domain mapping

Let me explain with my real domain shehas.net. I’m going to use wp.shehas.net for the base domain and use the subdomain option for the multisite installation. Thus other sites will have *.wp.shehas.net domain names. This time I’ll create self signed certificate for SSL access. Here I’m using Ubuntu Trusty. If you are using different OS, the file paths and details in the openssl.cnf file may different.

First take a backup of the original openssl.cnf.

$ sudo cp /etc/ssl/openssl.cnf /etc/ssl/openssl.cnf.org

Edit the openssl.cnf and make the following changes:

[ CA_default ]
..
..
copy_extensions = copy
..
..
[ v3_ca ]
..
..
keyUsage = digitalSignature, keyEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = wp.shehas.net
DNS.2 = *.wp.shehas.net

Then create a self signed certificate:

$ openssl genrsa -out wp.key
$ openssl req -new -x509 -key wp.key -sha256 -out wp.crt -days 730

Now you have a private key wp.key and an SSL cert wp.crt.

Go to Custom Domains Settings, verify your domain ownership, and add two subdomains; wp and *.wp.

Then go to App Engine SSL Certificate Settings, upload the private key and the cert, enable SSL access on the newly created 2 domains (wp and *.wp).

Now you’re ready for the first deployment!

Install WordPress and enable multisite

This time, we’re going to enable Multisite feature, so you need to add the following line to your wordpress/wp-config.php above the line reading /* That’s all, stop editing! Happy blogging. */:

define('WP_ALLOW_MULTISITE', true);

In some previous posts, I installed WordPress locally, but it will cause some issues related to site_url and home settings for the sites in the new Multisite network, so please deploy the app and install WordPress on App Engine flexible environment. Don’t forget to access the site immediately after the deployment. Otherwise anyone can take over your site!

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

Then access https://wp.shehas.net/, you should see the form for WordPress installation. Follow the instructions there and complete the WordPress installation.

Sign in to the WordPress Dashboard, and go to Administration > Tools > Network Setup. Choose Sub-domains, and fill the rest of the forms, then click Install button. On the next screen, WordPress shows you something like the following:

wordpress-network-setup

It says that you need to update both wp-config.php and .htaccess, but only take care of wp-config.php. You don’t have to add .htaccess.

Update the plugins and themes (you need to run Cloud SQL proxy for the wp command to do the job):

$ vendor/bin/wp plugin update --all --path=wordpress
$ vendor/bin/wp theme update --all --path=wordpress

Add the lines to wp-config.php above the line reading /* That’s all, stop editing! Happy blogging. */ then deploy your WordPress again with the following command(this time you don’t have to specify cron.yaml):

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

Now you can create a new site on the Network! On the multisite network, you can enable the plugins at the network level if the plugin is compatible with Multisite network. Let’s enable the gcs-media plugin at the network level so that you don’t have to enable it for every new domain.

For some reason that I still don’t understand, if you add a new site, the new site will have http site_url and home setting. You may want to fix them on the UI. Yes, this is annoying, probably WordPress fails to detect the schema. I’ll look into why, hopefully fix the issue and update here.

Send mails with Mailgun WordPress plugin

On Compute Engine (where App Engine flexible instances are running), normal SMTP ports (25, 465, 587, etc) are blocked. One option for sending mails is to use the erd party services like Mailgun, or SendGrid. In this post, I’ll use Mailgun because the Mailgun WordPress plugin supports multisite while the SendGrid WordPress plugin doesn’t support it as of Mar 26, 2016.

First download the Mailgun plugin:

$ vendor/bin/wp plugin install mailgun --path=wordpress

Add the following lines to wordpress/wp-config.php above the line reading /* That’s all, stop editing! Happy blogging. */:

// Mailgun
$_SERVER['SERVER_NAME'] = HTTP_HOST;
define('MAILGUN_USEAPI', true);
define('MAILGUN_APIKEY', '<replace this with your mailgun API key>');
define('MAILGUN_DOMAIN', '<replace this with your domain registered on Mailgun>');

Then deploy the app again:

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

After network activating the Mailgun plugin, you’ll start to receive e-mails.

Use WordPress MU Domain Mapping plugin

You may want to use WordPress MU Domain Mapping plugin. It works with the CNAME method on App Engine. Use ghs.googlehosted.com for the target domain of the CNAMEs. Also there are extra steps for verifying the domain ownership and setting up the domain mapping on Custom Domains Settings, and uploading an SSL certificate on App Engine SSL Certificate Settings if you want to use SSL on the new domain.

Conclusion

We walked through how to configure WordPress with multisite network enabled on App Engine flexible environment with custom domain SSL. This configuration allows you to host multiple blogs from the single WordPress installation. I also introduced the Mailgun WordPress plugin for sending e-mails. I hope this setup can meat many real world use cases with WordPress. Try it out and let us know what you think.

One comment on “Using WordPress multisite with your own domains and Mailgun

  1. Thank you for the detailed instructions. I’m successfully running WP-Multisite with custom domains on App Engine (Standard env). However, I noticed that my wp-cron tasks fail. That’s because it tries to execute [MY-PROJECT].appspot.com/wp-cron.php but WP-Multisite redirects such requests to https://[MY-CUSTOM-DOMAIN]/wp-signup.php?new=%5BMY-PROJECT%5D.appspot.com

    Do you know if there is any way to trick WP to correctly handle such /wp-cron.php requests or do I have to set up a new dummy blog with [MY-PROJECT].appspot.com as site URL?

    Thanks!

Leave a Reply

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

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