Dieser Artikel ist eine Fortsetzung eines Artikels über die Organisation von Continuous Integration / Continuous Delivery-Prozessen, die das Zusammenstellen, Testen und Bereitstellen von Anwendungen für Lösungen automatisieren, die auf der InterSystems-Plattform basieren.
Betrachten Sie Themen wie:
- Behälter 101
- Container in verschiedenen Phasen des Softwareentwicklungszyklus
- Kontinuierliche Lieferung mit Containern
Behälter 101
Es wurden viele Artikel und Bücher über Container und Containerisierung geschrieben, daher werde ich hier eine kleine Einführung machen, die jedoch nicht den Anspruch erhebt, endgültig zu sein. Also fangen wir an.
Container sind technisch gesehen eine Virtualisierungsmethode, bei der der Kernel des Betriebssystems mehrere isolierte Instanzen des Benutzerbereichs (Container) anstelle von einer unterstützt. Das sieht optisch so aus:

Es ist wichtig zu beachten, dass Container keine virtuellen Maschinen sind. Hier ist ein guter Artikel über ihre Unterschiede.
Containervorteile
Die Verwendung von Containern bietet mehrere Vorteile:
- Portabilität
- Wirksamkeit
- Isolierung
- Leichtigkeit
- Unveränderlichkeit
Portabilität
Der Container enthält die Anwendung zusammen mit allen Abhängigkeiten. Dies erleichtert das Ausführen von Anwendungen in verschiedenen Umgebungen, z. B. physischen Servern, virtuellen Maschinen, Testumgebungen und Produktumgebungen sowie Clouds.
Die Portabilität besteht auch in der Tatsache, dass das Docker-Image nach dem Zusammenstellen und der korrekten Funktion überall funktioniert, wenn Docker dort arbeitet, d. H. auf Windows-, Linux- und MacOS-Servern.
Wirksamkeit
Benötigen Sie bei der Arbeit mit Anwendungen für virtuelle Maschinen wirklich Betriebssystemprozesse, Systemprogramme usw.? Nein, in der Regel ist nur der Prozess Ihrer Bewerbung interessant. Container bieten genau dies: Im Container werden nur die Prozesse gestartet, die eindeutig benötigt werden, und nicht mehr. Da Container kein separates Betriebssystem benötigen, verbrauchen sie weniger Ressourcen. Eine virtuelle Maschine nimmt häufig mehrere Gigabyte ein, während ein Container nur wenige Megabyte groß sein kann, sodass Sie viel mehr Container als virtuelle Maschinen auf einem einzelnen Server ausführen können.
Da Container eine höhere Serverauslastung aufweisen, ist weniger Hardware erforderlich, was zu geringeren Kosten führt.
Isolierung
Container isolieren die Anwendung von allen anderen Prozessen, und obwohl mehrere Container auf demselben Server ausgeführt werden können, können sie völlig unabhängig voneinander sein. Jede Interaktion zwischen Containern muss explizit deklariert werden. Wenn ein Container ausfällt, wirkt sich dies nicht auf andere Container aus und kann schnell neu gestartet werden. Die Sicherheit wird auch durch diese Isolierung erhöht. Wenn Sie beispielsweise eine Webserver-Sicherheitsanfälligkeit auf einem Host ausnutzen, kann ein Angreifer Zugriff auf den gesamten Server erhalten. Bei einem Container erhält ein Angreifer jedoch nur Zugriff auf den Webserver-Container.
Leichtigkeit
Da für die Container kein separates Betriebssystem erforderlich ist, können sie innerhalb von Sekunden gestartet, gestoppt oder neu gestartet werden, wodurch alle zugehörigen Prozesse, einschließlich der Prozesse für die kontinuierliche Integration, beschleunigt werden. Sie können schneller mit der Entwicklung beginnen und keine Zeit damit verschwenden, Ihre Umgebung einzurichten.
Unveränderlichkeit
Die unveränderliche Infrastruktur besteht aus unveränderlichen Komponenten, die bei jeder Bereitstellung ersetzt und nicht aktualisiert werden. Konsistenz reduziert Inkonsistenzen und ermöglicht es Ihnen, einfach und schnell zu replizieren und zwischen verschiedenen Status Ihrer Anwendung zu wechseln. Mehr zur Unveränderlichkeit .
Neue Funktionen
Mit all diesen Vorteilen können Sie Ihre Infrastruktur und Anwendungen auf neue Weise verwalten.
Orchestrierung
Virtuelle Maschinen und Server gewinnen im Laufe der Zeit häufig an "Persönlichkeit", was in Zukunft zu vielen allgemein unangenehmen Überraschungen führt. Eine Lösung für dieses Problem ist Infrastructure as a Code (IoC) - Infrastrukturverwaltung unter Verwendung eines beschreibenden Modells unter Verwendung eines Versionskontrollsystems.
Bei Verwendung von IoC bringt das Umgebungsbereitstellungsteam die Zielumgebung unabhängig vom Ausgangszustand der Umgebung immer auf dieselbe Konfiguration. Dies wird erreicht, indem automatisch eine vorhandene Umgebung eingerichtet oder die Umgebung von Grund auf neu erstellt wird.
Mit IoC nehmen Entwickler Änderungen an der Beschreibung der Umgebung vor. Anschließend wird die Zielumgebung in einen neuen Status geändert. Wenn Sie am Mittwoch Änderungen vornehmen müssen, wird die Beschreibung bearbeitet.
All dies ist mit Containern viel einfacher. Das Herunterfahren des Containers und das Starten eines neuen Containers dauert einige Sekunden, und das Zuweisen einer neuen virtuellen Maschine dauert einige Minuten.
Skalieren
Orchestrierungswerkzeuge können auch eine horizontale Skalierung basierend auf der aktuellen Last bereitstellen. Es ist möglich, so viele Container wie derzeit erforderlich auszuführen und die Anwendung entsprechend zu skalieren. All dies reduziert auch die Kosten der Anwendung.
Container in verschiedenen Phasen des Software-Lebenszyklus
Berücksichtigen Sie die Vorteile von Containern in verschiedenen Phasen des Software-Lebenszyklus.

