ہم نے جینکنز، ڈوکر کمپوز، اور ٹریفیک کا استعمال کرتے ہوئے مونوریپو پر مبنی مائیکرو سروسز سسٹم کے لیے پروڈکشن کے لیے تیار CI/CD پائپ لائن کیسے بنائی

یہ ٹیوٹوریل ایک واحد لینکس سرور پر جینکنز، ڈوکر کمپوز، اور ٹریفک کا استعمال کرتے ہوئے پیداوار کے لیے تیار CI/CD پائپ لائن بنانے کے لیے ایک مکمل، عملی رہنما ہے۔

خودکار تجدید کرنے والے HTTPS کا استعمال کرتے ہوئے اپنی مرضی کے ڈومین میں خدمات کو کس طرح ظاہر کرنا ہے اور ایک سمارٹ تعیناتی حکمت عملی کو نافذ کرنے کا طریقہ سیکھیں جو تبدیلیوں کا پتہ لگاتی ہے اور صرف متاثرہ مائیکرو سروسز کو دوبارہ تعینات کرتی ہے۔ یہ غیر ضروری مکمل اسٹیک کی دوبارہ تقسیم کو روکنے میں مدد کرتا ہے۔ ہم حقیقی دنیا کے پیداواری مسائل اور ہر مسئلے کے لیے درست اصلاحات کا بھی احاطہ کریں گے۔

انڈیکس

1. کیا بنانا ہے۔

اس ٹیوٹوریل میں، آپ ایک جینکنز مثال بناتے ہیں جو آپ کے ایپلیکیشن اسٹیک کے طور پر اسی لینکس سرور پر ڈوکر کے اندر چل رہا ہے۔

