Docker-Support

Eine Einführung, wie WinCC OA innerhalb eines Docker-Containers verwendet werden kann, welche Besonderheiten zu beachten sind und wo Sie zusätzliche Informationen zu diesem Thema finden können.

Was ist Docker?

Docker dient als innovative Plattform, die darauf ausgelegt ist, den gesamten Lebenszyklus von Softwareanwendungen – von der Entwicklung über die Bereitstellung bis hin zur Ausführung – zu vereinfachen. Dies wird durch die Nutzung von "Containern" erreicht: eigenständigen, isolierten Einheiten, die eine Anwendung zusammen mit allen notwendigen Komponenten wie Code, Bibliotheken und Konfigurationen bündeln. Diese elegante Lösung bietet einen deutlichen Vorteil gegenüber herkömmlichen Methoden oder ressourcenintensiven virtuellen Maschinen, da Container äußerst leichtgewichtig sind und eine konsistente Anwendungsleistung über verschiedene Computerumgebungen hinweg gewährleisten. Dadurch wird die Zuverlässigkeit und Effizienz erheblich gesteigert.

Docker-Image

Ein Docker-Image ist ein standardisiertes, portables Softwarepaket, das eine Anwendung zusammen mit ihrer Laufzeitumgebung, Bibliotheken und Abhängigkeiten enthält. Es dient als grundlegende Vorlage für das Bereitstellen von Containern in konsistenten und isolierten Umgebungen. Während für WinCC OA derzeit kein offizielles Docker-Image verfügbar ist, können benutzerdefinierte Lösungen erstellt werden, indem Debian-Pakete extrahiert und Docker-Dateien konfiguriert werden.
docker build -t winccoa321. #Executed in the local directory. 
#You must download the Debian packages before executing this command
Zukünftige Unterstützung für patch-basierte Images ist geplant, um die Effizienz der Bereitstellung zu verbessern.

Beispiel: Um ein PostgreSQL®-Image von GitHub zu laden:

docker pull postgres:16​

Containerverwaltung und Lizenzierung

Die Verwaltung von Docker-Containern ermöglicht es, Anwendungen wie WinCC OA in isolierten, konfigurierbaren Umgebungen auszuführen. Container können gestartet, gestoppt, inspiziert und über grafische Tools wie Portainer oder über Befehle in der Kommandozeile verwaltet werden. Zu den wichtigsten Funktionen gehören das Anzeigen von Logs, das Öffnen von Terminalsitzungen und das Weiterleiten von Netzwerkports für den Webzugriff. Die Lizenzierung erfolgt dynamisch: Der Container verbindet sich mit einem Lizenzserver, der durch eine Umgebungsvariable definiert ist. Wenn mehrere Lizenzcontainer vorhanden sind, muss der richtige in der Projektkonfiguration über eine Seriennummer angegeben werden. Dies stellt sicher, dass die Anwendung mit einer gültigen Lizenz und ohne Warnungen ausgeführt wird. Persistente Daten können durch das Einbinden externer Volumes erhalten bleiben.
Note:
Für die Lizenzierung von innerhalb eines Docker Containers ist es erforderlich einen eigenen CodeMeter-Lizenzserver bereitzustellen (Sie können den Lizenzcontainer nicht direkt verwenden).

Der CodeMeter-Lizenzserver kann wahlweise auf einem eigenständigen Server betrieben werden, oder als Service auf dem Hostrechner der Docker-Umgebung betrieben werden.

Ein CodeMeter-Lizenzserver erfordert die Installation und entsprechende Server-Konfiguration der CodeMeter Runtime. Diese wird als Teil des Setups zur Verfügung gestellt oder kann (nur für Linux) von www.winccoa.com heruntergeladen oder direkt über den Hersteller unter www.wibu.com bezogen werden.

Unter http://www.wibu.com finden Sie auch ausführliche Beschreibungen für die Konfiguration eines CodeMeter-Lizenzservers.

Je nachdem wie die DNS-Konfiguration in Docker weitergegeben werden kann, geben Sie den Lizenzserver entweder als Hostnamen oder als IP‑Adresse an.

Verwenden Sie eine der folgenden Optionen, um den Container mit dem erstellten Docker-Image zu starten.

Important:
Es muss sichergestellt werden, dass das Projekt in das korrekte Verzeichnis gemountet wurde.

