Deploy an app to multiple environments with Vercel

It's possible to deploy an application hosted on the Vercel platform (formerly Zeit Now) to multiple environments with a little extra configuration. This post will explain the following:

  • How to deploy an application to two different environments (e.g. staging & production) that are accessible at 2 different subdomains (e.g. staging.app.com and app.com).
  • Deploy to multiple environments from a local machine that is already authenticated with Vercel using now login
  • Deploy to multiple environments from a CI machine that is not authenticated with Vercel

Vercel project setup

In order to deploy an app to 2 different environments, it's required to have Vercel projects for each environment. In your project directory, you can execute the now command to deploy a new project. Once you've deployed the project for one environment (e.g. staging), take note of the projectId and orgId values found in the generated .now/project.json file as those values will be needed later.

Once the projectId and orgId values have been recorded somewhere for the first environment, delete the .now directory and re-execute the now command to setup a project for the other environment (e.g. prod). Again, record the projectId and orgId values found in the generated .now/project.json file and then delete the .now directory.

If you've already created a project in Vercel, you can still run the now command above since the now command will prompt you to create a new project OR link to an existing project.

Each environment will likely have a different set of environment variable values, so make sure to setup 2 different now.json configuration files for each environment. For example you can create a now.staging.json and a now.prod.json file to map your environment variables to the appropriate Now secret.

Make sure to configure the domain names for each environment in the Vercel dashboard in order to have the deployed apps accessible at custom domain names.

Deploy from local machine that is already authenticated with Vercel

With the projectId and orgId values known for each environment and the Vercel configuration files set for each environment, it's possible to deploy to both environments using the Vercel CLI.

bash
1# Deploy to staging environment
2export NOW_PROJECT_ID=xxx && export NOW_ORG_ID=xxx && now --prod --local-config ./now.staging.json
3# Deploy to prod environment
4export NOW_PROJECT_ID=xxx && export NOW_ORG_ID=xxx && now --prod --local-config ./now.prod.json

Replace the xxx for NOW_PROJECT_ID and NOW_ORG_ID with the values of projectId and orgId, respectively, that correspond with the Vercel project you wish to deploy. The above commands sets the NOW_PROJECT_ID and NOW_ORG_ID environment variables which are used by the Now CLI to determine to which project the app should be deployed.

Personally, I use the dotenv-cli library to set the NOW_PROJECT_ID and NOW_ORG_ID environment variables. It requires installing dotenv-cli and creating a file that will hold the values of the environment variables.

bash
1# .now.env.staging
2NOW_ORG_ID=xxx
3NOW_PROJECT_ID=xxx

Then the command to deploy to Vercel is as follows:

bash
1# Deploy to staging environment
2dotenv -e now.env.staging -- now --prod --local-config ./now.staging.json
3# Deploy to prod environment
4dotenv -e now.env.prod -- now --prod --local-config ./now.prod.json

This allows me to store the values of the NOW_ORG_ID and NOW_PROJECT_ID environment variables in files that can be ignored by git so I don't need to commit secrets to source control.

Deploy from CI machine that is not authenticated with Vercel

On CI machines, make sure to load the environment variables using the environment variable system that comes with your CI provider. For example, with GitHub actions you would set GitHub secrets that contain the projectId and orgId for all your deployment environments and then map the values of those secrets to environment variables specified in a workflow file.

Also, in order to run Now CLI commands from a CI machine, it is required to provide a ZEIT Now token to the Now CLI command to be executed. You can generate a Vercel token here.

bash
1now --prod --local-config ./now.staging.json --token xxx

References

Spectrum chat discussion on project linking and CI/CD pipelines

GitHub issue comment by Honza Javorek about the environment variables needed to be set



Robert Cooper's big ol' head

Hey, I'm Robert Cooper and I write articles related to web development. If you find these articles interesting, follow me on Twitter to get more bite-sized content related to web development.