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).
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.
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.
You may encounter some blockers along the way like I did. Here are some tips to help you:
deploy.sh
file and read ® and write (w) access in the app’s directory for a successful git pull request.