How to create Preview Environment with separate client+API repositories (render.yaml)

My app is split between two repositories, one client and one API. My render.yaml lives in my client repository.

When I create a Preview Environment I run into two challenges:

  1. How can I tell my preview environment to also use a separate branch for the API?
  2. How can I dynamically rewrite my routes to point to the preview API?

My render.yaml looks something like this:

previewsEnabled: true
services:
  - type: web
    env: static
    repo: https://github.com/me/foobar.git
    routes:
      - type: rewrite
        source: /api/*
        destination: https://foobar-api.onrender.com/*
  - type: web
    env: node
    repo: https://github.com/me/foobar-api.git

I assume the right answer to (1) is to just use two render.yaml files, one for each repository.

As for the rewrites, I can of course manually change them in the render.yaml but it would make it easy to accidentally push wrong routes to production. I think my setup is a common one so I’m guessing there must be a more elegant solution to this?

Hi @Moon, these are great questions, but unfortunately I don’t have great answers.

Preview environments currently work a lot better with a monorepo approach (see, for example: preview-environment/render.yaml at main · render-examples/preview-environment · GitHub). With multiple repositories it would currently be difficult for our system to realize that the separate pull request events are related. As you point out, using two render.yaml files is probably the best workaround. You could give each repository its own render.yaml file with previewsEnabled: true , and then manually update the rewrite rule, not in the render.yaml file, but in the dashboard itself. This would involve a manual step, but would eliminate the risk of accidentally pushing the wrong route to production. With our forthcoming public API you should be able to automate this flow.

To elaborate, you’d have something like this in the render.yaml in me/foobar:

previewsEnabled: true
services:
  - type: web
    env: static
    routes:
      - type: rewrite
        source: /api/*
         # Update in dashboard to foobar-api PR URL
        destination: https://foobar-api-staging.onrender.com/* 
    ...

And this in the render.yaml in me/foobar-api:

previewsEnabled: true
services:
  - type: web
    env: node
    ...

With this approach I’d recommend creating dedicated staging resources for the times when you open a PR on one repo but not the other.

To elaborate on your second question, we don’t currently support dynamic rewrite destinations, but we are planning to add this functionality.

All things considered, you may want to switch to a monorepo :frowning:

Our product is constantly evolving, so we’d love to hear your feedback on how we could better meet your needs here. Thanks!

2 Likes

Thank you for the advice.

Taking this in, I think the most elegant solution for me would be to have two services connected to the same repo, one staging that auto-deploys and one production that I manually deploy. Then I can have have two routes in my render.yaml, /api/ and /api-staging/, and us my NODE_ENV environment variable to choose which to use when.

Once more people join my project, we can use pull requests auto-previews with a dashboard override of the route paths. Maybe later automate that via the API. Amazing, thank you.

That, or switch to a monorepo of course…

I have only good things to say about Render, it’s really an incredible service and has allowed me to set up an entire staging/production pipeline without prior experience and without losing sleep. An absolute game changer.

2 Likes

Thanks for the kind words @Moon! Don’t hesitate to follow up with more questions.

That would be amazing! :metal: