How To Set Up Bitbucket Pipelines for PHP & Node.js

Introduction:

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: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.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) without having to SSH into it and run the deployment script.

Enable Pipelines in Bitbucket

Go to Your repository Settings -> Under the section of the pipeline, click 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 adviseagainst 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.[pastacode lang="bash" manual="%23%20Enter%20.ssh%20folder%0A%24%20cd%20~%2F.ssh%0A%23%20Copy%20key%20to%20authorized_keys%20file%0A%23%20Open%20file%20using%20your%20favourite%20editor%20e.g.%20nano%0A%24%20sudo%20nano%20authorized_keys%0A%23%20Add%20the%20copied%20public%20key%20from%20bitbucket%20on%20a%20new%20line%20then%20save(there's%20a%20'Copy%20public%20key'%20button%20on%20the%20SSH%20keys%20page)%0A" message="" highlight="" provider="manual"/]

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.[pastacode lang="bash" manual="%24%20sudo%20nano%20~%2F.bashrc%0A" message="" highlight="" provider="manual"/]Copy the following contents to the bottom of your .bashrc file.[pastacode lang="bash" manual="%23%20SSH%20Permanent%20passphrase%0ASSH_ENV%3D%24HOME%2F.ssh%2Fenvironment%0A%23%20start%20the%20ssh-agent%0Afunction%20start_agent%20%7B%0A%20%20%20echo%20%22Initializing%20new%20SSH%20agent...%22%0A%20%20%20%23%20spawn%20ssh-agent%0A%20%20%20%2Fusr%2Fbin%2Fssh-agent%20%7C%20sed%20's%2F%5Eecho%2F%23echo%2F'%20%3E%20%24%7BSSH_ENV%7D%0A%20echo%20succeeded%0A%20%20%20chmod%20600%20%24%7BSSH_ENV%7D%0A%20%20%20.%20%24%7BSSH_ENV%7D%20%3E%20%2Fdev%2Fnull%0A%20%20%20%2Fusr%2Fbin%2Fssh-add%0A%7D%0Aif%20%5B%20-f%20%22%24%7BSSH_ENV%7D%22%20%5D%3B%20then%0A%20%20%20%20.%20%24%7BSSH_ENV%7D%20%3E%20%2Fdev%2Fnull%0A%20%20ps%20-ef%20%7C%20grep%20%24%7BSSH_AGENT_PID%7D%20%7C%20grep%20ssh-agent%24%20%3E%20%2Fdev%2Fnull%20%7C%7C%20%7B%0A%20%20%20%20%20%20%20start_agent%3B%0A%20%20%20%7D%0Aelse%0A%20%20%20start_agent%3B%0Afi%0A" message="" highlight="" provider="manual"/]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 log in to your server. Once you log in, 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 serverThis 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.[pastacode lang="bash" manual="%23%20Create%20script%20at%20the%20root%0A%24%20cd%0A%24%20touch%20deployApi.sh%0A%23%20make%20executable%0A%24%20chmod%20%2Bx%20deployApi.sh%0A%23%20Executing%20script%0A%24%20.%2FdeployApi.sh%0A" message="" highlight="" provider="manual"/]A sample PHP application deployment script:[pastacode lang="bash" manual="%23!%2Fbin%2Fbash%0Aroot%3D%22%2Fvar%2Fwww%2Fexample.com%2Fpublic_html%22%0Acd%20%24root%0Aecho%20-e%20'%5Ce%5B1m%5Ce%5B34mPulling%20code%20from%20remote..%5Ce%5B0m%5Cn'%0Agit%20pull%20origin%20master%0Aecho%20-e%20'%5Ce%5B1m%5Ce%5B34m%5CnInstalling%20required%20packages..%5Ce%5B0m%5Cn'%0A%23%20Install%20required%20packages%0Acomposer%20install%0Aecho%20-e%20'%5Ce%5B1m%5Ce%5B34m%5CnAPI%20deployed%5Ce%5B0m%5Cn'%0A" message="" highlight="" provider="manual"/]A sample Node.js application deployment script:[pastacode lang="bash" manual="%23!%2Fbin%2Fbash%0Aroot%3D%22%2Fvar%2Fwww%2Fexample.com%2Fhtml%22%0Acd%20%24root%0Aecho%20-e%20'%5Ce%5B1m%5Ce%5B34mPulling%20code%20from%20remote..%5Ce%5B0m%5Cn'%0Agit%20pull%20origin%20master%0Aecho%20-e%20'%5Ce%5B1m%5Ce%5B34m%5CnChecking%20for%20new%20npm%20version%20and%20installing..%5Ce%5B0m%5Cn'%0Anpm%20install%20-g%20npm%0Aecho%20-e%20'%5Ce%5B1m%5Ce%5B34m%5CnInstalling%20required%20packages..%5Ce%5B0m%5Cn'%0Anpm%20install%0Aecho%20-e%20'%5Ce%5B1m%5Ce%5B34m%5CnRestarting%20service..%5Ce%5B0m%5Cn'%0A%23%20Replace%201%20with%20the%20ID%20of%20the%20service%20running%20your%20application%0Apm2%20restart%201%0Aecho%20-e%20'%5Cn%5Ce%5B1m%5Ce%5B34mDeployment%20successful%5Ce%5B0m'%0A%0A" message="" highlight="" provider="manual"/]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.

  1. Go to the Pipelines menu item on your left to proceed.
  2. Choose a language template. In this case, PHP or Node.js.
  3. Set up a YML file.
  4. 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.[pastacode lang="bash" manual="%23%20This%20is%20a%20sample%20build%20configuration%20for%20PHP.%0A%23%20Check%20our%20guides%20at%20https%3A%2F%2Fconfluence.atlassian.com%2Fx%2Fe8YWN%20for%20more%20examples.%0A%23%20Only%20use%20spaces%20to%20indent%20your%20.yml%20configuration.%0A%23%20-----%0A%23%20You%20can%20specify%20a%20custom%20docker%20image%20from%20Docker%20Hub%20as%20your%20build%20environment.%0Aimage%3A%20php%3A7.1.29%0Apipelines%3A%0A%20%20%23%20default%20-%20contains%20the%20steps%20that%20will%20run%20on%20every%20push.%0A%20%20%23%20default%3A%0A%20%20branches%3A%0A%20%20%20%23%20You%20can%20include%20your%20custom%20branches%20and%20the%20steps%20you'd%20like%20to%20undertake%20e.g.%20testing%0A%20%20%20%23staging%3A%0A%20%20%20master%3A%0A%20%20%20%20-%20step%3A%0A%20%20%20%20%20%20%20%20caches%3A%0A%20%20%20%20%20%20%20%20%20%20-%20composer%0A%20%20%20%20%20%20%20%20script%3A%0A%20%20%20%20%20%20%20%20%20%20-%20apt-get%20update%20%26%26%20apt-get%20install%20-y%20unzip%0A%20%20%20%20%20%20%20%20%20%20-%20curl%20-sS%20https%3A%2F%2Fgetcomposer.org%2Finstaller%20%7C%20php%20--%20--install-dir%3D%2Fusr%2Flocal%2Fbin%20--filename%3Dcomposer%0A%20%20%20%20%20%20%20%20%20%20-%20composer%20install%0A%20%20%20%20-%20step%3A%0A%20%20%20%20%20%20%20name%3A%20Deploy%20to%20production%0A%20%20%20%20%20%20%20deployment%3A%20production%0A%20%20%20%20%20%20%20script%3A%0A%20%20%20%20%20%20%20%20%20-%20pipe%3A%20atlassian%2Fssh-run%3A0.2.2%0A%20%20%20%20%20%20%20%20%20%20%20variables%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20SSH_USER%3A%20'your-server-username'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20SERVER%3A%20'your-server-ip-address'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20COMMAND%3A%20'.%2Fyour-deployment-script.sh'" message="" highlight="" provider="manual"/]

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