Standardmäßig wird der Pfad home/winccoa/oaproj/ verwendet. Um einen anderen Pfad anzugeben, verwenden Sie das optionale Argument -e OAPROJ= des docker run-Befehls und binden Sie ein Volume mit dem Parameter -v ein.

Um die erforderlichen Ports des Projektes mit dem Docker-Container abzugleichen wird das optionale -p-Argument des docker run-Befehls verwendet.

Option 1: Manuell ausführen:

docker run --rm --name Demo -p 8443:8443 -e OAPROJ=/opt/WinCC_OA/3.20/DemoApplication_3.20_mount -e LICENSESERVER=<IP from License server e.g. 172.28.224.1> -v /mnt/c/WinCC_OA_Proj/DemoApplication_3.20:/opt/WinCC_OA/3.20/DemoApplication_3.20_mount winccoa320_4

Ersetzen Sie den Platzhalter für den Lizenzserver im Befehl durch die IP-Adresse Ihres Servers (zum Beispiel 172.28.224.1).

Option 2: Docker Compose mit einer YAML-Datei verwenden:
docker compose -f docker-compose_0.yml up
#YAML FILE:
#docker run -d --rm --name winccoa -p 8443:8443 -e OAPROJ=/opt/WinCC_OA/3.20/DemoApplication_3.20_mount -e LICENSESERVER=172.28.224.1 -v /mnt/c/WinCC_OA_Proj/DemoApplication_3.20:/opt/WinCC_OA/3.20/DemoApplication_3.20_mount winccoa320

services:
  Demo: #name
    image: winccoa320_4 #image name
    container_name: Demo
    volumes:
      - /mnt/c/WinCC_OA_Proj/DemoApplication_3.20:/opt/WinCC_OA/3.20/DemoApplication_3.20_mount
    environment:
      - OAPROJ=/opt/WinCC_OA/3.20/DemoApplication_3.20_mount
      - LICENSESERVER=172.28.224.1
    ports:
      - 8443:8443

Ausführen mehrerer Container

Figure 1. Docker-Architektur - Diese Architekturabbildung ist nur ein Beispiel, und die Befehle in diesem Kapitel entsprechen genau dieser Konfiguration
//Starting Docker Compose
docker compose -f docker-compose.yml up​

Die Verwaltung mehrerer Docker-Container erfolgt am besten mit Docker Compose, das es ermöglicht, Dienste, Volumes, Netzwerke und Umgebungsvariablen in einer einzigen YAML-Datei zu definieren. Dieser Ansatz sorgt für eine konsistente Konfiguration und vereinfacht die Bereitstellung. In einer typischen Umgebung werden Container für WinCC OA, PostgreSQL® (lokal und in der Cloud) sowie einen abgesetzten Webserver gemeinsam orchestriert. Jeder Dienst wird mit eigenem Image, eigenen Ports und Volumes konfiguriert (Um den gesamten Projektsource in einem einzigen Verzeichnis zu halten, bindet das Projekt verschiedene Konfigurations- und Log-Verzeichnisse in die Docker-Container ein), was eine modulare und skalierbare Architektur ermöglicht. Die Datenpersistenz wird durch gemountete Volumes sichergestellt, und Umgebungsvariablen werden zur Konfiguration von Lizenzierung und Konnektivität verwendet. Die Architektur unterstützt verteiltes Archivieren, indem mehrere PostgreSQL®-Instanzen verbunden und Archivgruppen definiert werden. Ein Remote-Manager-Container in der DMZ dient als sichere Schnittstelle für den externen Zugriff und verwendet eine minimale Projektstruktur sowie eigene Konfigurations- und Log-Ordner. Docker Compose-Befehle wie up and down sowie --force-recreate verwalten den Lebenszyklus der Container, während Port-Mapping und Diensttrennung eine sichere und effiziente Kommunikation zwischen den Komponenten gewährleisten.

Das folgende Beispiel zeigt eine schrittweise Konfiguration:

services:
  winccoa: #name
    build: ../../WinCCOA_320_4
    image: winccoa320_4 #image name
    container_name: winccoa
    volumes:
      - ./dockerExample_ED:/opt/WinCC_OA_proj/dockerExample_ED
    environment:
      - OAPROJ=/opt/WinCC_OA_proj/dockerExample_ED
      - LICENSESERVER=172.28.224.1
    ports:
      - 127.0.0.1:4897:4897 #dataPort for remote GEDI/PARA
      - 127.0.0.1:4998:4998 #eventPort for remote GEDI/PARA
      - 8449:8449 #webSocket (dashboard server)
      - 8843:8843 #webServer https://localhost:8843/#/login?dbrw
