Trusted answers to developer questions

How to do continuous deployment using bitbucket and Linux server

Free System Design Interview Course

Many candidates are rejected or down-leveled due to poor performance in their System Design Interview. Stand out in System Design Interviews and get hired in 2024 with this popular free course.

Ever seen the acronym CI/CD before? It stands for Continuous Integration and Continuous Deployment.

What does that even mean? I’ll explain with a scenario.

Say you’re a software developer who writes code for an application. Typically, after you make an update, you’ll test your changes to see that nothing is broken. Afterward, your new build (or code changes) will be handed over to the server admin who will then deploy the application to a live server where users can access it.

Here’s the challenge: If you make changes often (which is common in Agile development), you will have to repeat that process several times. This can be tiring and, in a bid to bypass that loop, you may decide to release new changes at the end of the week or at a later time. This then defeats the aim of DevOps of having small, iterative changes accessible to the application users.

Don’t hinder the process, embrace a continuous workflow!

CI/CD simply automates that process. You write the codes and commit to version control (git). Each time you push your codes to a service, like GitHub or Bitbucket, automation kicks in. Your codes are then tested using a predefined metric (testing) system and, if the minimum testing threshold is reached (CI), the changes are deployed to the live server (CD).

Continuous Deployment - Bitbucket & Linux Server

Note: This hands-on section is to set up a continuous deployment (CD) workflow excluding any form of testing (CI). A fair understanding of Git, Bitbucket, Linux & the CLI (goes without saying, right?) is required to maximize this section.

  1. Enable Pipelines in your Bitbucket repository and configure it using the bitbucket-pipelines.yml file.
  2. Add the server (remote) deploy key to the repository.
  3. Set up the SSH key pair on the repository.
  4. Add the repository’s public key to the server’s authorized keys.
  5. Clone the repository onto the server.

Details

Enable Pipelines in your Bitbucket repository and configure it using the bitbucket-pipelines.yml file.

In the repository settings, enable Pipelines. This will provide you with a file named bitbucket-pipelines.yml. Here is a sample file:

pipelines:
  default:
     - step:
         name: Deploy to production
         deployment: production
         script:
           - echo "Deploying to production environment"
           - pipe: atlassian/ssh-run:0.2.2
             variables:
               SSH_USER: 'root'
               SERVER: '<ip-address>'
               COMMAND: '/home/deploy.sh'

The file above provides the repository with the information it needs to deploy the application upon any new code push. It logs into the server using SSH with the mentioned user (in my case – root) and host (IP address supplied). Once the connection is successful, it runs the deploy.sh script. Here is a sample deploy script:

echo -e $PWD

echo -e '\e[1m\e[34mEntering into frontend directory...\e[0m\n'

cd /home/my-application

echo -e $PWD

echo -e '\e[1m\e[34mPulling code from remote...\e[0m\n'

git pull origin master

echo -e '\e[1m\e[34mAll done now!\e[0m\n'

echo -e '\e[1m\e[34mThanks to Ileriayo for automating this deployment process!\e[0m\n'

In the deploy script, we change the directory to the app’s directory on the server and pull the recent code changes. The echo commands are for logging purposes that you’ll see in Bitbucket Pipelines. Of course, your deployment script can be more complex than this, I’d just like to keep things simple for the sake of this article.

Add server (remote) deploy key to the repository.

Under the Access Keys tab of the repo’s settings (Settings > Access Keys), add the public key of the server (in my case, it’s that of the server’s root user), and give it a descriptive name.

Setup SSH key pair on the repository.

Now, we need to create SSH keys for the repository. This will be used for a secure connection between the repo and the server (remote). To do so, go to the repo’s settings and then the SSH Keys. Afterwards, add the host address and click fetch to see the host’s fingerprint (and add the remote to known hosts).

Add the repository’s public key to the server’s authorized keys.

Copy the public key from the repository and paste it in the server’s authorized_keys file. In my case, it’s found here: /root/.ssh/authorized_keys.

Clone the repository onto the server.

If you have not already cloned the repo onto the server, do that now. Ensure that the app directory in your deploy.sh script matches with wherever you clone the app to.

Going forward, whenever you push a change to the repository, Bitbucket will run the pipeline and deploy the codes onto the server.

Debugging

You may encounter some blockers along the way like I did. Here are some tips to help you:

  • User Permissions: Observe that I used the root user, which is a superuser. For security concerns, you may have chosen to use another user other than the root user.
  • Directory/file Permissions: Check to see that the SSH user has the appropriate permissions in the file/directory of concern. For instance, the SSH user should have permission to execute (x) the deploy.sh file and read ® and write (w) access in the app’s directory for a successful git pull request.
  • Commands: If your SSH user requires you to prepend sudo for certain commands in your deploy script, you may then be required to enter passwords at some point in the pipeline. You do not want this to happen. Always, strive to run pipeline commands in a non-interactive mode (that’s one of the reasons I used the root user).

RELATED TAGS

bitbucket
Did you find this helpful?