How to build and deploy React.js with no downtime
In the following guide, we'll show you how to configure a pipeline that will build, test, and deploy a React.js application with zero-downtime. Zero-downtime is a deployment technique that lets you update websites by making them fully available to the end-user during the process.
Image loading...
Creating new project
📺 Video Timestamp: 03:10
Fire up Buddy and create a new project. Select your Git provider and choose the project with the React application:
Image loading...
Buddy will synchronize with your repository and fetch essential data, including branch structure and tech used. In this case you'll see it detected React:
Image loading...
Click the button to begin pipeline configuration.
Pipeline configuration
Here we set the trigger conditions and the branch from which we'll deploy. Since we're going full auto, set the trigger mode to On push
. The project we are using has only one branch (master), so leave it as it is:
Image loading...
Build configuration
Now, Buddy will ask you to add actions to the pipeline. Basing on the contents of the repository, it will suggest a couple of corresponding actions at the top. Select Node.js – we will use it as a template for our build:
Image loading...
Here you can configure build details, such as the version of Node used and commands that will be run in the container. You can leave the commands as they are – just add npm run build
at the end:
bashnpm install npm test npm run build
$$$
Image loading...
Testing build
Run the pipeline to see if everything works. In the first step, Buddy will fetch the latest changes from your repository and set up environment variables. In the second step, Buddy will download the required dependencies and cache them in the container – they will remain there for future executions so that you don't have to download them again. You can click the running execution and expand the logs in the actions for details:
Image loading...
Filesystem
Once the execution has finished, it will produce the build to the pipeline filesystem. The filesystem contains a clone of your repository in the last executed revision, artifacts generated by build actions, and static files uploaded manually (e.g. config files). You will notice that the artifacts are marked with a small gem icon:
Image loading...
Deployment configuration
The next step is adding an action that will upload our build to the server. In this case, we are deploying to a DigitalOcean droplet over SSH. We should use SFTP:
Image loading...
The action screen lets you configure deployment details: credentials to the server, the path from which Buddy will upload the files, and the target path on the server. You can choose from several authentication methods – we always recommend Buddy's workspace key as the most secure.
In our case the website will be deployed from the build
directory in the repository (source path) to /var/www/html/hello
on the server (remote path):
Image loading...
Testing deployment
Click the Test button to check if you configured everything properly. Buddy will connect to the server, upload a test file, and delete it afterward. When done, click the Run pipeline button or push something to the repository to trigger the pipeline and upload the website to the server:
Image loading...
Zero-downtime deployment
📺 Video Timestamp: 15:01
The pipeline is now fully operational: whenever a push is made, Buddy will fetch the changes, run unit tests, prepare the build, and upload it to the server. Now it's time to upgrade the process to ensure the application doesn't suffer any downtime during the deployment.
We'll apply a simple trick: upload the application to a newly created folder first, and, once the deployment has finished, switch the serving process to the new location.
Editing deployment folder
Click the deployment action to edit its details and change the folder to which you deploy (remote path) to $BUDDY_EXECUTION_REVISION/
. This will automatically create a new folder named after the currently deployed revision on every execution. If you are using our project on GitHub, the full path will look like this:
/var/www/html/$BUDDY_EXECUTION_REVISION
Image loading...
Buddy will detect the remote path has changed and will ask you to take action. Leave it as it is and click Proceed – we need to add some commands on the server first:
Image loading...
Adding server commands
Now, we'll add an action that will connect to our server and run commands that will switch the serving process to a new location after the deployment. Look up SSH in the action roster:
Image loading...
The action is defined in an exact way as the deployment: you need to provide the authentication method, server credentials, and the directory in which the commands will be executed (leave this one as default). Of course, we need proper commands, too. Fill the server details and paste the following to the command window:
default#kill current http-server process kill $(lsof -t -i:80) || true #run maintenance page http-server -p 80 /var/www/html/$BUDDY_EXECUTION_REVISION > http.log 2>&1 &
The action should look like this:
Image loading...
Testing zero-downtime deployment
Make a push to the repository to trigger the pipeline and check the execution logs if everything's passed properly:
Image loading...
Staging Environment configuration
Before deploying the website to the production server, it's a good practice to preview the changes – and perhaps run some end-to-end tests – on a staging server. In this part of the tutorial, we'll reconfigure the pipeline to serve the website from port 3000
and run the deploy to production – but only once the changes have been manually confirmed.
📺 Video Timestamp: 19:08
Creating Staging server
The first step is adding yet another SSH action that will create a new serving process on the server. Instead of configuring everything from scratch, you can use the Clone option on the action adding screen:
Image loading...
When cloning, leave the project and the pipeline as default, but instead of cloning all actions, select the SSH action only:
Image loading...
You should have two the same SSH actions in the pipeline. Click the first one to edit its details and change the port from 80
to 3000
:
default#kill current http-server process kill $(lsof -t -i:3000) || true #run maintenance page http-server -p 3000 /var/www/html/$BUDDY_EXECUTION_REVISION > http.log 2>&1 &
Image loading...
The complete pipeline should look like this, with the first SSH action set to port 3000
, and the second one to port 80
:
Image loading...
Run STAGING server
and Update PRODUCTION server
. You can do that in the Overview tab.
Adding manual confirmation
Deploying websites to production on every push without checking the changes is a risky business. Unless you have the process fully covered with tests and released through multiple environments, it is strongly recommended to either switch the pipeline's trigger mode to manual, or add a manual confirmation step before the deployment to production – the last one is what we're going to do now.
Click the +
button before the final release step and look up Wait for approval on the action list:
Image loading...
Here you can define the question and restrict approval permissions to a selected group of users:
Image loading...
Now, once you run the pipeline, it will automatically stop and will not proceed until the changes have been confirmed. But how will people know there's a website waiting for their approval?
We need to notify them.
Notifying users of deployment
Click the +
button once again – this time before the approval action. Jump to Notifications in the right column, and select your preferred service:
Image loading...
In this example, we're going to use Slack as it's the most popular notification service among our users.
Whenever you add an action that integrates with a third-party service for the first time, Buddy will ask you to configure the integration details. Here you can define the scope of the integration, i.e. who can modify its details and add pipeline actions that require it:
Image loading...
The last step is accepting the OAuth permissions of the chosen application:
Image loading...
With the integration configured, you can specify the message. A good idea is to paste the URL to the staged website so that your teammates can quickly access it:
Image loading...
Testing Staging-to-Production deployment
Make some changes to the website and run the pipeline. The execution should stop right before the release to production:
Image loading...
You should also receive a notification in the selected service:
Image loading...
Click the Approve button to proceed with the remaining action and release the website live.
Extra: Conditional notifications
📺 Video Timestamp: 28:39
The pipeline is now fully functional. It delivers the application with no downtime, uploads the website to a staging server, informs the team there's a new version waiting for review, and, once the changes have been approved, releases it to production.
But what if something goes wrong during the process? For example, what if the tests fail? Well, the first thing to do is to inform the right people. We already have a notification action about the new release targeted at capable developers. However, in this case, we need to inform the QA – yet only if the pipeline breaks.
Go to your pipeline's overview and click the button in the Actions run on failure section:
Image loading...
Add another notification of your choice. Edit the message and select the proper channel/recipient:
Image loading...
BUDDY_FAILED_ACTION_LOGS
environment variable to attach the logs from the failed action.
Testing conditional notifications
Time for the fun part – go ahead and mess up something with your website. For instance, let's break an assert in /src/App.test.js
:
Image loading...
Push the changes to trigger the pipeline. The execution will fail on the step with the tests. No further actions will be performed – except the notification at the very end:
Image loading...
If you added BUDDY_FAILED_ACTION_LOGS
variable to the notification, Buddy will attach the logs to help your team streamline debugging:
Image loading...
Extra: Debugging in terminal
📺 Video Timestamp: 30:52
Buddy has a cool feature that lets you debug errors directly from the terminal. To access it, go to the desired execution and click Debug action in terminal
on the failed action:
Image loading...
Buddy will fire the container back up allowing you to run commands and debug the problem in interactive mode:
Image loading...
Summary
The practices presented in this guide cover the basics of Continuous Integration and Deployment with Buddy. Applying deployment automation alone is a game-changer on its own in terms of frequency at which the software is released, providing a massive boost to efficiency and work comfort. The flexible nature of pipelines and visualized interface allows you to add and remove actions on-the-fly without referring to documentation, while Docker containers ensure one consistent environment across the whole team.
All in all, Buddy is more like a playground in which you can create automation workflows just like you build a house of bricks: pick an element that you need, adjust where necessary, and see how it fits in. Do not be deceived by the looks, though, as Buddy is as much powerful as any other CI/CD tool that you might've used so far – it just lowers the entry threshold to the obscure arcana of DevOps magic.
Jarek Dylewski
Customer Support
A journalist and an SEO specialist trying to find himself in the unforgiving world of coders. Gamer, a non-fiction literature fan and obsessive carnivore. Jarek uses his talents to convert the programming lingo into a cohesive and approachable narration.