Docker für die ERP-Bereitstellung in der Produktion: Ein vollständiger Betriebsleitfaden
Organisationen, die ERP-Systeme in Docker-Containern betreiben, berichten von 73 % schnelleren Bereitstellungszyklen und 45 % weniger umgebungsbedingten Vorfällen im Vergleich zu herkömmlichen Bare-Metal-Bereitstellungen. Docker verwandelt die ERP-Bereitstellung von einem mehrtägigen, fehleranfälligen Prozess in einen wiederholbaren, versionierten Vorgang, den jedes Teammitglied ausführen kann.
Dieser Leitfaden deckt den gesamten Lebenszyklus der Ausführung von Unternehmens-ERP-Systemen ab – einschließlich Odoo, benutzerdefinierten NestJS-Backends und Next.js-Frontends – in Docker-Produktionsumgebungen.
Wichtige Erkenntnisse
– Mehrstufige Docker-Builds reduzieren die Größe der ERP-Container-Images um 60–80 % und verbessern so die Bereitstellungsgeschwindigkeit – Docker Compose orchestriert ERP-, Datenbank-, Reverse-Proxy- und Cache-Dienste als eine einzige bereitstellbare Einheit – Benannte Volumes und Bind-Mounts stellen die Datenpersistenz bei Container-Neustarts und -Upgrades sicher
- Gesundheitsprüfungen und Neustartrichtlinien sorgen für eine automatische Wiederherstellung nach vorübergehenden Ausfällen
Architektur eines Docker-ERP-Stacks
Eine ERP-Produktionsbereitstellung umfasst typischerweise fünf oder mehr miteinander verbundene Dienste. Docker Compose definiert diese Dienste deklarativ und gewährleistet so eine konsistente Bereitstellung in allen Umgebungen.
Diensttopologie
Der standardmäßige Dockerized ERP-Stack:
- Anwendungsserver: Die ERP-Laufzeit (Odoo, NestJS oder ähnlich)
- Datenbank: PostgreSQL mit persistentem Volume-Speicher
- Reverse-Proxy: Nginx kümmert sich um die SSL-Terminierung, statische Dateien und das Anforderungsrouting
- Cache-Ebene: Redis für Sitzungsspeicher, Jobwarteschlangen und Anwendungs-Caching
- Hintergrundarbeiter: Asynchrone Jobprozessoren für E-Mails, Berichte und Integrationen
Zu den optionalen Diensten gehören Backup-Container (pg_dump auf cron), Überwachungs-Sidecars (Prometheus-Exporter) und Protokollversender (Fluent Bit).
Mehrstufige Builds für ERP-Anwendungen
Mehrstufige Builds sind für die Produktion von Docker-Images unerlässlich. Sie trennen Abhängigkeiten zur Build-Zeit von der Laufzeit und erzeugen so schlanke, sichere Images.
NestJS-Backend-Build
# 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"]
Next.js Frontend Build
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"]
Bildgrößenvergleich
| Build-Typ | Image Size | Bauzeit |
|---|---|---|
| Einstufig (vollständiges Knotenbild) | 1,8 GB | 4 Minuten |
| Einstufig (Alpin) | 650 MB | 3,5 Minuten |
| Mehrstufig (Alpin) | 180 MB | 5 Minuten |
| Mehrstufige + beschnittene Deps | 120 MB | 5,5 Minuten |
Die Buildzeit von 5,5 Minuten ist akzeptabel, da sie in CI und nicht auf Entwicklermaschinen erfolgt.
Docker Compose für die Produktion
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:
Netzwerkisolation
Die obige Konfiguration verwendet zwei Netzwerke:
- Frontend: Nginx, Web und API (Nginx-Proxys für beide)
- Backend: API, Datenbank und Redis
Auf die Datenbank und Redis kann nicht über den Nginx-Container oder das externe Netzwerk zugegriffen werden. Diese Netzwerksegmentierung ist eine wichtige Sicherheitsmaßnahme.
Volume-Management und Datenpersistenz
Volumes sind der kritischste Teil einer Docker-ERP-Bereitstellung. Wenn Sie Ihre Datenträger verlieren, verlieren Sie Ihre Daten.
Volume-Typen
| Geben Sie | ein Anwendungsfall | Beharrlichkeit | Leistung |
|---|---|---|---|
| Benannte Bände | Datenbank, Redis | Überlebt Containerentfernung | Geschwindigkeit des nativen Dateisystems |
| Halterungen binden | Konfigurationsdateien, Protokolle | An Host-Dateisystem gebunden | Geschwindigkeit des nativen Dateisystems |
| tmpfs mountet | Temporäre Dateien, Geheimnisse | Nur Speicher, geht beim Neustart verloren | Speichergeschwindigkeit |
Backup-Strategie für Docker-Volumes
#!/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
Integritätsprüfungen und Neustartrichtlinien
Produktionscontainer müssen ihren Zustand selbst melden und sich nach Ausfällen automatisch erholen.
Endpunkt zur Anwendungsintegritätsprüfung
// 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;
}
}
}
Richtlinienauswahl neu starten
| Politik | Verhalten | Anwendungsfall |
|---|---|---|
no | Nie neu starten | Entwicklung, einmalige Aufgaben |
on-failure | Nur bei Exit ungleich Null neu starten | Arbeiter, Batch-Jobs |
always | Immer neu starten (auch beim Neustart des Docker-Daemons) | Produktionsdienstleistungen |
unless-stopped | Wie always, berücksichtigt aber manuelle Stopps | Die meisten Produktionsdienstleistungen |
Verwenden Sie unless-stopped für Produktionsdienste. Dies stellt sicher, dass Container nach einem Server-Neustart oder einem Docker-Daemon-Neustart neu gestartet werden, berücksichtigt aber manuelle docker compose stop-Befehle während der Wartung.
Bereitstellungsworkflow
Rolling Updates mit Docker Compose
#!/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
Sicherheit der Datenbankmigration
Führen Sie Migrationen niemals innerhalb des Anwendungsstarts durch. Führen Sie sie stattdessen als separaten Schritt aus:
# Run migrations before deploying new containers
docker compose run --rm api npx drizzle-kit push
# Then deploy the new version
docker compose up -d
Dieses Muster stellt sicher, dass die alte Version unbeeinträchtigt weiterläuft, wenn eine Migration fehlschlägt.
Protokollierung und Debugging
Zentralisierte Protokollierung
# Add to docker-compose.yml
services:
api:
logging:
driver: json-file
options:
max-size: "10m"
max-file: "5"
labels: "service"
labels:
service: "ecosire-api"
Allgemeine Debugging-Befehle
# 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
Häufig gestellte Fragen
Wie gehen wir mit Datenbankmigrationen in Docker um?
Führen Sie Migrationen als separaten Schritt aus, bevor Sie neue Anwendungscontainer bereitstellen. Verwenden Sie docker compose run --rm api npx drizzle-kit push (oder den Migrationsbefehl Ihres ORM) als Schritt vor der Bereitstellung. Betten Sie die Migrationsausführung niemals in den Container-Startbefehl ein – eine fehlgeschlagene Migration sollte nicht verhindern, dass die aktuelle Version weiterhin ausgeführt wird.
Wie hoch ist der Leistungsaufwand von Docker?
Unter Linux ist der Leistungsaufwand von Docker vernachlässigbar – typischerweise weniger als 2 % für CPU-gebundene Arbeitslasten und kein messbarer Unterschied für E/A-gebundene Arbeitslasten. Unter macOS und Windows läuft Docker in einer virtuellen Maschine, was einen Mehraufwand von 5–15 % verursacht. Für die Produktion (die Linux sein sollte) stellt Docker kein nennenswertes Leistungsproblem dar.
Wie verwalten wir Geheimnisse in Docker?
Fügen Sie niemals Geheimnisse in Dockerfiles- oder docker-compose.yml-Dateien ein. Verwenden Sie Umgebungsvariablendateien (.env), die von der Versionskontrolle ausgeschlossen sind, Docker-Geheimnisse (für den Swarm-Modus) oder externe Geheimnismanager (AWS Secrets Manager, HashiCorp Vault). Für Docker Compose ist eine .env-Datei im Projektstamm der einfachste Ansatz.
Sollten wir Docker Swarm oder Kubernetes verwenden?
Für die meisten KMU-ERP-Bereitstellungen ist Docker Compose ausreichend. Docker Swarm fügt Multi-Host-Orchestrierung mit minimalem Komplexitätsaufwand hinzu. Kubernetes eignet sich, wenn Sie automatische Skalierung, komplexe Netzwerkrichtlinien oder Service-Mesh-Funktionen benötigen. Weitere Informationen zu Entscheidungsframeworks finden Sie in unserem Kubernetes-Skalierungsleitfaden und unserem Microservices-Architekturleitfaden.
Wie gehen wir mit benutzerdefinierten Odoo-Modulen in Docker um?
Hängen Sie benutzerdefinierte Module als Bind-Mount-Volume ein, das auf Ihr Add-On-Verzeichnis verweist. Stellen Sie in der Docker-Datei sicher, dass der Add-On-Pfad in odoo.conf konfiguriert ist. Erstellen Sie für CI/CD ein benutzerdefiniertes Docker-Image, das Ihre Module einbettet und so die Versionskonsistenz gewährleistet. Informationen zur Odoo-spezifischen Konfiguration finden Sie in unserem bestehenden Docker Odoo-Bereitstellungsleitfaden.
Was als nächstes kommt
Docker ist die Grundlage für die moderne ERP-Bereitstellung. Sobald Ihr Container-Stack stabil ist, erkunden Sie Bereitstellungsstrategien ohne Ausfallzeiten, Produktionsüberwachung und Infrastruktur als Code, um eine vollständig automatisierte Betriebspipeline aufzubauen.
Kontaktieren Sie ECOSIRE für Beratung zur Docker-Bereitstellung oder erkunden Sie unsere Odoo-Implementierungsdienste für die vollständig verwaltete Container-ERP-Bereitstellung.
Herausgegeben von ECOSIRE – hilft Unternehmen dabei, Unternehmenssoftware sicher bereitzustellen.
Geschrieben von
ECOSIRE TeamTechnical Writing
The ECOSIRE technical writing team covers Odoo ERP, Shopify eCommerce, AI agents, Power BI analytics, GoHighLevel automation, and enterprise software best practices. Our guides help businesses make informed technology decisions.
ECOSIRE
Transformieren Sie Ihr Unternehmen mit Odoo ERP
Kompetente Odoo-Implementierung, Anpassung und Support zur Optimierung Ihrer Abläufe.
Verwandte Artikel
Back-Market-Integration: Verbinden Sie generalüberholte Produkte mit Odoo ERP
Leitfaden zur Integration von Back Market mit Odoo ERP für Verkäufer generalüberholter Elektronik. Automatisieren Sie Einstufung, Bestellungen, Inventar und Qualitätskonformität.
Bestes ERP für E-Commerce-Unternehmen im Jahr 2026: Top 8 im Vergleich
Vergleichen Sie die Top 8 ERPs für E-Commerce im Jahr 2026: Odoo, NetSuite, SAP B1, Acumatica, Brightpearl, Cin7, Dear Inventory und QuickBooks Commerce mit Preisgestaltung.
Beste ERP-Software im Jahr 2026: Umfassender Kaufratgeber
Die 12 besten ERP-Systeme für 2026: Odoo, SAP, Oracle NetSuite, Microsoft Dynamics, Acumatica, ERPNext, Sage, Epicor, Infor, QAD, Syspro und Brightpearl.