Why Do We Need a CI/CD Pipeline?
A CI/CD (Continuous Integration/Continuous Deployment) pipeline automates the entire process of building, testing, and deploying code changes. By setting up this pipeline for DoodleDeck's backend, we can:
- Automate deployments: Every time there’s a change in the codebase, the pipeline can automatically deploy the changes to production, ensuring no manual intervention is required.
- Increase consistency: CI/CD helps ensure that the process remains consistent across various environments, reducing human error during deployment.
- Speed up delivery: With automated testing and deployment, changes can be pushed to production faster.
For example, every time there is a change in the codebase, we don't want to manually SSH into the server, run git pull origin main
, and restart the server. With a CI/CD pipeline, this process will be automated, ensuring that the code is always up-to-date and that the server restarts automatically after deployment.
Setting Up GitHub Actions for CI/CD
To automate our deployment process, we'll use GitHub Actions, a powerful and flexible CI/CD tool that integrates seamlessly with GitHub repositories. The following GitHub Actions workflow will deploy changes to our EC2 instance whenever there’s a push to the main
branch.
Here’s how you can set up the pipeline:
name: Deploy to EC2
on:
push:
branches:
- main # Trigger the pipeline when there is a push to the 'main' branch
jobs:
deploy:
name: Deploy to EC2
runs-on: ubuntu-latest # Use the latest Ubuntu image for the runner
steps:
- name: Checkout the repository code
uses: actions/checkout@v4 # Checkout the code from GitHub repository
- name: Run remote SSH commands
uses: appleboy/ssh-action@v1.2.0 # Use SSH action to run commands on the EC2 instance
with:
host: ${{ secrets.HOST }} # EC2 instance host address
username: ${{ secrets.USERNAME }} # Username for SSH login
key: ${{ secrets.PRIVATE_SSH_KEY }} # Private SSH key for authentication
port: ${{ secrets.PORT }} # The port to connect to on the EC2 instance (default is 22)
script: ./deploy.sh # Path to the deploy script that will be run on the EC2 instance
Explanation of the Workflow
- on.push.branches: This specifies that the workflow will trigger whenever there’s a push to the main branch.
- jobs.deploy: This job defines all the steps that need to be executed during the deployment.
- actions/checkout@v4: This action checks out the code from the repository so that it can be used by the pipeline.
- appleboy/ssh-action@v1.2.0: This action allows the GitHub Actions runner to SSH into the EC2 instance and execute commands remotely.
Adding Secrets to Your Repository
For the SSH authentication to work, you’ll need to set up secrets in your GitHub repository. Follow these steps:
- Generate SSH key pair: • On your local machine, generate a new SSH key pair using the following command:
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
Save the key pair and make sure to copy the contents of the public key (id_rsa.pub).
- Add public key to EC2 instance: • SSH into your EC2 instance and add the contents of the public key (id_rsa.pub) to the ~/.ssh/authorized_keys file:
echo "your-public-key-content" >> ~/.ssh/authorized_keys
- Add private key as GitHub Secrets: • In your GitHub repository, go to Settings -> Secrets -> New repository secret and add the following secrets: • HOST: The public IP or hostname of your EC2 instance. • USERNAME: The username you use to SSH into the EC2 instance (commonly ec2-user, ubuntu, etc.). • PRIVATE_SSH_KEY: The contents of your private SSH key (id_rsa). • PORT: The SSH port (usually 22 unless you’ve configured a custom port).
For more information on using the appleboy/ssh-action action, refer to the appleboy/ssh-action documentation.
Writing the deploy.sh script
The deploy.sh script is responsible for pulling the latest changes from the repository and restarting the application. Below is an example of the script:
# Change to the project directory
cd /path/to/DoodleDeck
# Pull the latest changes from the main branch
git pull origin main
# Check if npm is installed and install dependencies
echo "Checking npm..."
which npm
npm -v # Ensure npm is installed
npm install # Install dependencies if necessary
Script Breakdown:
- cd /path/to/DoodleDeck: This navigates to your project directory.
- git pull origin main: Pulls the latest changes from the main branch.
- npm install: Ensures all dependencies are installed.
By using this script, the backend application will automatically be updated and restarted whenever a change is pushed to the main branch.
With this CI/CD pipeline, every change pushed to the main branch will be automatically deployed to your EC2 instance, saving you time and reducing the chance of errors. This setup ensures that your deployment process is streamlined and consistent.
Next blog -> Setting up pm2 for Auto-Restart on Reboot and File Changes