The importance of the release stage in deployment

David Dahan
Feb 2022 2 min

Do you know It's a PaaS aiming to replace Heroku, taking advantage of its decline. You get plenty of new welcomed features like free static sites on CDN, attached disks, infrastructure as code, HTTP2, a fast dashboard, a clean and up-to-date documentation, lower pricing at scale, and so on.

In a word, a better Heroku? Not so fast.

If you already played with Heroku, you're probably aware of their pipeline feature. Simply speaking, it's a way to group apps sharing the same codebase, in which each pipeline represents a stage, in a delivery workflow (for example : development → staging → production).

What's brillant here is not just the idea of organising and representing apps by stage, but the workflow itself: you build your code once, and as soon as you're happy with your code at stage N, you promote it at stage N+1. A promotion does not re-build the code, which gives you some advantages. For example, promoting your app between a staging and production environments:

  • Takes one second to deploy your app in production
  • Gives you the assurance to run the exact same code in production that the code you just tested in staging (there are several reasons why 2 different builds can lead to different deployed code)

Now let's dive a little bit deeper to understand whats makes this workflow possible. Back in the days, Heroku team published a 12factors app methodology for building SaaS apps, in which the 5th rule is about a strict separation between the following 3 stages:

  • Build stage: transforms a code repo into an executable bundle known as a build.
  • Release stage: takes the build and combines it with current config, to output a release ready for immediate execution. This stage if often used to run database migrations (rake db:migrate in Rails, python migrate in Django, etc.). And this makes perfect sense: if you're aiming to use the same build for each environment, you need to run everything's tied to the environment itself, in a specific stage. For pipelines, promoting an app to stage N+1 will not rebuild the app but will run the release phase.
  • Run stage: the runtime, launching the app's process (like your server) against a selected release.

However, the release phase is absent from Render architecture (and probably many other PaaS). Why? Honestly, I don't know. However, for hosting services, I already noticed two pain points (and there may have more):

1) As just explained, pipeline workflow is almost impossible without a release phase. You could technically organise apps in pipelines, but having to rebuild for each promotion would make this feature a cosmetic one rather than a true workflow improvement.

2) Unlike Heroku, gives access to mounted disks, which allows an app to use SQLite as a database. But disks are not available at build stage, which is understandable. But wait… when am I supposed to run migrations sthen? I have no choice, I have to run my migrations at runtime!!! And I see two problems with that:

  • Even if it works in most cases, it makes no sense. It means as soon as you server starts, it tries to run migrations. And it means if some day you get a long migration, your app could take a while to start.
  • Another issue is consistency between your Render apps. In my first app, I have a managed PostgreSQL. In that case, migrations are run at build time. In my second app, I have a SQLite database, and migrations are run at runtime. Not having an intermediary release phase forces me to think differently, according to the database I chose.

Some would argue that these are not crucial issues. But I'd answer that a clean architecture and a clean deployment process require simplicity, clarity, sense, and consistency, and that human errors often come from workarounds and inconsistencies like these.

In the meantime, adding a release phase is considered like an upvotable feature in Render community. I'm not sure I see it this way. Having a release phase is more an architectural decision which allows more features to exist (pipelines) and make the whole deployments more robust.

Once implements the release phase, I think I'll be able to say to the world:

We got our new Heroku!

written by
David Dahan