{"id":19997,"date":"2026-04-26T12:24:28","date_gmt":"2026-04-26T06:39:28","guid":{"rendered":"https:\/\/www.bisup.com\/blog\/?p=19997"},"modified":"2026-04-26T12:24:29","modified_gmt":"2026-04-26T06:39:29","slug":"how-to-set-up-cicd-pipeline","status":"publish","type":"post","link":"https:\/\/www.bisup.com\/blog\/how-to-set-up-cicd-pipeline\/","title":{"rendered":"How to Set Up a CI\/CD Pipeline: Step-by-Step 2025 Guide"},"content":{"rendered":"\n<p>Let&#8217;s set up your first CI\/CD pipeline from scratch. Learn GitHub Actions, automated testing, and deployment to a cloud VPS server.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What is a CI\/CD Pipeline?<\/h2>\n\n\n\n<p>Every time a change is made, your code is automatically built, tested, and deployed using a CI\/CD pipeline.<\/p>\n\n\n\n<p>When developers make changes, Continuous Integration (CI) automatically builds and tests the code.<br>Code is automatically prepared or released to production with Continuous Delivery\/Deployment (CD).<\/p>\n\n\n\n<p>To put it simply:<br>Code may be moved from development to production more quickly, safely, and without the need for human labour, thanks to CI\/CD.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">CI vs CD vs CD \u2014 What\u2019s the Difference?<\/h2>\n\n\n\n<p>This is confusing to a lot of people, so let&#8217;s make it simple:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>CI, or continuous integration:<br>Code is often merged by developers, resulting in automatic build and test runs.<\/li>\n\n\n\n<li>Continuous Delivery (CD):<br>Code is always prepared for deployment, but it needs to be approved manually.<\/li>\n\n\n\n<li>CD, or continuous deployment:<br>Without human intervention, code is automatically delivered to production.<\/li>\n<\/ul>\n\n\n\n<p>A brief synopsis<\/p>\n\n\n\n<p>CI stands for Build &amp; Test.<br>CD (Deployment) = Auto Deploy <br>CD (Delivery) = Ready to Deploy<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"683\" src=\"https:\/\/www.bisup.com\/blog\/wp-content\/uploads\/2026\/04\/ChatGPT-Image-Apr-24-2026-09_20_54-PM-1024x683.webp\" alt=\"CI\/CD Pipeline Flow Diagram \u2014 Dev \u2192 Build \u2192 Test \u2192 Deploy\" class=\"wp-image-20000\" srcset=\"https:\/\/www.bisup.com\/blog\/wp-content\/uploads\/2026\/04\/ChatGPT-Image-Apr-24-2026-09_20_54-PM-1024x683.webp 1024w, https:\/\/www.bisup.com\/blog\/wp-content\/uploads\/2026\/04\/ChatGPT-Image-Apr-24-2026-09_20_54-PM-300x200.webp 300w, https:\/\/www.bisup.com\/blog\/wp-content\/uploads\/2026\/04\/ChatGPT-Image-Apr-24-2026-09_20_54-PM-768x512.webp 768w, https:\/\/www.bisup.com\/blog\/wp-content\/uploads\/2026\/04\/ChatGPT-Image-Apr-24-2026-09_20_54-PM-400x267.webp 400w, https:\/\/www.bisup.com\/blog\/wp-content\/uploads\/2026\/04\/ChatGPT-Image-Apr-24-2026-09_20_54-PM-800x533.webp 800w, https:\/\/www.bisup.com\/blog\/wp-content\/uploads\/2026\/04\/ChatGPT-Image-Apr-24-2026-09_20_54-PM-832x555.webp 832w, https:\/\/www.bisup.com\/blog\/wp-content\/uploads\/2026\/04\/ChatGPT-Image-Apr-24-2026-09_20_54-PM-1248x832.webp 1248w, https:\/\/www.bisup.com\/blog\/wp-content\/uploads\/2026\/04\/ChatGPT-Image-Apr-24-2026-09_20_54-PM.webp 1536w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Prerequisites Before You Start<\/h2>\n\n\n\n<p>Before setting up a CI\/CD pipeline, make sure you have:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Basic <a href=\"https:\/\/git-scm.com\/\" data-type=\"link\" data-id=\"https:\/\/git-scm.com\/\">Git<\/a> knowledge (clone, commit, push)<\/li>\n\n\n\n<li>Comfortable with Linux server commands<\/li>\n\n\n\n<li>Access to a cloud server (VPS \/ EC2 \/ Hetzner)<\/li>\n\n\n\n<li>A Git repository (<a href=\"http:\/\/github.com\" data-type=\"link\" data-id=\"github.com\">GitHub<\/a>\/<a href=\"http:\/\/gitlab.com\" data-type=\"link\" data-id=\"gitlab.com\">GitLab<\/a>)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Step 1 \u2014 Choose Your CI\/CD Tool<\/h3>\n\n\n\n<p>There are many CI\/CD tools available. Here\u2019s a practical comparison:<\/p>\n\n\n\n<p>Commonly Used Tools<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Actions on <a href=\"http:\/\/github.com\">GitHub<\/a><\/li>\n\n\n\n<li><a href=\"http:\/\/gitlab.com\">GitLab<\/a> CI\/CD<\/li>\n\n\n\n<li><a href=\"https:\/\/www.jenkins.io\/\" data-type=\"link\" data-id=\"https:\/\/www.jenkins.io\/\">Jenkins<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/circleci.com\/\">CircleCI<\/a><\/li>\n<\/ul>\n\n\n\n<p><strong>Recommendation Matrix<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Team Size<\/th><th>Recommended Tool<\/th><\/tr><\/thead><tbody><tr><td>Solo \/ Beginner<\/td><td>GitHub Actions<\/td><\/tr><tr><td>Small Team<\/td><td>GitLab CI<\/td><\/tr><tr><td>Large Enterprise<\/td><td>Jenkins<\/td><\/tr><tr><td>SaaS Teams<\/td><td>CircleCI<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>GitHub Actions is the best option for 2025.<\/p>\n\n\n\n<p>Since it&#8217;s<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Free for brief use<\/li>\n\n\n\n<li>GitHub integration<\/li>\n\n\n\n<li>Simple to set up<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Step 2: Establish Your Branching and Repository Strategy<\/strong><\/h3>\n\n\n\n<p>An effective branching strategy keeps deployment pandemonium at bay.<\/p>\n\n\n\n<p><strong>Suggested Organization<\/strong>: Main \u2192 Production dev \u2192 Development feature\u2192New features<\/p>\n\n\n\n<p><strong>Workflow<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>A feature branch is created by the developer<\/li>\n\n\n\n<li>Code is pushed \u2190 Pull Request<\/li>\n\n\n\n<li>Deployment is triggered by merging into the main CI\/CD pipeline after testing.<\/li>\n<\/ul>\n\n\n\n<p>We refer to this as a streamlined Git Flow.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 3: Create Your Initial Pipeline File (GitHub Actions)<\/h3>\n\n\n\n<p>The crucial step is now to build your pipeline.<\/p>\n\n\n\n<p>Create this file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.github\/workflows\/deploy.yml<\/code><\/pre>\n\n\n\n<p>Example CI\/CD Pipeline (Node.js App)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>name: CI\/CD Pipeline\n\non:\n  push:\n    branches:\n      - main\n\njobs:\n  build-test-deploy:\n    runs-on: ubuntu-latest\n\n    steps:\n    - name: Checkout code\n      uses: actions\/checkout@v3\n\n    - name: Setup Node.js\n      uses: actions\/setup-node@v3\n      with:\n        node-version: '18'\n\n    - name: Install dependencies\n      run: npm install\n\n    - name: Run tests\n      run: npm test\n\n    - name: Deploy to VPS via SSH\n      uses: appleboy\/ssh-action@v0.1.6\n      with:\n        host: ${{ secrets.SERVER_IP }}\n        username: root\n        key: ${{ secrets.SSH_PRIVATE_KEY }}\n        script: |\n          cd \/var\/www\/app\n          git pull origin main\n          npm install\n          pm2 restart app<\/code><\/pre>\n\n\n\n<p>The Functions of This Pipeline<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>pulls code from GitHub<\/li>\n\n\n\n<li>Dependencies are installed<\/li>\n\n\n\n<li>conducts tests<\/li>\n\n\n\n<li>uses SSH to deploy to your server<\/li>\n<\/ul>\n\n\n\n<p>This pipeline consists of Build \u2192 Test \u2192 Deploy.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 4 \u2014 Add Automated Tests<\/h3>\n\n\n\n<p>CI\/CD is dependable because of testing.<\/p>\n\n\n\n<p><strong>Examples of Tools<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>PHP: PHPUnit <\/li>\n\n\n\n<li>Node.js: Jest<\/li>\n\n\n\n<li>Java: JUnit <\/li>\n<\/ul>\n\n\n\n<p><strong>The Significance of Tests<\/strong><\/p>\n\n\n\n<p>Without assessments:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Production is affected by bugs.<\/li>\n\n\n\n<li>Deployments become dangerous<\/li>\n<\/ul>\n\n\n\n<p><strong>Fail-Fast Approach<\/strong><\/p>\n\n\n\n<p>If testing are unsuccessful, the pipeline stops right away.<\/p>\n\n\n\n<p>Broken deployments are avoided as a result.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 5: Deploy on Your Server<\/h3>\n\n\n\n<p>Let&#8217;s now link your pipeline to your VPS.<\/p>\n\n\n\n<p><strong>Option 1: SSH Deployment (Easy &amp; Popular)<\/strong><\/p>\n\n\n\n<p>Steps<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Generate SSH key:<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>ssh-keygen -t rsa<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Add public key to your server:<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>~\/.ssh\/authorized_keys<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Add secrets in GitHub:<br><code>- SERVER_IP<\/code><br>&#8211; <code>SSH_PRIVATE_KEY<\/code><\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Use SSH action (already shown above)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Option 2: Advanced Docker Deployment<\/h3>\n\n\n\n<p>Rather than directly installing code:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Construct a Docker image<\/li>\n\n\n\n<li>Push to the registry<\/li>\n\n\n\n<li>Pull and launch the server&#8217;s container<\/li>\n<\/ol>\n\n\n\n<p>Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>- name: Build Docker image\n  run: docker build -t myapp .\n\n- name: Run container\n  run: docker run -d -p 80:80 myapp<\/code><\/pre>\n\n\n\n<p>Docker creates deployments:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Reliable and scalable<\/li>\n\n\n\n<li>Easier to reverse<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Common CI\/CD Errors &amp; How to Fix Them<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Permission Denied (SSH)<\/strong><br><strong>Cause:<\/strong> Wrong SSH key or permissions<br><strong>Fix:<\/strong> chmod 600 ~\/.ssh\/id_rsa<\/li>\n\n\n\n<li><strong>Environment Variables Not Working<\/strong><br><strong>Cause:<\/strong> Missing secrets in pipeline<br><strong>Fix:<\/strong> Add them in GitHub Secrets<\/li>\n\n\n\n<li><strong>Pipeline Fails Randomly<\/strong><br>Cause: Dependency or caching issue<br>Fix:<br>&#8211; Clear cache<br>&#8211; Lock dependency versions<\/li>\n\n\n\n<li><strong>Deployment Not Updating<\/strong><br><strong>Cause:<\/strong> Git not pulling latest code<br><strong>Fix:<\/strong> git pull origin main<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">FAQ<\/h2>\n\n\n\n<p><strong>What is the setup time for CI\/CD?<\/strong><\/p>\n\n\n\n<p>For beginners: Approximately two to five hours<br>30 to 60 minutes for seasoned engineers<\/p>\n\n\n\n<p><strong>Does Docker have to be used for CI\/CD?<\/strong><\/p>\n\n\n\n<p>No, because Docker creates deployments:<\/p>\n\n\n\n<p>More dependable and easier to grow <br>Suggested for production settings.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Final Remarks<\/h2>\n\n\n\n<p>CI\/CD is now essential for modern uses and is no longer optional.<\/p>\n\n\n\n<p>By establishing a pipeline for CI\/CD, you:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Deploy more quickly<\/li>\n\n\n\n<li>Cut down on human error<\/li>\n\n\n\n<li>Boost dependability<\/li>\n\n\n\n<li>Easily scale your infrastructure<\/li>\n<\/ul>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"Let&#8217;s set up your first CI\/CD pipeline from scratch. Learn GitHub Actions, automated testing, and deployment to a&hellip;","protected":false},"author":4,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_singular_sidebar":"","csco_page_header_type":"","csco_page_load_nextpost":"","footnotes":""},"categories":[87,89,1,29],"tags":[94,93,90],"class_list":{"0":"post-19997","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-devops","7":"category-devops-for-small-business","8":"category-uncategorized","9":"category-web-development-in-nepal","10":"tag-ci-cd","11":"tag-ci-cd-pipeline-setup","12":"tag-devops","13":"cs-entry"},"_links":{"self":[{"href":"https:\/\/www.bisup.com\/blog\/wp-json\/wp\/v2\/posts\/19997","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.bisup.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.bisup.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.bisup.com\/blog\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/www.bisup.com\/blog\/wp-json\/wp\/v2\/comments?post=19997"}],"version-history":[{"count":2,"href":"https:\/\/www.bisup.com\/blog\/wp-json\/wp\/v2\/posts\/19997\/revisions"}],"predecessor-version":[{"id":20002,"href":"https:\/\/www.bisup.com\/blog\/wp-json\/wp\/v2\/posts\/19997\/revisions\/20002"}],"wp:attachment":[{"href":"https:\/\/www.bisup.com\/blog\/wp-json\/wp\/v2\/media?parent=19997"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.bisup.com\/blog\/wp-json\/wp\/v2\/categories?post=19997"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.bisup.com\/blog\/wp-json\/wp\/v2\/tags?post=19997"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}