[pastacode lang="bash" manual="%23%20This%20is%20a%20sample%20build%20configuration%20for%20JavaScript.%0A%23%20Check%20our%20guides%20at%20https%3A%2F%2Fconfluence.atlassian.com%2Fx%2F14UWN%20for%20more%20examples.%0A%23%20Only%20use%20spaces%20to%20indent%20your%20.yml%20configuration.%0A%23%20-----%0A%23%20You%20can%20specify%20a%20custom%20docker%20image%20from%20Docker%20Hub%20as%20your%20build%20environment.%0Aimage%3A%20node%3A10.15.3%0Apipelines%3A%0A%20%20default%3A%0A%20%20%20%20-%20step%3A%0A%20%20%20%20%20%20%20%20caches%3A%0A%20%20%20%20%20%20%20%20%20%20-%20node%0A%20%20%20%20%20%20%20%20script%3A%20%23%20Modify%20the%20commands%20below%20to%20build%20your%20repository.%0A%20%20%20%20%20%20%20%20%20%20-%20npm%20install%20%0A%20%20%20%20%20%20%20%20%20%20-%20npm%20test%0A%20%20%20%20-%20step%3A%0A%20%20%20%20%20%20%20%20name%3A%20Deploy%20to%20production%0A%20%20%20%20%20%20%20%20deployment%3A%20production%0A%20%20%20%20%20%20%20%20%23%20trigger%3A%20manual%20%20%23%20Uncomment%20to%20make%20this%20a%20manual%20deployment.%0A%20%20%20%20%20%20%20%20script%3A%0A%20%20%20%20%20%20%20%20%20%20-%20echo%20%22Deploying%20to%20production%20environment%22%0A%20%20%20%20%20%20%20%20%20%20-%20pipe%3A%20atlassian%2Fssh-run%3A0.2.2%0A%20%20%20%20%20%20%20%20%20%20%20%20variables%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20SSH_USER%3A%20'your-server-username'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20SERVER%3A%20'your-server-ip-address'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20COMMAND%3A%20'.%2Fyour-deployment-script.sh'" message="" highlight="" provider="manual"/]

Conclusion

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 you 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.

Sources:

READ: Setting Expectations For Software Engineering Teams

Related posts

The latest articles from Andela.

Visit our blog

How to Build a RAG-Powered LLM Chat App with ChromaDB and Python

Harness the power of retrieval augmented generation (RAG) and large language models (LLMs) to create a generative AI app. Andela community member Oladimeji Sowole explains how.

Navigating the future of work with generative AI and stellar UX design

In this Writer's Room blog, Carlos Tay discusses why ethical AI and user-centric design are essential in shaping a future where technology amplifies human potential.

Platform and Mobile App Engineering: How They Work Together

In this Writer's Room blog, Usman Siddiqui explores how these engineering disciplines must coexist and work in parallel to provide secure and reliable applications in an ever-evolving digital landscape.

We have a 96%+
talent match success rate.

The Andela Talent Operating Platform provides transparency to talent profiles and assessment before hiring. AI-driven algorithms match the right talent for the job.