It's day three of our four-part series of posts about running Static Site Generators (SSGs) and alternative Content Management Systems on Platform.sh. Today, we're looking at GatsbyJS, an SSG publishing framework built on top of React Facebook's Javascript library. What makes Gatsby unique and interesting is that it's written as a Progressive Web App (PWA).
Gatsby and other PWAs use a combination of client-side (Javascript) and server-side components, which can be both static assets and dynamic APIs. This gets to our third, three-letter-acronym: JAM or JAMstack—an architecture built on client-side Javascript, APIs, and Markup, as opposed to the LAMP (Linux, Apache, MySQL, PHP) server-side stack we know so well from Drupal, WordPress, and so on.
While Gatsby uses a different language (Javascript) and server-side framework (Node) than the other SSGs we're demonstrating, setting it up on Platform.sh is very similar to how we ran Hugo, the Go-based SSG.
Let's run GatsbyJS on Platform.sh
We'll start as we have before with a local version of our application. Since we're starting from scratch, we need a few prerequisites installed on our machine. If you have an existing Gatsby app, you can skip ahead. You can also download a ready-to-run copy of a Gatsby project for Platform.sh, if that's more your speed.
1. Set up your local machine
You'll need four tools to deploy your Gatsby site on Platform.sh:
- Git: install git if it's not already on your machine
- Node 8+: install node
- npx:
sudo npm install -g npx
- Optional (but really, you should): the platform.sh cli tool
For each of these tools, please refer to their own install pages.
2. Bootstrap your GatsbyJS project
You need to create a new GatsbyJS folder from a template:
$ npx gatsby new gatsby-hello https://github.com/gatsbyjs/gatsby-starter-blog
npx: installed 1384 in 33.248s
info Creating new site from git: https://github.com/gatsbyjs/gatsby-starter-blog.git
Cloning into 'gatsby-hello'...
...... (Lots of output here)
Initialized empty Git repository in /media/psh/customers/gatsby-hello/.git/
info Create initial git commit in gatsby-hello
You can now run the local development server:
$ cd gatsby-hello && npm run develop
> gatsby-starter-blog@0.1.0 develop /media/psh/customers/gatsby-hello
> gatsby develop
... (Lots of output here)
You can now view Gatsby-starter-blog in the browser.
http://localhost:8000/
View GraphiQL, an in-browser IDE, to explore your site's data and schema.
http://localhost:8000/___graphql
Note that the development build is not optimized.
To create a production build, use npm run build.
ℹ 「wdm」:
ℹ 「wdm」: Compiled successfully.
Browse http://localhost:8000/ to check that everything is working as expected.
The npx
template already creates a basic Git repository:
$ git log
commit cd34e2366e6c28de7e0db53b527d6d4ddb1b7952 (HEAD -> master)
Author: Guillaume Moigneu <***@platform.sh>
Date: Mon Feb 18 12:33:26 2019 +0100
Initial commit from Gatsby: (https://github.com/gatsbyjs/gatsby-starter-blog.git)
Create a Platform.sh project by signing to a trial account or log in to your account.
Select a Standard
project, then choose the region you want your project to be hosted in.
Review and validate. You can now access your newly provisioned project. On the wizard, click Git remote
and copy it.
Add the remote to your local project:
git remote add platform <project ID>@git.<region>.platform.sh:<project ID>.git
Don't push anything for now. You still need to add the Platform.sh configuration.
4. Set up the
Platform.sh relies on yaml
configurations to configure the different containers to deploy. Create the .platform.app.yaml
file at the root of your project, and add the following code:
# .platform.app.yaml
# The name of this application, which must be unique within a project.
name: "gatsbyjs"
# The type key specifies the language and version for your application.
type: "nodejs:8.9"
# The hooks that will be triggered when the package is deployed.
hooks:
# Build hooks can modify the application files on disk but not access any services like databases.
build: |
npm run build
# The size of the persistent disk of the application (in MB).
disk: 256
# The configuration of the application when it's exposed to the web.
web:
commands:
start: sleep infinity
locations:
"/":
# The public directory of the application relative to its root.
root: "public"
index: ["index.html"]
scripts: false
allow: true
The web
section is nearly identical to the Hugo version. Really, serving any static site on Platform.sh is the same at runtime. The build hook is a bit simpler in this case as it need only run npm run build
to compile Gatsby.
Because the container type
is NodeJS, and the build flavor is left at the default, Platform.sh will automatically run npm install
before the build hook automatically to ensure all dependencies are available.
We need also two other files: routes.yaml
and services.yaml
. services.yaml
is used to configure additional services like databases, so we don't need it for that project. Just create the file:
mkdir .platform
touch services.yaml
Add routes.yaml
in the .platform
folder, and add the following configuration:
"https://{default}/":
type: upstream
upstream: "gatsbyjs:http"
This file tells the Platform.sh router to direct all incoming requests to our gatsbyjs
container. Commit these new files:
git add .platform.app.yaml .platform
git commit -m "Add platform.sh configuration"
5. Test and deploy
You're now ready to deploy the project on Platform.sh. Push the repository to the new remote:
git push platform master
Platform.sh will then build and deploy your Gatsby application, with the following output:
Counting objects: 44, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (38/38), done.
Writing objects: 100% (44/44), 1.04 MiB | 16.98 MiB/s, done.
Total 44 (delta 2), reused 0 (delta 0)
Validating submodules
Validating configuration files
Building application 'gatsbyjs' (runtime type: nodejs:8.9, tree: fafb3d4) Generating runtime configuration.
Building a NodeJS application, let's make it fly.
Found a `package.json`, installing dependencies.
> sharp@0.21.3 install node_modules/sharp
> (node install/libvips && node install/dll-copy && prebuild-install) || (node-gyp rebuild && node install/dll-copy)
...
up to date in 14.102s
success open and validate gatsby-configs — 0.009 s
success load plugins — 0.325 s
success onPreInit — 0.895 s
success delete html and css files from previous builds — 0.096 s
success initialize cache — 0.016 s
success copy gatsby files — 0.024 s
success onPreBootstrap — 0.006 s
success source and transform nodes — 0.104 s
success building schema — 0.326 s
success createPages — 0.056 s
success createPagesStatefully — 0.032 s
success onPreExtractQueries — 0.004 s
success update schema — 0.185 s
success extract queries from components — 0.134 s
success run graphql queries — 0.694 s — 9/9 13.00 queries/second
success write out page data — 0.012 s
success write out redirect data — 0.001 s
info bootstrap finished - 5.674 s
done generating icons for manifest
success onPostBootstrap — 0.287 s
success Building production JavaScript and CSS bundles — 11.784 s
success Building static HTML for pages — 0.844 s — 7/7 28.27 pages/second
Generated public/sw.js, which will precache 11 files, totaling 283621 bytes.
info Done building in 18.685 sec
Executing pre-flight checks...
Compressing application.
Beaming package to its final destination.
W: Route '{default}' doesn't map to a domain of the project, mangling the route.
Provisioning certificates
Validating 1 new domain
Provisioned new certificate for 1 domains of this environment
(Next refresh will be at 2019-04-20 20:19:01+00:00.)
Environment certificates
- certificate 18bf626: expiring on 2019-05-18 20:19:01+00:00, covering master-7rqtwti-<project ID>.<region>.platformsh.site
Creating environment <project ID>-master-7rqtwti
Environment configuration
gatsbyjs (type: nodejs:8.9, size: M, disk: 5120)
Environment routes
http://master-7rqtwti-<project ID>.<region>.platformsh.site/ redirects to https://master-7rqtwti-<project ID>.<region>.platformsh.site/
https://master-7rqtwti-<project ID>.<region>.platformsh.site/ is served by application `gatsbyjs`
Let's review the output of your push
. After a basic Git push output, Platform.sh kicks in and runs the build script. Under where it says Executing build hook
you can see it downloading npm packages and then running Gatsby.
Building application 'gatsbyjs' (runtime type: nodejs:8.9, tree: fafb3d4)
Generating runtime configuration.
Building a NodeJS application, let's make it fly.
Found a `package.json`, installing dependencies.
> sharp@0.21.3 install node_modules/sharp
> (node install/libvips && node install/dll-copy && prebuild-install) || (node-gyp rebuild && node install/dll-copy)
...
up to date in 14.102s
success open and validate gatsby-configs — 0.009 s
success load plugins — 0.325 s
success onPreInit — 0.895 s
success delete html and css files from previous builds — 0.096 s
success initialize cache — 0.016 s
success copy gatsby files — 0.024 s
success onPreBootstrap — 0.006 s
success source and transform nodes — 0.104 s
success building schema — 0.326 s
success createPages — 0.056 s
success createPagesStatefully — 0.032 s
success onPreExtractQueries — 0.004 s
success update schema — 0.185 s
success extract queries from components — 0.134 s
success run graphql queries — 0.694 s — 9/9 13.00 queries/second
success write out page data — 0.012 s
success write out redirect data — 0.001 s
info bootstrap finished - 5.674 s
done generating icons for manifest
success onPostBootstrap — 0.287 s
success Building production JavaScript and CSS bundles — 11.784 s
success Building static HTML for pages — 0.844 s — 7/7 28.27 pages/second
Generated public/sw.js, which will precache 11 files, totaling 283621 bytes.
info Done building in 18.685 sec
(It's not as fast as Hugo, but still decently fast.)
Platform.sh then checks that everything seems correct and deploys the container to a host. Again, it generates Let's Encrypt TLS certificates for every route automatically and ends with the URLs of the application:
Environment routes
http://master-7rqtwti-<project ID>.<region>.platformsh.site/ redirects to https://master-7rqtwti-<project ID>.<region>.platformsh.site/
https://master-7rqtwti-<project ID>.<region>.platformsh.site/ is served by application `gatsbyjs`
The last output is your application's new URL. You can also check that the project has been successfully deployed on the web interface. If you've got the Platform.sh CLI installed, jumping to the web interface from your project is simple; no need to remember project IDs, just type platform web
.
Now your basic GatsbyJS site is up and running!
As a side note, we've been focused this week on showing how you can run alternate frameworks and a variety of languages on Platform.sh. Did you know that you can run multiple applications inside the same project? This multi-app setup is a subject for another post, however it's worth noting that combining purpose-built services, like a site built with an SSG, with a blog powered by WordPress, or a headless e-commerce back end powered by Magento or Drupal Commerce, is quite straightforward. Gatsby makes it especially easy, since it's client-side framework was designed to consume APIs directly.
Tomorrow, we'll take a look at our final SSG, and the most popular, Jekyll a SSG written in Ruby.
Read the series: Four days, four languages, four frameworks
- Day 1, Java: Running Brightspot CMS on Platform.sh
- Day 2, Go: Hugo, a fast static site generator