Entwicklung
Der wichtigste Vorteil ist der einfache Start der Entwicklung. Nach der Installation von Docker reichen zwei Befehle aus: docker pull
zum Laden des Images und docker run
zum Starten. Alle Abhängigkeiten werden bereits in der Phase der Anwendungserstellung aufgelöst.
Debuggen
Alle Umgebungen sind konsistent und ihre Definitionen existieren. Darüber hinaus ist es einfach, die erforderliche Umgebung bereitzustellen. Es reicht aus, docker pull
zu bringen, den docker pull
Container zu docker pull
und auszuführen.
Testen / QS
Im Fehlerfall können die Problemumgebung und die Bedingungen für die Reproduktion des Fehlers mit dem Container übertragen werden. Alle Infrastrukturänderungen werden „dokumentiert“. Die Anzahl der Variablen nimmt ab - Versionen von Bibliotheken, Frameworks, Betriebssystemen ... Es ist möglich, mehrere Container auszuführen, um Tests zu parallelisieren.
Lieferung
Durch die Verwendung von Containern können Sie einmal erstellen. Zusätzlich zur Verwendung von Containern benötigen Sie einen hohen Automatisierungsgrad der Montage- und Bereitstellungsprozesse. Die Containerzustellung einer Anwendung kann aufgrund zusätzlicher Isolation sicherer sein.
Kontinuierliche Lieferung
Gehen wir von der Theorie zur Praxis. Hier ein allgemeiner Überblick über unsere Montage- und Lieferautomatisierungslösung:

