Continuous Deployment(CD) using Bitbucket Pipelines and Ubuntu Linux Server

Source —

In this tutorial, you will learn how to set up Bitbucket Pipelines for a PHP & Node.js application and deploy them to your Ubuntu 18.04 server.

I’m writing this because I wasn’t able to get a step-by-step guide for how to do it from one source. I had to do some research and use different sources(some of which can be found at the bottom of the article) to achieve what I wanted. Hopefully this will be of help to someone.

Let’s get to it, shall we?

For starters, let’s define terms — I was just copying the first results off a google search to be honest so don’t be too harsh on me.

  1. Continuous Integration(CI) — is a development practice where developers integrate code into a shared repository frequently, preferably several times a day. Each integration can then be verified by an automated build and automated tests.
  2. Continuous Deployment(CD) — is a strategy for software releases wherein any code commit that passes the automated testing phase is automatically released into the production environment, making changes that are visible to the software’s users.

My primary target was deploying an application to my Ubuntu DigitalOcean server(get some credit when you sign up by clicking here — Full disclosure: I get something in return)with out having to SSH into it and run the deployment script.

Enable Pipelines in Bitbucket

Go to Your repository Settings -> Under the pipelines sectionclick on Settings -> Click on the Enable Pipelines Switch to enable pipelines.

Pipelines are now enabled.

Next up, we’ll set up SSH keys for our repository.

Set up repository SSH Keys

These are the keys you’ll set up on your production or staging server to enable external logins to your server from bitbucket during the deployment steps which we will discuss later on.

To set these up, got to SSH Keys(still within the Pipelines Section in your repository settings) -> then click on Generate keys. You could use your own keys but there are a couple of sources that have had issues and ended up advice against it. Generating your own keys is the best alternative.

After that, set up Known Hosts. Enter the IP address of your Ubuntu server as the Host address then click Fetch to generate the host’s fingerprint. After the fingerprint is generated, click on the Add Host button.

Next up, we’ll add the public key from our repository to the authorized_keys file of our Ubuntu server.

Adding public key from Bitbucket Repository to Ubuntu server authorized_keys

Login to your Ubuntu server. It’s important to note that SSH login should be enabled for your server. If you haven’t enabled it, kindly follow the steps outlined here.

# Enter .ssh folder
$ cd ~/.ssh
# Copy key to authorized_keys file
# Open file using your favourite editor e.g. nano
$ sudo nano authorized_keys
# Add the copied public key from bitbucket on a new line then save(there's a 'Copy public key' button on the SSH keys page)

Permanently add private key identity to the authentication agent

To prevent entering the passphrase to your private key while pulling your bitbucket repositories to your servers, you need to persist your identity using ssh-add. By default, the identity is lost every time you log out hence the need to persist it. This is important if your key has a passphrase set up. If not, you can ignore this part.

Open up your .bashrc using the following command.

$ sudo nano ~/.bashrc

Copy the following contents to the bottom of your .bashrc file.

# SSH Permanent passphrase
# start the ssh-agent
function start_agent {
echo “Initializing new SSH agent…”
# spawn ssh-agent
/usr/bin/ssh-agent | sed ‘s/^echo/#echo/’ > ${SSH_ENV}
echo succeeded
chmod 600 ${SSH_ENV}
. ${SSH_ENV} > /dev/null
if [ -f “${SSH_ENV}” ]; then
. ${SSH_ENV} > /dev/null
ps -ef | grep ${SSH_AGENT_PID} | grep ssh-agent$ > /dev/null || {

This keeps the ssh-agent running even when you log out of your server and persists your private key identity. To get it going however, you’ll need to log out and login into your server. One you login, the SSH Agent will be initialized and you’ll be requested to add the passphrase to your private key.

Set up a deployment script on your server
This is the script that we will run to deploy your application. It is basically a list of the commands you use to deploy your application on your server.

Run the following commands to set up an executable deployment script.

# Create script at the root
$ cd
$ touch
# make executable
$ chmod +x
# Executing script
$ ./

A sample PHP application deployment script:

cd $root
echo -e '\e[1m\e[34mPulling code from remote..\e[0m\n'
git pull origin master
echo -e '\e[1m\e[34m\nInstalling required packages..\e[0m\n'
# Install required packages
composer install
echo -e '\e[1m\e[34m\nAPI deployed\e[0m\n'

A sample Node.js application deployment script:

cd $root
echo -e '\e[1m\e[34mPulling code from remote..\e[0m\n'
git pull origin master
echo -e '\e[1m\e[34m\nChecking for new npm version and installing..\e[0m\n'
npm install -g npm
echo -e '\e[1m\e[34m\nInstalling required packages..\e[0m\n'
npm install
echo -e '\e[1m\e[34m\nRestarting service..\e[0m\n'
# Replace 1 with the ID of the service running your application
pm2 restart 1
echo -e '\n\e[1m\e[34mDeployment successful\e[0m'

Setting up this script is important as bitbucket will run it once it’s logged into your server.

Once you are done with that, we can now set up the bitbucket-pipelines.yml.

Setting up bitbucket-pipelines.yml

This is the file that defines your build, test and deployment configurations. It can be configured per branch i.e. what tests to run when some code is pushed to master and where it will be deployed. If you are using a staging server, you can set up the server details separate from the production server details.

Bitbucket has made it easy to set this up by providing templates based on the type of application you are running.

a. Go to the Pipelines menu item on your left to proceed.
b. Choose a language template. In this case, PHP or Node.js.
c. Set up YML file.
d. Click on Save. This will commit to your branch and create a new pipeline based on your YML file.

*Note: These are sample yml files. In your script section, you can run the commands necessary for your application.

Setting up bitbucket-pipelines.yml file for our PHP application

This script showcases how you can deploy changes based on different branches.

# This is a sample build configuration for PHP.
# Check our guides at for more examples.
# Only use spaces to indent your .yml configuration.
# —–
# You can specify a custom docker image from Docker Hub as your build environment.
image: php:7.1.29
# default – contains the steps that will run on every push.
# default:
# You can include your custom branches and the steps you’d like to undertake e.g. testing
– step:
– composer
– apt-get update && apt-get install -y unzip
– curl -sS | php — –install-dir=/usr/local/bin –filename=composer
– composer install
– step:
name: Deploy to production
deployment: production
– pipe: atlassian/ssh-run:0.2.2
SSH_USER: ‘your-server-username’
SERVER: ‘your-server-ip-address’

Setting up bitbucket-pipelines.yml file for your Node.js application

# This is a sample build configuration for JavaScript.
# Check our guides at for more examples.
# Only use spaces to indent your .yml configuration.
# —–
# You can specify a custom docker image from Docker Hub as your build environment.
image: node:10.15.3
– step:
– node
script: # Modify the commands below to build your repository.
– npm install
– npm test
– step:
name: Deploy to production
deployment: production
# trigger: manual # Uncomment to make this a manual deployment.
– echo “Deploying to production environment”
– pipe: atlassian/ssh-run:0.2.2
SSH_USER: ‘your-server-username’
SERVER: ‘your-server-ip-address’


By following this tutorial, you will be able to deploy your applications to your Ubuntu server.

Bitbucket allocates 50 free build minutes per account so keep that in mind as your write your YML files. The builds won’t run if you are past your allocated minutes. Keep the YML files short and sweet.

Thank you for reading ❤

If you find any errors, have any issues or questions don’t hesitate to reach out via the comment section.


Digital For Africa

Resources: Checklists

Let's chat
Hello 👋
Thank you for visiting the Digital 4 Africa website.

Don't hesitate to reach out if you need any help.

~ Caleb 😎