Zeit Now Continuous Deployment

This guide shows you how to use Semaphore to set up continuous integration and deployment to Zeit Now.

Demo project

Semaphore provides a demo project:

The demo consists of an API server that replies with a simple JSON payload. The project runs on Node.js. It uses Express for the web framework and Jest for testing.

Overview of the pipelines

The pipeline performs the following tasks:

  • Install dependencies.
  • Run unit tests.
  • Continuously deploy master branch to production site.

On manual approval:

  • Deploy to staging site.

The .semaphore directory in the repository contains annotated pipeline configuration files.

Pipelines for Zeit Now

Continuous integration pipeline

# Use the latest stable version of Semaphore 2.0 YML syntax:
version: v1.0

# Name your pipeline. In case you connect multiple pipelines with promotions,
# the name will help you differentiate between, for example, a CI build phase
# and delivery phases.
name: Build and test Express.js app

# An agent defines the environment in which your code runs.
# It is a combination of one of available machine types and operating
# system images.
# See https://docs.semaphoreci.com/article/20-machine-types
# and https://docs.semaphoreci.com/article/32-ubuntu-1804-image
    type: e1-standard-2
    os_image: ubuntu1804

# Blocks are the heart of a pipeline and are executed sequentially.
# Each block has a task that defines one or more jobs. Jobs define the
# commands to execute.
# See https://docs.semaphoreci.com/article/62-concepts
  - name: Install dependencies
        - name: npm install and cache
            # Get the latest version of our source code from GitHub:
            - checkout

            # Use the version of Node.js specified in .nvmrc.
            # Semaphore provides nvm preinstalled.
            - nvm use
            - node --version
            - npm --version

            # Restore dependencies from cache. This command will not fail in
            # case of a cache miss. In case of a cache hit, npm install will
            # run very fast.
            # For more info on caching, see https://docs.semaphoreci.com/article/149-caching
            - cache restore
            - npm install

            # Store the latest version of node modules in cache to reuse in
            # further blocks:
            - cache store

  - name: Run tests
        - name: npm test
            - checkout
            - nvm use
            - cache restore
            - npm test

  # Deployment to staging can be triggered manually:
  - name: Deploy to staging
    pipeline_file: deploy-staging.yml

  # Automatically deploy to production on successful builds on master branch:
  - name: Deploy to production
    pipeline_file: deploy-production.yml
      - result: passed
          - master

Just 2 blocks make the CI pipeline:

CI Pipeline

  • npm install and cache:
    • Downloads and installs the Node.js packages.
    • Builds the app and saves it to the cache.
  • npm test:
    • Runs unit and coverage tests.

Two promotions branch out of the CI pipeline:

  • Deploy to production: automatically started once all tests are green for the master branch.
  • Deploy to staging: can be manually initiated from a Semaphore workflow on any branch.

Continuous deployment pipeline

version: v1.0
name: Deploy to production
    type: e1-standard-2
    os_image: ubuntu1804
  - name: Deploy to production
        - name: now
      - name: Deploy to Zeit Now
          - checkout
          - nvm use
          - npm install now -g
          - now --token $ZEIT_TOKEN --local-config production.json

The deployment pipeline consists of one block:

CD Pipeline


Both nvm and npm are pre-installed on Semaphore's Ubuntu image. We can use the them to switch Node.js versions and install packages.


Zeit Now is a cloud service for serverless websites and web applications. Deployment is performed with the Now CLI and a config file:

  "version": 2,
  "name": "semaphore-demo",
  "builds": [
      { "src": "**/*.js", "use": "@now/node" }

Both staging and production pipelines are practically identical. They only differ on the app name, which maps to the final URL:

  • Production: semaphore-demo.USERNAME.now.sh
  • Staging: semaphore-demo-staging.USERNAME.now.sh

Run the demo yourself

You can get started right away with Semaphore. Running and deploying the demo by yourself takes only a few minutes:

Get a Zeit token

  1. Create a Zeit account.
  2. Open your account Settings
  3. Go to the Tokens tab.
  4. Click on the Create button.
  5. Enter a name for the token, something descriptive like: semaphore-zeit-now

Create Token

  1. Copy the generated token and keep it safe.

Create the pipeline on Semaphore

Now add the token to Semaphore:

  1. Create an account for Semaphore.
  2. On the left navigation bar, under Configuration click on Secrets.
  3. Hit the Create New Secret button.
  4. Create the secret as shown below. Copy the token obtained earlier.

Create Secret

To run the project on Semaphore:

  1. Fork the Demo project on GitHub.
  2. Clone the repository on your local machine.
  3. In Semaphore, follow the link on the sidebar to create a new project.
  4. Edit any file and do a push to GitHub, Semaphore starts automatically.

Once deployment is completed, the API service should be online. Browse the production URL:


See also

Still need help? Contact Us Contact Us