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.
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.
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 Containeron the top right of the environment dashboard.
- Give your container a
Starting Instance Count,
Deployment Strategy, and
Tagswith their default settings.
Import New Imagefrom the
Docker Hubto import the latest WordPress image. The
Image Namefield should be
Tagfield will be
- After you click
importthe 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.
wordpressand will be automatically filled in to match the name of the container.
- With all the settings in place, click
cycleplatform/wordpress:latestimage 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.
- The name and hostname of the container should be
Importform will need to be set with the
Public Networkwill be set to
Now that both of the containers have been created, we can now configure our environment variables. By clicking the
config 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.
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:
WORDPRESS_DB_HOST → db WORDPRESS_DB_USER → wordpress WORDPRESS_DB_PASSWORD → wordpress WORDPRESS_DB_NAME → wordpress
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.
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).
Note: If the domain doesn’t take you to the installation directly, try appending
/wp-adminto the domain
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:
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:
- Download the ZIP file from GitHub.
- Choose the Upload Plugin button at the top of the plugin manager page.
Choose Fileto open an explorer for your local filesystem, and upload the ZIP file you downloaded from GitHub.
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
twentynineteenas of this article).
- Copy the functions file to your local system and add the following code at the end of the file.
- Overwrite the existing
functions.phpfile with your updated
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 Newa custom field sub-menu.
- Name the new field group Blender Meta.
- Scroll to the bottom and make sure to enter
GraphQL Field Name.
- Switch the
Show in GraphQLtoggle over.
- Associate the post to toasters by changing the rules section from
Post Type is Equal to Poststo
Post Type is Equal to Blenders.
- Click the
Add Fieldbutton at the top to start adding fields.
- Add the following fields:
- Check that it’s correct using the GraphQL IDE.
The GraphQL IDE is accesssed by clicking
GraphiQLfrom 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.
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 .
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.
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.