Back to articles
Technology Insight

Integrating CI/CD Pipelines to Automate Code Deployment to VPS

April 14, 2026
Integrating CI/CD Pipelines for Automated VPS Deployment 2026

Optimizing Deployment: Integrating CI/CD Pipelines for Automated VPS Delivery

In the modern software development era of 2026, manual code uploads via FTP or tools like FileZilla have become relics of the past. These processes are not only slow but also carry a high risk of human error. For any web project to operate smoothly, setting up CI/CD (Continuous Integration/Continuous Deployment) is a mandatory requirement. This article provides an in-depth analysis of using GitHub Actions and GitLab CI to fully automate everything from testing and packaging to direct deployment onto your VPS.

1. What is CI/CD? Why Modern Developers Can't Live Without It

CI/CD is a methodology that bridges the gap between development and operations. Instead of worrying every time you update a new feature, an automated system performs every task with absolute precision on your behalf.

[Image of CI/CD Pipeline workflow]
  • Continuous Integration (CI): Every time you git commit, the source code is automatically checked for syntax errors (Linting), runs Unit Tests, and performs a trial Build. If any error is found, the process stops immediately.
  • Continuous Deployment (CD): After the code passes the CI phase, the system automatically connects to the VPS via SSH, pulls the latest code, reinstalls libraries, and restarts services (such as PM2, Docker, or Nginx).

// Example data structure simulating a Pipeline process
interface PipelineStage {
    name: string;
    status: 'pending' | 'running' | 'success' | 'failed';
    commands: string[];
}

function executePipeline(stages: PipelineStage[]): boolean {
    for (const stage of stages) {
        console.log(`Executing stage: ${stage.name}...`);
        // Simulating status check logic
        if (stage.status === 'failed') {
            console.error(`Pipeline interrupted at stage: ${stage.name}`);
            return false;
        }
    }
    return true;
}

const myActions: PipelineStage[] = [
    { name: 'Build', status: 'success', commands: ['npm install', 'npm run build'] },
    { name: 'Test', status: 'success', commands: ['npm test'] },
    { name: 'Deploy', status: 'pending', commands: ['ssh root@vps "cd /app && git pull"'] }
];

executePipeline(myActions);
    

2. Setting up GitHub Actions - The Top Choice for Developers

GitHub Actions has become the world's most popular CI/CD tool due to its deep integration with repositories. To start, you need to create a configuration file at .github/workflows/deploy.yml within your project.

A basic Workflow typically consists of "Jobs" running on GitHub's virtual machines (Ubuntu-latest). Once complete, it uses an SSH Key to securely access your VPS.


// Basic deployment configuration structure (Simulated Object)
interface GitHubWorkflow {
    on: string; // trigger: 'push'
    jobs: {
        build_and_deploy: {
            runs_on: 'ubuntu-latest';
            steps: Array<{
                name: string;
                run?: string;
                uses?: string;
                with?: Record;
            }>;
        }
    };
}

const deployWorkflow: GitHubWorkflow = {
    on: 'push',
    jobs: {
        build_and_deploy: {
            runs_on: 'ubuntu-latest',
            steps: [
                { name: 'Checkout code', uses: 'actions/checkout@v3' },
                { name: 'Install Node.js', uses: 'actions/setup-node@v3', with: { 'node-version': '22' } },
                { name: 'Build project', run: 'npm install && npm run build' },
                { name: 'Deploy to VPS', run: 'scp -r ./dist user@vps:/var/www/app' }
            ]
        }
    }
};
    

3. Security in CI/CD: Managing Secrets and SSH Keys

One of the fatal mistakes when setting up CI/CD is exposing your VPS password or SSH Private Key directly in the code. You must never do this. Instead, use the Environment Secrets feature.

Secret Name Stored Value Purpose
SSH_PRIVATE_KEY Content of the id_rsa file Allows GitHub/GitLab to securely connect to the VPS.
REMOTE_HOST VPS IP Address Identifies the destination of the source code.
REMOTE_USER root or deploy_user The account executing commands on Linux.

Pro Tip: Create a dedicated User on Linux with permissions limited only to the Web directory, rather than using root, to maximize security in case the CI/CD pipeline is compromised.

4. Advanced CD Workflows: Blue-Green Deployment and Rollback

When your application has thousands of visitors, you don't want the site to go "down" for even a few seconds while the system updates new code. This is where advanced deployment techniques come in.

The CI/CD system can be configured to check the health of the new version before shutting down the old one. If the new version encounters an error (crashes immediately upon startup), the system will automatically perform a Rollback to the previous version instantly without the user ever noticing.


// Simulating a health check process before official Deployment
async function checkHealth(endpoint: string): Promise {
    try {
        const response = await fetch(endpoint);
        return response.status === 200;
    } catch (e) {
        return false;
    }
}

async function safeDeploy(appVersion: string): Promise {
    console.log(`Deploying version: ${appVersion}`);
    const isHealthy = await checkHealth("http://localhost:3001/health"); // new port
    
    if (isHealthy) {
        return "Deployment successful. Switching traffic to the new version.";
    } else {
        return "ERROR: New version not responding. Executing emergency Rollback!";
    }
}

safeDeploy("v2.1.0").then(res => console.log(res));
    

5. GitLab CI/CD - Power for Self-Hosted Projects

If you are operating your own Self-hosted GitLab server, using GitLab CI via the .gitlab-ci.yml file offers extremely high customization. GitLab uses "Runners" to execute command lines.

  • Shared Runners: Free but have limited monthly runtime.
  • Specific Runners: You can use another VPS as a Runner to speed up the Build process and save costs.

// Defining network configuration for VPS in a Deployment management system
type DeployMethod = "DOCKER" | "RSYNC" | "GIT_PULL";

interface ServerConfig {
    host: string;
    method: DeployMethod;
    autoRestart: boolean;
}

const vpsConfig: ServerConfig = {
    host: "103.45.xx.xx",
    method: "DOCKER",
    autoRestart: true
};

console.log(`CD process will use the ${vpsConfig.method} method to push code to ${vpsConfig.host}.`);
    

6. Optimizing Pipeline Speed: Cache and Artifacts

One downside of CI/CD is that it can be time-consuming. If every deployment requires you to npm install thousands of libraries from scratch, you'll lose 5-10 minutes per commit. To solve this, use Caching.

By caching the node_modules directory between runs, build time can drop from 5 minutes to 30 seconds. Additionally, using Artifacts allows you to store the Build output (dist/build folder) for easy comparison or downloading when needed.


// Calculating time saved using Cache
function calculateSavedTime(totalCommits: number, installTime: number, cacheTime: number): number {
    const timeWithoutCache = totalCommits * installTime;
    const timeWithCache = totalCommits * cacheTime;
    return timeWithoutCache - timeWithCache;
}

const savedMinutes = calculateSavedTime(100, 5, 0.5); // 100 commits, 5m no cache, 30s with cache
console.log(`Total time saved last month: ${savedMinutes} minutes (~${(savedMinutes/60).toFixed(1)} hours).`);
    

7. Conclusion: Checklist for a Perfect Pipeline

Before officially trusting an automated system with your VPS, carefully check these questions:

  1. Have you tested the deployment process on a staging branch before pushing to main/master?
  2. Does the SSH Key have an expiration date, and is it configured with least privilege?
  3. Does the system automatically notify you via Telegram/Slack if a Pipeline fails?
  4. Have you configured the application to automatically Restart after a successful deployment?

We hope this guide helps you liberate your labor, eliminate the fear of uploading the wrong files, and achieve a professional, secure deployment process for your project!