Skip to content

Instantly share code, notes, and snippets.

@jrr
Last active March 2, 2023 20:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jrr/57c84848c72ebdd0f3364a86b7d55163 to your computer and use it in GitHub Desktop.
Save jrr/57c84848c72ebdd0f3364a86b7d55163 to your computer and use it in GitHub Desktop.
Render deployment with multiple environments

This is an excerpt from my project's README.


Deployment

The app is deployed to Render.

Cloud resources are provisioned using a feature called Blueprints. Resources are defined in render.yml (server, database, etc.) and Render watches for changes to them on particular Git branches.

Code is deployed via Git integration, as well. (Render "Auto-Deploy"). For a given environment, code will deploy when changes are made to a particular git branch, or when the underlying cloud resources are re-provisioned.

Review Apps

When a PR is opened against the dev branch, a temporary review app will be created with a URL like https://project-dev-pr-66.onrender.com/. When the PR is merged or closed, the environment is destroyed.

Note that we're using Render's "Preview Environments", which produce isolated apps comprising the full stack, including the database. (contrast with Render's "Pull Request Previews", which create only a single service)

Dev

When a change is made on the dev branch:

  • If render.yaml is changed, the cloud resources will reprovision ("Blueprint sync").
  • The app's code will be built and deployed.

Production

When a change is made to the prod-render-yaml branch, the production resources will be provisioned. When a change is made to the main branch, the production code will be deployed.

This awkward two-branch setup is due to limitations in how Render works. Hopefully support for multiple environments is improved in the future.

For now, the setup requires that we carefully coordinate deployment of render.yaml changes to production. For a given change, the lifecycle goes something like this:

  1. Change is made to render.yaml on a feature branch.

  2. A PR is opened to merge the feature branch into dev. A temporary review app is automatically created, reflecting the changes to render.yaml.

  3. The PR is merged to dev. Render automatically provisions the dev resources and deploys the dev code.

  4. A PR is opened from dev to main carrying the code changes for a production release.

  5. A PR is opened bringing changes from dev to prod-render-yaml, carrying the render.yaml changes for the production release.

    Pay close attention to this diff! We need to carefully bring across the intended changes without overwriting the bits that are meant to differ between dev and prod (e.g. configuration values).

    Practically, it's recommended to create an intermediate branch from prod-render-yaml, merge in the changes from dev, then open the PR:

    git checkout dev
    git pull
    git checkout prod-render-yaml
    git pull
    git checkout -b prod-render-23.02.28
    git merge dev
    // resolve conflicts very carefully!
    // open PR prod-render-23.02.28 -> prod-render-yaml
    
  6. Merge both PRs to provision resources and deploy code. Unfortunately this cannot be done atomically, so plan for an intermediate mismatched state. Consider the dependencies and sequence to avoid a broken interval if possible. (e.g. resources then code vs. code then resources)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment