Service Previews

With Render service previews, you can test out proposed changes to a web service or static site before you deploy those changes to production.

Service preview in GitHub pull request

For each service preview, Render creates a separate instance of your service with its own onrender.com URL (served over HTTP/2 with full TLS), so you can validate your changes safely. Render automatically sets the HTTP response header X-Robots-Tag: noindex for all preview instances.

There are two types of service previews:

See details for each below.

A service preview creates an instance of only the service with changes. If you need to test changes against separate instances of other services (including databases), instead create a preview environment.

Pull request previews (Git-backed)

For Git-backed services, Render can automatically create a service preview for each pull request that’s opened against your deployed branch.

Enable service previews from the Render Dashboard:

  1. Select your service and open its Previews tab.
  2. In the Pull Request Previews section, set the toggle to Enabled.

Now, Render will create a separate preview instance of your service whenever a PR is opened against your deployed branch.

You can view all active previews from your service’s Previews tab. A preview link also appears in each PR’s activity feed on GitHub or GitLab:

Service preview in GitHub pull request

Skipping a PR preview

If you don’t want Render to create a preview instance for a particular pull request, include any of the following strings in the pull request’s title (not in a commit message):

  • [skip render]
  • [skip preview]
  • [render skip]
  • [preview skip]

Working with PR previews

  • Preview instances copy all of their settings over from their base service when they’re first created. This includes environment variables, such as database connection information.

    Make sure to change environment variables on your preview instance if you want it to use a staging or test database.
  • Your app can detect whether it’s a PR preview by checking the value of the IS_PULL_REQUEST environment variable (true for a PR preview, false otherwise).

  • Whenever you push to the branch for an open PR, Render automatically updates the PR preview by building and deploying the latest commit.

  • Render automatically deletes a PR preview instance when its associated PR is merged or closed.

    • You can manually delete a PR preview instance from its Settings tab on the Render Dashboard. However, Render recreates the instance if you push new changes to the associated PR branch.
  • If you’re using a monorepo, you can fine-tune its PR preview behavior by defining the root directory or specifying build filters.

  • If you make changes to your base service after creating a PR preview, those changes are not applied to the preview instance.

Billing for PR previews

PR Previews are billed at the same rate as your base service. They are always prorated by the second.

  • If your base service is a free static site, its PR previews are also free.
  • If your base service costs $7 per month and one of its PR preview instances is active for half of a month, that preview instance costs a total of $3.50.

Image previews

For image-backed services, you can create a service preview using the Render API. Specifically, you use the Create preview for image-backed service endpoint:

POST https://api.render.com/v1/services/{serviceId}/preview

You can add this API request to your CI pipeline to automatically generate an image preview whenever an image tag is created or updated in your container registry. See an example.

Preview instances can deploy any tag or digest for the base service’s associated Docker image. For details, see the API reference.

You can view all active previews from your service’s Previews tab on the Render Dashboard:

List of image previews in the Render Dashboard

Working with image previews

  • Preview instances copy all of their settings over from their base service when they’re first created. This includes environment variables, such as database connection information.

    Make sure to change environment variables on your preview instance if you want it to use a staging or test database.
  • Render does not automatically delete image previews. Make sure to delete image previews when you’re finished with them, either from the Render Dashboard or via the Render API.

  • If you make changes to your base service after creating an image preview, those changes are not applied to the preview instance.

Billing for image previews

An image preview is billed according to the instance type you specify in your API request. If you don’t specify an instance type, Render uses the same instance type as the base service.

If your base service uses a paid instance type, its previews can’t use the Free instance type.

Example GitHub Action

This example uses GitHub Actions and pushes images to Docker Hub, but the high-level steps apply to any combination of CI provider and container registry.

# This GitHub Action demonstrates building a Docker image,
# pushing it to Docker Hub, and creating a Render build
# preview with every push to the main branch.
#
# This Action requires setting the following secrets:
#
# - DOCKERHUB_USERNAME
# - DOCKERHUB_ACCESS_TOKEN (create in Docker Hub)
# - RENDER_API_KEY (create from the Account Settings page)
# - RENDER_SERVICE_ID (the service to create a preview for)
#
# You must also set env.DOCKERHUB_REPOSITORY_URL below.
#
# Remember to delete previews when you're done with them!
# You can do this from the Render Dashboard or via the
# Render API.

name: Preview Docker Image on Render

# Fires whenever commits are pushed to the main branch
# (including when a PR is merged)
on:
  push:
    branches: [ "main" ]

env:
  # Replace with the URL for your image's repository
  DOCKERHUB_REPOSITORY_URL: REPLACE_ME
jobs:

  build:

    runs-on: ubuntu-latest

    steps:
    - name: Check out the repo
      uses: actions/checkout@v3

    - name: Build the Docker image
      run: docker build . --file Dockerfile --tag $DOCKERHUB_REPOSITORY_URL:$(date +%s)

    - name: Log in to Docker Hub
      uses: docker/login-action@v2.2.0
      with:
        username: ${{ secrets.DOCKERHUB_USERNAME }}
        password: ${{ secrets.DOCKERHUB_ACCESS_TOKEN }}

    - name: Docker Metadata action
      uses: docker/metadata-action@v4.6.0
      id: meta
      with:
        images: ${{env.DOCKERHUB_REPOSITORY_URL}}

    - name: Build and push Docker image
      uses: docker/build-push-action@v4.1.1
      id: build
      with:
        context: .
        file: ./Dockerfile
        push: true
        tags: ${{ steps.meta.outputs.tags }}
        labels: ${{ steps.meta.outputs.labels }}

    - name: Create Render service preview
      uses: fjogeleit/http-request-action@v1
      with:
        # Render API endpoint for creating a service preview
        url: 'https://api.render.com/v1/services/${{ secrets.RENDER_SERVICE_ID }}/preview'
        method: 'POST'

        # All Render API requests require a valid API key.
        bearerToken: ${{ secrets.RENDER_API_KEY }}

        # Here we specify the digest of the image we just
        # built. You can alternatively provide the image's
        # tag (main) instead of a digest.
        data: '{"imagePath": "${{ env.DOCKERHUB_REPOSITORY_URL }}@${{ steps.build.outputs.digest }}"}'