Docker-(Container-)Installation im Detail — plantpulse-edge.service
Ab 2026.05 ist die Standardauslieferung von PlantPulse Edge für Serienfertigung/Vor-Ort ein einzelnes Docker-Container-Image.
Sieben Komponenten (Tomcat / Cassandra / Redis / HiveMQ / TSE / Dashboard / Node-RED) stecken in einem einzigen Image;
install.sh erledigt alles von den OS-Abhängigkeiten bis zur systemd-Registrierung, anschließend verwaltet plantpulse-edge.service
den Container.
Die Kurzfassung des Ablaufs, um Vor-Ort ein Gerät schnell in Betrieb zu nehmen, steht unter Schnellinstallation (install.sh).
Diese Seite ist die Referenz dazu, was diese Installation intern tut — Image-Koordinaten, docker run-Flags, Bind Mounts,
EnvironmentFile, OTA. Für den täglichen Betrieb siehe
Betriebsleitfaden Container-Modus.
Container ist plantpulse-edge.service, native ist plantpulse.service. In der systemd-Unit ist zwar
Conflicts=plantpulse.service gesetzt, aber wenn beide Dienste erzwungenermaßen gleichzeitig laufen, kollidieren Ports und Daten.
1. Image-Koordinaten
| Eintrag | Wert |
|---|---|
| Registry | docker.kopens.io/pe (anonymous pull) |
| Image-Name | plantpulse-edge |
| Vollständige Koordinate | docker.kopens.io/pe/plantpulse-edge:<tag> |
| Tag-Format | <VERSION>-<BUILD_DATE> z. B.: 2026-20260524 (oder latest) |
| Download-Server | https://product.kopens.io/plantpulse-edge/ (LAN alias) |
Feste Pfade im Image: KOPENS_HOME=/opt/kopens, PE_HOME=/opt/kopens/plantpulse-edge,
PE_DATA_DIR=/data1, JAVA_HOME=/usr/lib/jvm/java-21-openjdk.
2. Installationsablauf — bootstrap.sh → install.sh
2.1 Einzeiler
curl -fsSL https://product.kopens.io/plantpulse-edge/install.sh | sudo bash
install.sh ist identisch mit bootstrap.sh. Dieses Skript:
- entpackt das repo-tarball (
plantpulse-edge-docker.tar.gz) nach/opt/kopens/plantpulse-edge-docker/(bei Fehlschlaggit cloneals Fallback) - wendet das
PROFILE-Preset an (falls vorhanden, siehe Kapitel 3) - interaktiver Prompt — Edge ID (MAC-basierter Vorschlag) / Site ID (Standard
SITE_00001) / Mode (1=EDGEStandard /2=STANDALONE) / bei EDGE-Modus Plattform-Server + API key - führt die 9 Schritte von
install.shaus
2.2 Die 9 Schritte von install.sh
| # | Schritt |
|---|---|
| 1 | OS-Erkennung (Rocky/Alma/RHEL/Ubuntu/Debian) |
| 2 | Docker-Installation (dnf oder apt) |
| 3 | Anlegen der Verzeichnisse /data1, /etc/kopens, /var/log/kopens |
| 4 | sysctl + firewalld-Ports + chrony + hostname + nmcli static IP |
| 5 | /etc/kopens/app.properties erzeugen (EDGE_ID / SITE_ID / gerätespezifische Zufallszugangsdaten) |
| 6 | systemd-Unit installieren — plantpulse-edge.service + OTA kopens-upgrade.path/.service |
| 7 | docker pull (cosign-Signaturprüfung — standardmäßig soft-fail) |
| 8 | systemctl enable --now plantpulse-edge.service |
| 9 | cron weekly cleanup registrieren |
Bei der Erstinstallation werden admin-, MQTT-, OPC-UA-, API-key- und keystore-Passwörter gerätespezifisch zufällig erzeugt
und einmalig in /etc/kopens/credentials.txt (chmod 0600 root) gespeichert.
3. PROFILE-Preset
Über die env PROFILE werden die Standardwerte je Standorttyp auf einen Schlag angewendet.
| PROFILE | Angewendete Standardwerte |
|---|---|
production | DEV_MODE=EDGE (Plattform SERVER_HOST/SERVER_API_KEY muss angegeben werden) |
staging | DEV_MODE=EDGE, EDGE_ID=EDGE_00303, SITE_ID=SITE_00001, SERVER_HOST=192.168.0.235, SKIP_COSIGN_VERIFY=1 |
standalone | DEV_MODE=STANDALONE, SKIP_COSIGN_VERIFY=1 (keine Plattformanbindung) |
airgap | IMAGE_URL=tarball, SKIP_PULL=1, DEV_MODE=STANDALONE (Offline-Installation) |
# 양산 (플랫폼 연결)
curl -fsSL https://product.kopens.io/plantpulse-edge/install.sh \
| sudo PROFILE=production EDGE_ID=EDGE_00303 \
SERVER_HOST=10.0.0.5 SERVER_API_KEY=<uuid> bash
# 단독 운영 (플랫폼 없이)
curl -fsSL https://product.kopens.io/plantpulse-edge/install.sh \
| sudo PROFILE=standalone EDGE_ID=EDGE_LOCAL_01 bash
Eine staging-Box ist ein Klon mit denselben EDGE_00303 / SITE_00001 wie dev. Unterscheiden müssen sich nur
die Plattform-Verbindungsdaten (SERVER_HOST=192.168.0.235 / API key). Wird eine auf der Plattform nicht registrierte site verwendet,
schlägt die Selbstdiagnose-OPC der Edge mit einer FK-Verletzung fehl — daher die registrierte EDGE/site unverändert verwenden.
Wird gleichzeitig mit dev eine Verbindung zur Plattform aufgebaut, werden beide als dieselbe Edge erkannt; Tests daher zeitlich getrennt fahren.
Die vollständige Liste der bei der Installation gebräuchlichen env-Variablen steht unter env-Konfiguration §6.
4. Anatomie der systemd-Unit — plantpulse-edge.service
Die tatsächliche Container-Startdefinition, die install.sh nach /etc/systemd/system/plantpulse-edge.service ablegt.
4.1 docker run (ExecStart)
/usr/bin/docker run --rm --name plantpulse-edge \
--network=host \
--init \
--stop-timeout=120 \
-v /data1:/data1:z \
-v /etc/kopens:/etc/kopens:z \
-v /etc/kopens/conf:/opt/kopens/plantpulse-edge/conf:z \
-v /var/security:/var/security:rw,z \
-v /etc/localtime:/etc/localtime:ro \
-v /var/run/docker.sock:/var/run/docker.sock \
-e PP_LANG=${PP_LANG} \
-e PP_TZ=${PP_TZ} \
-e CERT_PASS=${CERT_PASS} \
--cap-drop=ALL \
--cap-add=NET_BIND_SERVICE \
--cap-add=NET_RAW \
--cap-add=DAC_OVERRIDE \
--cap-add=CHOWN \
--cap-add=FOWNER \
--log-driver=journald \
--log-opt tag="plantpulse-edge" \
${KOPENS_IMAGE}:${PE_VERSION}
| Flag | Bedeutung |
|---|---|
--network=host | 9 Ports automatisch freigegeben + multicast / OPC-UA discovery funktionieren nativ |
--init | tini als PID 1 (zombie reap + signal forward) |
--stop-timeout=120 | schafft Zeit für einen graceful drain von Cassandra |
--cap-drop=ALL + einzelne --cap-add | Minimalrechte. NET_RAW für PLC-ping, NET_BIND_SERVICE zum Binden von 80/443 |
4.2 Bind Mounts
| Host-Pfad | Container-Pfad | Modus | Zweck |
|---|---|---|---|
/data1 | /data1 | rw,z | Daten (Cassandra/Redis/HiveMQ/Node-RED) — bleiben auch beim Containertausch erhalten |
/etc/kopens | /etc/kopens | rw,z | Konfiguration + Signaldateien |
/etc/kopens/conf | /opt/kopens/plantpulse-edge/conf | rw,z | app.properties / log4j2.xml |
/var/security | /var/security | rw,z | TLS keystore |
/etc/localtime | /etc/localtime | ro | Zeitzone des Hosts |
/var/run/docker.sock | /var/run/docker.sock | rw | /ui/apps Docker-App-Verwaltung |
4.3 EnvironmentFile + Standardwerte
In der Unit hinterlegte Standardwerte (wenn keine Datei vorhanden):
Environment=PE_VERSION=latest
Environment=KOPENS_IMAGE=docker.kopens.io/pe/plantpulse-edge
Environment=PP_LANG=en
Environment=PP_TZ=Asia/Seoul
Environment=CERT_PASS=kopens123!
EnvironmentFile (falls vorhanden, override — der neueste Wert gewinnt):
| Datei | Schlüssel | Erzeuger |
|---|---|---|
/etc/kopens/version.env | PE_VERSION=<tag> | OTA upgrade.sh |
/etc/kopens/i18n.env | PP_LANG / PP_TZ | install.sh |
/etc/kopens/cert.env | CERT_PASS | TLS-Ausstellungsskript |
4.4 Ressourcenlimits / Neustartverhalten
MemoryMax=12G # 16GB 박스 기준 — 호스트 OOM 방지
MemoryHigh=11G
CPUQuota=600% # 6 cores
TasksMax=8192
Restart=on-failure
RestartSec=30s
TimeoutStartSec=300
TimeoutStopSec=180
Das heap-verkleinernde Override (drop-in) für 8-GB-Boxen steht unter Container-Modus §Ressourcenlimits.
5. Lesepfade der Container-Laufzeitkonfiguration
Im WAR-Modus (ab 2026-06-13) wird die Konfiguration direkt aus /etc/kopens des Hosts gelesen — kein Neubau des Images nötig.
/etc/kopens/app.properties ← 운영자가 편집하는 canonical
│ (entrypoint 가 symlink 생성)
▼
/etc/kopens/conf/app.properties ──bind──▶ /opt/kopens/plantpulse-edge/conf/app.properties
▲
Tomcat setenv.sh: -Dpe.conf.dir=/opt/kopens/plantpulse-edge/conf
- app.properties:
/etc/kopens/app.propertiesauf dem Host ist die Source of Truth. Fehlt sie, seedet das entrypoint den image default. Bearbeitung durch den Betreiber → Übernahme perconfig.sh --restart. - log4j2.xml: Das entrypoint kopiert bei jedem Start vom webapp default nach
conf/log4j2.xml(Code-Artefakt — Loglevel ohne Image-Neubau ändern und restart). - HiveMQ auth.properties: Das entrypoint synchronisiert bei jedem Start automatisch mit
mqtt.server.*ausapp.properties— es genügt,app.propertiesanzupassen. - TLS-Passwörter: Das entrypoint löst
CERT_PASSauscert.envauf und patcht die Passwörter für Tomcatserver.xml, HiveMQ config und OPC-UA keystore gesammelt.
Zur env→Konfigurations-Spiegelung im Detail siehe env-Konfiguration, zur Bedeutung der einzelnen Schlüssel den app.properties-Leitfaden.
6. OTA-Upgrade / Rollback
Die Version wird durch die eine Zeile PE_VERSION in /etc/kopens/version.env festgelegt — OTA ändert nur diese Datei und startet neu.
# 최신으로 업그레이드 (pre-snapshot → pull → restart → 90초 health probe → 실패 시 auto-rollback)
sudo bash /opt/kopens/install/upgrade.sh
# 특정 tag 로
sudo bash /opt/kopens/install/upgrade.sh --to 2026-20260601
# 직전 tag 로 rollback
sudo bash /opt/kopens/install/upgrade.sh --rollback
# 새 빌드 존재만 확인
sudo bash /opt/kopens/install/upgrade.sh --check
Manuelles Rollback:
echo 'PE_VERSION=2026-20260524' > /etc/kopens/version.env
sudo systemctl restart plantpulse-edge.service
Status: cat /etc/kopens/upgrade.status → idle | running | success | rolling-back | rolled-back | error.
Ablauf im Detail unter Container-Modus §OTA.
7. Manuelles docker run zum Debuggen
Im Betrieb ausschließlich über systemd / install.sh, für isoliertes Debugging jedoch manueller Start:
sudo docker run --rm --name pe-debug \
--network=host --init \
-v /data1:/data1:z \
-v /etc/kopens:/etc/kopens:z \
-v /etc/kopens/conf:/opt/kopens/plantpulse-edge/conf:z \
-v /var/security:/var/security:rw,z \
-e PP_LANG=en -e PP_TZ=Asia/Seoul -e CERT_PASS="$(. /etc/kopens/cert.env; echo $CERT_PASS)" \
docker.kopens.io/pe/plantpulse-edge:<tag>
Deployment ausschließlich über die Pipeline — Image-(Re-)Build / push / staging-Redeployment nicht lokal ausführen, sondern über die Release-Kette von
plantpulse-edge-docker(edge:libs→edge:deploy-dev→edge:image→edge:staging→edge:version, Trigger über die Pipeline-VariableRELEASE=1). Der obige Befehl gilt nur für isoliertes Debugging.
8. Verifizierung nach der Installation
systemctl is-active plantpulse-edge.service
sudo bash /opt/kopens/install/bin/status.sh
# version: container_mode=true 여야 함
curl -ks https://127.0.0.1/api/v1/system/version | python3 -m json.tool
# health: HTTP 200 + components UP
curl -ks https://127.0.0.1/api/v1/system/health | python3 -m json.tool
| Oberfläche | URL |
|---|---|
| Web-UI | https://<gateway-ip>/ui/main |
| Node-RED | https://<gateway-ip>/ui/flow/ |
| Swagger UI | https://<gateway-ip>/public/swagger-ui/index.html |
Maßnahmen je Symptom unter Installations-Troubleshooting, Betrieb/Störungen unter Betriebsleitfaden Container-Modus.
9. Weiterführende Dokumente
- Schnellinstallation (
install.sh) — Kurzfassung der Vor-Ort-Installation eines Geräts - env-Konfiguration —
PROFILE/PP_LANG/CERT_PASS/-Dpe.conf.dir - Native Installation — Direktinstallation ohne Container (dev/legacy)
- Betriebsleitfaden Container-Modus — pe-*-Werkzeuge / Logs / Störungsbehebung
- Offline- / Air-Gap-Netzwerk-Installation / Serienfertigungslinie (
factory.sh) - Abnahmekriterien für Produktion