Static All The Things

There is a lot of talk these days about startups dealing with their “monolith problem”. Generally solving the monolith problem means breaking the giant application that runs your product into smaller single–use miniservices. Belly had a monolith, and has gone through this exact process. We happily now run all of our product–serving backend on a bunch of different miniservices. However, Belly’s public–facing websites have always lived in a separate Rails app, which has unfortunately become its own monolith.

When I first started at Belly, this was the first problem I wanted to solve. We have a lot of big plans for Belly’s web presence, and there is no way we can accomplish them inside of the beast of an application that we currently have. So a bunch of the tech team and I got together and brainstormed about what the dream web platform would look like. We had some “needs” and a lot of “wants”:

  • All pages must be indexable by search engines
  • It must use technology we are familiar with, and can easily scale as the team grows
  • It must support our marketing team’s needs to easily update/test content
  • Domain names should be independent of codebases (ie: bellycard.com/account and bellycard.com/bites can be separate repos)
  • It should be ridiculously fast

We’ve landed on a couple different technologies to support this structure, and so far we are very pleased.

Prismic.io

Up until now, any copy changes that needed to happen on any of Belly’s websites required someone on the engineering team to make the change, submit a pull request, and deploy the new code. As the company has grown and our marketing team has become more interested in what our websites say, this strategy has scaled very poorly. Engineering is busy building out the product, and copy changes have usually been labeled low priority.

Obviously that wasn’t going to work. We used a CMS for the Belly Blog, but it was mostly broken and barely met our needs. We needed to find a fresh solution. This is a hard task – there are a lot of CMSs out there, but most of them are either geared towards a specific use (blogging), or are terribly difficult for non–tech savvy users. Our infrastructure is also very biased towards Ruby, so if we were going to host something internally it had to run on Ruby.

After poking around a bunch of different solutions and not being pleased with any of them, I landed on Prismic. Prismic is essentially a CMS as a service. They let you define any sort of content type using a fairly simple JSON schema, which they then plug into their writing room. The interface for our marketing team is super simple, and has been much quicker to train on than any other CMS I’ve used in the past. Once the content is written, Prismic provides a really nice API to retrieve that content. All of the assets are hosted on a CDN so you get ridiculously fast load times.

As an added benefit, the team behind Prismic has been super helpful. A CMS as a service is kind of a new idea, which has caused me to have a lot of questions about the best way to do things. The support is quick and always has a good answer – we’ve actually had a lot of deeper conversations regarding content creation, which have evolved my idea of the best way to do writing. I can’t fit it all in this blog post, but I think Prismic is fixing a much larger problem regarding content writing that most of us probably don’t even recognize. I’ll write another blog post about that, I promise.

Middleman

Belly has been testing out middleman (mostly on this site) for a few months. We’ve really enjoyed it, and some of the team members have actually started contributing code. Middleman is a static site generator, similar to things you’re familiar with like Jekyll, but on steroids. Middleman gives you a full ruby app structure to play with – you can pull content from APIs, do crazy data manipulation, and pretty much any other sort of logic you could accomplish in Ruby.

The trouble with any static site generator, though, is that data isn’t static. Belly is constantly updating content on its website, writing new blog posts, and adding new merchants. All of those things change the structure and the content of our site, and they happen much too often for someone to have to manually regenerate the site every time. To solve this, we are using a build server that hooks into middleman to regenerate all of the pages that need to be updated. Currently we’ve got this running on a simple schedule, but soon enough we’ll be setting up our build server to receive webhooks whenever any content changes.

Belly LB and S3

We’ve got a pretty stellar infrastructure team here at Belly, and they’ve built this system called the Belly Load Balancer. How the Belly LB works seems mostly like magic to me, so I can’t say too much about how it works, but it allows us to spin up nginx load balancers through Chef. To support this new static site structure, they added an amazing feature that allows me to write RegExp matchers that will direct certain URLs to an S3 bucket.

We use and contribute to middleman–s3_sync, which allows us to build our middleman sites and then intelligently sync them with S3. It’s got some logic in there to only find files that have changed an update those, instead of rebuilding our entire site every time. All of this put together lets us develop different portions of the site separately and then just sync them into their appropriate folders. The Belly LB does the rest of the work for mapping URLs.

WIP

We’re still in the process of moving all of our web property over to this new architecture, but the parts that are done are working wonderfully. The engineering site is entirely middleman, as is the Belly Blog which also pulls content from Prismic. Most of the BellyCard website website is staying in a Rails app while we redo some designs, but all of the content is coming from Prismic.

It’s been very exciting to watch our web properties make this transition. The marketing team love managing content in a sane system like Prismic, and the load times on the Blog have been cut in half (< 500ms now!).

Ask a question or share this article, we’d love to hear from you!

Tweet