ٹریفک جینکنز کے سامنے ایک ریورس پراکسی کے طور پر کام کرتا ہے، صاف یو آر ایل فراہم کرتا ہے (https://jenkins.example.com) کے ساتھ خود کار طریقے سے قابل تجدید آئیے انکرپٹ سرٹیفکیٹ.

ہم ایپلیکیشن ریپوزٹری میں درج ذیل جینکنز فائل بھی بناتے ہیں۔

  • جب بھی آپ دھکا دیتے ہیں تو خود بخود متحرک ہوجاتا ہے۔ staging درخت کی شاخ،

  • معلوم کریں کہ ہر کمٹ میں کون سی مائیکرو سروسز تبدیل ہوئی ہیں۔

  • اپنے میزبان سسٹم سے تازہ ترین کوڈ حاصل کریں۔

  • دوبارہ تعمیر کریں اور دوبارہ شروع کریں۔ صرف متاثرہ خدمات.

ہر دھکا صرف متعلقہ خدمات کو دوبارہ تقسیم کرتا ہے۔

شرطیں

شروع کرنے سے پہلے، یہ گائیڈ فرض کرتا ہے کہ آپ کچھ بنیادی تصورات اور ٹولز سے پہلے ہی واقف ہیں۔

یہ ابتدائی سطح کا سبق نہیں ہے۔ آپ انفراسٹرکچر، کنٹینرز، اور CI/CD پائپ لائنوں کے ساتھ براہ راست کام کریں گے۔

آپ کو درج ذیل چیزوں سے آگاہ ہونا چاہیے:

  • بنیادی لینکس کمانڈز (SSH، فائل سسٹم نیویگیشن، اجازت)

  • ڈاکر کی بنیادی باتیں (تصاویر، کنٹینرز، حجم، نیٹ ورک)

  • گٹ ورک فلو (کلون، پل، برانچ)

  • CI/CD پائپ لائن کا عمومی خیال

مطلوبہ اوزار اور ماحول:

  • لینکس سرور (اوبنٹو تجویز کردہ)

  • ڈوکر انجن + ڈوکر کمپوز (v2)

  • ڈومین کا نام (Trefik + HTTPS کے لیے)

  • GitHub ذخیرہ (بیک اینڈ پروجیکٹس کے لیے)

  • مائیکرو سروس فن تعمیر کی بنیادی تفہیم

اگر آپ مندرجہ بالا سے واقف ہیں، تو آپ اس کی پیروی کرنے کے لیے تیار ہیں۔

2. فن تعمیر

فن تعمیر کا جائزہ حسب ذیل ہے:

┌──────────────────────────── Linux server (Ubuntu) ────────────────────────────┐
│                                                                               │
│   /home/developer/projects/                                                  │
│       └── project-prod-configs/             ← infra repo (compose, Traefik) │
│              ├── docker-compose.staging.yml                                   │
│              ├── traefik.staging.yml                                          │
│              └── project-backend/          ← app repo (services, gateways) │
│                     ├── Jenkinsfile                                           │
│                     ├── docker-compose.staging.yml                            │
│                     └── apps/                                                 │
│                            ├── services//                               │
│                            ├── gateways//                               │
│                            └── core//                                   │
│                                                                               │
│   ┌─────────────────────── Docker network: proxy ──────────────────────┐      │
│   │  traefik (80, 443)                                                 │      │
│   │     │                                                              │      │
│   │     ├──► jenkins  (projects-jenkins-staging)                     │      │
│   │     │      ↳ /projects  ← bind-mount of the host project tree     │      │
│   │     │      ↳ /var/run/docker.sock ← controls host Docker           │      │
│   │     │                                                              │      │
│   │     └──► your services & gateways (built by the pipeline)          │      │
│   └────────────────────────────────────────────────────────────────────┘      │
│                                                                               │
└───────────────────────────────────────────────────────────────────────────────┘
            ▲
            │  webhook on push
            │
   GitHub: /project-backend (branch: staging)

یہاں دو اہم خیالات ہیں۔

  1. جینکنز کنٹینرز میں چلتا ہے۔لیکن یہ میزبان کی ڈوکر سے لیس /var/run/docker.sock. میں پروجیکٹ فولڈر کو اس طرح ماؤنٹ کرتا ہوں: /projects/...تو یہ ہو سکتا ہے cd اسے اپنے میزبان کے اصل کوڈ میں ڈالیں اور اسے چلائیں۔ docker compose وہاں

  2. کہ جینکنز فائل ایپ کے ذخیرے میں واقع ہے۔لہذا، پائپ لائن کی تعریف کوڈ کے طور پر ورژن ہے. جینکنز آسانی سے اس کی نشاندہی کرتے ہیں۔

3. سرور کی شرائط

اس سے پہلے کہ آپ جینکنز یا ٹریفک کو ترتیب دینا شروع کریں، آپ کو اپنے سرور کو مناسب طریقے سے تیار کرنا چاہیے۔

اس مرحلے میں:

  • پراجیکٹ مینجمنٹ کے لیے ایک وقف شدہ لینکس صارف بنائیں

  • ڈوکر اور ڈوکر کمپوز انسٹال کریں۔

  • اپنے ذخیرہ کے لیے فولڈر کا ڈھانچہ ترتیب دیں۔

یہ اس بات کو یقینی بناتا ہے کہ آپ کی CI/CD پائپ لائن صاف اور پیش گوئی کے قابل ماحول میں چلتی ہے۔

# Linux user that owns the project tree
sudo adduser developer

# Docker engine + Compose plugin
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker developer

# Sanity check Compose v2
docker compose version
# -> Docker Compose version v2.x.y

# Find where the Compose plugin binary lives — write it down, you'll need it
ls /usr/libexec/docker/cli-plugins/docker-compose
# (some distros use /usr/lib/docker/cli-plugins/docker-compose)

# Project layout
sudo mkdir -p /home/developer/project
sudo chown -R developer:developer /home/developer/project

# Clone both repos in the right place
cd /home/developer/projects
git clone https://github.com//projects-prod-configs.git
cd projects-prod-configs
git clone -b staging https://github.com//projects-backend.git

اب آپ کے پاس ہونا چاہئے:

/home/developer/projects/projects-prod-configs/projects-backend

اس راستے کو یاد رکھیں۔ جینکنز فائل اس کا حوالہ دیتی ہے۔

ڈی این ایس

اپنے جینکنز ذیلی ڈومین کے ریکارڈ کو سرور کے عوامی IP کی طرف اشارہ کریں۔ پہلے HTTP چیلنج کے ذریعے توثیق کرنے کے لیے Let’s Encrypt کو فعال کرنے کے لیے ان اقدامات پر عمل کریں۔

jenkins.example.com   A   

4. Traefik – ریورس پراکسی

Traefik پورے نظام میں داخلے کے نقطہ کے طور پر کام کرتا ہے۔ ہر سروس کو دستی طور پر ایک بندرگاہ کے طور پر ظاہر کرنے کے بجائے، Traefik خود بخود:

  • ڈومین نام کی بنیاد پر ٹریفک کی روٹنگ

  • Let’s Encrypt کا استعمال کرتے ہوئے HTTPS سرٹیفکیٹ بنائیں اور ان کی تجدید کریں۔

  • ڈوکر سے جڑیں اور متحرک طور پر خدمات کا پتہ لگائیں۔

مختصراً، Traefik آپ کو درج ذیل خدمات تک رسائی فراہم کرتا ہے:

https://jenkins.example.com
https://api.example.com

… یہ NGINX کو دستی طور پر کنفیگر کیے بغیر یا SSL سرٹیفکیٹس کا انتظام کیے بغیر ممکن ہے۔

اس سیٹ اپ میں، Traefik Docker کنٹینرز کو دیکھتا ہے اور لیبلز کا استعمال کرتے ہوئے ٹریفک کو روٹ کرتا ہے جس کی آپ بعد میں وضاحت کریں گے۔

Traefik ہر کنٹینر کے لیے ایک حقیقی ڈومین اور ایک حقیقی سرٹیفکیٹ فراہم کرتا ہے۔ کوئی سروس مخصوص کنفیگریشن نہیں ہے۔ – بس چند لیبلز شامل کریں۔

traefik.staging.yml (جامد ترتیب)

اپنے بنیادی ڈھانچے کے ذخیرے کی جڑ میں درج ذیل درج کریں:

api:
  dashboard: true

entryPoints:
  web:
    address: ":80"
  websecure:
    address: ":443"

certificatesResolvers:
  letsencrypt:
    acme:
      httpChallenge:
        entryPoint: web
      email: admin@example.com           # ← change me
      storage: /etc/traefik/acme.json

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false              # only containers with traefik.enable=true
    network: proxy
  file:
    directory: /etc/traefik/dynamic
    watch: true

log:
  level: INFO

accessLog: {}

ٹریفک سروس docker-compose.staging.yml

networks:
  proxy:
    name: proxy
    driver: bridge
  internal:
    name: internal
    driver: bridge

volumes:
  acme-data:
  traefik-logs:
  jenkins-data:

services:
  traefik:
    image: traefik:v2.11
    container_name: projects-traefik-staging
    restart: unless-stopped
    ports:
      - "80:80"        # HTTP (auto-redirects to HTTPS)
      - "443:443"      # HTTPS
      - "8080:8080"    # Traefik dashboard (internal only — protect via firewall)
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./traefik.staging.yml:/etc/traefik/traefik.yml:ro
      - ./dynamic:/etc/traefik/dynamic:ro
      - acme-data:/etc/traefik           # persists Let's Encrypt certs
      - traefik-logs:/var/log/traefik
    networks:
      - proxy
    command:
      - '--api.insecure=false'
      - '--api.dashboard=true'
      - '--providers.docker=true'
      - '--providers.docker.exposedbydefault=false'
      - '--providers.docker.network=proxy'
      - '--entrypoints.web.address=:80'
      - '--entrypoints.websecure.address=:443'
      - '--entrypoints.web.http.redirections.entryPoint.to=websecure'
      - '--entrypoints.web.http.redirections.entryPoint.scheme=https'
      - '--certificatesresolvers.letsencrypt.acme.httpchallenge=true'
      - '--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web'
      - '--certificatesresolvers.letsencrypt.acme.email=${ACME_EMAIL:-admin@example.com}'
      - '--certificatesresolvers.letsencrypt.acme.storage=/etc/traefik/acme.json'
      - '--log.level=INFO'
      - '--accesslog=true'
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=proxy"
      # Traefik's own dashboard
      - "traefik.http.routers.traefik-dash.rule=Host(`traefik.example.com`)"
      - "traefik.http.routers.traefik-dash.entrypoints=websecure"
      - "traefik.http.routers.traefik-dash.tls.certresolver=letsencrypt"
      - "traefik.http.routers.traefik-dash.service=api@internal"

براہ کرم لائیں:

cd /home/developer/projects/projects-prod-configs
docker compose -f docker-compose.staging.yml up -d traefik

پہلی بار لاگز چیک کریں۔ DNS حل ہوتے ہی Traefik آپ کے ڈیش بورڈ میزبان کے لیے ایک سرٹیفکیٹ کی درخواست کرے گا۔

docker logs -f projects-traefik-staging

ٹپ جانچ کے دوران، ACME کو سٹیجنگ اینڈ پوائنٹ کے طور پر استعمال کریں (acme.caServer=https://acme-staging-v02.api.letsencrypt.org/directory) اگر آپ اپنے DNS کو غلط طریقے سے ترتیب دیتے ہیں تو Let’s Encrypt کی شرح کی حد سے تجاوز کرنے سے بچنے کے لیے۔ براہ کرم لائیو جانے سے پہلے اس جھنڈے کو ہٹا دیں۔

5. ڈوکر پر جینکنز چلانا

اس جینکنز سروس کو اسی سروس میں شامل کریں۔ docker-compose.staging.yml. ہر سطر اہم ہے (اور تبصرے اس کی وجہ بتاتے ہیں)۔

  jenkins:
    image: jenkins/jenkins:lts
    container_name: projects-jenkins-staging
    restart: unless-stopped
    user: root                           # to use host docker.sock without UID juggling
    environment:
      - JAVA_OPTS=-Xmx1g -Xms512m -Duser.timezone=Asia/Dhaka
      - TZ=Asia/Dhaka                    # OS-level timezone inside container
      - JENKINS_OPTS=--prefix=/
    ports:
      - "3095:8080"                      # web UI (also reachable directly if needed)
      - "50000:50000"                    # inbound agent port
    volumes:
      - jenkins-data:/var/jenkins_home   # Jenkins config/jobs/secrets persistence
      - /var/run/docker.sock:/var/run/docker.sock                          # control host Docker
      - /usr/bin/docker:/usr/bin/docker                                     # docker CLI from host
      - /usr/libexec/docker/cli-plugins:/usr/libexec/docker/cli-plugins:ro  # docker compose plugin
      - /home/developer/projects:/projects                                # project tree
      - /etc/localtime:/etc/localtime:ro                                    # match host clock
      - /etc/timezone:/etc/timezone:ro
    networks:
      - proxy
      - internal
    healthcheck:
      test: ['CMD', 'curl', '-f', 'http://localhost:8080/login']
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 120s
    deploy:
      resources:
        limits:
          memory: 1024M

کیوں user: root? شیئر کرنے کا آسان ترین طریقہ docker.sock UID/GID جمناسٹکس کے بغیر پروجیکٹ بائنڈ ماؤنٹ۔ اگر آپ غیر مراعات یافتہ صارفین کو ترجیح دیتے ہیں، تو آپ کو ترتیب دینے کی ضرورت ہے: group: docker UID/perms کو میزبان فولڈر میں ترتیب دیں۔ یہ ممکن ہے، لیکن یہاں گنجائش سے باہر ہے۔

6. Traefik کے ذریعے جینکنز کو اپنے ڈومین پر ظاہر کریں۔

یہ ایک ایسا حصہ ہے جسے بہت سے رہنما چھوڑ دیتے ہیں۔ ہم شامل کریں گے لیبل اپنی جینکنز سروس سے جڑیں اور Traefik کو اسے اپنے لیے لینے دیں۔ Traefik کنفیگریشن میں ترمیم کرنے کی ضرورت نہیں ہے۔

  jenkins:
    # ... everything above ...
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=proxy"

      # 1) Router — match incoming Host
      - "traefik.http.routers.jenkins.rule=Host(`jenkins.example.com`)"
      - "traefik.http.routers.jenkins.entrypoints=websecure"
      - "traefik.http.routers.jenkins.tls.certresolver=letsencrypt"
      - "traefik.http.routers.jenkins.service=jenkins"

      # 2) Service — tell Traefik which container port is the app
      - "traefik.http.services.jenkins.loadbalancer.server.port=8080"

      # 3) Middleware — Jenkins needs X-Forwarded-Proto so it knows it's behind HTTPS
      - "traefik.http.middlewares.jenkins-headers.headers.customrequestheaders.X-Forwarded-Proto=https"
      - "traefik.http.routers.jenkins.middlewares=jenkins-headers"

ہر سطر کا کردار حسب ذیل ہے:

برانڈ مقصد
traefik.enable=true اس کنٹینر کو منتخب کریں (ہم exposedByDefault=false
traefik.docker.network=proxy Traefik کو بتائیں کہ جینکنز کے ساتھ کون سا نیٹ ورک رابطہ کرے (جینکنز دونوں نیٹ ورکس پر ہے)۔ proxy اور internal
routers.jenkins.rule=Host(...) ہم یہ میزبان نام صرف جینکنز کو دیتے ہیں۔
routers.jenkins.entrypoints=websecure صرف 443 پر سنتا ہے۔ (HTTP ری ڈائریکشن سیکشن 4 میں ترتیب دیا گیا تھا۔)
routers.jenkins.tls.certresolver=letsencrypt خودکار اجراء + سرٹیفکیٹ کی تجدید
services.jenkins.loadbalancer.server.port=8080 جینکنز کنٹینر کے اندر 8080 سنتے ہیں۔
customrequestheaders.X-Forwarded-Proto=https اگر یہ موجود نہیں ہے تو، جینکنز ایک بنائیں گے۔ http:// ویب ہک/لنک اور وقفے کا URL۔

جینکنز کو اٹھاؤ۔

cd /home/developer/projects/projects-prod-configs
docker compose -f docker-compose.staging.yml up -d jenkins

# Watch Traefik issue the certificate
docker logs -f projects-traefik-staging | grep -i acme

آپ کو اسے 10 سے 60 سیکنڈ کے بعد کھولنے کے قابل ہونا چاہئے۔ https://jenkins.example.com ایک درست لاک آئیکن کے ساتھ جینکنز کا سیٹ اپ وزرڈ دیکھیں۔

جینکنز کے اندر (پہلے لاگ ان کے بعد):

جینکنز مینجمنٹ → سسٹم → جینکنز URL → https://jenkins.example.com/ کے بطور سیٹ کریں۔

یہ ضروری ہے کیونکہ جینکنز اس بنیادی URL کو بنانے کے لیے استعمال کرتے ہیں:

اگر یہ صحیح طریقے سے ترتیب نہیں دیا گیا ہے تو، آپ کے GitHub ویب ہکس ناکام ہو سکتے ہیں اور جینکنز کے جو بھی لنکس تیار کرتے ہیں وہ غلط ایڈریس (اکثر آپ کے لوکل ہوسٹ یا اندرونی IP) کی طرف اشارہ کریں گے۔

7. پہلا جینکنز سیٹ اپ

اگر آپ پہلی بار اس سرور پر جینکنز چلا رہے ہیں، تو ابتدائی سیٹ اپ مکمل کرنے کے لیے اس سیکشن کی پیروی کریں۔

اگر آپ پہلے ہی جینکنز کو کنفیگر کر چکے ہیں تو آپ اس سیکشن کو چھوڑ سکتے ہیں۔ تاہم، یقینی بنائیں کہ مطلوبہ پلگ ان اور سیٹنگز ان سے میل کھاتی ہیں جو آپ بعد میں اس گائیڈ میں استعمال کرتے ہیں۔

  1. کھلا https://jenkins.example.com. اپنا ابتدائی ایڈمنسٹریٹر پاس ورڈ حاصل کریں:

    docker exec projects-jenkins-staging cat /var/jenkins_home/secrets/initialAdminPassword
    
  2. اسے چسپاں کریں اور فیچرڈ پلگ ان انسٹال کریں کو منتخب کریں۔

  3. ایک انتظامی صارف بنائیں۔

  4. جینکنز مینجمنٹ → پلگ انز → دستیاب اور انسٹال:

یہ وہ تمام پلگ ان ہیں جن کی آپ کو باقی گائیڈ کے لیے ضرورت ہوگی۔

8. GitHub اسناد شامل کریں۔

جینکنز کو آپ کے GitHub ذخیرہ تک رسائی کے لیے اجازت درکار ہے۔

یہ ایک GitHub ذاتی رسائی ٹوکن (PAT) کا استعمال کرتے ہوئے کیا جاتا ہے، جو محفوظ APIs اور Git آپریشنز کے لیے پاس ورڈ کے طور پر کام کرتا ہے۔

آپ پائپ لائن پر عمل درآمد کے دوران اپنے کوڈ کو بازیافت کرنے اور اپنے رازوں کو اپنے کوڈ پر ظاہر کیے بغیر محفوظ طریقے سے تصدیق کرنے کے لیے اس ٹوکن کو جینکنز کے اندر بطور اسناد اسٹور کر سکتے ہیں۔

یہ واحد سند SCM چیک آؤٹ اور تعیناتی کے وقت دونوں کے لیے استعمال ہوتی ہے۔ git pull.

  1. GitHub میں ذاتی رسائی کا ٹوکن (کلاسک) اس کا استعمال کرتے ہوئے بنائیں: repo رینج

  2. جینکنز میں: جینکنز کا نظم کریں → اسناد → سسٹم → گلوبل → اسناد شامل کریں۔

  3. لکھیں:

    • قسم: پاس ورڈ کے ساتھ صارف نام

    • صارف نام: GitHub صارف نام

    • پاس ورڈ: ٹوکن

    • ID: github_classic_token (Jenkinsfile اس عین ID کا حوالہ دیتا ہے)

9. ایک پائپ لائن جاب بنائیں

اب جب کہ جینکنز کو ریپوزٹری تک رسائی حاصل ہے، اگلا مرحلہ اس بات کی وضاحت کرنا ہے کہ تعیناتی کیسے چلے گی۔

ایک پائپ لائن کام جینکنز کو بتاتا ہے:

جینکنز میں ایک نئی پائپ لائن جاب بنائیں اور اسے اپنے GitHub ریپوزٹری سے جوڑیں۔ ایک بار جب یہ سیٹ ہو جائے گا، جینکنز ہر بار جب آپ دبائیں گے تو خود بخود ایک تعیناتی کو متحرک کر دے گا۔ staging درخت کی شاخیں۔

ایک نیا کام بنا کر شروع کریں۔

نیا آئٹم → پائپ لائن → ایک نام کی وضاحت کریں۔ projects-staging → ٹھیک ہے۔

پھر کام کو ترتیب دیں۔

اپنی ترتیب کو محفوظ کریں۔

اس وقت، جینکنز آپ کے ذخیرے سے مکمل طور پر منسلک ہے اور آپ کی تعیناتی پائپ لائن کو خود بخود چلانے کے لیے تیار ہے۔

10. جینکنز فائل (صرف تبدیلیاں تعینات کریں)

اسے اپنی جڑ میں رکھیں۔ ایپ ریپو (projects-backend/Jenkinsfile)، درخت کی شاخیں staging.

pipeline {
  agent any

  environment {
    PROJECT_PATH = "/projects/projects-prod-configs/projects-backend"
    COMPOSE_FILE = "docker-compose.staging.yml"
  }

  stages {

    stage('Checkout') {
      steps {
        checkout scm
        echo "Checkout completed for branch: ${env.BRANCH_NAME ?: 'staging'}"
      }
    }

    stage('Detect Changes') {
      steps {
        script {
          def changedFiles = sh(
            script: "git diff --name-only HEAD~1 HEAD",
            returnStdout: true
          ).trim()

          echo "Changed files:\n${changedFiles}"

          def services = [] as Set
          changedFiles.split('\n').each { file ->
            def svc  = file =~ /^apps\/services\/([a-z0-9-]+)\//
            def gw   = file =~ /^apps\/gateways\/([a-z0-9-]+)\//
            def core = file =~ /^apps\/core\/([a-z0-9-]+)\//
            if (svc)  { services << svc[0][1]  }
            if (gw)   { services << gw[0][1]   }
            if (core) { services << core[0][1] }
          }
          services = services.findAll { !it.endsWith('-e2e') }
          env.CHANGED_SERVICES = services.join(' ')

          echo "Services to deploy: ${env.CHANGED_SERVICES ?: '(none)'}"
        }
      }
    }

    stage('Deploy') {
      when { expression { return env.CHANGED_SERVICES?.trim() } }
      steps {
        withCredentials([usernamePassword(
          credentialsId: 'github_classic_token',
          usernameVariable: 'GIT_USER',
          passwordVariable: 'GIT_TOKEN'
        )]) {
          sh '''
            set -eu
            git config --global --add safe.directory "${PROJECT_PATH}"
            cd "${PROJECT_PATH}"
            git remote set-url origin "https://github.com//projects-backend.git"
            git -c credential.helper= \
                -c "credential.helper=!f() { echo username=\({GIT_USER}; echo password=\){GIT_TOKEN}; }; f" \
                pull origin staging
            docker compose -f "\({COMPOSE_FILE}" up -d --build \){CHANGED_SERVICES}
          '''
        }
        echo "Deployed: ${env.CHANGED_SERVICES}"
      }
    }

    stage('Skip Deployment') {
      when { expression { return !env.CHANGED_SERVICES?.trim() } }
      steps { echo "No service changes detected — nothing to deploy." }
    }
  }
}

یہاں ہر ایک مشکل لائن کیوں ہے:

  • git config --global --add safe.directory ... – گٹ ریپوزٹریوں پر کارروائیوں کو مسترد کرتا ہے جن کا مالک UID موجودہ صارف سے مختلف ہے۔ ڈسک پر اسٹوریج کی ملکیت ہے: developerلیکن کنٹینر کے اندر گٹ اس طرح چلتا ہے: root. اس سے وائٹ لسٹ میں راستہ شامل ہو جائے گا۔

  • git remote set-url origin "https://..." – آن ڈسک ریموٹ کو HTTPS میں تبدیل کرکے ٹوکن دستیاب ہیں۔. (PAT کی توثیق نہیں کی جا سکتی۔ git@github.com: URL – SSH استعمال کرتا ہے۔) Idempotent – دوبارہ چلانے کے لیے محفوظ۔

  • git -c credential.helper="!f() { echo username=...; echo password=...; }; f" — اس کمانڈ کے لیے گٹ کو صارف نام/ٹوکن فراہم کریں بغیر ٹوکن کو ڈسک پر لکھے اور اسے عمل کی کمانڈ لائن پر ظاہر کیے بغیر۔

  • ${CHANGED_SERVICES} وہ جان بوجھ کر غیر نقل شدہ ہیں، لہذا متعدد سروس کے ناموں کو الگ الگ دلائل میں بڑھا دیا گیا ہے۔

11. اینڈ ٹو اینڈ ٹیسٹنگ

سیٹ اپ مکمل کرنے پر غور کرنے سے پہلے، آپ کو تصدیق کرنی چاہیے کہ پوری پائپ لائن توقع کے مطابق کام کر رہی ہے۔

یہ آخر سے آخر تک جانچ یقینی بناتی ہے:

  • GitHub ویب ہک جینکنز کو صحیح طریقے سے متحرک کر رہا ہے۔

  • جینکنز اس بات کا پتہ لگا سکتے ہیں کہ کون سی خدمات تبدیل ہوئی ہیں۔

  • صرف متاثرہ خدمات کو دوبارہ تعمیر اور تعینات کیا جاتا ہے۔

دوسرے الفاظ میں، یہ ایک حقیقی پیداوار کی تعیناتی کی نقل کرتا ہے۔

اپنے ذخیرے میں کچھ تبدیلیاں کرکے شروع کریں۔ مثال کے طور پر، فائلوں کے اندر ترمیم کریں:

app/gateway/student-apigw/

پھر اپنی تبدیلیاں کریں۔ staging درخت کی شاخیں۔

جب دھکا دیا جاتا ہے، جینکنز خود بخود ویب ہک کے ذریعے متحرک ہوجاتا ہے۔ اگر نہیں، تو آپ اسے دستی طور پر کلک کر سکتے ہیں۔ ابھی بنائیں.

اب تعمیر کھولیں۔ کنسول آؤٹ پٹ اور بہاؤ چیک کریں۔ آپ کو کچھ اس طرح نظر آئے گا:

  • برانچ ادائیگی مکمل: تیاری

  • تعینات کرنے کی خدمت: طالب علم-apigw

  • گٹ پل سورس تیار کریں (کامیابی)

  • docker کمپوز … up -d –build student-apigw

  • تعینات: طالب علم-apigw

اگر آپ یہ ترتیب دیکھتے ہیں، تو آپ کی پائپ لائن صحیح طریقے سے کام کر رہی ہے۔

اگر آپ کو کوئی پریشانی ہوتی ہے تو پریشان نہ ہوں۔ براہ کرم سیکشن 12 پر جائیں جہاں تمام عام مسائل اور حل دستاویز کیے گئے ہیں۔

12. خرابیوں کا سراغ لگانا – کسی بھی خرابی کا سامنا کرنا پڑا

اس حصے میں ان حقیقی مسائل کا احاطہ کیا گیا ہے جن کا ہمیں اس پائپ لائن کو قائم کرتے وقت سامنا کرنا پڑا، اور اس سے بھی اہم: ہر فکس کیوں کام کرتا ہے۔. "کیوں” کو سمجھنا آپ کو اپنے سیٹ اپ میں اسی طرح کے مسائل کو ٹھیک کرنے میں مدد کرے گا۔

CD: /projects/projects-prod-configs/projects-backend کو CD کرنے سے قاصر ہے۔

وجہ:
جینکنز فائل چلتا ہے۔ cd $PROJECT_PATHتاہم، وہ راستہ کنٹینر کے اندر موجود نہیں ہے۔ یہ عام طور پر ہوتا ہے جب:

  • پروجیکٹ کو میزبان پر نقل نہیں کیا گیا ہے، یا

  • بائنڈ ماؤنٹ درست طریقے سے ترتیب نہیں دیا گیا ہے۔

درست کریں:

ls /home/developer/projects/projects-prod-configs/projects-backend
# If missing: git clone -b staging  there.

بائنڈ ماؤنٹ کو چیک کریں۔

docker inspect projects-jenkins-staging --format '{{range .Mounts}}{{.Source}} -> {{.Destination}}{{println}}{{end}}'

اگر کنٹینر غائب ہے تو اسے دوبارہ بنائیں۔

docker compose -f docker-compose.staging.yml up -d --force-recreate jenkins

یہ کیوں کام کرتا ہے:

جینکنز ایک کنٹینر کے اندر چلتا ہے، لیکن اس کا کوڈ میزبان پر رہتا ہے۔ ایک بائنڈ ماؤنٹ ان کو جوڑتا ہے۔ اس کے بغیر، جینکنز آپ کی پروجیکٹ ڈائرکٹری تک رسائی حاصل نہیں کر سکیں گے۔

مہلک: ذخیرہ میں مبہم ملکیت کا پتہ چلا۔

وجہ:
اگر ذخیرہ کا مالک موجودہ صارف سے مختلف ہے تو گٹ رسائی کو روکتا ہے۔

درست کریں:

git config --global --add safe.directory "${PROJECT_PATH}"

یہ کیوں کام کرتا ہے:

یہ واضح طور پر Git کو بتاتا ہے کہ ڈائریکٹری قابل اعتماد ہے، ملکیت کی مماثلت سے متعلق حفاظتی پابندیوں کو نظرانداز کرتے ہوئے۔

Host key verification failed / Could not read from remote repository

وجہ:

ذخیرہ SSH کے ذریعے ہے (git@github.com:...لیکن:

مزید برآں، SSH کے ذریعے GitHub ٹوکنز کی توثیق نہیں کی جا سکتی ہے۔

ترمیم (تجویز کردہ):

git remote set-url origin "https://github.com//projects-backend.git"

یہ کیوں کام کرتا ہے:

HTTPS ٹوکن پر مبنی توثیق (PAT) کا استعمال کرتا ہے، جو SSH کنفیگریشن کے بغیر کنٹینر کے اندر کام کرتا ہے۔

unknown shorthand flag: 'f' in -f ( docker compose)

وجہ:
ڈوکر سی ایل آئی موجود ہے، لیکن ڈوکر کمپوز پلگ ان کنٹینر کے اندر غائب ہے۔

درست کریں:

volumes:
  - /usr/libexec/docker/cli-plugins:/usr/libexec/docker/cli-plugins:ro

اگر ضروری ہو تو ہدایات تلاش کریں۔

find /usr -name docker-compose -type f 2>/dev/null

چیک کریں:

docker exec projects-jenkins-staging docker compose version

یہ کیوں کام کرتا ہے:

Docker Compose v2 ایک CLI پلگ ان ہے۔ اگر میں اس ڈائریکٹری کو ماؤنٹ کرتا ہوں۔ docker compose وہ کمانڈز جو کنٹینر کے اندر استعمال کی جا سکتی ہیں۔

جینکنز UI میں ٹائم اسٹیمپ اور ٹائم زون کی تعمیر غلط ہے۔

درست کریں: env var اور JVM دونوں جھنڈے سیٹ کریں اور میزبان کی کلاک فائل کو بائنڈ کریں۔

environment:
  - TZ=Asia/Dhaka
  - JAVA_OPTS=... -Duser.timezone=Asia/Dhaka
volumes:
  - /etc/localtime:/etc/localtime:ro
  - /etc/timezone:/etc/timezone:ro

آپ ~ کرنا ہے۔ env-var تبدیلیاں لاگو کرنے کے لیے کنٹینر کو دوبارہ بنائیں۔

docker compose -f docker-compose.staging.yml up -d --force-recreate jenkins

یہ کیوں کام کرتا ہے:
جینکنز جاوا پر OS سے آزاد اپنے ٹائم زون کے ساتھ چلتا ہے۔
OS ٹائم زون، JVM ٹائم زون، اور میزبان گھڑی کو سیدھ میں لانا ہر جگہ مستقل ٹائم سٹیمپ کو یقینی بناتا ہے۔

ERR_SOCKET_TIMEOUT (pnpm انسٹالیشن ناکام)

وجہ:

اگر آپ متوازی طور پر متعدد خدمات بناتے ہیں اور pnpm انسٹال کو ~1500 پیکجوں کے ساتھ چلاتے ہیں، تو نیٹ ورک سیر ہو جائے گا اور ٹائم آؤٹ ہو جائے گا۔

اصلاحات:

a) ٹائم آؤٹ + کنکرنسی کنٹرول میں اضافہ کریں۔

RUN pnpm install --frozen-lockfile --ignore-scripts 
--network-timeout 600000 
--network-concurrency 8

وجہ: pnpm کو مزید وقت دیں اور نیٹ ورک اوورلوڈ کو کم کریں۔

b) pnpm کیشے کو فعال کریں (BuildKit)

RUN --mount=type=cache,id=pnpm-store,target=/root/.local/share/pnpm/store 
pnpm install --frozen-lockfile --ignore-scripts

کیوں: ہر بار ڈاؤن لوڈ ہونے کے بجائے انحصار کو کیش کیا جاتا ہے اور دوبارہ استعمال کیا جاتا ہے۔

ج) غیر ضروری تعمیر نو سے گریز کریں۔

docker compose -f \(COMPOSE_FILE build \)CHANGED_SERVICES docker compose -f \(COMPOSE_FILE up -d --no-build \)CHANGED_SERVICES

وجہ: صرف تبدیل شدہ خدمات کو دوبارہ بنائیں → نیٹ ورک کا بوجھ کم کریں → غلطیوں کو کم کریں۔

docker-compose.yml میں ترمیم کرنے کے بعد کنٹینر کی تبدیلیاں لاگو نہیں ہوتی ہیں۔

وجہ:

ڈوکر کمپوز اپ -d چلنے والے کنٹینرز کو اپ ڈیٹ نہیں کرتا ہے۔

درست کریں:

docker compose -f docker-compose.staging.yml up -d --force-recreate jenkins

یہ کیوں کام کرتا ہے:

یہ ڈوکر کو اپ ڈیٹ کنفیگریشن (env، حجم، لیبل) کے ساتھ کنٹینر کو دوبارہ بنانے کا سبب بنے گا۔

Traefik ڈیفالٹ سرٹیفکیٹ دکھاتا ہے (کوئی HTTPS نہیں)۔

عام وجوہات:

DNS سرور پورٹ 80 کی طرف اشارہ نہیں کرتا غلط ڈوکر نیٹ ورک بلاک ہے۔

چیک کریں:

dig +short jenkins.example.com docker logs projects-traefik-staging 2>&1 | grep -i acme

یہ کیوں کام کرتا ہے:

آئیے انکرپٹ ایک HTTP-01 چیلنج کا استعمال کرتا ہے، لہذا اسے پورٹ 80 پر آپ کے سرور تک پہنچنا چاہیے۔ اگر آپ کا DNS یا نیٹ ورکنگ غلط ہے، تو سرٹیفکیٹ کا اجراء ناکام ہو جائے گا۔

جینکنز: "آپ کی ریورس پراکسی سیٹنگز خراب ہو گئی ہیں۔”

درست کریں:

جینکنز URL کو https://jenkins.example.com/ پر سیٹ کریں۔
ہیڈر چیک کریں:

X-Forwarded-Proto: https

یہ کیوں کام کرتا ہے:

آپ کو معلوم ہونا چاہئے کہ جینکنز HTTPS کے پیچھے ہے۔ اس کے بغیر، غلط یو آر ایل بنائے جائیں گے (https کے بجائے HTTP)، ری ڈائریکٹس اور ویب ہکس کو توڑتے ہوئے.

13. ذہنی ماڈل: میزبان بمقابلہ کنٹینر

ترتیب میں بہت سی غلطیاں کی جاتی ہیں۔ ماسٹر فائل سسٹم کنٹینر فائل سسٹم. جدول واضح طور پر کہتا ہے:

جینکنز کنٹینر کے اندر میزبان کے ذریعہ فراہم کردہ
/var/jenkins_home ڈاکر حجم jenkins-data (جینکنز کی ترتیب، کام، راز)
/projects/... /home/developer/projects/... (پروجیکٹ ٹری)
/usr/bin/docker میزبان کی /usr/bin/docker
/usr/libexec/docker/cli-plugins/docker-compose ہوسٹ پلگ ان ( can docker compose کام)
/var/run/docker.sock میزبان ڈوکر ڈیمون (میزبان انجن پر تعمیرات ہوتی ہیں)
/etc/localtime, /etc/timezone میزبان گھڑی
~/.ssh کچھ نہیں – یہی وجہ ہے کہ SSH-to-GitHub اضافی سیٹ اپ کے بغیر کام نہیں کرتا ہے۔

ڈیبگ کرتے وقت، ہمیشہ درج ذیل سوالات پوچھیں: "یہ کمانڈ کس فائل سسٹم کے اندر چل رہا ہے، اور کیا آپ جس فائل/فولڈر کی تلاش کر رہے ہیں وہ وہاں موجود ہے؟”

14. روزانہ آپریشنز چیٹ شیٹ

# Recreate Jenkins after changing compose
cd /home/developer/Projects/projects-prod-configs
docker compose -f docker-compose.staging.yml up -d --force-recreate jenkins

# Tail Jenkins logs
docker logs -f projects-jenkins-staging

# Open a shell inside the Jenkins container
docker exec -it projects-jenkins-staging bash

# From inside the container — sanity checks
docker compose version
ls /projects/projects-prod-configs/projects-backend
git -C /projects/projects-prod-configs/projects-backend remote -v

# Manually trigger the same deploy the pipeline does
cd /projects/projects-configs/projects-backend
git pull origin staging
docker compose -f docker-compose.staging.yml up -d --build student-apigw

# Inspect Traefik routing decisions
docker logs projects-traefik-staging 2>&1 | grep -i jenkins

# Check renewed certs
docker exec projects-traefik-staging cat /etc/traefik/acme.json | head -50

15. اگلی بار چیزیں مختلف طریقے سے کریں۔

  • پری بلڈ بیس امیج تمام node_modules شامل ہیں۔ ~1500 پیکجز × 15 سروسز کے ساتھ، ہر کلین بلڈ ~22,000 ٹربالز کو دوبارہ ڈاؤن لوڈ کرتا ہے۔ مشترکہ بنیاد پر 90% کی بچت ہوتی ہے۔

  • نجی این پی ایم پراکسی چلانا اسی ڈوکر نیٹ ورک پر (Verdaccio/Nexus/GitHub پیکیج) – عدم استحکام کو ختم کریں npmjs.org یہ مکمل طور پر ختم ہو جاتا ہے.

  • ہر سروس کے لیے جینکنز فائل اگر آپ کی سروس ٹولنگ سے الگ ہے۔ ایک Jenkinsfile کے ساتھ، تمام ٹیمیں ایک ہی پائپ لائن کی تعریف کے لیے مقابلہ کرتی ہیں۔

  • تبدیلی git diff HEAD~1 HEAD کے ساتھ git diff $(git merge-base HEAD origin/staging~1) HEAD یہ اس بات کو یقینی بناتا ہے کہ آپ اسکواش کے انضمام اور زبردستی دھکے کی وجہ سے حادثاتی طور پر خدمات کو نہیں چھوڑتے ہیں۔

  • رازوں کو والٹ میں منتقل کریں۔ (HashiCorp Vault/AWS Secrets Manager/doppler)۔ جینکنز کا پی اے ٹی کام کرتا ہے، لیکن متعدد ملازمتوں میں گھومنا ایک تکلیف ہے۔

  • جینکنز میں کنفیگریشن-ایس-کوڈ (JCasC) کا استعمال لہذا جینکنز کا پورا سیٹ اپ (نوکریاں، اسناد کی تعریفیں، پلگ ان) گٹ میں رہتا ہے۔ سرور کو دوبارہ بنانا پھر ایک واحد کمانڈ آپریشن ہے۔

اختتامی خیالات

پائپ لائن خود تین مراحل پر مشتمل ہے: چیک آؤٹ → تبدیلیوں کا پتہ لگائیں → تعینات کریں۔ – لیکن سب سے زیادہ اصل پیداوار کی ترتیبات ہیں رشتہ: ریورس پراکسی، سرٹیفکیٹ، بائنڈ ماؤنٹ، اسناد، ٹائم زون، کیش بنائیں۔ ان میں سے کوئی بھی غیر ملکی نہیں ہے۔ وہ مل کر فیصلہ کرتے ہیں کہ آیا جمعہ کی دوپہر کی تعیناتی خاموشی سے سبز ہو جائے گی یا ہفتے کے آخر میں کھا جائے گی۔

ورکنگ پائپ لائن حاصل کرنے کے لیے سیکشن 1-11 پر عمل کریں۔ کام جاری رکھنے کے لیے براہ کرم سیکشن 12 کو بک مارک کریں۔

مبارک شپنگ.

اوپر تک سکرول کریں۔