Drei Hauptstufen können unterschieden werden:
Montage
Im vorherigen Artikel war die Assembly inkrementell - wir haben den Unterschied zwischen der aktuellen Umgebung und der neuen Codebasis berücksichtigt und unsere Umgebung so geändert, dass sie der neuen Codebasis entspricht. Bei Containern ist jede Montage abgeschlossen. Das Build-Ergebnis ist ein Docker-Image, das überall ausgeführt werden kann.
Lieferung
Nachdem unser Image kompiliert und getestet wurde, wird es in die Docker-Registrierung hochgeladen, eine spezielle Anwendung zum Hosten des Docker-Images. Dort kann er das vorherige Bild durch den gleichen Namen (Tag) ersetzen. Zum Beispiel haben wir aufgrund eines neuen Commits für den Master-Zweig ein neues Image ( MyProject/MyApp:master
) zusammengestellt. Wenn die Tests bestanden wurden, können wir das Image in der Docker-Registrierung aktualisieren und jeder, der MyProject/MyApp:master
herunterlädt, erhält eine neue Version.
Starten
Schließlich muss das Image gestartet werden. Ein CD-System wie GitLab kann dies entweder direkt oder mithilfe eines spezialisierten Orchestrators verwalten. Der Vorgang ist jedoch im Allgemeinen der gleiche: Einige Images werden gestartet, regelmäßig auf ihre Leistung überprüft und aktualisiert, wenn eine neue Version verfügbar wird.
Lesen Sie das Webinar , in dem diese Schritte erläutert werden.
Alternativ in Bezug auf Commit:

In unserer Konfiguration für die kontinuierliche Lieferung haben wir:
- Übernehmen Sie den Code in das GitLab-Repository
- Wir sammeln das Bild
- Testen
- Veröffentlichen Sie ein neues Bild in unserer Docker-Registrierung
- Aktualisieren Sie den alten Container aus der Docker-Registrierung auf die neue Version
Dafür brauchen wir:
- Docker
- Docker-Registrierung
- Registrierte Domain (optional, aber wünschenswert)
- GUI-Tools (optional)
Docker
Zunächst müssen wir Docker starten. Ich würde empfehlen, mit einem einzelnen Server mit einer gängigen Linux-Version wie Ubuntu, RHEL oder Suse zu beginnen. Ich empfehle nicht, mit Distributionen wie CoreOS, RancherOS usw. zu beginnen - sie richten sich nicht an Anfänger. Denken Sie daran, den Speichertreiber auf Devicemapper umzustellen .
Wenn wir über umfangreiche Bereitstellungen sprechen und Orchestrierungs-Tools wie Kubernetes, Rancher oder Swarm verwenden, können Sie die meisten Aufgaben automatisieren, aber wir werden sie nicht diskutieren (zumindest im Rahmen dieses Artikels).
Docker-Registrierung
Dies ist der erste Container, den wir ausführen müssen. Es handelt sich um eine eigenständige Anwendung, mit der wir Docker-Images speichern und verteilen können. Sie müssen die Docker-Registrierung verwenden, wenn Sie:
- Steuern Sie, wo Ihre Bilder gespeichert werden
- Besitzen Sie einen Bildverteilungsserver
- Integrieren Sie die Speicherung und Verteilung von Bildern in den Entwicklungsprozess
Hier finden Sie die Dokumentation zum Starten und Konfigurieren der Docker-Registrierung.
Verbinden Sie Docker Registry und GitLab
Um die Docker-Registrierung mit GitLab zu verbinden, müssen Sie die Docker-Registrierung mit HTTPS-Unterstützung ausführen. Ich verwende Let's Encrypt, um Zertifikate zu erhalten, und habe diese Anweisung befolgt, um ein Zertifikat zu erhalten. Nachdem Sie überprüft haben, ob auf die Docker-Registrierung über HTTPS zugegriffen werden kann (Sie können dies im Browser überprüfen), befolgen Sie diese Anweisungen , um die Docker-Registrierung mit GitLab zu verbinden. Diese Anweisungen unterscheiden sich je nach Ihrer GitLab-Installation und der von Ihnen benötigten Konfiguration. In meinem Fall bestand das Setup darin, das Docker-Registrierungszertifikat und den Schlüssel zu /etc/gitlab/ssl
und diese Zeilen zu /etc/gitlab/gitlab.rb
:
registry_external_url 'https://docker.domain.com' gitlab_rails ['registry_api_url'] = "https://docker.domain.com"
Nach der Neukonfiguration von GitLab wurde eine neue Registerkarte "Registrierung" angezeigt, die Informationen zum korrekten Benennen der erstellten Bilder enthält, damit sie hier angezeigt werden.

