مرکزی مواد پر جائیں

Docker Compose for Development: Local Infrastructure

Docker Compose for local development: PostgreSQL, Redis, Authentik, networking, health checks, volume management, and environment-specific configurations for TypeScript monorepos.

E
ECOSIRE Research and Development Team
|19 مارچ، 202612 منٹ پڑھیں2.2k الفاظ|

آن بورڈنگ کے خوشگوار تجربے ("کلون اور رن pnpm dev:infra") اور ایک تکلیف دہ ("پہلے پوسٹگری ایس کیو ایل سیٹ اپ کریں، پھر ریڈیس کو ترتیب دیں، پھر...") کے درمیان فرق اس بات پر آتا ہے کہ آپ کا ڈوکر کمپوز سیٹ اپ آپ کے بنیادی ڈھانچے کی ضروریات کو کس حد تک پورا کرتا ہے۔ ایک اچھی طرح سے تیار کردہ docker-compose.dev.yml کسی بھی…

آن بورڈنگ کے خوشگوار تجربے ("کلون اور رن pnpm dev:infra") اور ایک تکلیف دہ ("پہلے پوسٹگری ایس کیو ایل سیٹ اپ کریں، پھر ریڈیس کو ترتیب دیں، پھر...") کے درمیان فرق اس بات پر آتا ہے کہ آپ کا ڈوکر کمپوز سیٹ اپ آپ کے بنیادی ڈھانچے کی ضروریات کو کس حد تک پورا کرتا ہے۔ ایک اچھی طرح سے تیار کردہ docker-compose.dev.yml کسی بھی مشین پر کسی بھی ڈویلپر کو منٹوں میں بالکل وہی انفراسٹرکچر چلانے دیتا ہے۔

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

اہم ٹیک ویز

  • سسٹم کی تنصیبات کے ساتھ تنازعات سے بچنے کے لیے مقامی طور پر PostgreSQL (5433) کے لیے ایک نان ڈیفالٹ پورٹ استعمال کریں۔
  • سروس کے انحصار پر صحت کی جانچ "کنکشن سے انکار" اسٹارٹ اپ کی غلطیوں کو روکتی ہے۔
  • کنٹینر کے دوبارہ شروع ہونے کے درمیان نامزد والیوم ڈیٹا بیس ڈیٹا کو برقرار رکھتے ہیں - بائنڈ ماؤنٹس ونڈوز پر قابل اعتماد طریقے سے کام نہیں کرتے ہیں
  • اپنی .env.local فائل سے ماحولیاتی متغیرات کو کنٹینرز میں لوڈ کرنے کے لیے env_file استعمال کریں
  • docker-compose.dev.yml کو docker-compose.prod.yml سے الگ کریں — وہ مختلف مقاصد کو پورا کرتے ہیں۔
  • depends_on.condition: service_healthy پیٹرن اصل تیاری کا انتظار کرتا ہے، نہ کہ صرف کنٹینر کے آغاز کا
  • اختیاری خدمات (ای میل، نگرانی) کو آپٹ ان کرنے کے لیے profiles استعمال کریں۔
  • چلائیں docker compose (v2) نہیں docker-compose (v1) — پلگ ان کا نحو موجودہ ہے

مکمل ترقیاتی اسٹیک

# infrastructure/docker-compose.dev.yml
name: ecosire-dev