services:
  winccoa: #name
    build: ../../WinCCOA_320_4
    image: winccoa320_4 #image name
    container_name: winccoa
    volumes:
      - ./dockerExample_ED:/opt/WinCC_OA_proj/dockerExample_ED
    environment:
      - OAPROJ=/opt/WinCC_OA_proj/dockerExample_ED
      - LICENSESERVER=172.28.224.1
    ports:
      - 127.0.0.1:4897:4897 #dataPort for remote GEDI/PARA
      - 127.0.0.1:4998:4998 #eventPort for remote GEDI/PARA
      - 8449:8449 #webSocket (dashboard server)
      - 8843:8843 #webServer https://localhost:8843/#/login?dbrw
  postgres: #name
    image: postgres:16
    container_name: postgres
    volumes:
      - ./dockerExample_ED/db/wincc_oa/localdb/postgresql/16:/var/lib/postgresql/data
    environment:
      - PGDATA=/var/lib/postgresql/data/pgdata
services:
  winccoa: #name
    build: ../../WinCCOA_320_4
    image: winccoa320_4 #image name
    container_name: winccoa
    volumes:
      - ./dockerExample_ED:/opt/WinCC_OA_proj/dockerExample_ED
    environment:
      - OAPROJ=/opt/WinCC_OA_proj/dockerExample_ED
      - LICENSESERVER=172.28.224.1
    ports:
      - 127.0.0.1:4897:4897 #dataPort for remote GEDI/PARA
      - 127.0.0.1:4998:4998 #eventPort for remote GEDI/PARA
      - 8449:8449 #webSocket (dashboard server)
      - 8843:8843 #webServer https://localhost:8843/#/login?dbrw
  postgres: #name
    image: postgres:16
    container_name: postgres
    volumes:
      - ./dockerExample_ED/db/wincc_oa/localdb/postgresql/16:/var/lib/postgresql/data
    environment:
      - PGDATA=/var/lib/postgresql/data/pgdata
  postgresCloud: #name
    image: postgres:16
    container_name: postgresCloud
    volumes:
      - postgresCloudDBFolder:/var/lib/postgresql/data
    environment:
      - POSTGRES_PASSWORD=etm#123
      - PGDATA=/var/lib/postgresql/data/pgdata
volumes:
services:
  winccoa: #name
    build: ../../WinCCOA_320_4
    image: winccoa320_4 #image name
    container_name: winccoa
    volumes:
      - ./dockerExample_ED:/opt/WinCC_OA_proj/dockerExample_ED
    environment:
      - OAPROJ=/opt/WinCC_OA_proj/dockerExample_ED
      - LICENSESERVER=172.28.224.1
    ports:
      - 127.0.0.1:4897:4897 #dataPort for remote GEDI/PARA
      - 127.0.0.1:4998:4998 #eventPort for remote GEDI/PARA
#      - 8449:8449 #webSocket (dashboard server)
#      - 8843:8843 #webServer https://localhost:8843/#/login?dbrw
  webserver: #name
    build: ../../remoteManager_320_4
    image: winccoa_remote320_4 #image name
    container_name: webserver
    volumes:
      - ./dockerExample_ED/web_config:/opt/WinCC_OA_proj/remote/config
      - ./dockerExample_ED/web_log:/opt/WinCC_OA_proj/remote/log
      - ./dockerExample_ED/data:/opt/WinCC_OA_proj/remote/data #webserver files
    environment:
      - EMPTYPROJ=/opt/WinCC_OA_proj/remote
      - OAPROJ=/opt/WinCC_OA_proj/remote
    ports:
      - 9449:8449 #webSocket (dashboard server)
      - 9843:8843 #webServer https://localhost:8879/#/login?dbrw  https://localhost:8843/#/login?dbrw
  postgres: #name
    image: postgres:16
    container_name: postgres
    volumes:
      - ./dockerExample_ED/db/wincc_oa/localdb/postgresql/16:/var/lib/postgresql/data
    environment:
      - PGDATA=/var/lib/postgresql/data/pgdata
  postgresCloud: #name
    image: postgres:16
    container_name: postgresCloud
    volumes:
      - postgresCloudDBFolder:/var/lib/postgresql/data
    environment:
      - POSTGRES_PASSWORD=etm#123
      - PGDATA=/var/lib/postgresql/data/pgdata
