How To Deploy WordPress as a Headless CMS on Cycle

With the release of the WordPress REST API (version 4.7 circa 2016), WordPress developers started deploying the application as a headless CMS. As the WordPress community started to embrace this architecture, more and more developers are starting to use it in production. Now thanks to the growing number of plugins, WordPress as a headless CMS is starting to become the go-to deployment strategy.

In this guide, we will explore how to deploy a decoupled WordPress application with a React.js frontend using containers and Cycle. As an added bonus, this specific application will use GraphQL instead of the base WordPress JSON endpoint.

Before We Begin

I’ve added gifs to nearly every single step of this process so if you’re just looking for new ideas, feel free to follow along with the article and skip the following prerequisites.

If you wish to deploy this application to Cycle you’ll need a Cycle account, a hub, and a running server. To get that set up, head over to our docs and visit our quick start guide.

Create a Cycle Environment

Before we begin deploying our WordPress application, let’s create an environment. The environment we are going to use today will need to be set to Legacy Networking as WordPress doesn’t natively use IPv6. Enable Legacy Networking by selecting the Legacy Networking checkbox during environment create.

Legacy Networking Checkbox Legacy Networking Checkbox

Deploy WordPress and MySQL

Once the environment is up and running we can get started deploying our app. We’ll deploy the WordPress container first, using a custom WordPress image provided by Cycle.

  • Go to the container wizard by clicking Deploy Container on the top right of the environment dashboard.
  • Give your container a name of wordpress.
  • Select Stateful from the Stateful dropdown.
  • Leave Starting Instance Count, Deployment Strategy, and Tags with their default settings.
  • Choose Import New Image from the Image form.
  • Use Docker Hub to import the latest WordPress image. The Image Name field should be cycleplatform/wordpress and the Tag field will be latest.
  • After you click import the image will begin importing. When it’s finished, a dropdown menu will appear. You can select your newly imported image from this dropdown.
  • The images we are using have volumes associated with them, so you will see volume information appear below image select. Set the volume size to at least 10GB.
  • Set Public Network to Enabled.
  • The Hostname should be wordpress and will be automatically filled in to match the name of the container.
  • With all the settings in place, click Create Container.

Deploy Container Wizard

The cycleplatform/wordpress:latest image has the maximum file upload increased to allow for larger plugins to be uploaded.

Next, we will deploy a database container using MySQL version 5.7. You can accomplish this using the same workflow as the WordPress container, but the following 3 things will be different.

  1. The name and hostname of the container should be db.
  2. The Import form will need to be set with the Image Name of mysql and the Tag will be 5.7.
  3. Public Network will be set to Disabled.

Container Configuration

Now that both of the containers have been created, we can now configure our environment variables. By clicking theconfig tab on our container’s dashboard, we can access the container(s) config. After you’ve set the variables, be sure to click Save Config at the bottom of the page to save your settings.

Database Navigation Configuration Changing Environment Variables Navigate to the config and change your environment variables

The MySQL environment variables for this demonstration are:

MYSQL_DATABASE → wordpress
MYSQL_USER → wordpress
MYSQL_PASSWORD → wordpress
MYSQL_ROOT_PASSWORD → somewordpress

The WordPress environment variables for this demonstration are:


If you’ve created WordPress sites before and want to set these values differently, feel free.

Start your WordPress Application for the First Time

Navigate back to the environment dashboard and hold the start button on the top right of the screen to start all of the containers we have imported so far.

Wordpress Environment Variables

WordPress Administration

With the environment started you’ll have a fully functional WordPress site up and running. To access the wp-admin area of your WordPress app, just visit the Cycle generated domain (pictured below).

Cycle Domain Finder

Note: If the domain doesn’t take you to the installation directly, try appending /wp-admin to the domain

Installing Plugins

