O Hai, Netlify
At NYC Planning Labs, we make lots of single-page apps (SPAs), usually in ember.js. These come with additional burden when deploying, as the source code needs to be built into the final set of static files that will be served up by a web server. We recently migrated all of our SPAs to Netlify, a cloud service that allows you to “Build, deploy, and manage modern web projects”.
What were we using before? Dokku, which is an open source Heroku-like platform as-a-service. Our old workflow looked like this:
CircleCI runs the test suite to ensure that we aren’t regressing. If everything looks good, the last step in the CircleCI config builds the site and deploys to Dokku. This workflow worked well for us, but added a lot of apps to our Dokku server (we need a production and staging site for each app) Combined with the APIs running in Dokku, we had almost 30 apps and services to keep track of.
Dokku (and Heroku) are kind of overkill for SPAs anyway. They’re just files that need to be served at a specific domain name. Dokku and Heroku make more sense for things that need to run a process, talk to a database, and do a lot more work behind the scenes.
So, the first perk of Netlify is simplifying our Dokku server, as we only need to manage a half-dozen or so APIs and services in that environment. The added perks are many, which I’ll outline below.
How it Works
Netlify connects to a Github repo (much like CircleCI and other Github-integrated services) and triggers builds and deploys when new commits are added to a branch.
It’s savvy enough to tell that it’s looking at an ember.js app, and knows the appropriate command `ember build`, and the correct destination folder to serve (`/dist`). Likewise, it will do the same for Gatsby, Jekyll, and other popular static site generators.
Once the build is complete, it hosts the site at a well-structured netlify.com domain name ({branchname} — {netlifyappname}.netlify.com). We’ve got it configured to automatically deploy on changes to ther master and develop branches, and have it fire off slack notifications when the deployment is successful.
Simple UI + Advanced Customization
Netlify brings a super-simple User Interface, making it easy to set up new github repositories for deployment, manage which branches should automatically deploy, and add custom build commands.
We also had to add a few Netlify-specifc config files to our repos to make sure the service would use different commands for production and staging sites.
Pull Request Builds
One big improvement over our old workflow is automatic builds for all pull requests. This means whenever anyone opens a new pull request on one of our frontend apps, Netlify will build the site and deploy it separately from the production and staging sites AND add a link to the pull request! This means reviewers can quickly try new features and manually test things out in a browser, instantly, instead of having to download the branch and build/run it locally.
This has been a huge time-saver for our team, and has also led to people catching regressions that weren’t covered in automated testing, saving us from future headaches down the line.
Does Netlify run the test suite?
No, CircleCI still plays an important role in running the automated tests. When new code is committed to master or develop, the Netlify Build and the CircleCI testing happen simultaneously. For our ember apps, it wasn’t feasible to run the tests in Netlify because they require a more complex environment.
What about domain names?
With the workflow described above, the many deployments of an app are all published at Netlify.com URLs. Netlify can also manage a custom domain name on the production build, and add SSL via Lets Encrypt. We tested this functionality and it worked great, but decided to keep our DNS configuration separate for a couple of reasons:
- We don’t have control of the DNS entries for our production domains (e.g. https://zola.planning.nyc.gov), and changing them is time-consuming and difficult to manage.
- We like to have a predictable planninglabs.nyc URL for all of our staging sites (e.g. https://zola-staging.planninglabs.nyc), as these get passed around more internally and sent to customers for review.
We use Nginx configuration to proxy the netlify.com urls, serving the production and staging builds on their respective domains.
The end users never see a netlify.com domain, and we were able manage the migration of all of our apps to netlify without making any DNS changes! The downside of this setup is that we must manage SSL on our own, and have to write new Nginx configs for each app we deploy. We’re looking into how to automate this with ansible.
Open Build Tracking
Another fun feature of Netlify is public build logs. With a single URL, anyone can inspect the various builds on an app. For example, here’s the public deployment log for ZoLa, which we’re actively working on in the current sprint: https://app.netlify.com/sites/labs-zola/deploys. This complements our already-open source code, automated testing, and issue tracking, and reflects the Planning Labs Core Value Open By Default.
Next Steps
This move comes from a desire to use more third-party services instead of managing our own infrastructure. We’re a small team, and don’t have dedicated personnel for devOPs and server maintenance. We are still using our old Dokku server, but it’s got a lot less running on it, and will be that much simpler to maintain and upgrade. We can now turn our attention to figuring out what’s best to get our APIs and databases off of self-maintained infrastructure.
Thanks for reading! Let us know on Twitter at @nycplanninglabs if you have any questions about deploying Ember apps on Netlify!