volumes:
  postgresCloudDBFolder:
#      - 8449:8449 #webSocket (dashboard server)
#      - 8843:8843 #webServer https://localhost:8843/#/login?dbrw
  webserver: #name
    build: ../../remoteManager_320_4
    image: winccoa_remote320_4 #image name
    container_name: webserver
    volumes:
      - ./dockerExample_ED/web_config:/opt/WinCC_OA_proj/remote/config
      - ./dockerExample_ED/web_log:/opt/WinCC_OA_proj/remote/log
      - ./dockerExample_ED/data:/opt/WinCC_OA_proj/remote/data #webserver files
    environment:
      - EMPTYPROJ=/opt/WinCC_OA_proj/remote
      - OAPROJ=/opt/WinCC_OA_proj/remote
    ports:
      - 9449:8449 #webSocket (dashboard server)
      - 9843:8843 #webServer https://localhost:8879/#/login?dbrw  https://localhost:8843/#/login?dbrw
services:
  winccoa: #name
    build: ../../WinCCOA_320_4
    image: winccoa320_4 #image name
    container_name: winccoa
    volumes:
      - ./dockerExample_ED:/opt/WinCC_OA_proj/dockerExample_ED
    environment:
      - OAPROJ=/opt/WinCC_OA_proj/dockerExample_ED
      - LICENSESERVER=172.28.224.1
    ports:
      - 127.0.0.1:4897:4897 #dataPort for remote GEDI/PARA
      - 127.0.0.1:4998:4998 #eventPort for remote GEDI/PARA
#      - 8449:8449 #webSocket (dashboard server)
#      - 8843:8843 #webServer https://localhost:8843/#/login?dbrw
  webserver: #name
    build: ../../remoteManager_320_4
    image: winccoa_remote320_4 #image name
    container_name: webserver
    volumes:
      - ./dockerExample_ED/web_config:/opt/WinCC_OA_proj/remote/config
      - ./dockerExample_ED/web_log:/opt/WinCC_OA_proj/remote/log
      - ./dockerExample_ED/data:/opt/WinCC_OA_proj/remote/data #webserver files
    environment:
      - EMPTYPROJ=/opt/WinCC_OA_proj/remote
      - OAPROJ=/opt/WinCC_OA_proj/remote
    ports:
      - 9449:8449 #webSocket (dashboard server)
      - 9843:8843 #webServer https://localhost:8879/#/login?dbrw  https://localhost:8843/#/login?dbrw
  postgres: #name
    image: postgres:16
    container_name: postgres
    volumes:
      - ./dockerExample_ED/db/wincc_oa/localdb/postgresql/16:/var/lib/postgresql/data
    environment:
      - PGDATA=/var/lib/postgresql/data/pgdata
  postgresCloud: #name
    image: postgres:16
    container_name: postgresCloud
    volumes:
      - postgresCloudDBFolder:/var/lib/postgresql/data
    environment:
      - POSTGRES_PASSWORD=etm#123
      - PGDATA=/var/lib/postgresql/data/pgdata
volumes:
  postgresCloudDBFolder:

Health Check

Docker-Health-Checks ermöglichen es Containern, ihren Bereitschaftsstatus zu melden. Durch die Integration eines Health-Check-Skripts für den WinCC OA-Dienst können abhängige Container, wie beispielsweise ein abgesetzter Webserver, den Start verzögern, bis der Dienst betriebsbereit ist. Dies gewährleistet eine zuverlässige Orchestrierung und verhindert verfrühte Verbindungsversuche in Docker-Compose-Umgebungen.
//dockerHealthCheck.ctl allows you to use ​the command:
system health state
depends_on:
winccoa:
condition: service_healthy
stop_grace_period: 2m
services:
  winccoa: #name
    build: ../../WinCCOA_320_4
    image: winccoa320_4 #image name
    container_name: winccoa
    volumes:
      - ./dockerExample_ED:/opt/WinCC_OA_proj/dockerExample_ED
    environment:
      - OAPROJ=/opt/WinCC_OA_proj/dockerExample_ED
      - LICENSESERVER=172.28.224.1
    ports:
      - 127.0.0.1:4897:4897 #dataPort for remote GEDI/PARA
      - 127.0.0.1:4998:4998 #eventPort for remote GEDI/PARA