Domain
In unserer Continuous Delivery-Konfiguration erstellen wir automatisch ein Image für jeden Zweig. Wenn das Image die Tests besteht, wird es in der Docker-Registrierung veröffentlicht und automatisch gestartet, sodass unsere Anwendung automatisch von allen Zweigen bereitgestellt wird, z.
- Mehrere
<featureName>.docker.domain.com
Zweige unter <featureName>.docker.domain.com
master.docker.domain.com
unter master.docker.domain.com
preprod.docker.domain.com
unter preprod.docker.domain.com
- Produktversion unter
prod.docker.domain.com
Dazu benötigen wir einen Domainnamen und einen Platzhalter-DNS- * .docker.domain.com
, der Anforderungen an * .docker.domain.com
an die IP-Adresse von docker.domain.com
. Alternativ können Sie verschiedene Ports verwenden.
Nginx
Da wir mehrere Umgebungen haben, müssen wir Anforderungen automatisch an Subdomains in den richtigen Container umleiten. Hierfür können wir Nginx als Reverse-Proxy verwenden. Hier ist eine Anleitung .
GUI-Tools
Um mit Containern zu arbeiten, können Sie entweder die Befehlszeile oder eine der grafischen Oberflächen verwenden. Es sind viele verfügbar, zum Beispiel:
- Rancher
- Mikrobadger
- Portainer
- Einfache Docker-Benutzeroberfläche
- ...
Mit ihnen können Sie Container erstellen und über die GUI anstelle der CLI verwalten. So sieht Rancher aus:

Gitlab-Läufer
Wie zuvor müssen wir den GitLab-Runner installieren, um Skripte auf anderen Servern ausführen zu können. Diese Frage wurde in einem früheren Artikel ausführlich beschrieben .
Beachten Sie, dass Sie die Executor-Shell verwenden müssen, nicht den Docker. Executor Docker wird verwendet, wenn Sie etwas aus dem Image benötigen, z. B. wenn Sie eine Android-Anwendung in einem Java-Container erstellen, und wenn Sie nur apk benötigen. In unserem Fall ist das Artefakt der gesamte Container, und dies erfordert die Executor-Shell.
Continuous Delivery-Konfiguration
Nachdem alle erforderlichen Komponenten konfiguriert wurden, können Sie mit der Erstellung einer Konfiguration für die kontinuierliche Bereitstellung beginnen.
Montage
Zuerst müssen wir ein Bild zusammenstellen.
Unser Code wird wie immer im Repository gespeichert, die Konfiguration der CD in gitlab-ci.yml
, aber zusätzlich (um die Sicherheit zu verbessern) werden wir mehrere Dateien, die sich auf das Image beziehen, auf dem Build-Server speichern.
Gitlab.xml
Enthält Rückrufcode für CD. Es wurde in einem früheren Artikel entwickelt und ist auf GitHub verfügbar. Dies ist eine kleine Bibliothek zum Herunterladen von Code, Ausführen verschiedener Rückrufe und zum Testen von Code. Es ist vorzuziehen, Git-Submodule zu verwenden, um dieses Projekt oder ähnliches in Ihr Repository aufzunehmen. Submodule sind besser, weil es einfacher ist, sie auf dem neuesten Stand zu halten. Eine andere Alternative besteht darin, eine Version auf GitLab zu erstellen und diese bereits zum Zeitpunkt der Erstellung mit dem Befehl ADD herunterzuladen.
iris.key
Lizenzschlüssel. Es kann während der Montage des Containers geladen und nicht auf dem Server gespeichert werden. Es ist nicht sicher, den Schlüssel im Repository zu speichern. Sie können einen Testschlüssel bei WRC erhalten oder InterSystems IRIS Experience ausprobieren.
pwd.txt
Datei mit dem Standardkennwort. Auch hier ist das Speichern des Kennworts im Repository ziemlich unsicher.
load_ci.script
Ein Skript, das:
set sc = ##Class(Security.System).Get("SYSTEM",.Properties) write:('sc) $System.Status.GetErrorText(sc) set AutheEnabled = Properties("AutheEnabled") set AutheEnabled = $ZBOOLEAN(+AutheEnabled,16,7) set Properties("AutheEnabled") = AutheEnabled set sc = ##Class(Security.System).Modify("SYSTEM",.Properties) write:('sc) $System.Status.GetErrorText(sc) zn "USER" do ##class(%SYSTEM.OBJ).Load(##class(%File).ManagerDirectory() _ "GitLab.xml","cdk") do ##class(isc.git.Settings).setSetting("hooks", "MyApp/Hooks/") do ##class(isc.git.Settings).setSetting("tests", "MyApp/Tests/") do ##class(isc.git.GitLab).load() halt
Beachten Sie, dass die erste Zeile absichtlich leer gelassen wird. Wenn dieses anfängliche Skript immer dasselbe ist, können Sie es einfach im Repository speichern.
gitlab-ci.yml
Fahren wir nun mit der Konfiguration für die kontinuierliche Lieferung fort:
build image: stage: build tags: - test script: - cp -r /InterSystems/mount ci - cd ci - echo 'SuperUser' | cat - pwd.txt load_ci.script > temp.txt - mv temp.txt load_ci.script - cd .. - docker build --build-arg CI_PROJECT_DIR=$CI_PROJECT_DIR -t docker.domain.com/test/docker:$CI_COMMIT_REF_NAME .
Was ist hier los?
Da der Image-Assemblierungsprozess nur auf Unterverzeichnisse des Basisverzeichnisses zugreifen kann - in unserem Fall auf das Stammverzeichnis des Repositorys - müssen Sie zunächst das "geheime" Verzeichnis (mit GitLab.xml
, iris.key
, pwd.txt
und load_ci.skript
) load_ci.skript
geklontes Repository.
Außerdem ist ein Benutzer / Passwort erforderlich, um auf das Terminal zuzugreifen, sodass wir sie zu load_ci.script
hinzufügen (dazu benötigen wir eine leere Zeile am Anfang von load_ci.script
).
Schließlich erstellen wir ein Docker-Image und nennen es: docker.domain.com/test/docker:$CI_COMMIT_REF_NAME
Dabei ist $CI_COMMIT_REF_NAME
der Name des Zweigs. Bitte beachten Sie: Der erste Teil des Image-Tags muss mit dem Namen des Repositorys in GitLab übereinstimmen, damit er auf der Registerkarte "Registrierung" angezeigt wird (ausführlichere Anweisungen zum korrekten Tagging finden Sie dort).
Dockerfile
Docker Image wird mit Dockerfile erstellt . Hier ist es:
FROM docker.intersystems.com/intersystems/iris:2018.1.1.613.0 ENV SRC_DIR=/tmp/src ENV CI_DIR=$SRC_DIR/ci ENV CI_PROJECT_DIR=$SRC_DIR COPY ./ $SRC_DIR RUN cp $CI_DIR/iris.key $ISC_PACKAGE_INSTALLDIR/mgr/ \ && cp $CI_DIR/GitLab.xml $ISC_PACKAGE_INSTALLDIR/mgr/ \ && $ISC_PACKAGE_INSTALLDIR/dev/Cloud/ICM/changePassword.sh $CI_DIR/pwd.txt \ && iris start $ISC_PACKAGE_INSTANCENAME \ && irissession $ISC_PACKAGE_INSTANCENAME -U%SYS < $CI_DIR/load_ci.script \ && iris stop $ISC_PACKAGE_INSTANCENAME quietly
Die folgenden Aktionen werden ausgeführt:
- Wir nehmen das Bild von InterSystems IRIS als Grundlage. Es sollte sich in Ihrer Docker-Registrierung befinden. Wenn Sie zuvor noch nicht mit Docker gearbeitet haben, versuchen Sie es mit First Look: Docker , in dem beschrieben wird, wie Sie ein InterSystems-IRIS-Image erhalten, es der Docker-Registrierung hinzufügen und manuell starten.
- Kopieren Sie zunächst unser Repository (und das "geheime" Verzeichnis) in den Container.
- Kopieren Sie den Lizenzschlüssel und
GitLab.xml
in das Verzeichnis mgr
. - Ändern Sie das Passwort in den Wert von
pwd.txt
. Beachten Sie, dass pwd.txt
während dieses Vorgangs gelöscht wird. - Startet InterSystems IRIS.
- Das
load_ci.script
wird load_ci.script
. - InterSystems IRIS stoppt.
Hier ist ein Teil-Build-Protokoll Running with gitlab-runner 10.6.0 (a3543a27) on docker 7b21e0c4 Using Shell executor... Running on docker... Fetching changes... Removing ci/ Removing temp.txt HEAD is now at 5ef9904 Build load_ci.script From http://gitlab.eduard.win/test/docker 5ef9904..9753a8d master -> origin/master Checking out 9753a8db as master... Skipping Git submodules setup $ cp -r /InterSystems/mount ci $ cd ci $ echo 'SuperUser' | cat - pwd.txt load_ci.script > temp.txt $ mv temp.txt load_ci.script $ cd .. $ docker build --build-arg CI_PROJECT_DIR=$CI_PROJECT_DIR -t docker.eduard.win/test/docker:$CI_COMMIT_REF_NAME . Sending build context to Docker daemon 401.4kB Step 1/6 : FROM docker.intersystems.com/intersystems/iris:2018.1.1.613.0 ---> cd2e53e7f850 Step 2/6 : ENV SRC_DIR=/tmp/src ---> Using cache ---> 68ba1cb00aff Step 3/6 : ENV CI_DIR=$SRC_DIR/ci ---> Using cache ---> 6784c34a9ee6 Step 4/6 : ENV CI_PROJECT_DIR=$SRC_DIR ---> Using cache ---> 3757fa88a28a Step 5/6 : COPY ./ $SRC_DIR ---> 5515e13741b0 Step 6/6 : RUN cp $CI_DIR/iris.key $ISC_PACKAGE_INSTALLDIR/mgr/ && cp $CI_DIR/GitLab.xml $ISC_PACKAGE_INSTALLDIR/mgr/ && $ISC_PACKAGE_INSTALLDIR/dev/Cloud/ICM/changePassword.sh $CI_DIR/pwd.txt && iris start $ISC_PACKAGE_INSTANCENAME && irissession $ISC_PACKAGE_INSTANCENAME -U%SYS < $CI_DIR/load_ci.script && iris stop $ISC_PACKAGE_INSTANCENAME quietly ---> Running in 86526183cf7c . Waited 1 seconds for InterSystems IRIS to start This copy of InterSystems IRIS has been licensed for use exclusively by: ISC Internal Container Sharding Copyright (c) 1986-2018 by InterSystems Corporation Any other use is a violation of your license agreement %SYS> 1 %SYS> Using 'iris.cpf' configuration file This copy of InterSystems IRIS has been licensed for use exclusively by: ISC Internal Container Sharding Copyright (c) 1986-2018 by InterSystems Corporation Any other use is a violation of your license agreement 1 alert(s) during startup. See messages.log for details. Starting IRIS Node: 39702b122ab6, Instance: IRIS Username: Password: Load started on 04/06/2018 17:38:21 Loading file /usr/irissys/mgr/GitLab.xml as xml Load finished successfully. USER> USER> [2018-04-06 17:38:22.017] Running init hooks: before [2018-04-06 17:38:22.017] Importing hooks dir /tmp/src/MyApp/Hooks/ [2018-04-06 17:38:22.374] Executing hook class: MyApp.Hooks.Global [2018-04-06 17:38:22.375] Executing hook class: MyApp.Hooks.Local [2018-04-06 17:38:22.375] Importing dir /tmp/src/ Loading file /tmp/src/MyApp/Tests/TestSuite.cls as udl Compilation started on 04/06/2018 17:38:22 with qualifiers 'c' Compilation finished successfully in 0.194s. Load finished successfully. [2018-04-06 17:38:22.876] Running init hooks: after [2018-04-06 17:38:22.878] Executing hook class: MyApp.Hooks.Local [2018-04-06 17:38:22.921] Executing hook class: MyApp.Hooks.Global Removing intermediate container 39702b122ab6 ---> dea6b2123165 [Warning] One or more build-args [CI_PROJECT_DIR] were not consumed Successfully built dea6b2123165 Successfully tagged docker.domain.com/test/docker:master Job succeeded
Starten
Wir haben ein Bild, führen Sie es aus. Bei Feature-Zweigen können Sie einfach den alten Container zerstören und einen neuen starten. Im Fall der Produktumgebung können wir zuerst den temporären Container starten und den mittleren Container ersetzen, wenn die Tests erfolgreich bestanden wurden.
Zuerst das Skript zum Löschen des alten Containers.
destroy old: stage: destroy tags: - test script: - docker stop iris-$CI_COMMIT_REF_NAME || true - docker rm -f iris-$CI_COMMIT_REF_NAME || true
Dieses Skript zerstört den laufenden Container und ist immer erfolgreich (standardmäßig gibt Docker einen Fehler zurück, wenn versucht wird, einen nicht vorhandenen Container zu stoppen / löschen).
Danach starten wir einen neuen Container und registrieren ihn als Umgebung.
run image: stage: run environment: name: $CI_COMMIT_REF_NAME url: http://$CI_COMMIT_REF_SLUG.docker.eduard.win/index.html tags: - test script: - docker run -d --expose 52773 --volume /InterSystems/durable/$CI_COMMIT_REF_SLUG:/data --env ISC_DATA_DIRECTORY=/data/sys --env VIRTUAL_HOST=$CI_COMMIT_REF_SLUG.docker.eduard.win --name iris-$CI_COMMIT_REF_NAME docker.eduard.win/test/docker:$CI_COMMIT_REF_NAME --log $ISC_PACKAGE_INSTALLDIR/mgr/messages.log
Der Nginx-Container leitet Anforderungen mithilfe der Umgebungsvariablen VIRTUAL_HOST
automatisch an den angegebenen Port um - in diesem Fall 52773.
Da in InterSystems IRIS einige Daten (Kennwörter,% SYS, Anwendungsdaten) auf dem Host gespeichert werden müssen, gibt es eine dauerhafte% SYS- Funktion, mit der Sie Daten auf dem Host speichern können, z.
iris.cpf
ist die Hauptkonfigurationsdatei.- Das
/csp
mit Webanwendungsdateien. /httpd/httpd.conf
mit privater Apache-Serverkonfiguration.- Das Verzeichnis
/mgr
in dem gespeichert sind:
- Datenbanken
IRISSYS
, IRISTEMP
, IRISAUDIT
, IRIS
, USER
. IRIS.WIJ
.- Verzeichnis
/journal
gespeichert sind. - Das Verzeichnis
/temp
für temporäre Dateien. - Protokolliert
messages.log
, journal.log
, SystemMonitor.log
.
Um Durable% SYS zu aktivieren, wird das volume
Argument angegeben, das ISC_DATA_DIRECTORY
Host-Verzeichnis ISC_DATA_DIRECTORY
und die Variable ISC_DATA_DIRECTORY
legt das Verzeichnis zum Speichern von Durable% SYS-Dateien fest. Dieses Verzeichnis sollte nicht existieren, es wird automatisch erstellt.
Daher ist die Architektur unserer containerisierten Anwendung wie folgt:

