Das AS4 System kann über docker bereitgestellt werden.
Es folgt der Aufbau unseres Testsystems. Dieses basiert auf docker-compose.yml
Dateien.
Das Testsystem trennt sich dabei in mehrere Bereiche, getrennt durch unterschiedliche docker-compose.yml
Dateien:
- Infrastruktur (RabbitMQ, Keycloak)
- AS4-Services
- AS4-Crypto-Services
- Traefik (zur Steuerung der externen API)
Die Dokumentation folgt dieser Struktur, wobei auf die Infrastruktur hier nicht weiter eingegangen wird.
Weitere Hinweise für den produktiven Einsatz finden Sie im Abschnitt Nächste Schritte.
Mehr Details zum Testsystem finden Arvato Mitarbeiter in der internen Doku.
Infrastruktur
Details zu RabbitMQ finden Sie hier.
Details zu Keycloak finden Sie hier.
AS4-Services
Vorbedingungen
Die AS4-Services erfordern Zugriff auf RabbitMQ. Hierfür werden von RabbitMQ Docker Images bereitgestellt.
Zur Absicherung der REST-APIs per oauth2 kann Keycloak genutzt werden.
Die AS4-Workflows können nur ausgeführt werden, wenn sowohl AS4-Services als auch die AS4-Crypto-Services eingerichtet sind.
AS4-Services in docker-compose
Die folgende docker-compose.yml
Datei beinhaltet die AS4 Services. Ebenso werden SQL Datenbanken bereitgestellt.
version: "3.7"
networks:
default:
name: localas4
volumes:
as4-database:
services:
as4-database:
image: docker.io/library/postgres:14.1-alpine
container_name: as4-database
hostname: as4-database
restart: always
ports:
- "5435:5432"
environment:
- TZ=${TIME_ZONE}
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=${AS4_DATABASE_PASSWORD}
volumes:
- as4-database:/var/lib/postgresql/data
- ./conf/as4-database/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d/
as4-outbound-market-message-service:
image: ${DOCKER_REPO}/as4-outbound-market-message-service:${VERSION_OUTBOUND_MARKET_MESSAGE_SERVICE}
container_name: as4-outbound-market-message-service
restart: always
environment:
- SPRING_CONFIG_ADDITIONAL-LOCATION=/var/lib/config/as4-outbound-market-message-service.properties
- TZ=${TIME_ZONE}
- RABBITMQ_PASSWORD=${RABBITMQ_PASSWORD}
volumes:
- ./conf/as4-outbound-market-message-service/:/var/lib/config
labels:
- "traefik.enable=true"
- "traefik.http.services.as4-outbound-market-message-service.loadbalancer.server.port=8080"
- "traefik.http.routers.as4-outbound-market-message-service.rule=Host(`${HOST}`) && PathPrefix(`/aep-as4-outbound-market-message-service`)"
- "traefik.http.routers.as4-outbound-market-message-service.entrypoints=websecure"
- "traefik.http.routers.as4-outbound-market-message-service.tls.certresolver=resolver1"
as4-outbound-sender:
image: ${DOCKER_REPO}/as4-outbound-sender:${VERSION_OUTBOUND_SENDER}
container_name: as4-outbound-sender
restart: always
ports:
- "8082:8080"
environment:
- SPRING_CONFIG_ADDITIONAL-LOCATION=/var/lib/config/as4-outbound-sender.properties
- TZ=${TIME_ZONE}
- RABBITMQ_PASSWORD=${RABBITMQ_PASSWORD}
volumes:
- ./conf/as4-outbound-sender/:/var/lib/config
as4-inbound-endpoint:
image: ${DOCKER_REPO}/as4-inbound-endpoint:${VERSION_INBOUND_ENDPOINT}
container_name: as4-inbound-endpoint
restart: always
hostname: as4-inbound-endpoint
ports:
- "8083:8080"
expose:
- "8083"
environment:
- SPRING_CONFIG_ADDITIONAL-LOCATION=/var/lib/config/as4-inbound-endpoint.properties
- TZ=${TIME_ZONE}
- RABBITMQ_PASSWORD=${RABBITMQ_PASSWORD}
volumes:
- ./conf/as4-inbound-endpoint:/var/lib/config
- ./conf/workspace/:/workspace/as4-data
as4-address-service:
image: ${DOCKER_REPO}/as4-address-service:${VERSION_ADDRESS_SERVICE}
container_name: as4-address-service
depends_on:
- as4-database
restart: always
environment:
- SPRING_CONFIG_ADDITIONAL-LOCATION=/var/lib/config/as4-address-service.properties
- TZ=${TIME_ZONE}
- DB_PASSWORD=${AS4_DATABASE_PASSWORD}
- RABBITMQ_PASSWORD=${RABBITMQ_PASSWORD}
volumes:
- ./conf/as4-address-service/:/var/lib/config
labels:
- "traefik.enable=true"
- "traefik.http.services.as4-address-service.loadbalancer.server.port=8080"
- "traefik.http.routers.as4-address-service.rule=Host(`${HOST}`) && PathPrefix(`/aep-as4-address-service`)"
- "traefik.http.routers.as4-address-service.entrypoints=websecure"
- "traefik.http.routers.as4-address-service.tls.certresolver=resolver1"
as4-message-service:
image: ${DOCKER_REPO}/as4-message-service:${VERSION_MESSAGE_SERVICE}
container_name: as4-message-service
depends_on:
- as4-database
restart: always
environment:
- SPRING_CONFIG_ADDITIONAL-LOCATION=/var/lib/config/as4-message-service.properties
- TZ=${TIME_ZONE}
- DB_PASSWORD=${AS4_DATABASE_PASSWORD}
- RABBITMQ_PASSWORD=${RABBITMQ_PASSWORD}
volumes:
- ./conf/as4-message-service/:/var/lib/config
labels:
- "traefik.enable=true"
- "traefik.http.services.as4-message-service.loadbalancer.server.port=8080"
- "traefik.http.routers.as4-message-service.rule=Host(`${HOST}`) && PathPrefix(`/aep-as4-message-service`)"
- "traefik.http.routers.as4-message-service.entrypoints=websecure"
- "traefik.http.routers.as4-message-service.tls.certresolver=resolver1"
as4-receipt-service:
image: ${DOCKER_REPO}/as4-receipt-service:${VERSION_RECEIPT_SERVICE}
container_name: as4-receipt-service
restart: always
ports:
- "8095:8080"
environment:
- SPRING_CONFIG_ADDITIONAL-LOCATION=/var/lib/config/as4-receipt-service.properties
- TZ=${TIME_ZONE}
- RABBITMQ_PASSWORD=${RABBITMQ_PASSWORD}
volumes:
- ./conf/as4-receipt-service/:/var/lib/config
Diese docker-compose.yml
ist von Umgebungsvariablen abhängig. Diese können in einer .env
Datei wie folgt konfiguriert werden:
COMPOSE_PROJECT_NAME=AS4-Market-Communication
TIME_ZONE=Europe/Berlin
#Image versions
DOCKER_REPO=docker-nob-erp.next-level-apps.com/as4
VERSION_OUTBOUND_MARKET_MESSAGE_SERVICE=2023-08-04
VERSION_OUTBOUND_SENDER=2023-08-04
VERSION_INBOUND_ENDPOINT=2023-08-04
VERSION_ADDRESS_SERVICE=2023-08-04
VERSION_MESSAGE_SERVICE=2023-08-04
VERSION_RECEIPT_SERVICE=2023-08-04
AS4_DATABASE_PASSWORD=change_me
RABBITMQ_PASSWORD=change_me
Beachten Sie die gemounteten Volumes in den volumes
Abschnitten. Hier sind entsprechende Konfigurationsdateien, z.B. application.yml
, zu hinterlegen. Weitere Details zu den Konfigurationsdateien finden Sie in den Dokumentationen der einzelnen Services. Falls Sie die gedockerten Datenbanken auf Ihrem Testsystem nutzen möchten, sind ebenfalls Datenbank-Create-Scripte zu hinterlegen.
Die Labels dienen der Traefik Konfiguration. Vergleichen Sie hierzu auch den Traefik-Doku-Abschnitt.
Gestartet wird die Umgebung mit dem üblichen Docker-Compose Befehl:
docker-compose --env-file .env up -d
AS4-Crypto-Services
Vorbedingungen
Die AS4-Crypto-Services erfordern Zugriff auf RabbitMQ. Hierfür werden von RabbitMQ Docker Images bereitgestellt.
Zur Absicherung der REST-APIs per oauth2 kann Keycloak genutzt werden.
Es wird zwingend ein HSM (Hardware Security Module) benötigt. Produktiv nutzbare HSMs sind NICHT als Docker-Image verfügbar.
Es wird ein FSS benötigt. Die Anbindung des FSS ans HSM wird hier beschrieben.
Die AS4-Workflows können nur ausgeführt werden, wenn sowohl AS4-Services als auch die AS4-Crypto-Services eingerichtet sind.
AS4-Crypto-Services in docker-compose
Die folgende docker-compose.yml
Datei beinhaltet die AS4 Crypto Services. Ebenso werden SQL Datenbanken sowie der FSS bereitgestellt.
version: '3.8'
networks:
default:
name: localas4
volumes:
csr-data:
csr-database:
services:
csr-service:
image: ${DOCKER_REPO}/as4/csr-service:${VER_CSR}
container_name: csr-service
ports:
- "3333:3333"
volumes:
- ./config/crypto-csr/application.properties:/opt/config/application.properties
- ./config/crypto-csr/application.yml:/opt/config/application.yml
- csr-data:/opt/out
environment:
- TZ=${TIME_ZONE}
- CSR_DATABASE_PASSWORD=${CSR_DATABASE_PASSWORD}
labels:
- "traefik.enable=true"
- "traefik.http.services.as4-crypto-csr.loadbalancer.server.port=3333"
- "traefik.http.routers.as4-crypto-csr.rule=Host(`${HOST}`) && PathPrefix(`/csr-service`)"
- "traefik.http.routers.as4-crypto-csr.entrypoints=websecure"
- "traefik.http.routers.as4-crypto-csr.tls.certresolver=resolver1"
csr-database:
image: docker.io/library/postgres:14.1-alpine
container_name: csr-database
hostname: csr-database
restart: always
ports:
- "7432:5432"
environment:
- TZ=${TIME_ZONE}
- POSTGRES_PASSWORD=${CSR_DATABASE_PASSWORD}
volumes:
- csr-database:/var/lib/postgresql/data
- ./config/csr-database/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
logging:
driver: "json-file"
options:
max-size: "20m"
max-file: "10"
crl-downloader:
image: ${DOCKER_REPO}/crypto/crl-downloader:${VER_CRL}
container_name: crl-downloader
ports:
- "8090:8090"
volumes:
- ./config/crl-downloader:/var/lib/config
environment:
- TZ=${TIME_ZONE}
- SPRING_CONFIG_ADDITIONAL-LOCATION=optional:${AS4_PROP_FILE}, optional:${AS4_YML_FILE}, optional:${AS4_KEYCLOAK_ENRICHED_FILE}
labels:
- "traefik.enable=true"
- "traefik.http.services.crl-downloader.loadbalancer.server.port=8090"
- "traefik.http.routers.crl-downloader.rule=Host(`${HOST}`) && PathPrefix(`/crl-downloader`)"
- "traefik.http.routers.crl-downloader.entrypoints=websecure"
- "traefik.http.routers.crl-downloader.tls.certresolver=resolver1"
as4-crypto-operations:
container_name: as4-crypto-operations
restart: always
image: ${DOCKER_REPO}/as4/as4-crypto-operations:${VER_CRYPTO}
pull_policy: always
ports:
- "8096:8096"
env_file:
- .env
volumes:
- ./config/as4-crypto-operations:/var/lib/config
environment:
- SPRING_CONFIG_ADDITIONAL-LOCATION=optional:${AS4_CRYPTO_OPERATIONS_PROP_FILE}, optional:${AS4_CRYPTO_OPERATIONS_YML_FILE}
- TZ=${TIME_ZONE}
- RABBITMQ_PASSWORD=${RABBITMQ_PASSWORD}
Diese docker-compose.yml
ist von Umgebungsvariablen abhängig. Diese können in einer .env
Datei wie folgt konfiguriert werden:
COMPOSE_PROJECT_NAME=as4-cryptography
DOCKER_REPO=docker-nob-erp.next-level-apps.com
CSR_DATABASE_PASSWORD=change_me
RABBITMQ_PASSWORD=change_me
TIME_ZONE=Europe/Berlin
VER_CSR=2023-07-29
VER_CRYPTO=2023-07-29
AS4_CRYPTO_OPERATIONS_PROP_FILE=/var/lib/config/application.properties
AS4_CRYPTO_OPERATIONS_YML_FILE=/var/lib/config/application.yml
AS4_PROP_FILE=/var/lib/config/application.properties
AS4_YML_FILE=/var/lib/config/application.yml
AS4_KEYCLOAK_ENRICHED_FILE=/var/lib/config/application-keycloak-enriched.properties
Beachten Sie die gemounteten Volumes in den volumes
Abschnitten. Hier sind entsprechende Konfigurationsdateien, z.B. application.yml
, zu hinterlegen. Weitere Details zu den Konfigurationsdateien finden Sie in den Dokumentationen der einzelnen Services. Falls Sie die gedockerten Datenbanken auf Ihrem Testsystem nutzen möchten, sind ebenfalls Datenbank-Create-Scripte zu hinterlegen.
Die Labels dienen der Traefik Konfiguration. Vergleichen Sie hierzu auch den Traefik-Doku-Abschnitt.
Gestartet wird die Umgebung mit dem üblichen Docker-Compose Befehl:
docker-compose --env-file .env up -d
HTTPS mit Docker-Compose und Traefik
Ziel
Sie möchten nur über HTTPS auf Ihre Frontends und REST-APIs zugreifen.
Voraussetzung:
- Sie haben eine Domain und einen Server mit einer öffentlichen IP-Adresse.
- Sie haben Docker und Docker-Compose auf Ihrem Server installiert.
- Sie haben Keycloak in Ihrer
docker-compose.yml
konfiguriert. - Sie haben Ihre Angular-Frontends in Ihrer
docker-compose.yml
konfiguriert. - Sie haben alle Anwendungen mit Frontends (z. B. RabbitMQ) in Ihrer
docker-compose.yml
konfiguriert.
Lösung
Sie können Traefik in Ihrer docker-compose.yml
konfigurieren und nutzen.
Schritte
Traefik in docker-compose
Fügen Sie eine neue docker-compose.yml
hinzu. Diese beinhaltet Traefik & letsEncrypt.
version: '3.8'
volumes:
letsencrypt:
networks:
default:
external:
name: localas4
services:
traefik:
image: "traefik:v2.8.1"
restart: always
ports:
- 443:443
command:
- "--api.insecure=true"
- "--api.dashboard=True"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.resolver1.acme.tlschallenge=true"
- "--certificatesresolvers.resolver1.acme.email=test@green-energy.de"
- "--certificatesresolvers.resolver1.acme.storage=/letsencrypt/acme.json"
- "--entrypoints.traefik.address=:7777"
- "--entryPoints.web.forwardedHeaders.insecure"
- "--accesslog=true"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- letsencrypt:/letsencrypt
Stellen Sie sicher, dass Traefik dasselbe Docker-Netzwerk verwendet wie Ihre anderen Anwendungen (Abschnitt networks
).
Traefik verwendet in dieser Konfiguration Lets Encrypt, um Zertifikate zu bestellen. Es speichert sie im Volume letsencrypt
.
Traefik stellt die websecure endpoints auf Port 443 (https) bereit.
Folgende Umgebungsvariable muss für alle anderen docker-compose.yml
konfiguriert werden: $HOST
.
Keycloak
Voraussetzung: Sie haben den Keycloak-Pfad auf /auth
konfiguriert. Sie können hierfür die folgende Umgebungsvariable verwenden:
KC_HTTP_RELATIVE_PATH=/auth
Fügen Sie Keycloak die folgenden Labels hinzu:
labels:
- "traefik.enable=true"
- "traefik.http.middlewares.sslheader.headers.sslProxyHeaders.X-Forwarded-Proto=https"
- "traefik.http.routers.keycloak.middlewares=sslheader"
- "traefik.http.routers.keycloak-https.rule=Host(`$HOST`) && PathPrefix(`/auth`)"
- "traefik.http.routers.keycloak-https.entrypoints=websecure"
- "traefik.http.routers.keycloak-https.tls=true"
- "traefik.http.routers.keycloak-https.tls.certresolver=resolver1"
Achten Sie darauf, dass die Umgebungsvariable HOST
gesetzt ist.
Ergänzen Sie folgende Umgebungsvariable:
KC_PROXY=passthrough
Sie müssen keinen Keycloak-Port freigeben, da wir Traefik verwenden.
Aktualisieren Sie in der Keycloak-Benutzeroberfläche die Redirect-URIs aller verwendeten Clients auf https.
Angular Frontends
Aktualisieren Sie in keycloak.json
die Auth-Server-URL auf https.
Fügen Sie die folgenden Labels hinzu (Beispiel: B2B-UI)
labels:
- "traefik.enable=true"
- "traefik.http.routers.b2b-ui.rule=Host(`${HOST}`) && PathPrefix(`/B2B-UI`)"
- "traefik.http.routers.b2b-ui.entrypoints=websecure"
- "traefik.http.routers.b2b-ui.tls.certresolver=resolver1"
Achten Sie darauf, dass die Umgebungsvariable HOST
gesetzt ist.
Der PathPrefix
muss gemäß Ihres jeweiligen Frontends konfiguriert werden.
Sie müssen keinen Port offenlegen, da wir Traefik verwenden.
RabbitMQ UI
Fügen Sie die folgenden Labels hinzu:
labels:
- "traefik.enable=true"
- "traefik.http.services.rabbitmq3ui.loadbalancer.server.port=15672"
- "traefik.http.routers.rabbitmq3.service=rabbitmq3ui"
- "traefik.http.routers.rabbitmq3.rule=Host(`${HOST}`)"
- "traefik.http.routers.rabbitmq3.entrypoints=websecure"
- "traefik.http.routers.rabbitmq3.tls.certresolver=resolver1"
Achten Sie darauf, dass die Umgebungsvariable HOST
gesetzt ist.
Sie müssen den Frontend Port 15672 nicht offenlegen, da wir Traefik verwenden.
Nächste Schritte
Dieses Testsystem stellt von jedem Service nur eine Instanz bereit. Für den produktiven Einsatz empfehlen wir den Einsatz mehrerer parallel ausgeführter Instanzen, aus Gründen der Ausfallsicherheit und Lastverteilung. Alle Services, die REST-APIs anbieten, benötigen dann entsprechend jeweils einen vorgeschalteten Loadbalancer. Kubernetes ist hervorragend geeignet, um mehrere Microservice-Instanzen parallel auszuführen.
Das AS4 System verfügt über kein eigenes Frontend, sondern nutzt das Frontend der B2B. Sie können das AS4 System an eine bestehende B2B anschließen. Zum Anschluss wird der neue B2B-Message-Service benötigt.
Falls Sie die B2B nicht für die Marktkommunikation einsetzen, empfehlen wir die Einrichtung der B2B Frontends sowie Backends, um die B2B allein als AS4 Frontend einzusetzen. Die B2B ist dann zwischen das AS4 System und Ihre Marktkommunikationsanwendung zu schalten.
View Me Edit Me