One place for hosting & domains

      Gatsbyjs

      How To Use WordPress Content with a Gatsby.js Application


      The author selected the Internet Archive to receive a donation as part of the Write for DOnations program.

      Introduction

      WordPress is a popular CMS (Content Management System). It allows you to edit posts within a visual editor, as opposed to hand-coding pages of your website with raw HTML, and offers additional features, such as collaborative editing and revision history.

      Traditionally, WordPress has functioned as both the backend and frontend of a website. The posts are edited within the Admin editor, and the backend dynamically generates each public page of your site when a visitor hits it by passing it through a PHP theme.

      A new paradigm in WordPress is using it only for the content part of your site (also known as running headless), and using Gatsby to statically generate the frontend. By leveraging both and decoupling content from the user interface (UI), you can keep the content editor and collaborative features of WordPress, but also enjoy the faster load times and React-based UI ecosystem of Gatsby.

      In this tutorial, you will provision WordPress to talk to Gatsby, set up a new Gatsby project based on a starter template, define the connection to WordPress in your Gatsby configuration, and put it all together to statically generate some pages based on posts that live inside your WordPress installation.

      Prerequisites

      Before you start on this guide, here are a few things you will need:

      • An environment with sufficient resources to support building and serving your site. If you are using the same server to both host WordPress and build your Gatsby site, the recommended minimum amount of RAM is 2GB. If you would like to use a DigitalOcean Droplet, check out our How to Create a Droplet from the DigitalOcean Control Panel article.
      • A working WordPress installation that is reachable from where Gatsby is running. If you are brand new to WordPress, you might want to start with a guide on What is WordPress first, but for general setup, there are also guides for multiple environments, such as Docker. This tutorial was tested on a LAMP stack set up by following How To Install WordPress on Ubuntu 20.04 with a LAMP Stack.
      • Node.js, installed locally, for running Gatsby and building your site. The installation procedure varies by operating system, but there are guides for installing Node.js on Ubuntu and installing Node.js on Mac, and you can always find the latest release on the official NodeJS download page.
      • The Gatsby CLI tool, installed locally. For how to install this and to learn some of the Gatsby basics, you can follow Step 1 of the How to Set Up Your First Gatsby Website tutorial.
      • Some familiarity with JavaScript, for working in Gatsby. There is a lot of depth to JavaScript, but a good starting spot is our How to Code in JavaScript series. Additionally, it will help to have some knowledge of HTML, such as understanding HTML elements, and if you want to customize the UI of your posts beyond what is covered in this tutorial, it will also help to know some React and JSX.

      This tutorial was tested on WordPress v5.7.1, Gatsby v3.3.0, and Node.js v14.17.0. Additionally, the WordPress setup was tested on both Windows 10 and Ubuntu 20.04 with Apache v2.4.41 and PHP v7.4.3.

      Step 1 — Installing and Configuring the Required WordPress Plugins

      In this first step, you will give WordPress the ability to talk to Gatsby by installing some plugins and adjusting settings. You will also verify that your local or hosted WordPress instance supports these changes, and record some details about your specific setup that will be needed later.

      Start by logging into the admin dashboard of your WordPress instance by navigating to https://your_domain_name/wp-admin in your browser and inputting your credentials. Then go to the plugins page by clicking Plugins in the left sidebar. Next, navigate to the plugin installation page by clicking Add New at the top of the page, or in the same sidebar. If your WordPress installation uses standard paths, you will also be able to find this page at https://your_domain/wp-admin/plugin-install.php. This will bring you to the plugins page, as shown in the following image:

      Screenshot showing the Add New link selected in the Plugins sidebar in WordPress Admin

      The two required plugins are as follows, and will be installed in this order:

      Screenshot of the WordPress plugin listing for WPGraphQL

      Screenshot of the WordPress plugin listing for WPGatsby

      Install and activate both of these plugins by searching for them and then pressing their associated Install Now buttons. Once they are installed, select the Activate button. After both plugins have been installed and activated, you will see some new settings panels within your WordPress admin dashboard. The following image shows these new settings panels.

      Screenshot showing that both required plugins, WPGraphQL and WPGatsby, are installed, activated, and have added settings panels around the admin dashboard

      To verify that the GraphQL connection will be available for connecting to Gatsby, open the Settings panel, under the GraphQL sub-section in the Admin sidebar.

      Screenshot of the WPGraphQL settings page, with the GraphQL endpoint URL highlighted. In this example, it is

      Take special note of the GraphQL endpoint. You can find this in the section labeled GraphQL Endpoint, below the text entry box. It is also highlighted in yellow in the screenshot. You will need this later, so to save some time you can copy it into your clipboard and/or paste it into a temporary text document.

      For the best results with WPGraphQL, it is recommended to use a WordPress permalink setting other than plain, especially if this is a new WordPress installation where changing the URL structure will not affect a live website. To navigate to your permalink settings, click on Settings in the left sidebar of your WordPress admin dashboard, then click on Permalinks in that expanded section. From the permalink settings page, change your setting to any option other than plain, and then press Save Changes to update your site.

      Setting your permalinks to something other than plain comes with some specific technical requirements; with the Apache web server, you need to enable the mod_rewrite module and set the AllowOverride directive to all. These will enable WordPress to dynamically route new paths. Step 3 of the WordPress on Ubuntu 20.04 tutorial covers this, with step-by-step instructions. If you ran Let’s Encrypt to provide an SSL certificate for your site, as is instructed in the How To Secure Apache with Let’s Encrypt on Ubuntu 20.04 tutorial, you will have to complete these steps for the new virtual host at /etc/apache2/sites-available/your_domain-le-ssl.conf.

      Now that you have a GraphQL endpoint configured, you will test this connection. You can do so immediately; no Gatsby is installation required yet. You can use the GraphiQL IDE for a visual query builder tool (accessible through the sidebar), or you can even query the endpoint directly with your favorite network request tool of choice.

      If you prefer the command line and have cURL installed, you could use the following command to retrieve all post titles:

      • curl --location --request POST 'https://your_domain/graphql'
      • --header 'Content-Type: application/json'
      • --data-raw '{
      • "query": "query { posts { nodes { title } } }"
      • }'

      This command makes a request to your GraphQL endpoint for a JSON response containing your WordPress posts, but only with their titles. With GraphQL, this is also called a query; the tutorial Understanding Queries in GraphQL explains them more in-depth.

      The response JSON to your query will be something like this:

      Output

      {"data":{"posts":{"nodes":[{"title":"Hello world!"}]}},"extensions":{"debug":[{"type":"DEBUG_LOGS_INACTIVE","message":"GraphQL Debug logging is not active. To see debug logs, GRAPHQL_DEBUG must be enabled."}]}}

      Now that you have successfully installed and configured the required WordPress plugins to communicate with Gatsby, you can move on to setting up your new Gatsby project.

      Step 2 — Setting Up a New Gatsby Project

      In this step, you will set up a new Gatsby project based on a starter template specifically designed for sourcing data from WordPress. It will require using the Gatsby CLI to download and install the starter and its dependencies.

      To speed up your development process and reduce the amount of setup that is required, you will start by using the Gatsby CLI and the Gatsby WordPress Blog Starter template.

      Navigate to the local parent directory that will hold your Gatsby project, then run the following command to have the Gatsby CLI download and pre-install most of what you will need to get started building your site:

      • gatsby new my-wordpress-gatsby-site https://github.com/gatsbyjs/gatsby-starter-wordpress-blog

      You can replace my-wordpress-gatsby-site with whatever you would like the directory name to be for your local Gatsby files.

      It will take a while for Gatsby to download and install all the necessary dependencies and assets. Once it has finished, you will receive a message similar to this one:

      Output

      ... Your new Gatsby site has been successfully bootstrapped. Start developing it by running: cd my-wordpress-gatsby-site gatsby develop

      Normally with a Gatsby site, this is the point at which you would hand-edit the gatsby-config.js file with details about your site known as metadata. However, in addition to pulling posts from WordPress, this starter also pulls the metadata in for you automatically; no need to hand-code the site title or description.

      Having scaffolded a new Gatsby project, you are now ready to modify its configuration to tell it to pull data from WordPress.

      Step 3 — Configuring Gatsby to Use WordPress Data

      Now that you have a working Gatsby project, the next step is for you to configure it to pull in the data from WordPress. You will do this by editing the main Gatsby configuration file and working with the gatsby-source-wordpress plugin.

      Thanks to the starter template you used, the gatsby-source-wordpress plugin will already be installed as a dependency and have a settings entry in the Gatsby config file; you just need to tweak it slightly.

      Move into your local Gatsby directory that was created in the previous step:

      • cd my-wordpress-gatsby-site

      Then, open the file named ./gatsby-config.js in your text editor of choice. This is the main configuration file for all Gatsby projects.

      Within the config file, you will find an existing settings entry for gatsby-source-wordpress within the plugins array. You can now take your specific GraphQL endpoint you copied from the previous step and replace the default demo endpoint, https://wpgatsbydemo.wpengine.com/graphql, with your value, as highlighted in the following code:

      gatsby-config.js

      module.exports = {
          plugins: [
              {
                  resolve: `gatsby-source-wordpress`,
                  options: {
                      url:
                          process.env.WPGRAPHQL_URL ||
                          `https://your_domain/graphql`,
                  },
              },
              ...
          ],
          ...
      }
      

      Save and close this file so that future builds of the site will use the updated value.

      Note: url is the only required setting option, but there are a lot that are available; take a look at the Gatsby GitHub repostory for more. For example, there are options for enabling debug output, connecting to an HTACCESS, password-protected site, and performance related options, such as schema.requestConcurrency, which is especially important if your WordPress site is running on a server with limited resources.

      Before moving on to customizing how Gatsby uses your WordPress data to build pages, build and preview your site as-is to make sure everything is working correctly. You can do this by running the following command:

      Or, if you are using the yarn package manager:

      Warning: If you get an error at this step, especially if it is an error about a missing dependency or can't resolve '...' in '....cache, it might be that part of the dependency install process has failed. This is a known issue in Gatsby projects. Try running npm i again (or yarn install if using yarn) to check for and install any missing dependencies. If that fails to fix the issue, completely rebuild your dependencies by deleting the node_modules folder, deleting package-lock.json or yarn.lock, and then running npm i or yarn install.

      This command will run the gatsby develop process, which will pull in data from WordPress, combine it with the starter template’s pre-built UI files, and start a local development server so you can view a preview of the actual generated website in a browser. This command also runs Gatsby in a mode that supports hot-reloading, so that if you make edits to your local files, you will see those changes reflected instantly in your web browser.

      Navigate to localhost:8000 in your browser and you will find your Gatsby site with WordPress content:

      Gatsby site entitled

      With your Gatsby project now pulling data from WordPress, the next step will be to customize the actual template files so that you can make your Gatsby site look and act just how you want it to.

      Step 4 — Customizing the Starter Template Files

      The Gatsby WordPress starter template provides a lot of default functionality, but in this step you will explore how you can customize the template files to make the project your own, in both form and function. By editing some Gatsby source files, you will bring a new piece of WordPress content—the post excerpt—into your Gatsby site and style it with CSS.

      For most Gatsby sites, your starter template included, there are a few key files and folders to be aware of when it comes to customization:

      • ./gatsby-node.js: This could be considered the center of the Static Site Generation process. It has the code for querying WordPress for all your content, then passing it through template files to generate the static output. If you want to modify what content ends up on your site, this is the main entry-point. In terms of WordPress development, this is similar to working with The Loop and similar concepts.
      • ./src/templates: This contains individual template files, each of which should contain and export a React component responsible for rendering the content passed in. If you want to change how content looks, integrate third-party UI libraries, or build skeletons around content, this is the usual place to do it. In terms of WordPress development, these are similar to Template Files.
      • ./src/components: Typically, each file in this folder is a singular React component that is dedicated to a specific UI task, and is meant to be pulled into template files. Think of these as UI building blocks, but not as templates. If you have a UI element that you want to share across multiple template files, this is a good place to put it and avoid copying and pasting the same code over and over. Some examples of this would be menus, author bio displays, header and footer elements, etc. In terms of WordPress development, these are similar to Template Partials.
      • ./src/css: This contains CSS files that are shared across the site, as opposed to inline-styling, or a popular css-in-js solution, such as styled-components. In this tutorial, and with your specific starter template, this folder provides the majority of styling for your new site. In terms of WordPress development, this is equivalent to style.css, or any number of stylesheets that a theme can inject into a page through WordPress’s enqueue system.

      For an example of how you can edit the existing template files, open ./src/templates/blog-post.js in your text editor.

      In WordPress, there is a special text value for each post called the excerpt, which is a short descriptive summary of the post. By default, this Gatsby template file pulls in the WordPress excerpt, but only uses it for SEO purposes, putting it in the <meta name="description" /> tag. You can modify the blog post template file to include the post excerpt visually, like so, adding the highlighted code to your file:

      /src/templates/blog-post.js

      const BlogPostTemplate = ({ data: { previous, next, post } }) => {
          ...
          return (
              <Layout>
                  ...
                  <h1 itemProp="headline">{parse(post.title)}</h1>
      
                  <p>{post.date}</p>
      
                  {/* Checking for and adding the post excerpt if the current post has one*/}
                  {post.excerpt && (
                      <div className="post-excerpt">{parse(post.excerpt)}</div>
                  )}
      
            {/* if we have a featured image for this post let's display it */}
              {featuredImage?.fluid && (
                <Image
                  fluid={featuredImage.fluid}
                    alt={featuredImage.alt}
                    style={{ marginBottom: 50 }}
                />
              )}
            ...
              </Layout>
          )
      }
      

      In this code, you are checking if the post has an excerpt (important since it is not mandatory in WordPress), and if it does, displaying the text content of the excerpt inside a <div> element. The parse() function comes from html-react-parser, and is being used here to make sure that the <p> tag that will hold your excerpt is parsed into HTML rather than plain text, so you can echo out the content directly. An alternative approach would be to use dangerouslySetInnerHTML, with <div className="post-excerpt" dangerouslySetInnerHTML={{__html: post.excerpt}} ></div>.

      Save and close the blog-post.js file.

      Since the excerpt is a summary of the post, it might help the visitors to your site if you visually separate it from the body of the post, highlighting it at the top of the page and making it easy to find. You can do this by editing the main shared CSS file at ./src/css/style.css:

      /src/css/style.css

      .post-list-item header {
        margin-bottom: var(--spacing-4);
      }
      
      /* CSS targeting your new post excerpt element */
      .post-excerpt {
        box-shadow: 0px 1px 9px 1px rgb(0 0 0 / 50%);
        padding: 6px;
        border-radius: 8px;
        margin-bottom: 14px;
      }
      
      .post-excerpt p {
        margin-bottom: 0px;
      }
      

      In your CSS, you have now used box-shadow to add a shadow effect around the excerpt container, contrasting it with the actual body of the post, as well as added padding, rounded edges, and spacing between itself and adjacent elements. Furthermore, you removed the default bottom margin from the text of the excerpt, since spacing is now provided by the container .post-excerpt element.

      Save the style.css file. To test this out, add an excerpt in WordPress to take advantage of this new visual feature. In the sidebar of the WordPress admin view, navigate to the Posts tab, then select the sample Hello world! post. This will take you to the WordPress post editor view. In the newer block-based editor, the excerpt field appears under the Post tab in the right sidebar, near the bottom. In the legacy editor, the location of the excerpt field is customizable, so it might appear in different locations depending on your theme and custom settings.

      Add in an excerpt, then select the Update button at the top of the screen. Then, go to your Gatsby site at localhost:8000, and select the Hello world! blog post. You will find the excerpt you wrote rendered on the page:

      The sample

      Note: If you are looking for pre-built themes that don’t require any additional coding or configuration, similar to how WordPress themes work, there is a growing number of both official and community themes for using WordPress with Gatsby.

      You have just embedded and styled a post excerpt from WordPress into a custom Gatsby static site. This used data that was already configured for use by your starter template. The next step will explore how to bring new pieces of data via GraphQL and integrate them into your Gatsby site.

      Step 5 — Using WordPress Data in Gatsby with Custom Templates

      In the previous steps, you edited an existing template and used some standard WordPress data (post title and post content) to render your blog posts with Gatsby’s static output. For many sites, this alone might be all that is needed. However, to showcase how decoupling the UI from WordPress gives you greater flexibility, in this step you will explore how you would add support for a special video post type in Gatsby, going beyond that existing blog post template.

      In this scenario, you are adding support for posts that each showcase a single video, sourced from YouTube. You will make it so that you or your content collaborators can copy and paste a YouTube URL into the WordPress post editor and the Gatsby site itself will show the video inside a customized YouTube embed widget.

      For the post template, create a new file under /src/templates, and name it video-post.js. Before building the UI of the page that will be generated, you can write a GraphQL query to retrieve data for it. In Gatsby, this is called a Page Query, and uses the graphql tag.

      Add the following code to the video-post.js file:

      /src/templates/video-post.js

      import React from "react"
      import { graphql } from "gatsby"
      
      export const pageQuery = graphql`
        query VideoPostById(
          # these variables are passed in via createPage.pageContext in gatsby-node.js
          $id: String!
        ) {
          # selecting the current post by id
          post: wpPost(id: { eq: $id }) {
            id
            content
            title
            date(formatString: "MMMM DD, YYYY")
          }
        }
      `
      

      In this snippet, you are using the post ID to query for specific values belonging to that exact post—such as the actual post content, title, and date.

      Next, you can add the actual React component that returns JSX, which will be rendered as the webpage. A good place to start is by copying most of the structure from the existing blog-post.js template file and adding the following highlighted lines:

      /src/templates/video-post.js

      import React from "react"
      import { graphql } from "gatsby"
      import parse from "html-react-parser"
      
      import Bio from "../components/bio"
      import Layout from "../components/layout"
      import Seo from "../components/seo"
      
      const VideoPostTemplate = ({ data: { post } }) => {
        return (
          <Layout>
            <Seo title={post.title} description={post.excerpt} />
      
            <article
              className="blog-post"
              itemScope
              itemType="http://schema.org/Article"
            >
              <header>
                <h1 itemProp="headline">{parse(post.title)}</h1>
                <p>{post.date}</p>
              </header>
      
              <footer>
                <Bio />
              </footer>
            </article>
          </Layout>
        )
      }
      
      export default VideoPostTemplate;
      
      export const pageQuery = graphql`
        query VideoPostById(
          # these variables are passed in via createPage.pageContext in gatsby-node.js
          $id: String!
        ) {
          # selecting the current post by id
          post: wpPost(id: { eq: $id }) {
            id
            content
            title
            date(formatString: "MMMM DD, YYYY")
          }
        }
      `
      

      In addition to creating the React component, you also used export default to make sure that the component is the default item exported from the file. This is important because of how the file is imported later on by Gatsby when it compiles the template against data from WordPress.

      Now, you can add some logic to your React component to check if there is a raw YouTube URL embedded in the body of the post:

      /src/templates/video-post.js

      ...
      
      const VideoPostTemplate = ({ data: { post } }) => {
        // RegEx to find YouTube IDs
        const youtubeIdPattern = /watch?v=([a-z_0-9-]+)|youtu.be/([a-z_0-9-]+)|youtube.com/embed/([a-z_0-9-]+)/i;
      
        const matches = youtubeIdPattern.exec(post.content);
        let videoId;
      
        if (matches) {
          // Use first available match
          videoId = matches[1] || matches[2] || matches[3];
        }
      
        return (
          <Layout>
            <Seo title={post.title} description={post.excerpt} />
      
            <article
              className="blog-post"
              itemScope
              itemType="http://schema.org/Article"
            >
              <header>
                <h1 itemProp="headline">{parse(post.title)}</h1>
                <p>{post.date}</p>
              </header>
      
              <footer>
                <Bio />
              </footer>
            </article>
          </Layout>
        )
      }
      ...
      

      In this code, youtubeIdPattern is a Regular Expression (or RegEx), which is a search pattern you are executing against the body of the post with youtubeIdPattern.exec(post.content) to try and find any YouTube IDs which were included. If matches are found, the variable videoId is set to the first match.

      Finally, you can add the JSX that renders the video based on the videoId you’ve extracted:

      /src/templates/video-post.js

      ...
      
        return (
          <Layout>
            <Seo title={post.title} description={post.excerpt} />
      
            <article
              className="blog-post"
              itemScope
              itemType="http://schema.org/Article"
            >
              <header>
                <h1 itemProp="headline">{parse(post.title)}</h1>
                <p>{post.date}</p>
              </header>
      
              {videoId ? (
                <div className="video-embed">
                  <iframe width="512" height="288" src={`https://www.youtube-nocookie.com/embed/${videoId}?controls=0&autoplay=1`} title={post.title} frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
                </div>
              ) : (
                <div className="no-video-found">
                  <p>Sorry, could not find a video in this post!</p>
                </div>
              )}
      
              <hr />
      
              <footer>
                <Bio />
              </footer>
            </article>
          </Layout>
        )
      }
      ...
      

      If a videoId is found, your code returns a customized, privacy-enhanced YouTube embed, served through an iframe, set to autoplay. Otherwise, it returns a message that no video was found. It also adds a horizontal break between the video embed and the footer of the post.

      Now that your component template file is built, you will tell Gatsby to use the new template for posts that are set to the Video type within WordPress, and not use the regular blog post template for them.

      Make sure to save your changes in video-post.js, then open gatsby-node.js in your text editor.

      First, modify the getPosts() function, which the starter uses as the main GraphQL query to the WordPress backend for posts. You’ll modify the query to pull in the postFormats that the given post belongs to:

      gatsby-node.js

      ...
      async function getPosts({ graphql, reporter }) {
        const graphqlResult = await graphql(/* GraphQL */ `
          query WpPosts {
            # Query all WordPress blog posts sorted by date
            allWpPost(sort: { fields: 2023, order: DESC }) {
              edges {
                previous {
                  id
                }
      
                ...
      
                post: node {
                  id
                  uri
                  postFormats {
                    formats: nodes {
                      name
                    }
                  }
                }
      
                next {
                  id
                }
              }
            }
          }
        `)
      
        ...
      
        return graphqlResult.data.allWpPost.edges
      }
      

      Next, you need to implement the logic that separates the video posts and sends them to their unique template file for rendering. For this, you can hook into the existing createIndividualBlogPostPages() function in the starter.

      You can pull the data from the GraphQL query you modified and use that to determine if the current post is a video post or not:

      gatsby-node.js

      const createIndividualBlogPostPages = async ({ posts, gatsbyUtilities }) =>
        Promise.all(
          posts.map(({ previous, post, next }) => {
            const postFormats = post.postFormats.formats;
            const isVideo = postFormats.length && postFormats[0].name === 'Video';
      ...
                // We also use the next and previous id's to query them and add links!
                previousPostId: previous ? previous.id : null,
                nextPostId: next ? next.id : null,
              },
            })}
          )
        )
      

      Then, change the component property in createPage to use the corresponding template file:

      gatsby-node.js

      const createIndividualBlogPostPages = async ({ posts, gatsbyUtilities }) =>
        Promise.all(
          posts.map(({ previous, post, next }) => {
            const postFormats = post.postFormats.formats;
            const isVideo = postFormats.length && postFormats[0].name === 'Video';
      
            return gatsbyUtilities.actions.createPage({
              // Use the WordPress uri as the Gatsby page path
              // This is a good idea so that internal links and menus work 👍
              path: post.uri,
      
              // Use special video template if post format === Video, else use blog post template
              component: isVideo ? path.resolve(`./src/templates/video-post.js`) : path.resolve(`./src/templates/blog-post.js`),
      
              ...
            });
          })
        )
      

      To keep things concise, this code statement uses a ternary operator, which is a way to return one value if another is truthy (truth-like) and a different value if it is falsy, all without an if/else statement. The code uses isVideo from your previous post format check, and if true, returns the path of the new video template. If false, it tells Gatsby to use the regular blog post template. The Node.js path.resolve() function is used to turn the relative path (./src/...) into an absolute path (the full filepath), which Gatsby requires to load a component file.

      Save and exit the file.

      Next, style your video embed by editing ./src/css/style.css again:

      /src/css/style.css

      .video-embed {
        /* Shadow effect around box to give it contrast */
        box-shadow: 0px 2px 12px 4px rgb(0 0 0 / 50%);
        /* All four declarations below help center our video and give it space */
        display: block;
        line-height: 0px;
        margin: 20px auto;
        max-width: 512px;
      }
      

      In adding the this CSS, you’ve given the video embed a shadow effect around it, which also gives it contrast with the page, as well as centered it and given it space away from other elements.

      To test the functionality of this new code, you can create a new post in WordPress that matches the criteria required by the template. From your WordPress Admin Dashboard, click on Posts in the left sidebar, then Add New to start building a new post. Give your post a title, and then make sure it meets these two criteria:

      • The Post Format will be set to Video. You can find the format dropdown in the right sidebar
      • The post body will contain a YouTube URL (and not as an embed). To test this, you can use this short link to a DigitalOcean promotional video: youtu.be/iom_nhYQIYk.

      Screenshot showing the WordPress post editor with a YouTube URL in the body of the post, and the post format type set to Video

      After filling out the post, select Publish (or Update if this is an existing post) and click to confirm the prompt that appears, so that your post goes live and Gatsby can fetch it over the GraphQL connection.

      Navigate to localhost:8000 in your browser and select your test video post. The YouTube video will be rendered in the browser, as shown in the following image:

      Video blog post with rendered DigitalOcean promotional video on page

      Conclusion

      By working through the steps in this tutorial, you now have a statically generated Gatsby site that sources its content from a WordPress backend. In decoupling content from UI, you have opened up new possibilities for speeding up your site, reduced the barriers to cross-discipline content collaboration, and taken advantage of the rich ecosystem that Gatsby and React provide for UI development.

      If you would like to read more Gatsby tutorials, try out the other tutorials in the How To Create Static Web Sites with Gatsby.js series.



      Source link

      Create a CI/CD Pipeline with Gatsby.js, Netlify and Travis CI


      Updated by Linode

      Contributed by

      Linode


      Use promo code DOCS10 for $10 credit on a new account.

      What is Gatsby?

      Gatsby is a Static Site Generator for React built on Node.js. Gatsby uses a modern web technology stack based on client-side Javascript, reusable APIs, and prebuilt Markdown, otherwise known as the JAMstack. This method of building a site is fast, secure, and scalable. All production site pages are prebuilt and static, so Gatsby does not have to build HTML for each page request.

      What is the CI/CD Pipeline?

      The CI/CD (continuous integration/continuous delivery) pipeline created in this guide is an automated sequence of events that is initiated after you update the code for your website on your local computer. These events take care of the work that you would otherwise need to perform manually: previewing your in-development site, testing your new code, and deploying it to your production server. These actions are powered by GitHub, Netlify, and Travis CI.

      Note

      This guide uses GitHub as your central Git repository, but you can use any service that is compatible with Netlify and Travis.

      Netlify

      Netlify is a PaaS (Platform as a Service) provider that allows you to quickly deploy static sites on the Netlify platform. In this guide Netlify will be used to provide a preview of your Gatsby site while it is in development. This preview can be shared with different stakeholders for site change approvals, or with anyone that is interested in your project. The production version of your website will ultimately be deployed to a Linode, so Netlify will only be used to preview development of the site.

      Travis CI

      Travis CI is a continuous integration tool that tests and deploys the code you upload to your GitHub repository. Travis will be used in this guide to deploy your Gatsby site to a Linode running Ubuntu 18.04. Testing your website code will not be explored in depth, but the method for integrating unit tests will be introduced.

      The CI/CD Pipeline Sequence

      This guide sets up the following flow of events:

      1. You create a new branch in your local Git repository and make code changes to your Gatsby project.

      2. You push your branch to your GitHub repository and create a pull request.

      3. Netlify automatically creates a preview of the site with a unique URL that can be shared.

      4. Travis CI automatically builds the site in an isolated container and runs any declared tests.

      5. When all tests pass, you merge the PR into the repository’s master branch, which automatically triggers a deployment to your production Linode.

      Before You Begin

      1. Follow the Getting Started guide and deploy a Linode running Ubuntu 18.04.

      2. Complete the Securing Your Server guide to create a limited Linux user account with sudo privileges, harden SSH access, and remove unnecessary network services.

        Note

        This guide is written for a non-root user. Commands that require elevated privileges are prefixed with sudo. If you’re not familiar with the sudo command, visit our Users and Groups guide.

        All configuration files should be edited with elevated privileges. Remember to include sudo before running your text editor.

      3. Configure DNS for your site by adding a domain zone and setting up reverse DNS on your Linode’s IP.

      4. Create a GitHub account if you don’t already have one. GitHub is free for open source projects.

      5. Install Git on your local computer. Later in this guide, Homebrew will be used to install Gatsby on a Mac, so it’s recommended that you also use Homebrew to install Git if you’re using a Mac.

      Prepare Your Production Linode

      Install NGINX

      1. Install NGINX from Ubuntu’s repository on your Linode:

        sudo apt install nginx
        

      Configure NGINX

      1. Delete the default welcome page:

        sudo rm /etc/nginx/sites-enabled/default
        
      2. Create a site configuration file for Gatsby. Replace example.com in the file name and in the file’s contents with your domain name:

        /etc/nginx/conf.d/example.com.conf
         1
         2
         3
         4
         5
         6
         7
         8
         9
        10
        11
        
        server {
            listen       80;
            server_name  example.com;
            #charset koi8-r;
            #access_log  /var/log/nginx/host.access.log  main;
        
            location / {
                root   /usr/share/nginx/html/example.com/public;
                index  index.html index.htm;
            }
        }

        Note

        Replace all future instances of example.com in this guide with your domain name.

      3. The root directive in your NGINX configuration points to a directory named public within /usr/share/nginx/html/example.com/. Later in this guide, Gatsby will be responsible for creating the public directory and building its static content within it (specifically, via the gatsby build command).

        The /usr/share/nginx/html/example.com/ directory does not exist on your server yet, so create it:

        sudo mkdir -p /usr/share/nginx/html/example.com/
        
      4. The Gatsby deployment script that will be introduced later in this guide will run under your limited Linux user. Set your limited user to be the owner of the new document root directory. This ensures the deployment script will be able write your site’s files to it:

        sudo chown $(whoami):$(id -gn) -R /usr/share/nginx/html/example.com/
        
      5. Test your NGINX configuration for errors:

        sudo nginx -t
        
      6. Reload the configuration:

        sudo nginx -s reload
        
      7. Navigate to your Linode’s domain or IP address in a browser. Your Gatsby site files aren’t deployed yet, so you should only see a 404 Not Found error. Still, this error indicates that your NGINX process is running as expected.

      Develop with Gatsby on Your Local Computer

      You will develop with Gatsby on your local computer. This guide walks through creating a simple sample Gatsby website, but more extensive website development is not explored, so review Gatsby’s official documentation afterwards for more information on the subject.

      Install Gatsby

      This section provides instructions for installing Gatsby via Node.js and the Node Package Manager (npm) on Mac and Linux computers. If you are using a Windows PC, read Gatsby’s official documentation for installation instructions.

      1. Install npm on your local computer. If you are running Ubuntu or Debian on your computer, use apt:

        sudo apt install nodejs npm
        

        If you have a Mac, use Homebrew:

        brew install nodejs npm
        
      2. Ensure Node.js was installed by checking its version:

        node --version
        
      3. Install the Gatsby command line:

        sudo npm install --global gatsby-cli
        

      Create a Gatsby Site

      1. Gatsby uses starters to provide a pre-configured base Gatsby site that you can customize and build on top of. This guide uses the Hello World starter. On your local computer, install the Hello World starter in your home directory (using the name example-site for your new project) and navigate into it:

        gatsby new example-site https://github.com/gatsbyjs/gatsby-starter-hello-world
        cd ~/example-site
        
      2. Inspect the contents of the directory:

        ls
        

        You should see output similar to:

          
        LICENSE  node_modules  package.json  package-lock.json  README.md  src
        
        

        The src directory contains your project’s source files. This starter will include the React Javascript component file src/pages/index.js, which will be mapped to our example site’s homepage.

        Gatsby uses React components to build your site’s static pages. Components are small and isolated pieces of code, and Gatsby stores them in the src/pages directory. When your Gatsby site is built, these will automatically become your site’s pages, with paths based on each file’s name.

      3. Gatsby offers a built-in development server which builds and serves your Gatsby site. This server will also monitor any changes made to your src directory’s React components and will rebuild Gatsby after every change, which helps you see your local changes as you make them.

        Open a new shell session (in addition the one you already have open) and run the Gatsby development server:

        cd ~/example-site
        gatsby develop
        
      4. The gatsby develop command will display messages from the build process, including a section similar to the following:

          
        You can now view gatsby-starter-hello-world in the browser.
        
            http://localhost:8000/
        
        

        Copy and paste the http://localhost:8000/ URL (or the specific string displayed in your terminal) into your web browser to view your Gatsby site. You should see a page that displays “Hello World”.

      5. In your original shell session, view the contents of your example-site directory again:

        ls
        
          
            LICENSE  node_modules  package.json  package-lock.json  README.md  src  public
            
        

        You should now see a public directory which was not present before. This directory holds the static files built by Gatsby. Your NGINX server will serve the static files located in the public directory.

      6. Open the src/pages/index.js file in your text editor, add new text between the <div> tags, and save your change:

        src/pages/index.js
        1
        2
        3
        4
        
        import React from "react"
        
        export default () => <div>Hello world and universe!</div>
        
      7. Navigate back to your browser window, where the updated text should automatically appear on the page.

      Version Control Your Gatsby Project

      In the workflow explored by this guide, Git and GitHub are used to:

      • Track changes you make during your site’s development.
      • Trigger the preview, test, and deployment functions offered by Netlify and Travis.

      The following steps present how to initialize a new local Git repository for your Gatsby project, and how to connect it to a central GitHub repository.

      1. Open a shell session on your local computer and navigate to the example-site directory. Initialize a Git repository to begin tracking your project files:

        git init
        

        Stage all the files you’ve created so far for your first commit:

        git add -A
        

        The Hello World starter includes a .gitignore file. Your .gitignore designates which files and directories to ignore in your Git commits. By default, it is set to ignore any files in the public directory. The public directory’s files will not be tracked in this repository, as they can be quickly rebuilt by anyone who clones your repository.

      2. Commit all the Hello World starter files:

        git commit -m "Initial commit"
        
      3. Navigate to your GitHub account and create a new repository named example-site. After the repository is created, copy its URL, which will have the form https://github.com/your-github-username/example-site.git.

      4. In your local computer’s shell session, add the GitHub repository as your local repository’s origin:

        git remote add origin https://github.com/your-github-username/example-site.git
        
      5. Verify the origin remote’s location:

        git remote -v
        
          
        origin	https://github.com/your-github-username/example-site.git (fetch)
        origin	https://github.com/your-github-username/example-site.git (push)
        
        
      6. Push the master branch of your local repository to the origin repository:

        git push origin master
        
      7. View your GitHub account in your browser, navigate to the example-site repository, and verify that all the files have been pushed to it successfully:

        GitHub Initial Commit

      Preview Your Site with Netlify

      In the course of developing a website (or any other software project), a common practice when you’ve finished a new feature and would like to share it with your collaborators is to create a pull request (also referred to as a PR). A pull request is an intermediate step between uploading your work to GitHub (by pushing the changes to a new branch) and later merging it into the master branch (or another release or development branch, according to your specific Git workflow).

      Once connected to your GitHub account, the Netlify service can build a site preview from your PR’s code every time you create a PR. Netlify will also regenerate your site preview if you commit and push new updates to your PR’s branch while the PR is still open. A random, unique URL is assigned to every preview, and you can share these URLs with your collaborators.

      Connect Your GitHub Repository to Netlify

      1. Navigate to the Netlify site and click on the Sign Up link:

        Netlify Home Page

      2. Click on the GitHub button to connect your GitHub account with Netlify. If you used a different version control service, select that option instead:

        GitHub and Netlify connection page

      3. You will be taken to the GitHub site and asked to authorize Netlify to access your account. Click on the Authorize Netlify button:

        GitHub Netlify Authorization

      4. Add your new site to Netlify and continue along with the prompts to finish connecting your repository to Netlify. Be sure to select the GitHub repository created in the previous steps:

        Add site to Netlify

      5. Provide the desired deploy settings for your repository. Unless you are sure you need to change these settings, keep the Netlify defaults:

        Netlify repository settings

        Note

        You can add a netlify.toml configuration file to your Git repository to define more deployment settings.

      Create a Pull Request

      1. In your local Git repository, create a new branch to test Netlify:

        git checkout -b test-netlify
        
      2. On your computer, edit your src/pages/index.js and update the message displayed:

        src/pages/index.js
        1
        2
        3
        4
        
        import React from "react"
        
        export default () => <div>Hello world, universe, and multiverse!</div>
        
      3. Commit those changes:

        git add .
        git commit -m "Testing Netlify"
        
      4. Push the new branch to the origin repository:

        git push origin test-netlify
        
      5. Navigate to the example-site repository in your GitHub account and create a pull request with the test-netlify branch:

        GitHub Compare and Pull Request Banner

      6. After you create the pull request, you will see a deploy/netlify row with a Details link. The accent color for this row will initially be yellow while the Netlify preview is being built. When the preview’s build process is finished, this row will turn green. At that point, you can click on the Details link to view your Gatsby site’s preview.

        Netlify GitHub Preview

        Every time you push changes to your branch, Netlify will provide a new preview link.

      Test and Deploy Your Site with Travis CI

      Travis CI manages testing your Gatsby site and deploying it to the Linode production server. Travis does this by monitoring updates to your GitHub repository:

      • Travis’s tests will run when a pull request is created, whenever new commits are pushed to that pull request’s branch, and whenever a branch is updated on your GitHub repository in general (including outside the context of a pull request).

      • Travis’s deployment function will trigger whenever a pull request has been merged into the master branch (and optionally when merging into other branches, depending on your configuration).

      Connect Your GitHub Repository to Travis CI

      1. Navigate to the Travis CI site and click on the Sign up with GitHub button.

        Note

        Be sure to visit travis-ci.com, not travis-ci.org. Travis originally operated travis-ci.com for paid/private repositories, and travis-ci.org was run separately for free/open source projects. As of May 2018, travis-ci.com supports open source projects and should be used for all new projects. Projects on travis-ci.org will eventually be migrated to travis-ci.com.
      2. You will be redirected to your GitHub account. Authorize Travis CI to access your GitHub account:

        Authorize Travis CI

      3. You will be redirected to your Travis CI account’s page where you will be able to see a listing of all your public repositories. Click on the toggle button next to your Gatsby repository to activate Travis CI for it.

      Configure Travis CI to Run Tests

      Travis’s functions are all configured by adding and editing a .travis.yml file in the root of your project. When .travis.yml is present in your project and you push a commit to your central GitHub respository, Travis performs one or more builds.

      Travis builds are run in new virtualized environments created for each build. The build lifecycle is primarily composed of an install step and a script step. The install step is responsible for installing your project’s dependencies in the new virtual environment. The script step invokes one or more bash scripts that you specify, usually test scripts of some kind.

      1. Navigate to your local Gatsby project and create a new Git branch to keep track of your Travis configurations:

        git checkout -b travis-configs
        
      2. Create your .travis.yml file at the root of the project:

        touch .travis.yml
        

        Note

        Make sure you commit changes at logical intervals as you modify the files in your Git repository.

      3. Open your .travis.yml file in a text editor and add the following lines:

        ~/example-site/.travis.yml
        1
        2
        3
        4
        5
        6
        
        language: node_js
        node_js:
          - '10.0'
        
        dist: trusty
        sudo: false

        This configuration specifies that the build’s virtual environment should be Ubuntu 14.04 (also known as trusty). sudo: false indicates that the virtual environment should be a container, and not a full virtual machine. Other environments are available.

        Gatsby is built with Node.js, so the Travis configuration is set to use node_js as the build language, and to use the latest version of Node (10.0 at the time of this guide’s publication). When Node is specified as the build language, Travis automatically sets default values for the install and script steps: install will run npm install, and script will run npm test. Other languages, like Python, are also available.

      4. The Gatsby Hello World starter provides a package.json file, which is a collection of metadata that describes your project. It is used by npm to install, run, and test your project. In particular, it includes a dependencies section used by npm install, and a scripts section where you can declare the tests run by npm test.

        No tests are listed by default in your starter’s package.json, so open the file with your editor and add a test line to the scripts section:

        package.json
         1
         2
         3
         4
         5
         6
         7
         8
         9
        10
        11
        12
        13
        14
        15
        
        {
          "name": "gatsby-starter-hello-world",
          "description": "Gatsby hello world starter",
          "license": "MIT",
          "scripts": {
            "develop": "gatsby develop",
            "build": "gatsby build",
            "serve": "gatsby serve",
            "test": "echo 'Run your tests here'"
          },
          "dependencies": {
            "gatsby": "^1.9.277",
            "gatsby-link": "^1.6.46"
          }
        }

        This entry is just a stub to illustrate where tests are declared. For more information on how to test your Gatsby project, review the unit testing documentation on Gatsby’s website. Jest is the testing framework recommended by Gatsby.

      View Output from Your Travis Build

      1. Commit the changes you’ve made and push your travis-configs branch to your origin repository:

        git add .
        git commit -m "Travis testing configuration"
        git push origin travis-configs
        
      2. View your GitHub repository in your browser and create a pull request for the travis-configs branch.

      3. Several rows that link to your Travis builds will appear in your new pull request. When a build finishes running without error, the build’s accent color will turn green:

        GitHub Travis Builds

        Note

        Four rows for your Travis builds will appear, which is more than you may expect. This is because Travis runs your builds whenever your branch is updated, and whenever your pull request is updated, and Travis considers these to be separate events.

        In addition, the rows prefixed by Travis CI - are links to GitHub’s preview of those builds, while rows prefixed with continuous-integration/travis-ci/ are direct links to the builds on travis-ci.com.

        For now, these builds will produce identical output. After the deployment functions of Travis have been configured, the pull request builds will skip the deployment step, while the branch builds will implement your deployment configuration.

      4. Click the Details link in the continuous-integration/travis-ci/push row to visit the logs for that build. A page with similar output will appear:

        Travis Build Logs - First Test

        Towards the end of your output, you should see the “Run your tests here” message from the test stub that you entered in your package.json. If you implement testing of your code with Jest or another library, the output from those tests will appear at this location in your build logs.

        If any of the commands that Travis CI runs in the script step (or in any preceding steps, like install) returns with a non-zero exit code, then the build will fail, and you will not be able to merge your pull request on GitHub.

      5. For now, do not merge your pull request, even if the builds were successful.

      Give Travis Permission to Deploy to Your Linode

      In order to let Travis push your code to your production Linode, you first need to give the Travis build environment access to the Linode. This will be accomplished by generating a public-private key pair for your build environment and then uploading the public key to your Linode. Your code will be deployed over SSH, and the SSH agent in the build environment will be configured to use your new private key.

      The private key will also need to be encrypted, as the key file will live in your Gatsby project’s Git repository, and you should never check a plain-text version of it into version control.

      1. Install the Travis CLI, which you will need to generate an encrypted version of your private key. The Travis CLI is distributed as a Ruby gem:

        On Linux:

        sudo apt install ruby ruby-dev
        sudo gem install travis
        

        On macOS:

        sudo gem install travis
        

        On Windows: Use RubyInstaller to install Ruby and the Travis CLI gem.

      2. Log in to Travis CI with the CLI:

        travis login --com
        

        Follow the prompts to provide your GitHub login credentials. These credentials are passed directly to GitHub and are not recorded by Travis. In exchange, GitHub returns a GitHub access token to Travis, after which Travis will provide your CLI with a Travis access token.

        Note

      3. Inside the root of your local example-site Git repository, create a scripts directory. This will hold files related to deploying your Gatsby site:

        mkdir scripts
        
      4. Generate a pair of SSH keys inside the scripts directory. The key pair will be named gatsby-deploy so that you don’t accidentally overwrite any preexisting key pairs. Replace [email protected] with your email address. When prompted for the key pair’s passphrase, enter no passphrase/leave the field empty:

        ssh-keygen -t rsa -b 4096 -C "[email protected]" -f scripts/gatsby-deploy
        

        Two files will be created: gatsby-deploy (your private key) and gatsby-deploy.pub (your public key).

      5. Add the location of the gatsby-deploy file to your project’s .gitignore file. This will ensure that you do not accidentally commit the secret key to your central repository:

        .gitignore
        1
        2
        3
        
        # Other .gitignore instructions
        # [...]
        scripts/gatsby-deploy
      6. Encrypt your private key using the Travis CLI:

        cd scripts && travis encrypt-file gatsby-deploy --add --com
        
      7. You should now see a gatsby-deploy.enc file in your scripts directory:

        ls
        
          
            gatsby-deploy		gatsby-deploy.enc	gatsby-deploy.pub
        
        
      8. The --add flag from the previous command also told the Travis CLI to add a few new lines to your .travis.yml file. These lines decrypt your private key and should look similar to the following snippet:

        .travis.yml
        1
        2
        3
        
        before_install:
        - openssl aes-256-cbc -K $encrypted_9e3557de08a3_key -iv $encrypted_9e3557de08a3_iv
          -in gatsby-deploy.enc -out gatsby-deploy -d


        About the openssl command and Travis build variables

        The second line (starting with -in gatsby-deploy.enc) is a continuation of the first line, and -in is an option passed to the openssl command. This line is not its own item in the before_install list.

        The openssl command accepts the encrypted gatsby-deploy.enc file and uses two environment variables to decrypt it, resulting in your original gatsby-deploy private key. These two variables are stored in the Settings page for your repository on travis-ci.com. Any variables stored there will be accessible to your build environment:

        Travis Environment Variables

      9. Edit the lines previously added by the travis encrypt-file command so that gatsby-deploy.enc and gatsby-deploy are prefixed with your scripts/ directory:

        .travis.yml
        1
        2
        3
        
        before_install:
        - openssl aes-256-cbc -K $encrypted_9e3557de08a3_key -iv $encrypted_9e3557de08a3_iv
          -in scripts/gatsby-deploy.enc -out scripts/gatsby-deploy -d
      10. Continue preparing the SSH agent in your build environment by adding the following lines to the before_install step, after the openssl command. Be sure to replace 192.0.2.2 with your Linode’s IP address:

        ~/example-site/.travis.yml
        1
        2
        3
        4
        5
        6
        7
        8
        
        before_install:
        - openssl aes-256-cbc -K $encrypted_9e3557de08a3_key -iv $encrypted_9e3557de08a3_iv
          -in scripts/gatsby-deploy.enc -out scripts/gatsby-deploy -d
        - eval "$(ssh-agent -s)"
        - cp scripts/gatsby-deploy ~/.ssh/gatsby-deploy
        - chmod 600 ~/.ssh/gatsby-deploy
        - ssh-add ~/.ssh/gatsby-deploy
        - echo -e "Host 192.0.2.2ntStrictHostKeyChecking non" >> ~/.ssh/config
      11. Travis CI can add entries to the build environment’s ~/.ssh/known_hosts prior to deploying your site. Insert the following addons step prior to the before_install step in your .travis.yml. Replace 192.0.2.2 with your Linode’s IP address:

        ~/example-site/.travis.yml
         1
         2
         3
         4
         5
         6
         7
         8
         9
        10
        
        # [...]
        dist: trusty
        sudo: false
        
        addons:
          ssh_known_hosts:
            - 192.0.2.2
        
        before_install:
        # [...]
      12. From your local computer, upload your Travis environment’s public key to the home directory of your limited Linux user on your Linode. Replace example_user with your Linode’s user and 192.0.2.2 with your Linode’s IP address:

        scp ~/example-site/scripts/gatsby-deploy.pub [email protected]:~/gatsby-deploy.pub
        
      13. Log in to your Linode (using the same user that the key was uploaded to) and copy the key into your authorized_keys file:

        mkdir -p .ssh
        cat gatsby-deploy.pub | tee -a .ssh/authorized_keys
        

      Create a Deployment Script

      1. Update your .travis.yml to include a deploy step. This section will be executed when a pull request is merged into the master branch. Add the following lines below the before_install step, at the end of the file:

        ~/example-site/.travis.yml
        1
        2
        3
        4
        5
        6
        
        deploy:
        - provider: script
          skip_cleanup: true
          script: bash scripts/deploy.sh
          on:
            branch: master

        The instructions for pushing your site to your Linode will be defined in a deploy.sh script that you will create.


        Full contents of your Travis configuration

        The complete and final version of your .travis.yml file should resemble the following:

        ~/example-site/.travis.yml
         1
         2
         3
         4
         5
         6
         7
         8
         9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        
        language: node_js
        node_js:
        - "10.0"
        
        dist: trusty
        sudo: false
        
        addons:
          ssh_known_hosts:
          - 192.0.2.2
        
        before_install:
        - openssl aes-256-cbc -K $encrypted_07d52615a665_key -iv $encrypted_07d52615a665_iv
          -in scripts/gatsby-deploy.enc -out scripts/gatsby-deploy -d
        - eval "$(ssh-agent -s)"
        - cp scripts/gatsby-deploy ~/.ssh/gatsby-deploy
        - chmod 600 ~/.ssh/gatsby-deploy
        - ssh-add ~/.ssh/gatsby-deploy
        - echo -e "Host 192.0.2.2ntStrictHostKeyChecking non" >> ~/.ssh/config
        
        deploy:
        - provider: script
          skip_cleanup: true
          script: bash scripts/deploy.sh
          on:
            branch: master
      2. From your local example-site Git repository, create a deploy.sh file in the scripts directory and make it executable:

        touch scripts/deploy.sh
        chmod +x scripts/deploy.sh
        
      3. Open your deploy.sh file in your text editor and add the following lines. Replace all instances of example_user with your Linode’s user, and replace 192.0.2.2 with your Linode’s IP:

        scripts/deploy.sh
         1
         2
         3
         4
         5
         6
         7
         8
         9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        
        #!/bin/bash
        set -x
        
        gatsby build
        
        # Configure Git to only push the current branch
        git config --global push.default simple
        
        # Remove .gitignore and replace with the production version
        rm -f .gitignore
        cp scripts/prodignore .gitignore
        cat .gitignore
        
        # Add the Linode production server as a remote repository
        git remote add production ssh://[email protected]:/home/example_user/gatsbybare.git
        
        # Add and commit all the static files generated by the Gatsby build
        git add . && git commit -m "Gatsby build"
        
        # Push all changes to the Linode production server
        git push -f production HEAD:refs/heads/master

        The deploy script builds the Gatsby static files (which are placed inside the public directory inside your repository) and pushes them to your Linode. Specifically, this script:

        • Commits the newly-built public directory to the Travis build environment’s copy of your Git repository.
        • Pushes that commit (over the SSH protocol) to a remote repository on your Linode, which you will create in the next section of this guide.

        Note

        Remember that because these instructions are executed in an isolated virtual environment, the git commit that is run here does not affect the repository on your local computer or on GitHub.

      4. You may recall that you previously updated your .gitignore file to exclude the public directory. To allow this directory to be committed in your build environment’s repository (and therefore pushed to your Linode), you will need to override that rule at deploy time.

        From the root of your local Gatsby project, copy your .gitignore to a new scripts/prodignore file:

        cp .gitignore scripts/prodignore
        

        Open your new prodignore file, remove the public line, and save the change:

        scripts/prodignore
        1
        2
        3
        
        .cache/
        public # Remove this line
        yarn-error.log

        The deploy.sh script you created includes a line that will copy this scripts/prodignore file into your repository’s root .gitgnore, which will then allow the script to commit the public directory.

      Prepare the Remote Git Repository on Your Linode

      In the previous section you completed the configuration for the Travis deployment step. In this section, you will prepare the Linode to receive Git pushes from your deployment script. The pushed website files will then be served by your NGINX web server.

      1. SSH into your Linode (under the same the user that holds your Travis build environment’s public key). Create a new directory inside your home folder named gatsbybare.git:

        mkdir ~/gatsbybare.git
        
      2. Navigate to the new directory and initialize it as a bare Git repository:

        cd ~/gatsbybare.git
        git init --bare
        

        A bare Git repository stores Git objects and does not maintain working copies (i.e. file changes that haven’t been committed) in the directory. Bare repositories provide a centralized place where users can push their changes. GitHub is an example of a bare Git repository. The common practice for naming a bare Git repository is to end the name with the .git extension.

      3. Configure the Git directory to allow linking two repositories together:

        git config receive.denyCurrentBranch updateInstead
        
      4. Your Travis build environment will now be able to push files into your Linode’s Git repository, but the files will not be located in your NGINX document root. To fix this, you will use the hooks feature of Git to copy your website files to the document root folder. Specifically, you can implement a post-receive hook that will run after every push to your Linode’s repository.

        In your Linode’s Git repository, create the post-receive file and make it executable:

        touch hooks/post-receive
        chmod +x hooks/post-receive
        
      5. Add the following lines to the post-receive file. Replace example.com with your domain name, and replace example_user with your Linode’s user:

        hooks/post-receive
        1
        2
        
        #!/bin/sh
        git --work-tree=/usr/share/nginx/html/example.com --git-dir=/home/example_user/gatsbybare.git checkout -f

        This script will check out the files from your Linode repository’s master branch into your document root folder.

        Note

        While a bare Git repository does not keep working copies of files within the repository’s directory, you can still use the --work-tree option to check out files into another directory.

      Deploy with Travis CI

      All of the test and deployment configuration work has been completed and can now be executed:

      1. Commit all remaining changes to your travis-configs branch and push them up to your central GitHub repository:

        git add .
        git commit -m "Travis deployment configuration"
        git push origin travis-configs
        
      2. Visit the pull request you previously created on GitHub for your travis-configs branch. If you visit this page shortly after the git push command is issued, the new Travis builds may still be in progress.

      3. After the linked continuous-integration/travis-ci/pr pull request Travis build completes, click on the corresponding Details link. If the build was successful, you should see the following message:

          
        Skipping a deployment with the script provider because the current build is a pull request.
        
        

        This message appears because pull request builds skip the deployment step.

      4. Back on the GitHub pull request page, after the linked continuous-integration/travis-ci/push branch build completes, click on the corresponding Details link. If the build was successful, you should see the following message:

          
        Skipping a deployment with the script provider because this branch is not permitted: travis-configs
        
        

        This message appears because your .travis.yml restricts the deployment script to updates on the master branch.

      5. If your Travis builds failed, review the build logs for the reason for the failure.

      6. If the builds succeeded, merge your pull request.

      7. After merging the pull request, visit travis-ci.com directly and view the example-site repository. A new Travis build corresponding to your Merge pull request commit will be in progress. When this build completes, a Deploying application message will appear at the end of the build logs. This message can be expanded to view the complete logs for the deploy step.

      8. If your deploy step succeeded, you can now visit your domain name in your browser. You should see the message from your Gatsby project’s index.js.

      Troubleshooting

      If your Travis builds are failing, here are some places to look when troubleshooting:

      • View the build logs for the failed Travis build.
      • Ensure all your .sh scripts are executable, including the Git hook on the Linode.
      • Test the Git hook on your Linode by running bash ~/gatsbybare.git/hooks/post-receive.
      • If you encounter permissions issues, make sure your Linode user can write files to your document root directory.
      • To view the contents of the bare Git repository, run git ls-tree --full-tree -r HEAD.

      Next Steps

      Read the Gatsby.js Tutorial to learn how to build a website with Gatsby.

      Join our Community

      Find answers, ask questions, and help others.

      This guide is published under a CC BY-ND 4.0 license.



      Source link