#      - 8449:8449 #webSocket (dashboard server)
#      - 8843:8843 #webServer https://localhost:8843/#/login?dbrw
  webserver: #name
    build: ../../remoteManager_320_4
    image: winccoa_remote320_4 #image name
    container_name: webserver
    volumes:
      - ./dockerExample_ED/web_config:/opt/WinCC_OA_proj/remote/config
      - ./dockerExample_ED/web_log:/opt/WinCC_OA_proj/remote/log
      - ./dockerExample_ED/data:/opt/WinCC_OA_proj/remote/data #webserver files
    environment:
      - EMPTYPROJ=/opt/WinCC_OA_proj/remote
      - OAPROJ=/opt/WinCC_OA_proj/remote
    ports:
      - 9449:8449 #webSocket (dashboard server)
      - 9843:8843 #webServer https://localhost:8879/#/login?dbrw  https://localhost:8843/#/login?dbrw
    depends_on:
      winccoa:
        condition: service_healthy
    stop_grace_period: 2m
  postgres: #name
    image: postgres:16
    container_name: postgres
    volumes:
      - ./dockerExample_ED/db/wincc_oa/localdb/postgresql/16:/var/lib/postgresql/data
    environment:
      - PGDATA=/var/lib/postgresql/data/pgdata
  postgresCloud: #name
    image: postgres:16
    container_name: postgresCloud
    volumes:
      - postgresCloudDBFolder:/var/lib/postgresql/data
    environment:
      - POSTGRES_PASSWORD=etm#123
      - PGDATA=/var/lib/postgresql/data/pgdata
volumes:
  postgresCloudDBFolder:
  

Updating

Docker vereinfacht Software-Updates, indem es eine nahtlose Bereitstellung neuer Images ermöglicht. Zum Beispiel umfasst das Aktualisieren von WinCC OA das Erstellen eines neuen Images über Docker Compose und das Neustarten der Umgebung. Dieser Ansatz gewährleistet ein effizientes Einspielen von Patches mit minimalen Unterbrechungen, sofern die bereitgestellte Anwendung ordnungsgemäß für eine containerisierte Bereitstellung vorbereitet ist.

// start a build
docker compose -f docker-compose.yml build​

Run with a new patch​
docker compose -f docker-compose.yml up
build: ../../WinCCOA_320_6
image: winccoa320_6 #image name
build: ../../remoteManager_320_6
image: winccoa_remote320_6 #image name
services:
  winccoa: #name
    build: ../../WinCCOA_320_6
    image: winccoa320_6 #image name
    container_name: winccoa
    volumes:
      - ./dockerExample_ED:/opt/WinCC_OA_proj/dockerExample_ED
    environment:
      - OAPROJ=/opt/WinCC_OA_proj/dockerExample_ED
      - LICENSESERVER=172.28.224.1
    ports:
      - 127.0.0.1:4897:4897 #dataPort for remote GEDI/PARA
      - 127.0.0.1:4998:4998 #eventPort for remote GEDI/PARA
#      - 8449:8449 #webSocket (dashboard server)
#      - 8843:8843 #webServer https://localhost:8843/#/login?dbrw
  webserver: #name
    build: ../../remoteManager_320_6
    image: winccoa_remote320_6 #image name
    container_name: webserver
    volumes:
      - ./dockerExample_ED/web_config:/opt/WinCC_OA_proj/remote/config
      - ./dockerExample_ED/web_log:/opt/WinCC_OA_proj/remote/log
      - ./dockerExample_ED/data:/opt/WinCC_OA_proj/remote/data #webserver files
    environment:
      - EMPTYPROJ=/opt/WinCC_OA_proj/remote
      - OAPROJ=/opt/WinCC_OA_proj/remote
    ports:
      - 9449:8449 #webSocket (dashboard server)
      - 9843:8843 #webServer https://localhost:8879/#/login?dbrw  https://localhost:8843/#/login?dbrw
    depends_on:
      winccoa:
        condition: service_healthy
    stop_grace_period: 2m
  postgres: #name
    image: postgres:16
    container_name: postgres
    volumes:
      - ./dockerExample_ED/db/wincc_oa/localdb/postgresql/16:/var/lib/postgresql/data
    environment:
      - PGDATA=/var/lib/postgresql/data/pgdata
  postgresCloud: #name
    image: postgres:16
    container_name: postgresCloud
    volumes:
      - postgresCloudDBFolder:/var/lib/postgresql/data
    environment:
      - POSTGRES_PASSWORD=etm#123
      - PGDATA=/var/lib/postgresql/data/pgdata
volumes:
  postgresCloudDBFolder: