Join us at JAMstack Conf San Francisco, October 16-18. Register today

Continuous Deployment

Continuous deployment works by connecting a Git repository to a Netlify site and keeping the two in sync.

It works for plain static sites, but it’s even more powerful when you’re using a static site generator or a frontend build tool like Grunt, Gulp, or Broccoli.

Netlify will run your build command and deploy the result whenever you push to your Git repo. The benefits of Netlify’s continuous deployment include:

  • No deploying without committing and pushing first
  • Easy collaboration through pull/merge requests
  • Fix a typo through your Git provider’s web UI from your mobile
  • Edit content without code by using a static site CMS, Netlify CMS

Branches & Deploys


  • Production branch: the Git branch that Netlify uses to build and deploy changes to your site’s main URL (e.g. and
  • Production deploy: a deploy from the production branch. If auto publishing is enabled, each new production deploy will update what is published at your site’s main URL.
  • Branch deploy: a deploy generated from a branch that is not your production branch. Branch deploys are published to a URL which includes the branch name as a prefix. For example, if a branch is called staging, it will deploy to If you use Netlify DNS, you can enable branch subdomains, so the staging branch example would deploy to
  • Deploy Preview: a deploy generated from a pull request or merge request, building the site as it would be if the proposed changes were merged. Deploy Previews are published to a URL which has the prefix deploy-preview followed by the identifier number of the pull request or merge request. For example, a Deploy Preview for pull/merge request #42 will deploy to

Branch deploy controls

Netlify lets you control which branches in your Git repository you want to deploy. By default, Netlify deploys the site’s production branch after every change.

To generate branch deploys for other branches in your repository, go to Settings > Build & deploy > Continuous Deployment > Deploy contexts, then click Edit settings. You can choose to deploy all branches (including future branches), or select individual branches you would like to deploy.


When selecting individual branches for deployment, type the name of each branch you want to deploy. You can also enter branch names you haven’t created yet.

Once you select some or all of your branches for branch deploys, Netlify will start watching those branches for new commits and pull/merge requests. As soon as you start pushing changes to those branches, you’ll see new deploys for those branches.

Deploy Preview controls

By default, Netlify automatically builds Deploy Previews for GitHub pull requests and GitLab merge requests when the base/target branch is your production branch. If you enable branch deploys for some or all of your other branches, we’ll also build Deploy Previews for pull/merge requests against those branches.

If your site’s repository is on GitHub and you have the Netlify App on GitHub installed, you can control in the UI whether or not Deploy Previews are generated for pull requests. To change this, go to Settings > Build & deploy > Continuous Deployment > Deploy contexts, then click Edit settings.

Deploy Summary

You can find a deploy summary on the detail page of any successful deploy, right above the deploy log. It allows you to quickly identify your deploy status and refer to the details in the log based on different types of information.

This summary indicates how many files have been uploaded to our CDN. It also indicates the status of site headers and redirects included in the deploy. It also indicates whether your site contains content served over insecure HTTP, known as mixed content.

When you have branch deploys enabled, the summary will inform you if the files to upload have already been uploaded by a previous deploy with the same commits. Netlify’s deployment infrastructure knows how to avoid uploading the same file twice, even between different deploys, so we get your changes ready without duplicating content. You can read more about how this works in this article about our deploying and routing infrastructure.

If the summary continually indicates that many more files were uploaded than you were expecting, your site may be taking longer to deploy than it needs to. Visit our Community forum topic about making the most of Netlify’s CDN cache to learn about why this might be happening and get advice about what you can do to reduce the number of files uploaded each time in order to speed up your deploys.

Status Badges

Status badges are visual representations of your site’s status, served as image files you can add to repository READMEs, documentation, or any other web page.

The deploy status badge automatically updates to show the status of a site’s most recent production deploy:

badges indicating deployment statuses: success, building, or failed

To find the specific image URL for your site, go to your site’s Settings > General > Status badges. For markdown files like repository READMEs, we include a one-click markdown snippet you can copy and paste directly, complete with a link to your site’s Deploys page when the badge is clicked.

Deploy Contexts

Deploy contexts are a way to tell Netlify how to build your site. They give you the flexibility to configure your site’s builds depending on the context they are going to be deployed to.

There are three predefined deploy contexts:

  • production: this context corresponds to the main site’s deployment, attached to the Git branch you set when the site is created.
  • deploy-preview: this context corresponds to the previews we build for pull/merge requests.
  • branch-deploy: this context corresponds to deploys from branches that are not the site’s main production branch.

Besides these three predefined contexts, sites can use also branch names as custom deploy contexts. For example, a branch called staging will match a deploy context called staging.

Currently, deploy contexts allow you to override four options from your site’s settings:

  • the base directory where your site is built from,
  • the build command,
  • the publish directory where the build puts the processed files,
  • and the environment variables added to the build.

All these options are overridden in a hierarchical order. The site’s global settings apply to each deploy, if we’re building the production site, and if you change options in your production context, they will be overridden. Only options that are set explicitly are overridden; if you leave one out, the build will use the value of the global settings or previous contexts. Environment variables are also overridden individually, for example, you can have access tokens as environment variables per context.

To configure deploy contexts, you must create a file called netlify.toml in the root of your Git repository. There, you can set as many contexts as you want to configure.

# Global settings applied to the whole site.  
# “base” is the directory to change to before starting build. If you set base:
#        that is where we will look for package.json/.nvmrc/etc, not repo root!
# “command” is your build command.
# “publish” is the directory to publish (relative to the root of your repo).

  base    = "site"
  command = "make"
  publish = "site/public"

# Production context: All deploys from the main
# repository branch will inherit these settings.
  command = "make production"
    ACCESS_TOKEN = "super secret"

# Deploy Preview context: All deploys generated from a pull/merge request
# will inherit these settings.
  ACCESS_TOKEN = "not so secret"

# Branch deploy context: All deploys that are not from a pull/merge request
# or from the production branch will inherit these settings.
  command = "make staging"

# Specific branch context: Deploys from this branch
# will take these settings and override their
# current ones.
  command = "make feature"

  command = "gulp"

These settings will override those set in the UI. In the netlify.toml file, settings for more specific contexts will override more general ones (e.g. settings for a specific branch will override those for branch-deploy).

We’ve also published this more thorough and complete netlify.toml example and description.

Skipping a Deploy

Sometimes, you may want to push commits to your production branch without triggering a deploy on Netlify. To do this, add [skip ci] anywhere in the Git commit message.

In the case of multiple commits pushed together, add [skip ci] to the most recent commit, and it will apply to all other commits in the push.

The next commit pushed without [skip ci] will trigger a new deploy, including all changes from the skipped commits as well. To trigger a deploy manually, go to your site’s Deploys page and click Trigger deploy at the top of the deploy list.

For another way to allow production branch changes without affecting your published site, you can visit our docs on locked deploys.

Canceling a Deploy

Sometimes, you may want to cancel a deploy after it has started. To do this, go to the detail page of the deploy in progress and select Cancel deploy. You’ll then be prompted to confirm the canceling action. Select Yes, cancel deploy to confirm.

If you later want to restart the deploy, go to the detail page for the deploy and select Retry deploy > Deploy site.

Environment Variables

Netlify environment variables are accessible during your build. This allows you to change behaviors based on deploy parameters or to include information you don’t want to save in your repository, such as API keys. You can create your own environment variables via the following channels:

  • In the netlify.toml file. Variable values set in the netlify.toml file will override values set in the UI.
  • In your site dashboard under Settings > Build & deploy > Environment > Environment variables. Variable values set under site settings will override the team-level settings.
  • In team settings, under Settings > Sites > Global site settings > Shared environment variables. Variables set at the team level are shared by all sites owned by the team. These can be overridden by settings at the site level. (This feature may not be available on all plans.)

In addition to the variables you choose to define, Netlify has a number of pre-defined variables built in. Note that the variables listed are automatically set for your builds, and their values are not changeable. These variables are:

  • REPOSITORY_URL: URL to the Git repository the build pulls changes from.
  • BRANCH: Reference to check out after fetching changes from the Git repository.
  • PULL_REQUEST: Whether the build is from a pull/merge request or not.
  • HEAD: Name of the head branch received from a Git provider.
  • COMMIT_REF: Reference of the commit we’re building.
  • CONTEXT: Name of the context a deploy is built around, it can be production, deploy-preview or branch-deploy.
  • REVIEW_ID: the ID of a Deploy Preview and the pull/merge request that generated it (e.g. 1211). These two numbers will always match (deploy-preview-12 is for PR # 12 in your repository).

If your build is triggered from one of your inbound webhooks, Netlify also has three webhook-specific variables:

  • INCOMING_HOOK_TITLE: Title of the incoming webhook.
  • INCOMING_HOOK_URL: URL of the incoming webhook.
  • INCOMING_HOOK_BODY: Body of the request sent to the incoming webhook URL.

Each build environment includes three URLs that you can use at your convenience. This section describes each one of them:

  • URL: This URL represents the main address to your site. It can be either a Netlify subdomain or your own custom domain if you set one; for example, or
  • DEPLOY_URL: This URL represents the unique URL for an individual deploy. It starts with a unique ID that identifies the deploy; for example,
  • DEPLOY_PRIME_URL: This URL represents the primary URL for an individual deploy, or a group of them, like branch deploys and Deploy Previews; for example, or

Set Node, Ruby, or Python version


Our default for new sites is pinned to the version that is preinstalled in your site’s initial build image, but you can choose the Node.js version we use to build your site in two different ways:

  • Add a /.nvmrc to your repository. This will also tell any other developer using the repository which version of Node.js it depends on. You can either set a specific version or just have a major version in the file, like the number 10 for the latest version of node 10.x
  • Set a NODE_VERSION environment variable. You can set this either while linking the repository or afterwards via the UI or netlify.toml file. The value can be anything you would use with nvm.


You can choose the Ruby version we use to build your site. The default version depends on your site’s selected build image, but you can specify a different version by adding a /.ruby-version file to your repository. We support any released version of Ruby that rvm understands. Choosing one of the Ruby versions preinstalled in your site’s selected build image will speed up build times.


The default Python version is determined by your site’s selected build image. You can select a different version from the list of versions preinstalled on your site’s build image with a runtime.txt containing the version number that you prefer.


Netlify will install any dependencies from any Gemfile, package.json, bower.json or requirements.txt in the root of your repository (or in the base directory if one has been set), before running your build. Any executables from these dependencies will be made available from the PATH.

Make sure to include your build tool in these dependencies:

  • If you’re using Jekyll, make sure to add a Gemfile that requires the Jekyll gem
  • If you’re using Grunt, make sure to add a package.json with grunt-cli as a dependency
  • If you’re using mkdocs, make sure to add a requirements.txt with mkdocs>=0.9.0

Dependency Cache

The first build you do can take some time while we install all of your dependencies. After the initial build, we’ll cache the dependencies so we don’t have to install them each time you push an update. This is intended to make subsequent builds really fast.

Build Settings

You can specify how Netlify will build your site by going to Settings > Build & deploy > Continuous Deployment > Build settings.

From here, you can link an existing site to a Git repository or change the currently linked repository, set a base directory, add a build command, and specify a publish directory. For public repos, you can also toggle your deploy log visibility.

build settings user interface


  • Base directory: Optional field that specifies the directory to change to before starting a build. This is where we will look for package.json/.nvmrc/etc. A common use for this field is linking a site to a monorepo (a repository that contains multiple sites or apps, each in its own subdirectory).
  • Build command: If you are using a static site generator or other build tool, this is where you should specify the command to run to build your site. Check out common configuration directives below for examples using common build tools.
  • Publish directory: Directory (relative to the root of your repo) that contains the deploy-ready HTML files and assets generated by the build. If a base directory has been specified, it should be included in the publish directory path. For example, if your base directory is set to site, the publish directory should include the site/ prefix like so: site/public. Check out common configuration directives below for examples using common build tools.

Common configuration directives

Common build tools

Here are some examples of configuring your site for common build tools:

Build Tool Publish Directory Command
Jekyll _site jekyll build
Grunt dist grunt build
Middleman build middleman build
Hexo public hexo generate
Hugo public hugo
Gatsby public gatsby build
VuePress docs/.vuepress/dist vuepress build docs
Build Tool
jekyll build
hexo generate
grunt build
middleman build
gatsby build
vuepress build docs

For Jekyll hosting, make sure you have a Gemfile and a Gemfile.lock checked into your repository, specifying the Jekyll version you want to use.

For Hugo hosting, the build command hugo will build and deploy with the version that is preinstalled in your site’s initial build image. For versions 0.13, 0.14, 0.15, 0.16, 0.17, 0.18, and 0.19, you can specify a specific Hugo release like this: hugo_0.15. For version 0.20 and above, use the regular hugo command and create an environment variable called HUGO_VERSION and set it to the version of your choice. (More details can be found on our blog.)

Single page apps

If you’re developing a single page app, and want to use history pushstate to get clean URLs, you’ll need to add a rewrite rule to serve the index.html no matter what URL the browser requests.

Notice something is incorrect or outdated?

First off, great catch! We appreciate your discovery and want to ensure it gets addressed immediately. Please let us know here.

Want to have a conversation?

Visit the Netlify Community to discuss ideas and questions with your fellow Netlify users.

Want to get started quick?