Um eine solche Anwendung zu erstellen, müssen wir mindestens eine zusätzliche Datenbank erstellen (um den Anwendungscode zu speichern) und deren Zuordnung im Anwendungsbereich erstellen. Ich habe den USER
Bereich zum Speichern von Anwendungsdaten verwendet, da dieser Bereich standardmäßig zu Durable% SYS hinzugefügt wurde. Der Anwendungscode wird in einem Container gespeichert, damit er aktualisiert werden kann.
Basierend auf dem Vorstehenden sollte % Installer :
APP
Bereich / Datenbank erstellen- Laden Sie den Code in den
APP
Bereich APP
- Erstellen Sie Mapping-Klassen unserer Anwendung im
USER
Bereich - Führen Sie eine andere Konfiguration durch (ich habe eine CSP-Webanwendung und eine REST-Webanwendung erstellt).
Code% Installer Class MyApp.Hooks.Local { Parameter Namespace = "APP"; /// See generated code in zsetup+1^MyApp.Hooks.Local.1 XData Install [ XMLNamespace = INSTALLER ] { <Manifest> <Log Text="Creating namespace ${Namespace}" Level="0"/> <Namespace Name="${Namespace}" Create="yes" Code="${Namespace}" Ensemble="" Data="IRISTEMP"> <Configuration> <Database Name="${Namespace}" Dir="/usr/irissys/mgr/${Namespace}" Create="yes" MountRequired="true" Resource="%DB_${Namespace}" PublicPermissions="RW" MountAtStartup="true"/> </Configuration> <Import File="${Dir}Form" Recurse="1" Flags="cdk" IgnoreErrors="1" /> </Namespace> <Log Text="End Creating namespace ${Namespace}" Level="0"/> <Log Text="Mapping to USER" Level="0"/> <Namespace Name="USER" Create="no" Code="USER" Data="USER" Ensemble="0"> <Configuration> <Log Text="Mapping Form package to USER namespace" Level="0"/> <ClassMapping From="${Namespace}" Package="Form"/> <RoutineMapping From="${Namespace}" Routines="Form" /> </Configuration> <CSPApplication Url="/" Directory="${Dir}client" AuthenticationMethods="64" IsNamespaceDefault="false" Grant="%ALL" Recurse="1" /> </Namespace> </Manifest> } /// This is a method generator whose code is generated by XGL. /// Main setup method /// set vars("Namespace")="TEMP3" /// do ##class(MyApp.Hooks.Global).setup(.vars) ClassMethod setup(ByRef pVars, pLogLevel As %Integer = 0, pInstaller As %Installer.Installer) As %Status [ CodeMode = objectgenerator, Internal ] { Quit ##class(%Installer.Manifest).%Generate(%compiledclass, %code, "Install") } /// Entry point ClassMethod onAfter() As %Status { try { write "START INSTALLER",! set vars("Namespace") = ..#Namespace set vars("Dir") = ..getDir() set sc = ..setup(.vars) write !,$System.Status.GetErrorText(sc),! set sc = ..createWebApp() } catch ex { set sc = ex.AsStatus() write !,$System.Status.GetErrorText(sc),! } quit sc } /// Modify web app REST ClassMethod createWebApp(appName As %String = "/forms") As %Status { set:$e(appName)'="/" appName = "/" _ appName #dim sc As %Status = $$$OK new $namespace set $namespace = "%SYS" if '##class(Security.Applications).Exists(appName) { set props("AutheEnabled") = $$$AutheUnauthenticated set props("NameSpace") = "USER" set props("IsNameSpaceDefault") = $$$NO set props("DispatchClass") = "Form.REST.Main" set props("MatchRoles")=":" _ $$$AllRoleName set sc =
Ich /usr/irissys/mgr
fest, dass ich zum Erstellen einer Datenbank, die sich nicht auf dem Host befindet, das Verzeichnis /usr/irissys/mgr
, da der Aufruf /usr/irissys/mgr
##class(%File).ManagerDirectory()
den Pfad zum Verzeichnis für Durable% SYS zurückgibt.
Tests
Führen Sie nun die Tests aus.
test image: stage: test tags: - test script: - docker exec iris-$CI_COMMIT_REF_NAME irissession iris -U USER "##class(isc.git.GitLab).test()"
Lieferung
Wenn die Tests bestanden sind, werden wir unser Bild in der Docker-Registrierung veröffentlichen.
publish image: stage: publish tags: - test script: - docker login docker.domain.com -u user -p pass - docker push docker.domain.com/test/docker:$CI_COMMIT_REF_NAME
Login / Passwort kann mit geheimen Variablen übergeben werden .
Jetzt wird das Bild auf GitLab angezeigt.

Andere Entwickler können es aus der Docker-Registrierung herunterladen. Auf der Registerkarte "Umgebungen" können alle unsere Umgebungen angezeigt werden:
Schlussfolgerungen
In dieser Artikelserie werden gängige Ansätze zur kontinuierlichen Integration erörtert. Die Automatisierung der Montage, des Testens und der Bereitstellung Ihrer Anwendung auf InterSystems-Plattformen ist möglich und einfach zu implementieren.
Der Einsatz von Containerisierungstechnologien wird dazu beitragen, die Anwendungsentwicklungs- und Bereitstellungsprozesse zu optimieren. Das Beseitigen von Inkonsistenzen zwischen Umgebungen erleichtert das Testen und Debuggen. Mit Orchestration können Sie skalierbare Anwendungen erstellen.
Referenzen