services:
  # ─── PostgreSQL ─────────────────────────────────────────────────
  postgres:
    image: postgres:17-alpine
    container_name: ecosire-postgres
    environment:
      POSTGRES_DB: ecosire_dev
      POSTGRES_USER: ecosire
      POSTGRES_PASSWORD: dev_password_change_in_prod
    ports:
      - "5433:5432"  # 5433 externally — avoids conflicts with system PostgreSQL
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./init-scripts:/docker-entrypoint-initdb.d  # Run SQL on first start
    command: >
      postgres
        -c shared_buffers=256MB
        -c effective_cache_size=1GB
        -c work_mem=16MB
        -c maintenance_work_mem=128MB
        -c checkpoint_completion_target=0.9
        -c wal_buffers=16MB
        -c max_connections=100
        -c log_min_duration_statement=100
        -c log_statement=ddl
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ecosire -d ecosire_dev"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 10s
    restart: unless-stopped

  # ─── Redis ──────────────────────────────────────────────────────
  redis:
    image: redis:7-alpine
    container_name: ecosire-redis
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data
    command: >
      redis-server
        --maxmemory 512mb
        --maxmemory-policy allkeys-lru
        --appendonly yes
        --appendfsync everysec
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped

  # ─── Authentik (Identity Provider) ──────────────────────────────
  authentik-server:
    image: ghcr.io/goauthentik/server:2024.12
    container_name: ecosire-authentik
    command: server
    environment:
      AUTHENTIK_REDIS__HOST: redis
      AUTHENTIK_POSTGRESQL__HOST: postgres
      AUTHENTIK_POSTGRESQL__USER: ecosire
      AUTHENTIK_POSTGRESQL__PASSWORD: dev_password_change_in_prod
      AUTHENTIK_POSTGRESQL__NAME: authentik
      AUTHENTIK_SECRET_KEY: dev-secret-key-change-in-production-32chars
      AUTHENTIK_ERROR_REPORTING__ENABLED: "false"
      AUTHENTIK_DISABLE_STARTUP_ANALYTICS: "true"
    volumes:
      - authentik_media:/media
      - authentik_certs:/certs
    ports:
      - "9000:9000"  # HTTP
      - "9443:9443"  # HTTPS
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
    healthcheck:
      test: ["CMD-SHELL", "ak healthcheck"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 60s  # Authentik takes time to initialize
    restart: unless-stopped

  authentik-worker:
    image: ghcr.io/goauthentik/server:2024.12
    container_name: ecosire-authentik-worker
    command: worker
    environment:
      AUTHENTIK_REDIS__HOST: redis
      AUTHENTIK_POSTGRESQL__HOST: postgres
      AUTHENTIK_POSTGRESQL__USER: ecosire
      AUTHENTIK_POSTGRESQL__PASSWORD: dev_password_change_in_prod
      AUTHENTIK_POSTGRESQL__NAME: authentik
      AUTHENTIK_SECRET_KEY: dev-secret-key-change-in-production-32chars
    volumes:
      - authentik_media:/media
      - authentik_certs:/certs
      - /var/run/docker.sock:/var/run/docker.sock  # For Authentik's proxy
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
    restart: unless-stopped

  # ─── Mailpit (Email Testing) ─────────────────────────────────────
  mailpit:
    image: axllent/mailpit:latest
    container_name: ecosire-mailpit
    ports:
      - "1025:1025"  # SMTP
      - "8025:8025"  # Web UI
    environment:
      MP_MAX_MESSAGES: 200
      MP_SMTP_AUTH_ACCEPT_ANY: true
      MP_SMTP_AUTH_ALLOW_INSECURE: true
    restart: unless-stopped
    profiles:
      - email  # Optional — use `docker compose --profile email up`

  # ─── pgAdmin (Database GUI) ─────────────────────────────────────
  pgadmin:
    image: dpage/pgadmin4:latest
    container_name: ecosire-pgadmin
    environment:
      PGADMIN_DEFAULT_EMAIL: admin@local.dev
      PGADMIN_DEFAULT_PASSWORD: admin
      PGADMIN_CONFIG_SERVER_MODE: "False"
      PGADMIN_CONFIG_MASTER_PASSWORD_REQUIRED: "False"
    ports:
      - "5050:80"
    volumes:
      - pgadmin_data:/var/lib/pgadmin
    depends_on:
      postgres:
        condition: service_healthy
    restart: unless-stopped
    profiles:
      - tools  # Optional

networks:
  default:
    name: ecosire-dev-network

volumes:
  postgres_data:
    name: ecosire-postgres-data
  redis_data:
    name: ecosire-redis-data
  authentik_media:
    name: ecosire-authentik-media
  authentik_certs:
    name: ecosire-authentik-certs
  pgadmin_data:
    name: ecosire-pgadmin-data

Package.json اسکرپٹس

ڈوکر کمپوز کمانڈز کو اپنے monorepo اسکرپٹس میں وائر کریں:

{
  "scripts": {
    "dev:infra": "docker compose -f infrastructure/docker-compose.dev.yml up -d",
    "dev:infra:down": "docker compose -f infrastructure/docker-compose.dev.yml down",
    "dev:infra:logs": "docker compose -f infrastructure/docker-compose.dev.yml logs -f",
    "dev:infra:reset": "docker compose -f infrastructure/docker-compose.dev.yml down -v && pnpm dev:infra",
    "dev:infra:email": "docker compose -f infrastructure/docker-compose.dev.yml --profile email up -d",
    "dev:infra:tools": "docker compose -f infrastructure/docker-compose.dev.yml --profile tools up -d"
  }
}

--profile جھنڈا اختیاری خدمات (Mailpit کے ساتھ ای میل ٹیسٹنگ، pgAdmin کے ساتھ ڈیٹا بیس GUI) کو اس وقت تک غیر فعال رہنے دیتا ہے جب تک کہ واضح طور پر درخواست نہ کی جائے۔


ڈیٹا بیس انیشیلائزیشن اسکرپٹس

ایس کیو ایل فائلوں کو infrastructure/init-scripts/ میں رکھیں - وہ پہلے کنٹینر کے آغاز پر چلتی ہیں:

-- infrastructure/init-scripts/01-create-databases.sql
-- Create all databases Authentik needs separately from the app DB
CREATE DATABASE authentik;
GRANT ALL PRIVILEGES ON DATABASE authentik TO ecosire;

-- Create test database for CI
CREATE DATABASE ecosire_test;
GRANT ALL PRIVILEGES ON DATABASE ecosire_test TO ecosire;
-- infrastructure/init-scripts/02-extensions.sql
-- Enable PostgreSQL extensions
\c ecosire_dev;
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS "pg_trgm";  -- Trigram search
CREATE EXTENSION IF NOT EXISTS "btree_gin"; -- Composite GIN indexes

\c ecosire_test;
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

ابتدائی اسکرپٹ حروف تہجی کی ترتیب میں چلتے ہیں۔ \c database_name psql metacommand فعال ڈیٹا بیس کو تبدیل کرتا ہے۔


ماحولیاتی متغیرات کا انٹیگریشن

آپ کی درخواست مونوریپو روٹ میں .env.local سے پڑھتی ہے۔ Docker سروسز کو یہ جاننے کی ضرورت ہے کہ سروس کے ناموں کا استعمال کرتے ہوئے ایک دوسرے سے کیسے جڑنا ہے (localhost نہیں):

# .env.local (monorepo root)

# PostgreSQL — use 5433 externally (host) or 5432 internally (container network)
DATABASE_URL=postgresql://ecosire:dev_password_change_in_prod@localhost:5433/ecosire_dev

# Redis
REDIS_URL=redis://localhost:6379

# Authentik — use 9000 for external calls from your dev machine
AUTHENTIK_URL=http://localhost:9000
# Use service name for server-to-server calls within Docker network
AUTHENTIK_INTERNAL_URL=http://authentik-server:9000

# Email (Mailpit SMTP)
SMTP_HOST=localhost
SMTP_PORT=1025
SMTP_SECURE=false

# Application
NODE_ENV=development

Docker کے اندر چلنے والی ایپلیکیشنز کے لیے جنہیں دوسری سروسز سے بات کرنے کی ضرورت ہے، سروس کے نام استعمال کریں۔ آپ کی میزبان مشین پر چلنے والی ایپلیکیشنز کے لیے (NestJS, Next.js dev mode میں)، localhost استعمال کریں ہوسٹ میپڈ پورٹس کے ساتھ۔


صحت کی گہرائی میں غوطہ لگاتا ہے۔

صحت کی جانچ پڑتال شروع ہونے والی ناکامیوں کو روکتی ہے۔ depends_on.condition: service_healthy اصل تیاری کا انتظار کرتا ہے، نہ کہ صرف کنٹینر کے آغاز کا:

# Without health checks — can fail because PostgreSQL isn't ready
depends_on:
  - postgres

# With health checks — waits for PostgreSQL to accept connections
depends_on:
  postgres:
    condition: service_healthy

آپ کی اپنی خدمات کے لیے حسب ضرورت صحت کی جانچ:

// apps/api/src/health/health.controller.ts
@Get()
@Public()
@HealthCheck()
async check() {
  return this.health.check([
    () => this.db.isHealthy('database'),
    () => this.redis.isHealthy('redis'),
  ]);
}
# If your API is also dockerized
api:
  image: ecosire-api:latest
  healthcheck:
    test: ["CMD", "curl", "-f", "http://localhost:3001/api/health"]
    interval: 30s
    timeout: 10s
    retries: 3
    start_period: 30s

والیوم مینجمنٹ

نامزد والیوم دوبارہ شروع ہونے کے درمیان ڈیٹا برقرار رہتا ہے۔ ہر حجم کی قسم کو کب استعمال کرنا ہے اس کو سمجھیں:

قسماستقامتکارکردگیکے لیے استعمال کریں
نامزد والیومجی ہاںبہترینڈیٹا بیس ڈیٹا
بائنڈ ماؤنٹجی ہاںاچھا (Linux)، ناقص (macOS)ماخذ کوڈ گرم دوبارہ لوڈ
tmpfsنہیںبہترینعارضی فائلیں، راز
# Use bind mounts for source code (enables hot reload)
volumes:
  - ./apps/api/src:/app/src  # Code changes reflected immediately

# Use named volumes for data
volumes:
  - postgres_data:/var/lib/postgresql/data

# Use tmpfs for ephemeral data
volumes:
  - type: tmpfs
    target: /tmp

ڈوکر ڈیسک ٹاپ کے ساتھ میک او ایس پر، بائنڈ ماونٹس gRPC FUSE استعمال کرتے ہیں جو لینکس کے مقابلے میں نمایاں طور پر سست ہے۔ NestJS اور Next.js dev سرورز کے لیے، مقامی فائل سسٹم کی کارکردگی حاصل کرنے کے لیے انہیں براہ راست اپنی میزبان مشین پر چلائیں (ڈوکر میں نہیں)۔


پروڈکشن ڈوکر کمپوز

پروڈکشن کمپوز فائل ساختی طور پر مختلف ہے — کوئی مقامی بندرگاہیں نہیں، پالیسیاں دوبارہ شروع کریں، پیداواری وسائل کی حدود:

# infrastructure/docker-compose.prod.yml
name: ecosire-prod

services:
  postgres:
    image: postgres:17-alpine
    environment:
      POSTGRES_DB: ${POSTGRES_DB}
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    # No port mapping — only accessible within Docker network
    restart: always
    deploy:
      resources:
        limits:
          memory: 2G
        reservations:
          memory: 512M

  redis:
    image: redis:7-alpine
    command: redis-server --requirepass ${REDIS_PASSWORD} --maxmemory 1gb
    volumes:
      - redis_data:/data
    restart: always
    # No port mapping — internal only

volumes:
  postgres_data:
  redis_data:

پیداوار بیرونی طور پر بندرگاہوں کو بے نقاب نہیں کرتی ہے - ایپلیکیشنز اندرونی ڈوکر نیٹ ورک کے ذریعے جڑتی ہیں۔ Nginx بیرونی ٹریفک کو ہینڈل کرتا ہے۔


مشترکہ نقصانات اور حل

خطرہ 1: سسٹم سروسز کے ساتھ پورٹ کا تنازعہ

PostgreSQL، Redis، اور دیگر خدمات اکثر سسٹم سروسز کے طور پر چلتی ہیں۔ ترقی میں ہمیشہ غیر معیاری بندرگاہوں کا نقشہ بنائیں:

  • PostgreSQL: 5433:5432 (نہیں 5432:5432)
  • Redis: 6379:6379 رکھیں (شاذ و نادر ہی تنازعات)
  • یہ چیک کرنے کے لیے lsof -i :5432 چلائیں کہ ڈیفالٹ پورٹ کیا استعمال کر رہا ہے۔

خطرہ 2: لینکس پر حجم کی اجازت کے مسائل

لینکس پر ڈوکر والیوم پہلے سے طے شدہ طور پر روٹ کی ملکیت کا استعمال کرتے ہیں۔ اگر آپ کا کنٹینر صارف نان روٹ ہے تو صحیح ملکیت سیٹ کریں:

postgres:
  image: postgres:17-alpine
  user: "999:999"  # postgres user's UID:GID
  # Or use init container to fix permissions

خطرہ 3: مستند آغاز میں 60+ سیکنڈ لگتے ہیں

Authentik پہلی شروعات پر ڈیٹا بیس کی منتقلی چلاتا ہے۔ صحت کی جانچ میں start_period: 60s اسے وقت دیتا ہے۔ اگر انحصاری خدمات Authentik کے تیار ہونے سے پہلے شروع ہو جاتی ہیں، تو وہ ناکام ہو جائیں گی۔ service_healthy شرط استعمال کریں اور اسے کافی start_period دیں۔

خطرہ 4: میک پر ڈوکر ڈیسک ٹاپ وسائل کی حدیں

ڈیفالٹ ڈوکر ڈیسک ٹاپ 2 سی پی یو اور 2 جی بی ریم مختص کرتا ہے - پوسٹگری ایس کیو ایل + ریڈیس + مستند بیک وقت چلانے کے لئے کافی نہیں ہے۔ ڈوکر ڈیسک ٹاپ سیٹنگز > وسائل کو کم از کم 4 سی پی یوز اور 6 جی بی ریم تک بڑھا دیں۔

خطرہ 5: docker-compose بمقابلہ docker compose

پرانا docker-compose (v1، Python میں لکھا ہوا) فرسودہ ہے۔ docker compose (v2، پلگ ان) استعمال کریں۔ اپنا ورژن چیک کریں: docker compose version۔ اگر آپ Docker Compose version v2.x.x دیکھتے ہیں، تو آپ v2 استعمال کر رہے ہیں۔


اکثر پوچھے گئے سوالات

کیا مجھے ڈوکر میں اپنی ایپلیکیشن سروسز (NestJS, Next.js) کو ڈیولپمنٹ کے دوران چلانا چاہیے؟

عام طور پر نہیں۔ ڈوکر کا استعمال صرف بنیادی ڈھانچے کی خدمات (ڈیٹا بیس، کیشز، شناخت فراہم کرنے والے) کے لیے کریں جو مستحکم ہیں اور انہیں بار بار دوبارہ شروع کرنے کی ضرورت نہیں ہے۔ استثناء یہ ہے کہ اگر آپ کی درخواست میں مقامی انحصار ہے جو آپ کے ترقیاتی OS اور پیداواری ماحول کے درمیان مختلف ہے۔

میں ڈوکر کمپوز ورک فلو میں ڈیٹا بیس کی منتقلی کو کیسے ہینڈل کروں؟

انفراسٹرکچر شروع کرنے کے بعد اپنی میزبان مشین سے ہجرتیں چلائیں: pnpm dev:infra && pnpm db:migrate۔ ڈیولپمنٹ کے دوران ڈوکر کنٹینر کے اندر ہجرت نہ چلائیں - آپ ٹائپ چیکنگ اور IDE انٹیگریشن سے محروم ہو جاتے ہیں جو بوندا باندی کی منتقلی کو محفوظ بناتا ہے۔ ابتدائی ڈیٹا بیس بنانے کے لیے، Docker کی initdb.d اسکرپٹس استعمال کریں۔

میں اپنے مقامی ڈوکر والیوم کا بیک اپ اور بحال کیسے کروں؟

بیک اپ کے لیے docker run --rm -v postgres_data:/data -v $(pwd):/backup alpine tar czf /backup/postgres-backup.tar.gz /data استعمال کریں۔ tar xzf کا استعمال کرتے ہوئے اسی نقطہ نظر کے ساتھ بحال کریں۔ ترقی کے لیے، آپ pg_dump کے ساتھ بھی ڈمپ کر سکتے ہیں اور psql کے ساتھ بحال کر سکتے ہیں کیونکہ آپ کے پاس پورٹ بے نقاب ہے۔

میں ٹیم کے دوسرے ممبران کے ساتھ Docker Compose اسٹیٹ کا اشتراک کیسے کروں؟

ڈوکر کمپوز فائل گٹ کے ذریعے شیئر کی گئی ہے، لیکن حجم میں موجود ڈیٹا مقامی ہے۔ ہر ڈویلپر ایک خالی ڈیٹا بیس سے شروع ہوتا ہے اور اسے آباد کرنے کے لیے ہجرت/بیج چلاتا ہے۔ مسلسل ٹیسٹ ڈیٹا بنانے کے لیے سیڈ اسکرپٹس (ریپو پر پابند) استعمال کریں۔ مشترکہ docker-compose.dev.yml یقینی بناتا ہے کہ ہر کوئی ایک جیسے سروس ورژن اور کنفیگریشن کا استعمال کرتا ہے۔

ڈیولپمنٹ میں اصلی ای میل کے بجائے میل پٹ کیوں استعمال کریں؟

میل پٹ ایک مقامی SMTP سرور ہے جو تمام باہر جانے والے ای میل کو کیپچر کرتا ہے اور انہیں دیکھنے کے لیے ویب UI فراہم کرتا ہے۔ یہ ترقی کے دوران حقیقی صارفین کو غلطی سے حقیقی ای میلز بھیجنے سے روکتا ہے، SMTP اسناد کی ضرورت نہیں ہے، اور آپ کو اپنے ان باکس کو چیک کیے بغیر ای میل ٹیمپلیٹس کی تصدیق کرنے دیتا ہے۔ اپنی ایپ کو SMTP_HOST=localhost SMTP_PORT=1025 استعمال کرنے کے لیے کنفیگر کریں اور کیپچر کی گئی ای میلز دیکھنے کے لیے http://localhost:8025 ملاحظہ کریں۔


اگلے اقدامات

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

اپنے مقامی ترقیاتی انفراسٹرکچر کو ڈیزائن کرنے یا پیداوار کے لیے اپنی درخواست کو کنٹینرائز کرنے میں مدد کی ضرورت ہے؟ یہ دیکھنے کے لیے کہ ہم کس طرح مدد کر سکتے ہیں ہماری DevOps سروسز کو دریافت کریں۔

E

تحریر

ECOSIRE Research and Development Team

تکنیکی تحریر

ECOSIRE کی تکنیکی تحریر کی ٹیم Odoo ERP، Shopify ای کامرس، AI ایجنٹس، Power BI اینالیٹکس، GoHighLevel آٹومیشن اور انٹرپرائز سافٹ ویئر کے بہترین طریقوں پر لکھتی ہے۔ ہماری گائیڈز کاروباروں کو سوچ سمجھ کر ٹیکنالوجی کے فیصلے کرنے میں مدد دیتی ہیں۔

ECOSIRE

ECOSIRE کے ساتھ اپنا کاروبار بڑھائیں

ERP، ای کامرس، AI، تجزیات، اور آٹومیشن میں انٹرپرائز حل۔