उत्पादन ईआरपी परिनियोजन के लिए डॉकर: एक पूर्ण संचालन गाइड
डॉकर कंटेनरों में ईआरपी सिस्टम चलाने वाले संगठन पारंपरिक बेयर-मेटल तैनाती की तुलना में 73% तेज तैनाती चक्र और 45% कम पर्यावरण-संबंधी घटनाओं की रिपोर्ट करते हैं। डॉकर ईआरपी तैनाती को एक बहु-दिवसीय, त्रुटि-प्रवण प्रक्रिया से एक दोहराने योग्य, संस्करण-नियंत्रित ऑपरेशन में बदल देता है जिसे टीम का कोई भी सदस्य निष्पादित कर सकता है।
यह मार्गदर्शिका उत्पादन डॉकर वातावरण में ओडू, कस्टम नेस्टजेएस बैकएंड और नेक्स्ट.जेएस फ्रंटएंड सहित एंटरप्राइज़ ईआरपी सिस्टम चलाने के पूरे जीवनचक्र को कवर करती है।
मुख्य बातें
- मल्टी-स्टेज डॉकर बिल्ड ईआरपी कंटेनर छवि आकार को 60-80% तक कम कर देता है, जिससे तैनाती की गति में सुधार होता है
- डॉकर कंपोज़ ईआरपी, डेटाबेस, रिवर्स प्रॉक्सी और कैश सेवाओं को एक एकल तैनाती योग्य इकाई के रूप में व्यवस्थित करता है
- नामित वॉल्यूम और बाइंड माउंट कंटेनर पुनरारंभ और अपग्रेड के दौरान डेटा दृढ़ता सुनिश्चित करते हैं
- स्वास्थ्य जांच और पुनरारंभ नीतियां क्षणिक विफलताओं से स्वचालित पुनर्प्राप्ति प्रदान करती हैं
डॉकरीकृत ईआरपी स्टैक की वास्तुकला
एक उत्पादन ईआरपी परिनियोजन में आम तौर पर पांच या अधिक परस्पर जुड़ी सेवाएं शामिल होती हैं। डॉकर कंपोज़ इन सेवाओं को घोषणात्मक रूप से परिभाषित करता है, जिससे पूरे वातावरण में लगातार तैनाती सुनिश्चित होती है।
सेवा टोपोलॉजी
मानक डॉकरीकृत ईआरपी स्टैक:
- एप्लिकेशन सर्वर: ईआरपी रनटाइम (ओडू, नेस्टजेएस, या समान)
- डेटाबेस: लगातार वॉल्यूम स्टोरेज के साथ PostgreSQL
- रिवर्स प्रॉक्सी: Nginx SSL समाप्ति, स्थिर फ़ाइलें और अनुरोध रूटिंग को संभालता है
- कैश लेयर: सेशन स्टोरेज, जॉब क्यू और एप्लिकेशन कैशिंग के लिए रेडिस
- बैकग्राउंड वर्कर: ईमेल, रिपोर्ट और एकीकरण के लिए एसिंक जॉब प्रोसेसर
वैकल्पिक सेवाओं में बैकअप कंटेनर (क्रोन पर pg_dump), मॉनिटरिंग साइडकार (प्रोमेथियस निर्यातक), और लॉग शिपर्स (फ्लुएंट बिट) शामिल हैं।
ईआरपी अनुप्रयोगों के लिए मल्टी-स्टेज बिल्ड
डॉकर छवियों के उत्पादन के लिए मल्टी-स्टेज बिल्ड आवश्यक हैं। वे रनटाइम से बिल्ड-टाइम निर्भरता को अलग करते हैं, दुबली, सुरक्षित छवियां बनाते हैं।
NestJS बैकएंड बिल्ड
# Stage 1: Install dependencies and build
FROM node:20-alpine AS builder
WORKDIR /app
# Install pnpm
RUN corepack enable
# Copy workspace configuration
COPY pnpm-lock.yaml pnpm-workspace.yaml package.json ./
COPY packages/ ./packages/
COPY apps/api/package.json ./apps/api/
# Install dependencies
RUN pnpm install --frozen-lockfile
# Copy source and build
COPY apps/api/ ./apps/api/
RUN pnpm --filter @ecosire/db build
RUN pnpm --filter @ecosire/types build
RUN pnpm --filter @ecosire/validators build
RUN pnpm --filter @ecosire/api build
# Stage 2: Production runtime
FROM node:20-alpine AS runner
WORKDIR /app
RUN addgroup -g 1001 -S appgroup && \
adduser -S appuser -u 1001 -G appgroup
COPY --from=builder --chown=appuser:appgroup /app/apps/api/dist ./dist
COPY --from=builder --chown=appuser:appgroup /app/node_modules ./node_modules
COPY --from=builder --chown=appuser:appgroup /app/apps/api/package.json ./
USER appuser
EXPOSE 3001
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:3001/health || exit 1
CMD ["node", "dist/main.js"]
नेक्स्ट.जेएस फ्रंटएंड बिल्ड
FROM node:20-alpine AS builder
WORKDIR /app
RUN corepack enable
COPY pnpm-lock.yaml pnpm-workspace.yaml package.json ./
COPY packages/ ./packages/
COPY apps/web/package.json ./apps/web/
RUN pnpm install --frozen-lockfile
COPY apps/web/ ./apps/web/
RUN pnpm --filter @ecosire/web build
FROM node:20-alpine AS runner
WORKDIR /app
RUN addgroup -g 1001 -S appgroup && \
adduser -S appuser -u 1001 -G appgroup
COPY --from=builder --chown=appuser:appgroup /app/apps/web/.next/standalone ./
COPY --from=builder --chown=appuser:appgroup /app/apps/web/.next/static ./.next/static
COPY --from=builder --chown=appuser:appgroup /app/apps/web/public ./public
USER appuser
EXPOSE 3000
ENV NODE_ENV=production
CMD ["node", "server.js"]
छवि आकार तुलना
| निर्माण प्रकार | छवि का आकार | निर्माण समय | |----|----|----|----| | एकल-चरण (पूर्ण नोड छवि) | 1.8 जीबी | 4 मिनट | | एकल-चरण (अल्पाइन) | 650 एमबी | 3.5 मिनट | | मल्टी-स्टेज (अल्पाइन) | 180 एमबी | 5 मिनट | | मल्टी-स्टेज + प्रून्ड डिप्स | 120 एमबी | 5.5 मिनट |
5.5 मिनट का निर्माण समय स्वीकार्य है क्योंकि यह सीआई में होता है, डेवलपर मशीनों पर नहीं।
उत्पादन के लिए डॉकर कंपोज़
version: "3.8"
services:
api:
build:
context: .
dockerfile: apps/api/Dockerfile
environment:
- DATABASE_URL=postgresql://app:${DB_PASSWORD}@db:5432/ecosire
- REDIS_URL=redis://redis:6379
- NODE_ENV=production
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
restart: unless-stopped
networks:
- backend
- frontend
web:
build:
context: .
dockerfile: apps/web/Dockerfile
environment:
- API_URL=http://api:3001
- NODE_ENV=production
depends_on:
- api
restart: unless-stopped
networks:
- frontend
db:
image: postgres:17-alpine
environment:
POSTGRES_USER: app
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: ecosire
volumes:
- postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U app -d ecosire"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
networks:
- backend
redis:
image: redis:7-alpine
command: redis-server --requirepass ${REDIS_PASSWORD} --maxmemory 256mb --maxmemory-policy allkeys-lru
volumes:
- redis-data:/data
healthcheck:
test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "ping"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
networks:
- backend
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./infrastructure/nginx/production.conf:/etc/nginx/conf.d/default.conf:ro
- ./certbot/conf:/etc/letsencrypt:ro
- ./certbot/www:/var/www/certbot:ro
depends_on:
- web
- api
restart: unless-stopped
networks:
- frontend
volumes:
postgres-data:
redis-data:
networks:
frontend:
backend:
नेटवर्क अलगाव
उपरोक्त कॉन्फ़िगरेशन दो नेटवर्क का उपयोग करता है:
- फ्रंटएंड: नग्नेक्स, वेब और एपीआई (दोनों के लिए नग्नेक्स प्रॉक्सी)
- बैकएंड: एपीआई, डेटाबेस और रेडिस
डेटाबेस और Redis Nginx कंटेनर या बाहरी नेटवर्क से पहुंच योग्य नहीं हैं। यह नेटवर्क विभाजन एक महत्वपूर्ण सुरक्षा अभ्यास है।
वॉल्यूम प्रबंधन और डेटा दृढ़ता
वॉल्यूम डॉकराइज़्ड ईआरपी परिनियोजन का सबसे महत्वपूर्ण हिस्सा है। अपना वॉल्यूम खो दें और आप अपना डेटा खो दें।
वॉल्यूम प्रकार
| प्रकार | केस का प्रयोग करें | दृढ़ता | प्रदर्शन |
|---|---|---|---|
| नामित खंड | डेटाबेस, रेडिस | कंटेनर हटाने से बच जाता है | मूल फ़ाइल सिस्टम गति |
| बाइंड माउंट | कॉन्फ़िग फ़ाइलें, लॉग | होस्ट फ़ाइल सिस्टम से बंधा हुआ | मूल फ़ाइल सिस्टम गति |
| tmpfs माउंट | अस्थायी फ़ाइलें, रहस्य | केवल मेमोरी, पुनरारंभ करने पर खो गई | मेमोरी स्पीड |
डॉकर वॉल्यूम के लिए बैकअप रणनीति
#!/bin/bash
# backup-volumes.sh - Run via cron every 6 hours
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/opt/backups"
# Stop the application briefly for consistent backup
docker compose stop api web
# Backup PostgreSQL
docker compose exec -T db pg_dump -U app ecosire | gzip > "$BACKUP_DIR/db_$TIMESTAMP.sql.gz"
# Backup Redis
docker compose exec -T redis redis-cli -a "$REDIS_PASSWORD" BGSAVE
sleep 5
docker cp $(docker compose ps -q redis):/data/dump.rdb "$BACKUP_DIR/redis_$TIMESTAMP.rdb"
# Restart services
docker compose start api web
# Upload to S3
aws s3 sync "$BACKUP_DIR" "s3://company-backups/docker-volumes/" --exclude "*.tmp"
# Retain 30 days locally
find "$BACKUP_DIR" -name "*.gz" -mtime +30 -delete
find "$BACKUP_DIR" -name "*.rdb" -mtime +30 -delete
स्वास्थ्य जांच और पुनरारंभ नीतियां
उत्पादन कंटेनरों को अपने स्वास्थ्य की स्वयं रिपोर्ट देनी होगी और विफलताओं से स्वचालित रूप से उबरना होगा।
एप्लिकेशन स्वास्थ्य जांच समापन बिंदु
// health.controller.ts
@Controller('health')
export class HealthController {
constructor(
private readonly db: DatabaseService,
private readonly redis: RedisService,
) {}
@Get()
@Public()
async check() {
const checks = {
database: await this.checkDatabase(),
redis: await this.checkRedis(),
uptime: process.uptime(),
memory: process.memoryUsage(),
};
const healthy = checks.database && checks.redis;
return { status: healthy ? 'ok' : 'degraded', checks };
}
private async checkDatabase(): Promise<boolean> {
try {
await this.db.execute('SELECT 1');
return true;
} catch {
return false;
}
}
private async checkRedis(): Promise<boolean> {
try {
await this.redis.ping();
return true;
} catch {
return false;
}
}
}
नीति चयन पुनः आरंभ करें
| नीति | व्यवहार | केस का प्रयोग करें |
|---|---|---|
no | कभी पुनः आरंभ न करें | विकास, एकमुश्त कार्य |
on-failure | केवल गैर-शून्य निकास पर पुनः प्रारंभ करें | श्रमिक, बैच नौकरियां |
always | हमेशा पुनरारंभ करें (डॉकर डेमॉन पुनरारंभ सहित) | उत्पादन सेवाएँ |
unless-stopped | always की तरह लेकिन मैन्युअल स्टॉप का सम्मान करता है | अधिकांश उत्पादन सेवाएँ |
उत्पादन सेवाओं के लिए unless-stopped का उपयोग करें। यह सुनिश्चित करता है कि सर्वर रीबूट या डॉकर डेमॉन पुनरारंभ होने के बाद कंटेनर पुनरारंभ हो, लेकिन रखरखाव के दौरान मैन्युअल docker compose stop कमांड का सम्मान करता है।
परिनियोजन वर्कफ़्लो
डॉकर कंपोज़ के साथ रोलिंग अपडेट
#!/bin/bash
# deploy.sh - Zero-downtime deployment
set -e
echo "Pulling latest code..."
git pull origin main
echo "Building new images..."
docker compose build --no-cache api web
echo "Rolling update - API first..."
docker compose up -d --no-deps api
sleep 10
# Verify API health
if ! curl -sf http://localhost:3001/health > /dev/null; then
echo "API health check failed, rolling back..."
docker compose up -d --no-deps api
exit 1
fi
echo "Rolling update - Web..."
docker compose up -d --no-deps web
sleep 5
# Verify Web health
if ! curl -sf http://localhost:3000 > /dev/null; then
echo "Web health check failed, rolling back..."
docker compose up -d --no-deps web
exit 1
fi
echo "Deployment complete!"
docker compose ps
डेटाबेस माइग्रेशन सुरक्षा
एप्लिकेशन स्टार्टअप के अंदर कभी भी माइग्रेशन न चलाएं। इसके बजाय, उन्हें एक अलग चरण के रूप में चलाएँ:
# Run migrations before deploying new containers
docker compose run --rm api npx drizzle-kit push
# Then deploy the new version
docker compose up -d
यह पैटर्न सुनिश्चित करता है कि यदि कोई माइग्रेशन विफल हो जाता है, तो पुराना संस्करण अप्रभावित चलता रहेगा।
लॉगिंग और डिबगिंग
केंद्रीकृत लॉगिंग
# Add to docker-compose.yml
services:
api:
logging:
driver: json-file
options:
max-size: "10m"
max-file: "5"
labels: "service"
labels:
service: "ecosire-api"
सामान्य डिबगिंग कमांड
# View logs for a specific service
docker compose logs -f api --tail 100
# Execute a shell inside a running container
docker compose exec api sh
# View resource usage
docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}"
# Inspect container networking
docker compose exec api ping db
# View container environment variables
docker compose exec api env | sort
अक्सर पूछे जाने वाले प्रश्न
हम डॉकर में डेटाबेस माइग्रेशन को कैसे संभालते हैं?
नए एप्लिकेशन कंटेनर तैनात करने से पहले माइग्रेशन को एक अलग चरण के रूप में चलाएँ। तैनाती-पूर्व चरण के रूप में docker compose run --rm api npx drizzle-kit push (या अपने ORM के माइग्रेशन कमांड) का उपयोग करें। कंटेनर स्टार्टअप कमांड में कभी भी माइग्रेशन निष्पादन को एम्बेड न करें --- एक असफल माइग्रेशन को वर्तमान संस्करण को चलने से नहीं रोकना चाहिए।
डॉकर का प्रदर्शन ओवरहेड क्या है?
लिनक्स पर, डॉकर का प्रदर्शन ओवरहेड नगण्य है --- आमतौर पर सीपीयू-बाउंड वर्कलोड के लिए 2% से कम और I/O-बाउंड वर्कलोड के लिए कोई मापने योग्य अंतर नहीं है। MacOS और Windows पर, डॉकर 5-15% ओवरहेड जोड़ते हुए एक वर्चुअल मशीन के अंदर चलता है। उत्पादन के लिए (जो लिनक्स होना चाहिए), डॉकर एक सार्थक प्रदर्शन चिंता का विषय नहीं है।
हम डॉकर में रहस्यों का प्रबंधन कैसे करते हैं?
Dockerfiles या docker-compose.yml फ़ाइलों में कभी भी रहस्य न डालें। संस्करण नियंत्रण, डॉकर सीक्रेट्स (स्वार्म मोड के लिए), या बाहरी सीक्रेट मैनेजर्स (AWS सीक्रेट्स मैनेजर, हाशीकॉर्प वॉल्ट) से बाहर रखे गए पर्यावरण परिवर्तनीय फ़ाइलों (.env) का उपयोग करें। डॉकर कंपोज़ के लिए, प्रोजेक्ट रूट पर एक .env फ़ाइल सबसे सरल तरीका है।
क्या हमें डॉकर झुंड या कुबेरनेट्स का उपयोग करना चाहिए?
अधिकांश एसएमबी ईआरपी परिनियोजन के लिए, डॉकर कंपोज़ पर्याप्त है। डॉकर झुंड न्यूनतम जटिलता ओवरहेड के साथ मल्टी-होस्ट ऑर्केस्ट्रेशन जोड़ता है। जब आपको ऑटो-स्केलिंग, जटिल नेटवर्किंग नीतियों या सर्विस मेश क्षमताओं की आवश्यकता हो तो कुबेरनेट्स उपयुक्त है। निर्णय रूपरेखाओं के लिए हमारी कुबेरनेट्स स्केलिंग गाइड और माइक्रोसर्विसेज आर्किटेक्चर गाइड देखें।
हम डॉकर में ओडू कस्टम मॉड्यूल को कैसे संभालते हैं?
अपने ऐडऑन निर्देशिका की ओर इंगित करते हुए कस्टम मॉड्यूल को बाइंड माउंट वॉल्यूम के रूप में माउंट करें। Dockerfile में, सुनिश्चित करें कि ऐडऑन पथ odoo.conf में कॉन्फ़िगर किया गया है। सीआई/सीडी के लिए, एक कस्टम डॉकर छवि बनाएं जो संस्करण स्थिरता सुनिश्चित करते हुए आपके मॉड्यूल में तैयार हो। Odoo-विशिष्ट कॉन्फ़िगरेशन के लिए हमारी मौजूदा Docker Odoo परिनियोजन मार्गदर्शिका देखें।
आगे क्या आता है
डॉकर आधुनिक ईआरपी परिनियोजन की नींव है। एक बार जब आपका कंटेनरीकृत स्टैक स्थिर हो जाए, तो पूरी तरह से स्वचालित संचालन पाइपलाइन बनाने के लिए [शून्य-डाउनटाइम परिनियोजन रणनीतियों] (/blog/zero-downtime-deployments), [उत्पादन निगरानी] (/blog/monitoring-alerting-setup), और [कोड के रूप में बुनियादी ढांचे] (/blog/infrastructure-as-code-terraform) का पता लगाएं।
डॉकर परिनियोजन परामर्श के लिए ECOSIRE से संपर्क करें, या पूरी तरह से प्रबंधित कंटेनरीकृत ईआरपी परिनियोजन के लिए हमारी Odoo कार्यान्वयन सेवाओं का पता लगाएं।
ECOSIRE द्वारा प्रकाशित - व्यवसायों को आत्मविश्वास के साथ एंटरप्राइज़ सॉफ़्टवेयर तैनात करने में मदद करना।
लेखक
ECOSIRE Research and Development Team
ECOSIRE में एंटरप्राइज़-ग्रेड डिजिटल उत्पाद बना रहे हैं। Odoo एकीकरण, ई-कॉमर्स ऑटोमेशन, और AI-संचालित व्यावसायिक समाधानों पर अंतर्दृष्टि साझा कर रहे हैं।
संबंधित लेख
Accounts Payable Automation: Cut Processing Costs by 80 Percent
Implement accounts payable automation to reduce invoice processing costs from $15 to $3 per invoice with OCR, three-way matching, and ERP workflows.
AI in Accounting and Bookkeeping Automation: The CFO Implementation Guide
Automate accounting with AI for invoice processing, bank reconciliation, expense management, and financial reporting. 85% faster close cycles.
API Gateway Patterns and Best Practices for Modern Applications
Implement API gateway patterns including rate limiting, authentication, request routing, circuit breakers, and API versioning for scalable web architectures.