{
  "$type": "site.standard.document",
  "bskyPostRef": {
    "cid": "bafyreiet7cfbq3b6wicwfu76jrdvb6ab5uj7k5hckzgmtnhqdqux2llowu",
    "uri": "at://did:plc:yaz3p6kpjacwypalo2scppxc/app.bsky.feed.post/3mkz3pnki4mb2"
  },
  "coverImage": {
    "$type": "blob",
    "ref": {
      "$link": "bafkreigcnmaxwrlj4p62qdu27wpdaxg4yah2vwb5ukzpbuckkloouxxjd4"
    },
    "mimeType": "image/jpeg",
    "size": 174620
  },
  "description": "Learn how to build a production-ready CI/CD pipeline from scratch using GitHub Actions, Docker, and automated testing. Step-by-step guide for developers who want to ship faster.",
  "path": "/cicd-pipeline-from-zero-to-hero/",
  "publishedAt": "2026-05-01T06:47:01.000Z",
  "site": "https://devopspack.com",
  "textContent": "## What is CI/CD and Why Does It Matter?\n\nContinuous Integration and Continuous Delivery (CI/CD) is the backbone of modern software delivery. Instead of manually building, testing, and deploying code, a CI/CD pipeline automates the entire process — from the moment a developer pushes a commit to the point where it reaches production.\n\nIn this guide, we'll build a real-world pipeline using **GitHub Actions** , **Docker** , and a simple Node.js application. By the end, you'll have a fully automated workflow that tests, builds, and deploys your app on every push.\n\n## The Three Pillars of a Good Pipeline\n\nBefore writing a single line of YAML, understand what your pipeline needs to do:\n\n  * **Build** — compile your code and create a Docker image\n  * **Test** — run unit tests, integration tests, and security scans\n  * **Deploy** — push the image to a registry and update your infrastructure\n\n\n\n## Step 1: Setting Up GitHub Actions\n\nCreate a `.github/workflows/pipeline.yml` file in your repository:\n\n\n    name: CI/CD Pipeline\n\n    on:\n      push:\n        branches: [main, develop]\n      pull_request:\n        branches: [main]\n\n    jobs:\n      build-and-test:\n        runs-on: ubuntu-latest\n        steps:\n          - uses: actions/checkout@v4\n\n          - name: Set up Node.js\n            uses: actions/setup-node@v4\n            with:\n              node-version: '20'\n              cache: 'npm'\n\n          - name: Install dependencies\n            run: npm ci\n\n          - name: Run tests\n            run: npm test\n\n          - name: Build Docker image\n            run: docker build -t myapp:${{ github.sha }} .\n\n\n## Step 2: Writing a Production-Ready Dockerfile\n\nA multi-stage Dockerfile keeps your final image lean and secure:\n\n\n    # Stage 1: Build\n    FROM node:20-alpine AS builder\n    WORKDIR /app\n    COPY package*.json ./\n    RUN npm ci --only=production\n\n    # Stage 2: Production\n    FROM node:20-alpine\n    WORKDIR /app\n    COPY --from=builder /app/node_modules ./node_modules\n    COPY . .\n    EXPOSE 3000\n    USER node\n    CMD [\"node\", \"server.js\"]\n\n\n## Step 3: Automated Deployments to AWS\n\nAdd a deploy job that only runs on pushes to `main`:\n\n\n      deploy:\n        needs: build-and-test\n        runs-on: ubuntu-latest\n        if: github.ref == 'refs/heads/main'\n        steps:\n          - name: Configure AWS credentials\n            uses: aws-actions/configure-aws-credentials@v4\n            with:\n              aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}\n              aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}\n              aws-region: eu-central-1\n\n          - name: Push to ECR and deploy\n            run: |\n              aws ecr get-login-password | docker login --username AWS --password-stdin $ECR_REGISTRY\n              docker tag myapp:${{ github.sha }} $ECR_REGISTRY/myapp:latest\n              docker push $ECR_REGISTRY/myapp:latest\n              aws ecs update-service --cluster production --service myapp --force-new-deployment\n\n\n## Common Pitfalls to Avoid\n\nAfter setting up dozens of pipelines, here are the mistakes I see most often:\n\n  * **Storing secrets in the repo** — always use GitHub Secrets or a secrets manager like AWS Secrets Manager\n  * **Skipping tests on feature branches** — test everything, every time\n  * **Fat Docker images** — use multi-stage builds and Alpine base images\n  * **No rollback strategy** — always keep the previous image tagged and ready\n\n\n\n## Next Steps\n\nOnce your basic pipeline is running, consider adding:\n\n  * Security scanning with **Trivy** or **Snyk**\n  * Code quality gates with **SonarQube**\n  * Notifications to **Slack** on deployment success or failure\n  * Blue/green deployments to eliminate downtime\n\n\n\nA solid CI/CD pipeline is the single biggest productivity boost you can give your team. Start simple, then layer on complexity as your needs grow.",
  "title": "CI/CD Pipeline from Zero to Hero: A Practical Guide",
  "updatedAt": "2026-05-04T06:55:31.067Z"
}