1. Architektur
Die Anwendung und alle ihre Abhängigkeiten werden in Docker-Images kompiliert.
Sobald die Container auf einer Windows Server-Instanz bereitgestellt werden, verbindet sich die Anwendung mit einer Salesforce-Org, in der das DQE One-Paket installiert ist.
Dieses Dokument beschreibt die Konfiguration zur Bereitstellung von DQE One Server auf einer virtuellen Windows Server-Maschine mithilfe von Docker Compose, das innerhalb von WSL2 (Windows Subsystem for Linux 2) ausgeführt wird.
Flussdiagramm
Das folgende Diagramm beschreibt alle eingehenden/ausgehenden Datenflüsse sowie die von der Anwendung benötigten IPs und Ports.
Sicherheitsmaßnahmen
Wir können kein Beispiel für die Implementierung der Sicherheitsebene liefern, das perfekt zu Ihrer Architektur passen würde. Wir können jedoch einige Empfehlungen geben, die für die Nutzung der Anwendung selbst relevant sind.
- Protokolle und Ports: Alle ausgehenden/eingehenden Datenflüsse der Anwendung erfolgen über das HTTPS-Protokoll (Port 443). Port 80 dient ausschließlich der Weiterleitung auf HTTPS. Es ist nicht notwendig, einen weiteren Port auf Ihrer VM zu öffnen. Die DQE-IPs, die erreichbar sein müssen, sind im vorherigen Diagramm beschrieben.
- IP-Filterung: Der Anwendungsserver selbst muss nur von den Salesforce-Servern aus erreichbar sein. Es wird daher empfohlen, eine Filterung der eingehenden IPs einzurichten. Die Salesforce-IP-Bereiche sind im Salesforce-Hilfeartikel Salesforce IP Addresses and Domains to Allow aufgeführt.
- Authentifizierungsprotokoll: Bei der Konfiguration der DQE One-App in Ihrer Salesforce-Org können Sie die Authentifizierungsmethode auswählen und Ihre Anwendungs-Firewall entsprechend konfigurieren.
Wenn die VM direkt dem Internet ausgesetzt ist, muss sie über einen DNS-Eintrag und ein zugehöriges SSL-Zertifikat verfügen, die auf sie verweisen.
Wenn die VM nicht direkt dem Internet ausgesetzt ist, bedeutet dies in der Regel, dass der Datenverkehr über eine Komponente wie ein Gateway oder einen Load Balancer geleitet wird. In diesem Fall müssen der DNS-Eintrag und das SSL-Zertifikat auf diesem Gateway installiert werden, das den Datenverkehr dann an die interne VM weiterleitet.
Empfehlung
In diesem Abschnitt beschreiben wir die Liste der Komponenten, die für die Installation der DQE One Server-Instanz auf einer Windows Server-VM erforderlich sind.
Hinweis: Die Schätzungen basieren auf 1 Million Datensätzen. Je nach Volumen der verarbeiteten Datenbanken kann es notwendig sein, die Speicherkapazität der Container-Instanzen zu erhöhen, um die Verarbeitungszeiten zu optimieren.
Bereitstellung mit Windows Server-VM:
- Servertyp: Windows Server 2025 (64-Bit), empfohlen. Windows Server 2022 wird unterstützt, erfordert jedoch einen zusätzlichen Schritt zur Portweiterleitung (siehe 2.4).
- Container-Laufzeitumgebung: Docker Engine, ausgeführt innerhalb von WSL2 (Ubuntu) — erforderlich, da Docker auf Windows Server nur Windows-Container ausführen kann, die DQE One-Images jedoch Linux-Images sind.
- Azure-VM: Wählen Sie eine Größe, die geschachtelte Virtualisierung unterstützt (z. B. Serien Dsv5 / Esv5), da WSL2 diese benötigt.
- Load Balancer: Nicht erforderlich, kann aber verwendet werden, falls bereits vorhanden.
Hardwareanforderungen:
| Komponente | Minimum | Empfohlen |
|---|---|---|
| CPU | 4 vCores | 8 vCores |
| RAM | 16 GB | 32 GB |
| Festplatte | 60 GB SSD | 120 GB SSD |
| Netzwerk | 100 Mbit/s | 1 Gbit/s |
Hinweis: 16 GB sind das Minimum, da allein der Worker bis zu 5 GB belegen kann und WSL2 genügend Arbeitsspeicher für den gesamten Stack zugewiesen werden muss (siehe 2.2).
Zusammensetzung und Dienste
Der Stack besteht aus Docker-Images, die über Docker Compose orchestriert werden. Jeder Dienst läuft als Container. Die Dienste kommunizieren über ihren Dienstnamen im internen Docker-Netzwerk miteinander.
Webanwendung (one-server)
Ein Backend-Container, der eine Microservices-Anwendung enthält. Diese Anwendung stellt alle APIs bereit, die von Salesforce zum Starten von Prozessen, zur Verwaltung von Verarbeitungswarteschlangen und zur Instanziierung von Verarbeitungs-Workern aufgerufen werden. Sie ist für ihre ordnungsgemäße Funktion von Redis und RabbitMQ abhängig. Dieser Dienst wird ausschließlich über den Nginx-Reverse-Proxy im Web bereitgestellt.
Docker Compose-Einstellungen
image: Der Name des Images, das in der DQE Azure Container Registry gehostet wird:
<registry-url>/<dqe-one-server-image>:<tag>- depends_on: redis (healthy), rabbitmq (healthy), one-ui (started)
- environment: SFAPIVERSION, PORT, REDIS_URL, CLOUDAMQP_URL, CUSTOMUI, UNIFYSERVERURL
- command:
bash ./entrypoint.sh
Worker (queue-worker)
Ein Backend-Container, der in der Warteschlange befindliche Aufgaben asynchron verarbeitet. Er verarbeitet Aufgaben aus der RabbitMQ-Warteschlange und führt sie aus.
In Docker Compose festzulegende Parameter
- image: von DQE Software bereitgestellt
- depends_on: redis (healthy), rabbitmq (healthy), one-server (started)
- environment: SFAPIVERSION, WORKDIRPATH, REDIS_URL, CLOUDAMQP_URL
- command:
python -u ./unify/queue_worker.pyc— das Image enthält kompilierten Python-Bytecode, keine Quelldateien.
Benutzeroberfläche (one-ui)
Die DQE One-Benutzeroberfläche, die von der Webanwendung aufgerufen wird. Sie ist nur innerhalb des Docker-Netzwerks erreichbar.
In Docker Compose festzulegende Parameter
- image: von DQE Software bereitgestellt
- environment: PORT, SESSION_SECRET
- command:
npm start
Nginx
Ein Reverse-Proxy, der HTTPS terminiert und eingehende Anfragen an den DQE One Server auf Port 8000 weiterleitet. Seine Konfigurationsdatei und das SSL-Zertifikat werden im Windows-Dateisystem (C:\dqe-one\nginxconf und C:\dqe-one\ssl) gespeichert und über WSL2-Pfade in den Container eingebunden.
- image:
nginx:1.28-alpine - ports: 80:80, 443:443
- volumes:
/mnt/c/dqe-one/nginxconf:/etc/nginx/conf.d:ro,/mnt/c/dqe-one/ssl:/etc/nginx/ssl:ro
Redis
Eine Key/Value-Datenbank, die zur Speicherung interner Betriebsschlüssel wie Salesforce-Org-Konfigurationen, Sitzungen usw. verwendet wird.
Es wird das offizielle Image redis verwendet. Die Daten werden in einem benannten Docker-Volume gespeichert, das im WSL2-Linux-Dateisystem liegt — Bind-Mounts auf dem Windows-NTFS-Dateisystem werden nicht verwendet, da sie die von Redis benötigten Dateiberechtigungen nicht unterstützen.
Parameter
- image:
redis:7.4-alpine - volumes:
redis-data:/data(benanntes Docker-Volume)
RabbitMQ
Ein Warteschlangen-Manager, der die Entgegennahme und Planung von Verarbeitungsanfragen ermöglicht. Bis ein Prozess einem Worker zugewiesen und abgeschlossen wurde, verbleibt er in der Warteschlange. Dies sorgt außerdem für Ausfallsicherheit — wird der Server neu gestartet, setzt er die letzte Verarbeitung in der Warteschlange an der Stelle fort, an der sie unterbrochen wurde.
Es wird das offizielle Image rabbitmq:3.13-management verwendet. Die Daten werden in einem benannten Docker-Volume gespeichert. Die Anmeldedaten werden in der Datei .env festgelegt. RabbitMQ ist außerhalb der VM nicht erreichbar; die Verwaltungsoberfläche ist nur von der VM aus zugänglich (http://localhost:15672).
Parameter
- image:
rabbitmq:3.13-management - volumes:
rabbitmq-data:/var/lib/rabbitmq(benanntes Docker-Volume) - environment: RABBITMQ_DEFAULT_USER, RABBITMQ_DEFAULT_PASS, RABBITMQ_DEFAULT_VHOST=admin
2. Installation
Alle Installationsschritte werden auf der Windows Server-VM durchgeführt. Mit [PowerShell] gekennzeichnete Schritte müssen in PowerShell als Administrator ausgeführt werden. Mit [WSL2] gekennzeichnete Schritte müssen im Ubuntu-WSL2-Terminal ausgeführt werden.
2.1 Voraussetzung
Verbinden Sie sich mit der Windows Server-VM über eine der verfügbaren Verbindungsoptionen (RDP, Azure Bastion usw.) und öffnen Sie PowerShell als Administrator.
Erstellen Sie die Verzeichnisstruktur der Anwendung über PowerShell:
New-Item -ItemType Directory -Path "C:\dqe-one\nginxconf", "C:\dqe-one\ssl" -Force2.2 WSL2-Installation [PowerShell]
wsl --install --no-distribution
wsl --update/!\ Neustart erforderlich — Starten Sie die VM neu, bevor Sie fortfahren.
Öffnen Sie nach dem Neustart PowerShell als Administrator und installieren Sie Ubuntu:
wsl --install -d Ubuntu-24.04Es öffnet sich ein Terminal, in dem Sie aufgefordert werden, einen Unix-Benutzernamen und ein Passwort zu erstellen. Schließen Sie die Einrichtung ab, bevor Sie fortfahren.
Erstellen Sie anschließend die WSL2-Konfigurationsdatei (wieder in PowerShell als Administrator):
@"
[wsl2]
networkingMode=mirrored
memory=12GB
processors=4
"@ | Set-Content -Path "$env:USERPROFILE\.wslconfig" -Encoding asciinetworkingMode=mirroredstellt die Container-Ports direkt auf der IP-Adresse der VM bereit (Windows Server 2025). Ohne diese Einstellung sind in WSL2 veröffentlichte Ports nur von der VM selbst aus erreichbar.memory: Standardmäßig nutzt WSL2 nur 50 % des Arbeitsspeichers der VM. Passen Sie den Wert an die Größe der VM an, jedoch nie unter 10 GB.
2.3 Docker- und Docker Compose-Installation [WSL2]
Öffnen Sie das Ubuntu-WSL2-Terminal und aktivieren Sie systemd, damit Docker automatisch mit WSL2 startet:
printf '[boot]\nsystemd=true\n' | sudo tee /etc/wsl.confStarten Sie WSL2 über PowerShell mit wsl --shutdown neu, öffnen Sie dann erneut das Ubuntu-WSL2-Terminal und installieren Sie Docker:
curl -fsSL https://get.docker.com | sudo shHinweis: Das Skript erkennt WSL und empfiehlt Docker Desktop — ignorieren Sie diese Meldung und warten Sie 20 Sekunden, bis die Installation automatisch fortgesetzt wird. Docker Compose ist in dieser Installation enthalten.
Fügen Sie Ihren Benutzer der docker-Gruppe hinzu und aktivieren Sie den Dienst:
sudo usermod -aG docker $USER
sudo systemctl enable --now dockerSchließen Sie das WSL2-Terminal und öffnen Sie es erneut, überprüfen Sie dann:
docker --version
docker compose version2.4 Netzwerk und Firewall [PowerShell]
New-NetFirewallRule -DisplayName "DQE One HTTP" -Direction Inbound -Protocol TCP -LocalPort 80 -Action Allow
New-NetFirewallRule -DisplayName "DQE One HTTPS" -Direction Inbound -Protocol TCP -LocalPort 443 -Action Allow
Set-NetFirewallHyperVVMSetting -Name '{40E0AC32-46A5-438A-A0B2-2B479E8F2E90}' -DefaultInboundAction AllowDer letzte Befehl erlaubt eingehenden Datenverkehr zu WSL2 durch die Hyper-V-Firewall, was im gespiegelten Modus (mirrored) erforderlich ist.
Nur Windows Server 2022: Der gespiegelte Modus ist nicht verfügbar. Leiten Sie die Ports 80 und 443 an die IP-Adresse von WSL2 weiter. Diese IP ändert sich bei jedem Neustart, daher müssen die Befehle auch beim Systemstart ausgeführt werden:
$ip = (wsl -d Ubuntu-24.04 hostname -I).Split(' ')[0]
foreach ($p in 80,443) {
netsh interface portproxy delete v4tov4 listenport=$p listenaddress=0.0.0.0
netsh interface portproxy add v4tov4 listenport=$p listenaddress=0.0.0.0 connectport=$p connectaddress=$ip
}2.5 Automatischer Start [PowerShell]
WSL2 startet nicht mit Windows und wird beendet, wenn kein Windows-Prozess es verwendet. Die folgende geplante Aufgabe hält es ab dem Systemstart aktiv, ohne dass eine Sitzung geöffnet sein muss. Docker startet dann über systemd, und die Container werden automatisch neu gestartet.
$cred = Get-Credential -UserName "$env:USERDOMAIN\$env:USERNAME" -Message "Account that runs WSL2 at startup"
$action = New-ScheduledTaskAction -Execute "wsl.exe" -Argument "-d Ubuntu-24.04 -u root -- sleep infinity"
$trigger = New-ScheduledTaskTrigger -AtStartup
$settings = New-ScheduledTaskSettingsSet -ExecutionTimeLimit ([TimeSpan]::Zero) -RestartCount 3 -RestartInterval (New-TimeSpan -Minutes 1)
Register-ScheduledTask -TaskName "DQE-One-WSL-KeepAlive" -Action $action -Trigger $trigger -Settings $settings `
-User $cred.UserName -Password $cred.GetNetworkCredential().Password -RunLevel Highest
Start-ScheduledTask -TaskName "DQE-One-WSL-KeepAlive"Hinweis: Verwenden Sie dasselbe Konto, mit dem Ubuntu installiert wurde — WSL2-Distributionen werden pro Benutzer installiert.
2.6 Nginx-Konfiguration [PowerShell]
Nginx läuft als Container — es gibt keine Installation auf Host-Ebene. Sie müssen lediglich das SSL-Zertifikat kopieren und die Konfigurationsdatei erstellen.
- Kopieren Sie das Zertifikat und seinen privaten Schlüssel nach
C:\dqe-one\ssl\cert.crtundC:\dqe-one\ssl\cert.key. - Öffnen Sie die Konfigurationsdatei in Notepad:
notepad C:\dqe-one\nginxconf\default.conf
Fügen Sie den folgenden Inhalt ein und speichern Sie:
server {
listen 80;
server_name <your-domain.com>;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name <your-domain.com>;
ssl_certificate /etc/nginx/ssl/cert.crt;
ssl_certificate_key /etc/nginx/ssl/cert.key;
ssl_protocols TLSv1.2 TLSv1.3;
location / {
proxy_pass http://one-server:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 300s;
}
}Hinweis: Im Gegensatz zur ACI-Version, bei der Nginx auf localhost:8000 zielt, kommunizieren die Dienste in Docker Compose über ihren Dienstnamen — das Proxy-Ziel ist http://one-server:8000.
Wenn SSL auf einem Gateway vor der VM terminiert wird, behalten Sie nur einen listen 80-Block mit dem Abschnitt location /.
2.7 Windows DQE One Server — .env und docker-compose.yml
Erstellen Sie die Datei C:\dqe-one\.env mit den von DQE Software bereitgestellten Werten. Verwenden Sie sichere Passwörter ohne die Zeichen @ : / ? # (das RabbitMQ-Passwort wird in eine Verbindungs-URL eingefügt).
# Copy to C:\dqe-one\.env and fill in
DQE_ONE_SERVER_IMAGE=<registry-url>/<dqe-one-server-image>:<tag>
DQE_ONE_WORKER_IMAGE=<registry-url>/<dqe-one-server-image>:<tag>
DQE_ONE_UI_IMAGE=<registry-url>/<dqe-one-ui-image>:<tag>
SFAPIVERSION=v65.0
# Avoid @ : / ? # (the password is injected into the AMQP URL)
RABBITMQ_USER=dqeone
RABBITMQ_PASSWORD=ChangeMe_Str0ngPassword
SESSION_SECRET=ChangeMe_LongRandomStringErstellen Sie die Datei C:\dqe-one\docker-compose.yml mit dem folgenden Inhalt über Notepad.
Hinweis: Im Gegensatz zur ACI-Version kommunizieren die Dienste in Docker Compose über Dienstnamen (redis, rabbitmq, one-ui) und nicht über localhost. Die Umgebungsvariablen sind entsprechend konfiguriert.
# =============================================================================
# DQE One for Salesforce — Windows Server VM (Docker Engine in WSL2)
# From WSL2: cd /mnt/c/dqe-one && docker compose up -d
# =============================================================================
name: dqe-one
x-logging: &default-logging # log rotation (json-file grows without limit otherwise)
driver: json-file
options:
max-size: "50m"
max-file: "5"
services:
# ── Redis ────────────────────────────────────────────────────────────────────
redis:
image: redis:7.4-alpine
restart: always
logging: *default-logging
volumes:
- redis-data:/data
networks:
- dqe-one-net
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 10
# ── RabbitMQ ─────────────────────────────────────────────────────────────────
rabbitmq:
image: rabbitmq:3.13-management
hostname: rabbitmq # stable node name => queues kept across re-creations
restart: always
logging: *default-logging
ports:
- "127.0.0.1:15672:15672" # management UI, reachable from the VM only
volumes:
- rabbitmq-data:/var/lib/rabbitmq
environment:
- RABBITMQ_DEFAULT_USER=${RABBITMQ_USER}
- RABBITMQ_DEFAULT_PASS=${RABBITMQ_PASSWORD}
- RABBITMQ_DEFAULT_VHOST=admin
networks:
- dqe-one-net
healthcheck:
test: ["CMD", "rabbitmq-diagnostics", "-q", "ping"]
interval: 10s
timeout: 10s
retries: 12
start_period: 30s
# ── Nginx reverse proxy ──────────────────────────────────────────────────────
nginx:
image: nginx:1.28-alpine
restart: always
logging: *default-logging
ports:
- "80:80"
- "443:443"
volumes:
- /mnt/c/dqe-one/nginxconf:/etc/nginx/conf.d:ro
- /mnt/c/dqe-one/ssl:/etc/nginx/ssl:ro
depends_on:
one-server:
condition: service_started
networks:
- dqe-one-net
# ── DQE One UI ───────────────────────────────────────────────────────────────
one-ui:
image: ${DQE_ONE_UI_IMAGE}
restart: always
logging: *default-logging
command: ["npm", "start"]
environment:
- PORT=8001
- SESSION_SECRET=${SESSION_SECRET}
networks:
- dqe-one-net
# ── DQE One Server (web) ─────────────────────────────────────────────────────
one-server:
image: ${DQE_ONE_SERVER_IMAGE}
hostname: oneserver
restart: always
logging: *default-logging
command: ["bash", "./entrypoint.sh"]
ports:
- "127.0.0.1:8000:8000" # local debugging only — public traffic goes through Nginx
environment:
- SFAPIVERSION=${SFAPIVERSION}
- PORT=8000
- REDIS_URL=redis://redis:6379
- CLOUDAMQP_URL=amqp://${RABBITMQ_USER}:${RABBITMQ_PASSWORD}@rabbitmq:5672/admin
- CUSTOMUI=http://one-ui:8001
- UNIFYSERVERURL=http://one-server:8000
depends_on:
redis:
condition: service_healthy
rabbitmq:
condition: service_healthy
one-ui:
condition: service_started
networks:
- dqe-one-net
deploy:
resources:
limits:
memory: 2g
cpus: '1.0'
# ── Queue Worker ─────────────────────────────────────────────────────────────
queue-worker:
image: ${DQE_ONE_WORKER_IMAGE}
restart: always
logging: *default-logging
command: ["python", "-u", "./unify/queue_worker.pyc"]
environment:
- SFAPIVERSION=${SFAPIVERSION}
- WORKDIRPATH=/app/unify
- REDIS_URL=redis://redis:6379
- CLOUDAMQP_URL=amqp://${RABBITMQ_USER}:${RABBITMQ_PASSWORD}@rabbitmq:5672/admin
depends_on:
redis:
condition: service_healthy
rabbitmq:
condition: service_healthy
one-server:
condition: service_started
networks:
- dqe-one-net
deploy:
resources:
limits:
memory: 5g
cpus: '1.0'
volumes:
redis-data:
rabbitmq-data:
networks:
dqe-one-net:
driver: bridgeWichtige Punkte:
- Nur Nginx ist im Netzwerk erreichbar. Redis, RabbitMQ und die Benutzeroberfläche sind nur innerhalb des Docker-Netzwerks erreichbar;
one-serverund die RabbitMQ-Verwaltungsoberfläche sind zur Fehlersuche von der VM aus an127.0.0.1gebunden. redis-dataundrabbitmq-datasind benannte Docker-Volumes, die im WSL2-Linux-Dateisystem gespeichert werden. Bind-Mounts zum Windows-NTFS-Dateisystem werden nicht verwendet, da NTFS die von diesen Containern benötigtenchown-Operationen nicht unterstützt.- Die Dienste starten in der richtigen Reihenfolge: Redis und RabbitMQ müssen betriebsbereit (healthy) sein, bevor
one-serverundqueue-workerstarten. - Die Protokolle werden rotiert (5 × 50 MB pro Container), damit sie die Festplatte nicht füllen können.
- Die Versionen der öffentlichen Images sind festgelegt, damit ein Neustart nie eine unerwartete neue Version herunterlädt.
3. Launcher
Die DQE-Docker-Images werden über eine von DQE Software verwaltete Azure Container Registry bereitgestellt. Alle Befehle in diesem Abschnitt werden über das Ubuntu-WSL2-Terminal ausgeführt.
3.1 Verbindung zur DQE Azure Container Registry herstellen
docker login <registry-url> --username <Login provided by DQE>Geben Sie das von DQE bereitgestellte Passwort ein, wenn Sie dazu aufgefordert werden (es wird nicht im Shell-Verlauf gespeichert). Eine erfolgreiche Anmeldung zeigt an: Login Succeeded
3.2 Start von docker-compose.yml
Wechseln Sie in das Anwendungsverzeichnis und laden Sie die Images herunter:
cd /mnt/c/dqe-one
docker compose pullStarten Sie alle Dienste im Hintergrundmodus (detached):
docker compose up -dÜberprüfen Sie, ob alle Container ausgeführt werden:
docker compose psErwartete Ausgabe — alle Dienste sollten den Status running anzeigen, Redis und RabbitMQ zusätzlich healthy:
NAME SERVICE STATUS
dqe-one-nginx-1 nginx running
dqe-one-one-server-1 one-server running
dqe-one-one-ui-1 one-ui running
dqe-one-queue-worker-1 queue-worker running
dqe-one-rabbitmq-1 rabbitmq running (healthy)
dqe-one-redis-1 redis running (healthy)/!\ Wichtig: Wenn ein Container den Status exited oder restarting anzeigt, überprüfen Sie dessen Protokolle: docker compose logs <service-name>
3.3 Überprüfung
Öffnen Sie von einem Rechner außerhalb der VM https://<your-domain.com>. Starten Sie die VM anschließend einmal neu und prüfen Sie mit docker compose ps, dass alle Container automatisch wieder gestartet wurden.
3.4 Aktualisierung
Wenn DQE Software eine neue Version bereitstellt, aktualisieren Sie die Image-Tags in C:\dqe-one\.env und führen Sie anschließend Folgendes aus:
cd /mnt/c/dqe-one
docker compose pull
docker compose up -d
Verknüpfung mit