Once you’ve reached the wp-admin area of the application, you can install the necessary plugins. The plugins that will be used for this project are:

  1. Advanced Custom Fields
  2. WP GraphQL
  3. WP GraphiQL
  4. WPGraphQL for Advanced Custom Fields

Advanced Custom Fields can be found through the traditional plugin import interface included in your WordPress backend. The others must be downloaded and installed from GitHub. The process for installing a WordPress plugin manually is as follows:

  1. Download the ZIP file from GitHub.
  2. Choose the Upload Plugin button at the top of the plugin manager page.
  3. Click Choose File to open an explorer for your local filesystem, and upload the ZIP file you downloaded from GitHub.

Install your plugin from a zip file. Install your plugin from a zip file.

Using SFTP to modify your functions.php file and add a post type

We want to add a custom post type. You can do this by accessing the active themes’ functions.php file and adding a snippet of code ( included below ) to the file. Today we’ll use Cycle’s SFTP functionality to get access to the file, copy it to our local system, update the file, and then add it back to our container volume.

To complete this process follow these steps:

  • Navigate to the volumes tab.
  • Make sure you have remote access enabled.
  • Go to the instance dash.
  • Expand the SFTP details modal.
  • Click open in SFTP.
  • Navigate to the functions.php file in your active theme (the default is twentynineteen as of this article).

Volume Remote Access Settings SFTP Connection Modal

  • Copy the functions file to your local system and add the following code at the end of the file.

  • Overwrite the existingfunctions.php file with your updated functions.php.

Once this file is updated, you’ll see a new post type of Blenders available in the admin area. For now, create a few Blender post types. They can be anything you like.

Using Advanced Custom Fields to add new fields

Head back over to the admin area of your WordPress installation. From there you can start adding custom fields through the ACF plugin.

  • Click the ACF plugin navigation and then the Add New a custom field sub-menu.
  • Name the new field group Blender Meta.
  • Scroll to the bottom and make sure to enter blenderMeta as the GraphQL Field Name.
  • Switch the Show in GraphQL toggle over.
  • Associate the post to toasters by changing the rules section from Post Type is Equal to Posts to Post Type is Equal to Blenders.
  • Click the Add Field button at the top to start adding fields.
  • Add the following fields: Price & Watts .

Adding New Custom Fields

  • Check that it’s correct using the GraphQL IDE.

The GraphQL IDE is accesssed by clicking GraphiQL from the left side navigation.

Go to the GraphiQL plugin and make sure that everything is working. You can do this by opening the GraphiQL WordPress IDE and entering a query ( like below ), followed by the play button at the top.

GraphQL Query Results

If that’s all working as expected we’re ready to move onto the frontend container.

The React Container

This guide isn’t about React or how to build a react app, so I’m not going to dive into the code at all. However, you will need the code from this repo in order to build your react container. After cloning the repo you’ll need to change the App.js file uri to your Cycle generated domain we spoke about above, with the slug /graphql appended to it. The Dockerfile is included and ready to go so you won’t need to change anything else.

After you’ve made the changes you can:

  • Build the image by running docker build -t username/imagename:tag.
  • Push the image to Docker Hub docker push username/imagename:tag.
  • Pull the image to Cycle .

Importing An Image

When you deploy this container the settings will be the same as the WordPress container, except that you will select stateless instead of stateful and there will be no volume. Once the container is created, hold the start button on the top right of the screen to start your new container. You can then use the Cycle generated domain to access your webpage.

Interact With Container

Congrats, You’ve Done It

That’s it, you’ve officially deployed a headless WordPress application. So where will you take it from here? I’d love to hear about your experience with this guide and the projects that you build. Reach out to me on this Slack channel with an update on what you’re up too!

Still Have Questions?

If you want to dive in and learn more, head over to our slack channel. Our community is growing, and our team hangs out there daily. Feel free to shoot us a message any time with your questions and we’ll be sure to respond!

Of course, for a more in-depth look at how to use Cycle, check out our documentation.