date: '2020-01-24T08:00:00Z'
short: How to automatically deploy your Next.js app to your server using git, Bitbucket pipelines and rsync
tags:
Next.js
Bitbucket
CI/CD
pm2
Assuming, that you:
are developing a Next.js application
host your Git repository on Bitbucket
want to run your Next.js app on a virtual private server, like DigitalOcean, Linode or any other machine you can ssh into
want your commits to be automatically published to your server
appreciate different environments for testing/staging/production based on git branches
Setting up Bitbucket Pipelines
Most of the steps required to setup Bitbucket Pipelines are documented well enough, so I'm just going to list the steps together with the relevant links here:
Exchange SSH keys:
In order to enable your pipeline to talk to your server via ssh, you will need to set up SSH keys. Please follow along this article to do so.
Create the Pipelines file
Bitbucket Pipelines allow you to run commands in a fresh docker image that already contains your code every time you push a commit to a certain branch. We'll use it to build our Next.js application and then push it to the server via rsync.
Create a file called bitbucket-pipelines.yml in the root of your git repository.
I use the following configuration:
# Using the node image provided by bitbucket
image: node:10.15.3
pipelines:
branches:
# run this on every commit to the branch "staging"
staging:
- step:
name: buildAndDeploy
# define which caches to use
caches:
- node # provided by bitbucket to cache node_modules
- nextcache # see definitions section below
script:
# install rsync
- apt-get update && apt-get -qq install rsync
# install node modules
- npm install
# build Next.js app
- npx next build
# create deploy directory (to contain .next folder, package.json, node_modules, public)
- mkdir deploy
- cp -a .next ./deploy
- cp package.json ./deploy
- cp -a node_modules ./deploy
- cp -a public ./deploy
# rsync to a temp directory on remote server
- rsync -arz --delete $BITBUCKET_CLONE_DIR/deploy/ $USER@$REMOTE_IP:/var/www/staging-temp
# clear current serving directory, sync from temp directory to serving directory, restart next server
- ssh $USER@$REMOTE_IP "rsync -ar --delete /var/www/staging-temp/ /var/www/staging && pm2 restart next-staging && rm -r /var/www/staging-temp"
definitions:
caches:
nextcache: .next/cache
A few things to note here:
By defining branches > staging we can specify that this script should only run on commits to branch staging
You likely want to do something similar for other branches like master, but deploy to a different server or folder depending on your server setup.
By creating a custom cache definition called nextcache we can cache the directory .next/cache between builds as recommended by Next.js.
In order to deploy only specific directories (.next, node_modules, ...) I copy them to a deploy directory first (another approach would be to use a include-list for rsync)
Target folder on the server is hardcoded here (/var/www/staging)
to minimize the time it takes for the files to land in the staging directory I am transferring them to a staging-temp folder first, then rsync'ing them locally to staging.
The pm2 part of the script assumes you already have your Next.js app running using pm2
This is a rather minimal setup, a more real world bitbucket-pipelines.yaml would probably include tests etc.
Add environment variables
If you don't want certain pieces of information about your target server in your repository (like the IP address or the user), I recommend using environment variables for the build process.
In the Bitbucket Repository page, go to Settings → Pipelines → Repository Variables. In my example I used these two variables:
Name: REMOTE_IP, Value: The IP address of your target server
Name: USER, Value: the username to use for ssh
These Repository Variables can be used in the bitbucket-pipelines.yaml file using $-notation, like $REMOTE_IP. There are also a bunch of default variables provided by Bitbucket.
Try it out!
If everything is setup correctly (especially ssh keys), your Next.js-app should be deployed to the target server after every commit to staging branch. Visit the Pipelines section of your repository on Bitbucket (<your-bitbucket-repo-url/addon/pipelines/home) to watch what's happening (or see what's going wrong ⚠️).
date: '2020-01-24T08:00:00Z' short: How to automatically deploy your Next.js app to your server using git, Bitbucket pipelines and rsync tags:
pm2
Assuming, that you:
Setting up Bitbucket Pipelines
Most of the steps required to setup Bitbucket Pipelines are documented well enough, so I'm just going to list the steps together with the relevant links here:
Getting Started: If you have never used Bitbucket Pipelines, I recommend reading the official guide for getting started with Bitbucket Pipelines first.
Exchange SSH keys: In order to enable your pipeline to talk to your server via ssh, you will need to set up SSH keys. Please follow along this article to do so.
Create the Pipelines file
Bitbucket Pipelines allow you to run commands in a fresh docker image that already contains your code every time you push a commit to a certain branch. We'll use it to build our Next.js application and then push it to the server via rsync.
Create a file called
bitbucket-pipelines.yml
in the root of your git repository.I use the following configuration:
A few things to note here:
staging
master
, but deploy to a different server or folder depending on your server setup.nextcache
we can cache the directory.next/cache
between builds as recommended by Next.js.deploy
directory first (another approach would be to use a include-list for rsync)/var/www/staging
)staging
directory I am transferring them to astaging-temp
folder first, then rsync'ing them locally tostaging
.bitbucket-pipelines.yaml
would probably include tests etc.Add environment variables
If you don't want certain pieces of information about your target server in your repository (like the IP address or the user), I recommend using environment variables for the build process.
In the Bitbucket Repository page, go to Settings → Pipelines → Repository Variables. In my example I used these two variables:
These Repository Variables can be used in the bitbucket-pipelines.yaml file using $-notation, like
$REMOTE_IP
. There are also a bunch of default variables provided by Bitbucket.Try it out!
If everything is setup correctly (especially ssh keys), your Next.js-app should be deployed to the target server after every commit to
staging
branch. Visit the Pipelines section of your repository on Bitbucket (<your-bitbucket-repo-url/addon/pipelines/home) to watch what's happening (or see what's going wrong ⚠️).Feedback
Let me know what you think of this approach: Send me a message on Twitter or an email