Symfony-Sitekit-Bridge-Skeleton

Neue Applikation erstellen: Beispiel fhms-whinchat

Eine neue Symfony Applikation erstellen:

In dem Verzeichnis wechseln, in dem die Git-Projekte liegen:

cd ~/git/

Ein initalies Symfony-Projekt erzeugen:

composer create-project symfony/skeleton:^6.4 fhms-whinchat-feds

Das Projekt wird für die PHP-Version angelegt die php -version liefert. Soll es für eine andere PHP-Version erzeugt werden, muss der composer-Aufruf mit der entsprechenden Version ausgeführt werden.

Beispiel:

php8.0 /usr/local/bin/composer create-project symfony/skeleton:^6.4 fhms-whinchat-feds

PHP 8.2 ist die minimal-Anforderung.

Weiter geht es mit:

cd fhms-whinchat
git checkout -b split/main
git subtree split -P src/publish -b split/php
cd ../fhms-whinchat-feds
git init .
git add .
git commit -m "Initial commit"
git pull ../fhms-whinchat split/php

.gitignore ergänzen:

target/
.idea/

Hier sollte die neu erstellte .gitignore erhalten bleiben (Initial commit). Dabei sind aber folgende Punkte zu übernehmen oder zu ergänzen:

  • target/
  • .idea/

Achtung: Änderungen mit git add . hinzufügen, aber noch nicht committen.

Als Nächstes aktualisieren wir die Ordnerstruktur, in dem die Source Dateien verschoben werden und alte Ordner gelöscht werden:

mv php/* src/
rmdir php

Update composer.json

composer config name sitepark/fhms-whinchat-feds
composer config repositories.sitepark composer https://satis.sitepark.com
composer config extra.symfony.allow-contrib true
composer config --json extra.symfony.endpoint \
'["'\
'https://api.github.com/repos/sitepark/'\
'symfony-recipes/contents/index.json'\
'?ref=flex/main'\
'"]'
composer config --json --merge extra.symfony.endpoint \
'["flex://defaults"]'

Auto-loading in der composer.json anpassen:

{
	"autoload": {
		"psr-4": {
			"SP\\FhmsWhinchat\\": "src/SP/FhmsWhinchat"
		}
	}
}

Verschieben der Symfony Kernel Klasse von src/Kernel.php nach src/SP/FhmsWhinchat/Kernel.php:

mv src/Kernel.php src/SP/FhmsWhinchat/

und anpassen des Namespace auf SP\FhmsWhinchat.

Da wir unseren Namespace beibehalten und nicht den default App verwenden, muss das Auto-wiring angepasst werden. Das geschieht in der config/services.yaml.

SP\FhmsWhinchat:
  resource: "../src/SP/FhmsWhinchat"
  exclude:
    - "../src/SP/FhmsWhinchat/DependencyInjection/"
    - "../src/SP/FhmsWhinchat/Entity/"
    - "../src/SP/FhmsWhinchat/Kernel.php"

Nun muss noch die Stellen aktualisiert werden, wo die Kernel Klasse bereits verwendet wird. Diese werden mit grep gefunden:

grep -rl "use App"

Nun müssen wir noch die Library installieren, die die Brücke zwischen sitekit und dem Kundenprojekt herstellt. Dabei kommet es häufig zu Fehlern. Diese müssen manuell korrigiert werden. Eventuelle Lösungen findest du in dem Abschnitt “Mögliche Probleme bei der Migration”.

# aktuell noch den Entwicklungsstand verwenden
composer require sitepark/sitekit:dev-develop
composer require sitekit/symfony-routing:^1.0

Nach dem Aufruf sind noch weitere Dateien erzeugt worden. Die config/routes.yaml und config/packages/security.yaml können gelöscht werden

rm config/routes.yaml
rm config/packages/security.yaml

Als Nächstes wird eine Firewall installiert, damit keine Pakete installiert werden, bei den Sicherheitslücken bekannt sind:

composer require --dev roave/security-advisories:dev-latest

Nun müssen noch maven build Attribute in der composer.json bereitgestellt werden:

composer config --json extra.maven \
'{'\
'"artifactId": "fhms-whinchat-feds",'\
'"groupId": "com.sitepark.sitekit"'\
'}'
phive install ergebnis/composer-normalize -t bin
phive update
composer update
php bin/composer-normalize

Für das neue Modul System muss nun die ies-module.toml erstellt werden. Diese wird vom IES benötigt, um die richtige deployment Strategie für das Modul zu finden. Dazu muss die Datei mit folgendem Inhalt angelegt werden:

cat <<EOT > ies-module.toml
id="fhms-whinchat-feds"
name="FH-Münster Whinchat - FEDS"
description="FH-Münster Whinchat - Frontend Delivery System"
type="FEDS"
EOT

Alle Änderungen müssen für den commit gestaged werden. Danach können die Änderungen committed werden:

git add .
git rebase --continue

Ab hier weiter mit Aktualisieren von Abhängigkeiten

Neue Applikation erstellen: Beispiel ruesselsheim-hoopoe

Eine neue Symfony Applikation erstellen:

In dem Verzeichnis wechseln, in dem die Git-Projekte liegen:

cd ~/git/

Ein initalies Symfony-Projekt erzeugen:

composer create-project symfony/skeleton:^6.2 ruesselsheim-hoopoe-feds

Das Projekt wird für die PHP-Version angelegt die php -version liefert. Soll es für eine andere PHP-Version erzeugt werden, muss der composer-Aufruf mit der entsprechenden Version ausgeführt werden.

Beispiel:

php8.0 /usr/local/bin/composer create-project symfony/skeleton:^6.2 ruesselsheim-hoopoe-feds

PHP 8.1 ist die minimal-Anforderung.

Weiter geht es mit:

cd ruesselsheim-hoopoe
git subtree split -P ruesselsheim-hoopoe-module/ -b split-php
cd ../ruesselsheim-hoopoe-feds
git init .
git add .
git commit -m "Initial commit"
git pull ../ruesselsheim-hoopoe split-php

Das wird in den meisten Fällen zu einem merge Konflikt in der composer.json, composer.lock und .gitignore führen.

Folgenden Hinweise sollen helfen die Konflikte zu lösen:

composer.json Konflikte lösen:

Hier sollte die neu erstellte composer.json erhalten bleiben (Initial commit). Dabei sind aber folgende Punkte zu übernehmen:

  • minimum-stabillity sollte auf stable gesetzt sein. Wenn dev-Abhängigkeiten verwendet werden, können diese mit @dev angegeben werden (im Aufbau immer der Fall)
  • autoload Konfigurationen übernehmen. Achtung! der Pfad wird weiter unten dann nochmal geändert
  • Die PHP Version im require muss auf die Version auf dem live Server gesetzt werden
  • Das name-Attribut muss neu angegeben werden. Z.B. sitepark/ruesselsheim-hoopoe-feds.
  • Prüfen, ob die scripts übernommen werden sollen.
  • repository übernehmen oder anlegen
      "repositories": {
          "sitepark": {
             "type": "composer",
             "url": "https://satis.sitepark.com"
          }
      },
    

composer.lock Konflikte lösen:

Hier kann einfach von einer Seite übernommen oder ein leeres JSON gesetzt werden. Die Datei wird in den nächsten Schritten noch neu generiert.

.gitignore Konflikte lösen:

Hier sollte die neu erstellte .gitignore erhalten bleiben (Initial commit). Dabei sind aber folgende Punkte zu übernehmen oder zu ergänzen:

  • target/
  • .idea/

Achtung: Änderungen mit git add . hinzufügen, aber noch nicht committen.

Als Nächstes aktualisieren wir die Ordnerstruktur, in dem die Source Dateien verschoben werden und alte Ordner gelöscht werden:

mv src/publish/php/* src/
rm -rf src/main src/publish/ src/site pom.xml src/assembly
rm -rf .buildpath .classpath .project .settings

Nun muss das Projekt überprüft werden, ob noch Konfigurationen angepasst, aktualisiert oder gelöscht werden können:

  • Doppelte Konfiguration für PHP Tools
  • Fehlende Konfigurationen für PHP Tools
  • Können IDE Konfigurationen aus git gelöscht werden
  • SiteKit Konfigurationen die im Symfony Fehler verursachen
    • An Stellen wie z.B. dem Header werden ggf. noch Pfade für das Frontend aus dem Modul ermittelt. Das funktioniert so nicht mehr und muss umgestellt werden. Die Stelle können wie folgt ermittelt werden.
      grep "getModule(" src/ -R
      
  • Es könnte sein, dass Pfade zu Medien mit Hilfe der Methode SP\SiteKit\Context::getResourceBaseDir() aufgebaut wurden. Das ist nicht mehr korrekt, da Medien keine Sitekit-Ressourcen (generierte PHP-Dateien) sind. Daher muss an diesen Stellen getResourceBaseDir() durch getPublicMediaBaseDir() ersetzt werden. Die Stelle können wie folgt ermittelt werden.
    grep "getResourceBaseDir(" src/ -R
    

Namespace der Applikation

Auto-loading in der composer.json anpassen:

{
	"autoload": {
		"psr-4": {
			"SP\\RuesselsheimHoopoe\\": "src/SP/RuesselsheimHoopoe"
		}
	}
}

Verschieben der Symfony Kernel Klasse von src/Kernel.php nach src/SP/Spinon/Kernel.php:

mv src/Kernel.php src/SP/RuesselsheimHoopoe/Kernel.php

und anpassen des Namespace auf SP\RuesselsheimHoopoe\Kernel.

Da wir unseren Namespace beibehalten und nicht den default App verwenden, muss das Auto-wiring angepasst werden. Das geschieht in der config/services.yaml.

SP\RuesselsheimHoopoe\:
  resource: "../src/SP/RuesselsheimHoopoe"
  exclude:
    - "../src/SP/RuesselsheimHoopoe/DependencyInjection/"
    - "../src/SP/RuesselsheimHoopoe/Entity/"
    - "../src/SP/RuesselsheimHoopoe/Kernel.php"

Nun muss noch die Stellen aktualisiert werden, wo die Kernel Klasse bereits verwendet wird. Diese werden mit grep gefunden:

grep -rl "use App"

Nun müssen wir noch die Library installieren, die die Brücke zwischen sitekit und dem Kundenprojekt herstellt. Dabei kommet es häufig zu Fehlern. Diese müssen manuell korrigiert werden. Eventuelle Lösungen findest du in dem Abschnitt “Mögliche Probleme bei der Migration”.

# aktuell noch den Entwicklungsstand verwenden
composer require sitepark/sitekit:^3.1
composer require --with-all-dependencies sitekit/symfony-routing:dev-develop@dev

In einigen Projekten wird auch sitepark/image verwendet. Dies muss dann auch noch hinzu kommen.

# aktuell noch den Entwicklungsstand verwenden
composer require sitepark/image:dev-develop@dev

Nach dem Aufruf sind noch weitere Dateien erzeugt worden, die noch korrigiert werden müssen.

config/routes.yaml

controllers:
  resource:
    path: ../src/SP/RuesselsheimHoopoe/Controller
    namespace: SP\RuesselsheimHoopoe\Controller
  type: attribute

Nach der Korrektur nochmal neu aufrufen

# aktuell noch den Entwicklungsstand verwenden
composer require --with-all-dependencies sitekit/symfony-routing:dev-develop@dev

Als Nächstes wird eine Firewall installiert, damit keine Pakete installiert werden, bei den Sicherheitslücken bekannt sind:

composer require --dev roave/security-advisories:dev-latest

Nun müssen noch maven build Attribute in der composer.json bereitgestellt werden:

{
	"extra": {
		"maven": {
			"artifactId": "ruesselsheim-hoopoe-feds",
			"groupId": "com.sitepark.sitekit"
		}
	}
}
phive install ergebnis/composer-normalize -t bin
phive update
php bin/composer-normalize

Für das neue Modul System muss nun die ies-module.toml erstellt werden. Diese wird vom IES benötigt, um die richtige deployment Strategie für das Modul zu finden. Dazu muss die Datei mit folgendem Inhalt angelegt werden:

cat <<EOT > ies-module.toml
id="ruesselsheim-hoopoe-feds"
name="Rüsselsheim Hoopoe - FEDS"
description="Rüsselsheim Hoopoe - Frontend Delivery System"
type="FEDS"
EOT

Alle Änderungen müssen für den commit gestaged werden. Danach können die Änderungen committed werden:

git add .
git rebase --continue

Aktualisieren von Abhängigkeiten

Entfernen von alten Abhängigkeiten und in der aktuellen Version wieder hinzufügen:

composer remove --no-install sitepark/coding-standard
composer require --dev sitepark/coding-standard

Hinweis: Es kann auch als sitepark/sitekit2 oder in require-dev eingetragen sein. Auch in diesen Fällen muss es entfernt werden.

php bin/composer-normalize

Beim Installieren der Abhängigkeiten wurde automatisch eine Standardkonfiguration für das Security-Bundle angelegt. Das Sitepark Routing Bundle bringt allerdings schon eine mit. Damit es nicht zu einem Konflikt kommt, muss die Datei config/packages/security.yaml gelöscht werden.

rm config/packages/security.yaml

Konfiguration der Routen

Zuerst muss das SiteparkRoutingBundle in der Anwendung registriert werden. Dazu muss in der config/bundles.php der Eintrag im array hinzugefügt werden:

return [
  // ...
  SP\Sitepark\RoutingBundle\SiteparkRoutingBundle::class => ['all' => true],
  // ...
];

Um die Routen aus dem sitekit/symfony-routing zu importieren muss folgenden Eintrag in der config/routes.yaml hinzugefügt werden:

routing_bundle:
  resource: "@SiteparkRoutingBundle/Resources/config/routing/webpage.yaml"

Die Konfiguration veranlasst Symfony dazu die, Routing Konfiguration aus dem sitekit/symfony-routing Bundle auszulesen und zur Verfügung zu stellen. Dazu gehören Routen aus der YAML Konfigurationen, aber auch Annotations der Controller.

Für den Publikationsbereich muss noch die config/services.yaml erweitert werden. Unterhalb der parameters muss der resource-root konfiguriert werden:

parameters:
  # Configuration for the path to the publication area where the webnode stores aggregates and assets.
  resource-root: "%env(resolve:RESOURCE_ROOT)%"
  sitekit.temp_dir: "%kernel.project_dir%/var/temp"

Konfiguration von .env

Die RESOURCE_ROOT-Variable ist notwendig zum Ausliefern der Website. Sie ist allerdings nicht notwendig für bin/console aufrufen oder den Warmup-Prozess. Da die Environment-Variable aber in jedem Fall gesetzt sein muss, ist es nötige diese ohne Wert in der .env-Date einzutragen. Gleiches gild für FRONTEND

cat <<EOT >> .env

###> sitekit
RESOURCE_ROOT=
FRONTEND=
LOG_DIR=var/log
LOG_BASENAME=sitekit
###< sitekit
EOT

Das Modul soll im Auslieferungszustand im prod Modus laufen. Dazu muss in der .env die Variable APP_ENV auf prod gesetzt werden.

sed -i 's/APP_ENV=.*/APP_ENV=prod/g' .env

Für lokale Entwickung kann mit der .env.local das System auf dev gesetzt werden.

cat <<EOT >> .env.local
APP_ENV=dev
EOT

Um wärend des Betriebs zu vermeiden, dass jedes mal die Env neu geparst werden muss, kann noch eine resultierende .env.local.php mit dem Kommando

composer symfony:dump-env prod

Ausgeführt werden. Da hier aber auch die lokalen definitionen berücksichtigt werden, darf diese nicht eingecheckt werden.

TODO: Dies wäre noch die Aufgabe des Warmup-Processes, das der IES-Webnode wärend des deployens ausführt.

Zu beachten ist noch das die APP_ENV Definition in der .env und .env.local nur für das Konsolenwerkzeugt bin/console gilt. Nützlich ist noch das mit bin/console -e prod die Environment aus der .env und .env.local überschrieben werden kann.

Für die Website wird APP_ENV über die Apache-Konfiguration gesetzt.

Ersatz für bootstrap.php

Die bootstrap.php wurde bisher dazu verwendet die Autoloader anzumelden und die Konfigurationen und Sprachdateien zu laden. Konfigurationen konnten auch Laufzeitspezifisch sein. Dies wird so nicht mehr unterstützt und wird nun anders gelöst.

Das Auto-loading wir jetzt vollständig von composer übernommen und muss nicht weiter berücksichtigt werden.

Für die Konfiguration und die Translations gibt es jetzt zwei Loader-Klassen, die in jedem Kunden-Projekt angelegt werden müssen.

Unter anderem wurden hier auch die Pfade für die Frontend-Dateien angegeben. Hier stellt das Frontend jetzt eine ies-module-asset-manifest.json bereitstellen, die ausgelesen wird, um die Pfade für JavaScript und CSS zu setzen. Hierfür ist im Kundenmodul nichts mehr zu berücksichten.

Die Konfigurationen werden jetzt über einen Warmup-Prozess zusammen gesammelt und als Cache abgelegt. Hierfür muss jedes Modul einen ConfigLoader implementieren.

ConfigLoader

mkdir src/SP/RuesselsheimHoopoe/Service

src/SP/RuesselsheimHoopoe/Service/ConfigLoader.php

<?php declare(strict_types=1);

namespace SP\RuesselsheimHoopoe\Service;

use SP\SiteKit\Config;
use SP\SiteKit\ConfigSet;
use SP\SiteKit\Provider\ConfigLoaderProvider;

/**
 * Loader der in Symfony-Projekte verwendet, wird um die Konfiguration zu laden.
 */
class ConfigLoader implements ConfigLoaderProvider {

	/** @var string */
	private $projectDir;

	public function __construct(string $projectDir) {
		$this->projectDir = $projectDir;
	}

	public function getConfigSets(): array {
		return [new ConfigSet('ruesselsheim-hoopoe')];
	}

	public function loadConfig(ConfigSet $configSet, Config $config) {
		$config->loadConfig($this->projectDir . '/src/config');
		/*
		 * TODO: sitepark/image muss noch ein Bundle werden, damit
		 * der das selber machen kann.
		 */
		$config->loadConfig($this->projectDir . '/vendor/sitepark/image/src/config');
	}
}

Wichtig ist hier das der ConfigLoader im Kunden-Projekt ConfigSets mit Anchor definiert. Alle anderen Module geben hier Wildcards an, wenn die Konfiguration Kunden unspezifisch ist. Zu beachten ist: Gibt es kein Konfiguration-Set mit einem Anchor, wird kein Konfiguration-Cache in der Warmup-Phase erzeugt.

Der Service muss noch angemeldet werden:

config/services.yaml

SP\RuesselsheimHoopoe\Service\ConfigLoader:
  arguments:
    - "%kernel.project_dir%"
  tags: ["sitekit.config.loader"]

TranslationLoader

Das Gleiche gilt für die Mehrsprachigkeit.

src/SP/RuesselsheimHoopoe/Service/TranslationLoader.php

<?php declare(strict_types=1);

namespace SP\RuesselsheimHoopoe\Service;

use SP\SiteKit\Provider\TranslationLoaderProvider;
use SP\SiteKit\TranslationSet;
use SP\SiteKit\Translator;

/**
 * Loader der in Symfony-Projekte verwendet, wird um die Sprach-Definitionen zu laden.
 */
class TranslationLoader implements TranslationLoaderProvider {

	/** @var string */
	private $projectDir;

	public function __construct(string $projectDir) {
		$this->projectDir = $projectDir;
	}

	/**
	 * @return TranslationSet[]
	 */
	public function getTranslationSets(): array {

		$translationSets = [];

		$localesToCache = ['de_DE'];

		foreach ($localesToCache as $local) {
			$translationSets[] = new TranslationSet(
				$local,
				'ruesselsheim-hoopoe',
				'internet');
		}
		return $translationSets;
	}

	/**
	 * @return void
	 */
	public function loadTranslation(TranslationSet $translationSet, Translator $translator) {
		$translator->addTranslation($this->getTranslationBaseDir());
	}

	private function getTranslationBaseDir(): string {
		return $this->projectDir . '/src/lang';
	}
}

Hier ist es wichtig, das ein Mandanten Anchor und auch ein Publisher-Nature angegeben wird. Das Publisher-Nature internet gilt auch für alle Publisher, die kein Nature konfiguriert haben.

Wichtig ist: Gibt es keinen TranslationLoader der eine Mandanten-Anchor und Publisher-Nature definiert, wird kein Translation-Cache in der Warmup-Phase erzeugt.

Der Service muss noch angemeldet werden:

config/services.yaml

SP\RuesselsheimHoopoe\Service\TranslationLoader:
  arguments:
    - "%kernel.project_dir%"
  tags: ["sitekit.translation.loader"]

Es ist möglich, das in der bootstrap.php auch Laufzeitabhängige Konfigurationen ergänzt werden. Beispielsweise durch die Abfrage des objectType der aktuellen Resource. Dies kann nicht über den ConfigLoader bereitgestellt werden. Hierzu muss ein zusätzlicher RuntimeConfigLoader implementiert werden. Siehe z.B. hier. Diese muss dann auch in der config/services.yaml angemeldet werden.

Wenn die Logik aus der bootstrap.php extrahiert ist können bootstrap.php und autoload.config.php gelöscht werden.

rm src/autoload.config.php  src/bootstrap.php

Bootstrapper

Es gibt noch Fälle bei denen noch Events oder Plugin am Sitekit angemeldet werden müssen. In dem Fall muss ein Bootloader definiert werden. Dazu wird das SP\SiteKit\Provider\BootstrapProvider implementiert.

<?php

declare(strict_types=1);

namespace SP\RuesselsheimHoopoe\Service;

use SP\SiteKit\Context;
use SP\SiteKit\Provider\BootstrapProvider;

class SiteKitBootstrapper implements BootstrapProvider
{
    public function bootstrap(Context $context): void
    {
        // bootstrap logic
    }
}

Es muss wie folgt als Service konfiguriert werden:

SP\RuesselsheimHoopoe\Service\SiteKitBootstrapper:
  tags: ["sitekit.bootstrapper"]

Twig-Templates

Sollte es ein Verzeichnis src/templates geben, wurde Twig-Templates verwendet. Die Integration wie im Sitekit konnte in Symfony-Projekte nicht erhalten bleiben. Die symfony-config/twig.xml wird nicht mit geladen. Siehe hier.

Grund dafür ist, dass mit der bestehenden integration Bundles wie z.B. OverblogGraphiQLBundle nicht funktionieren. Nach langem debuggen ist der Grund auf die twig.loader.chain zurückzuführen, bei denen die Bundles ihren Namespace wohl nicht registieren und damit dessen Templates nicht gefunden werden.

Hierfür gibt es noch keinen Ersatz. Hier muss bei der Umstellung des ersten Projekts das Twig-Templates verwendet noch eine Lösung gefunden werden.

Modul integration

CityGov

composer require sitekit/citygov:dev-develop
bin/console cache:warmup
bin/console feds:warm-up

Veranstaltungskalender

TODO: muss noch ein Bundle werden

composer require sitekit/events-calendar:dev-develop
bin/console cache:warmup
bin/console feds:warm-up

Wiederholbare Migration

Projekten, in denen aktiv gearbeitet wird und für die eine Migration durchgeführt werden muss, wird diese Migration mehrfach erfolgen müssen, um die änderungen zu übernehmen.

Erfolgte Anpassungen in den PHP-Klassen gehen dann bei einer erneuten Migration verloren. Eine Lösung hierfür ist die Erstellung einer Patch-Datei.

Diese kann wie folgt erstellt werden.

diff -ru ../ruesselsheim-hoopoe/ruesselsheim-hoopoe-module/src/publish/php/SP src/SP/ > ../ruesselsheim-hoopoe/symfony-migration.patch

Diese kann auch vorübergehend eingecheckt werden, wenn sich die Migration über einen längeren Zeitraum hinzieht.

Nach einer neuen Migration kann die Patch-Datei wie folgt angewendet werden:

patch -p0 < ../ruesselsheim-hoopoe/symfony-migration.patch

API absichern

Die API wird dazu verwendet, dass der IES-Webnode den Warmup-Prozess starten kann (auch wenn ies-webnode und fpm zwei verschiedene Docker-Container sind)

Zur Absicherung der API werden Keys benötigt. Diese können über die Symfony Konsole generiert werden:

bin/console lexik:jwt:generate-keypair

Dadurch wird ein neues Schlüsselpaar aus privatem und öffentlichem Schlüssel generiert. Diese werden verwendet um die Tokens der API zu signieren.

Auf dem Produktiv-System wird dieses Schlüsselpaar vom Webnode bereit gestellt. Das lokal generierte Schlüsselpaar soll nicht mit eingescheckt werden.

Dazu dient der Eintrag in der .gitignore

###> lexik/jwt-authentication-bundle ###
/config/jwt/*.pem
###< lexik/jwt-authentication-bundle ###

Projekt verpacken und installieren

Das Projekt muss verpackt werden, damit es im IES installiert werden kann. Dazu wird das Sitepark Composer-Plugin composer-ies verwendet.

Dies wird wie folgt installiert:

composer global config repositories.sitepark composer "https://satis.sitepark.com"
composer global require "sitepark/composer-ies" --dev

Vor dem Verpacken sollte noch genau definiert werden, welche Dateien in dem Archive enthalten sein sollen. Dazu kann die composer.json wie folgt ergänzt werden:

    "archive": {
        "exclude": [
            "/.*",
            "/*.*",
            "/config/jwt/*.pem",
            "/config/secrets/prod/prod.decrypt.private.php",
            "/target",
            "/var",
            "!/.env",
            "!/.env.prod",
            "!/vendor",
            "!/ies-module.build.toml",
            "!/composer.json",
            "!/composer.lock"
        ]
    },

Siehe auch composer-ies

Dann kann mit

composer ies:package

das Projekt verpackt werden. Das Ergebnis ist ein tar.gz das als Modul im IES hochgeladen werden kann.

Dies kann auch in einem Schritt erfolgen, mit dem Kommando

composer ies:install --mavenProfile [maven-profile-id]

Kundensystem umstellen

Publikationsbereich

Für die Publisher muss das neue Publisher-Attribut publicationLayout auf resources gesetzt werden.

publicationLayout=resources

Weiter muss der Document-Root in der Publisher-Konfiguration geändert werden. Es muss noch das Verzeichnis resources angehängt werden.

/var/www/ruesselsheim.de/www/resources

und

/var/www/ruesselsheim.de/preview/resources

In der Publisher-Konfiguration wird noch das Label Document-Root verwendet. Für die neuen Systeme ist dies aber nicht mehr der Document-Root. Er wird dann als Resource-Root bezeichnet.

Alle publizierten Inhalte sollen gelöscht werden.

rm -rf /var/www/ruesselsheim.de/preview/*
rm -rf /var/www/ruesselsheim.de/www/*

Dann wird alles neu generiert.

iesadmin generate ruesselsheim-hoopoe -a -async

Danach den Publisher-Service einmal stoppen und wieder starten. (Nur notwendig, damit die context.php wieder neu rausgeschrieben wird)

Apache-Konfiguration

Für die neuen Strukturen gibt es ein eigenes Apache-Marco. Dies muss nun für die virtuellen Hosts verwendet werden. Dazu ist in der Datei (docker)

data/ies-webnode/data/apache2/sites/www-ruesselsheim-hoopoe.veltrup.sitepark.de.conf

(non-docker)

/srv/sitepark/ies-webnode/data/apache2/sites/www-ruesselsheim-hoopoe.veltrup.sitepark.de.conf

anzupassen. Aus site wird fedsSite und die Konfigurationen für $type (4. Parameter, z.B. www), $directory (5. Parameter, meistens ‘/’) und $micrositePath (6. Parameter, meistens ‘/’) müssen entfernt werden. Directories werden in der neuen Struktur nicht mehr unterstützt)

Der Pfad für $wwwBase muss um den $type erweitert werden.

Beispiel: aus

# <Macro site $configName $wwwBase $serverName $type $directory $micrositePath $sitekitToken>
Use site www-test-ruesselsheim.sitepark.com "/var/www/ruesselsheim.de" www-test-ruesselsheim.sitepark.com www / / 4OAmHZPbNmtYLr3OJOL0

wird

# <Macro fedsSite $configName $baseDir $serverName $sitekitToken>
Use fedsSite www-test-ruesselsheim.sitepark.com "/var/www/ruesselsheim.de/www" www-test-ruesselsheim.sitepark.com 4OAmHZPbNmtYLr3OJOL0

Das Verhalten der FEDS-Site kann über Environment-Variablen gesteuert werden. Dazu kann die Datei

/etc/apache2/includes/extra.conf angelegt bzw. ergänzt werden

Sinvoll ist z.B die Definition eines APP_SECRET, damit nicht der in Git eingecheckte Wert verwendet wird.

SetEnv LOG_DIR "/var/log/sitepark/fpm"
SetEnv APP_ENV=prod
SetEnv APP_SECRET=558324F1B654B39E

Dies läßt sich auch pro Publikations-Bereich mit einer Datei wie /etc/apache/includes/www-test-ruesselsheim.sitepark.com.extra.conf einstellen.

Siehe auch Webserver Integration fedsSite Macro

Docker

Bei eine Docker-Umgebung, sollte in der docker-compose.yaml für den fpm-Service noch geprüft werden, ob die LOG_DIR-Variable auf /var/log/sitepark/fpm gesetzt ist.

Module und MCP

Sicherstellen, das der neue MCP-Server https://mcp.sitepark.com/mcp angebunden ist.

Die neuen Kunden-Module (Frontend und FEDS) installieren

Entwicklungssystem Umgebung (Docker) umstellen

Publikationsbereich

Für die Publisher muss das neue Publisher-Attribut publicationLayout auf resources gesetzt werden.

publicationLayout=resources

Weiter muss der Document-Root in der Publisher-Konfiguration geändert werden. Es muss noch das Verzeichnis resources angehängt werden.

/var/www/ruesselsheim-hoopoe.veltrup.sitepark.de/www/resources

In der Publisher-Konfiguration wird noch das Label Document-Root verwendet. Für die neuen Systeme ist dies aber nicht mehr der Document-Root. Er wird dann als Resource-Root bezeichnet.

Alle publizierten Inhalte sollen gelöscht werden.

rm -rf data/publications/*

Dann wird alles neu generiert.

docker compose exec -u root ies iesadmin generate --all --asynchron

Danach den Publisher-Service einmal stoppen und wieder starten. (Nur notwendig, damit die context.php wieder neu rausgeschrieben wird)

Apache-Konfiguration

Für die neuen Strukturen gibt es ein eigenes Apache-Marco. Dies muss nun für die virtuellen Hosts verwendet werden. Dazu ist in der Datei

data/ies-webnode/data/apache2/sites/www-ruesselsheim-hoopoe.veltrup.sitepark.de.conf

anzupassen. Aus site wird fedsSite und die Konfigurationen für $type (3. Parameter, z.B. www), $directory (5. Parameter, meistens ‘/’) und $micrositePath (6. Parameter, meistens ‘/’) müssen entfernt werden. Directories werden in der neuen Struktur nicht mehr unterstützt)

Der Pfad für $wwwBase muss um den $type erweitert werden.

Beispiel: aus

# <Macro site $configName $wwwBase $serverName $type $directory $micrositePath $sitekitToken>
Use site www-ruesselsheim-hoopoe.veltrup.sitepark.de "/var/www/ruesselsheim-hoopoe.veltrup.sitepark.de" www-ruesselsheim-hoopoe.veltrup.sitepark.de www / / Djfjhgr4jfdu

wird

# <Macro fedsSite $configName $baseDir $serverName $sitekitToken>
Use fedsSite www-ruesselsheim-hoopoe.veltrup.sitepark.de "/var/www/ruesselsheim-hoopoe.veltrup.sitepark.de/www" www-ruesselsheim-hoopoe.veltrup.sitepark.de Djfjhgr4jfdu

Siehe auch Webserver Integration fedsSite Macro

Frontend und FEDS deployment

Das Styleguide- und das FEDS-Projekt werden vom Jenkins gebaut und als Maven-Artifact in unseren Nexus-Server übertragen. Damit steht des über den MCP-Service zur Verfügung über den die Module-Updates im IES heruntergeladen werden.

Im IES-Admin können die Module installiert und aktualisiert werden. Der IES überträgt die Module an den IES-Webnode. Hier werden sie in Verzeichnissen der folgenden Form entpackt:

ruesselsheim-hoopoe-frontend-extract-1.0.0-SNAPSHOT-73fe02056514febf17d90d609ee914b0

Bei FEDS-Modulen wird vom IES-Webnode noch ein Warmup-Prozess getriggert.

War das Deployment der Module erfolgreich, wird der Link auf das neu installierte Module gesetzt:

ruesselsheim-hoopoe-frontend -> ruesselsheim-hoopoe-frontend-extract-1.0.0-SNAPSHOT-73fe02056514febf17d90d609ee914b0/

Das Frontend-Modul sollte nun hier zu finden sein:

veltrup@veltrup:~/ies-environments/ruesselsheim-hoopoe-neu$ ll data/ies-webnode/frontend/
insgesamt 16
drwxrwxr-x 3 veltrup veltrup 4096 Nov  7 10:59 ./
drwxrwxr-x 9 veltrup veltrup 4096 Nov  7 10:32 ../
lrwxrwxrwx 1 veltrup veltrup   84 Nov  7 10:59 ruesselsheim-hoopoe-frontend -> ruesselsheim-hoopoe-frontend-extract-1.0.0-SNAPSHOT-73fe02056514febf17d90d609ee914b0/
drwxrwxr-x 3 veltrup veltrup 4096 Nov  7 10:59 ruesselsheim-hoopoe-frontend-extract-1.0.0-SNAPSHOT-73fe02056514febf17d90d609ee914b0/

Das FEDS-Modul sollte hier zu finden sein

veltrup@veltrup:~/ies-environments/ruesselsheim-hoopoe-neu$ ll data/ies-webnode/feds/
insgesamt 16
drwxrwxr-x 3 veltrup veltrup 4096 Nov  7 10:59 ./
drwxrwxr-x 9 veltrup veltrup 4096 Nov  7 10:32 ../
lrwxrwxrwx 1 veltrup veltrup   80 Nov  7 10:59 ruesselsheim-hoopoe-feds -> ruesselsheim-hoopoe-feds-extract-1.0.0-SNAPSHOT-ebf53b2bcb28bcb8a038928ff3e1d952/
drwxrwxr-x 9 veltrup veltrup 4096 Nov  7 10:42 ruesselsheim-hoopoe-feds-extract-1.0.0-SNAPSHOT-ebf53b2bcb28bcb8a038928ff3e1d952/

Frontend und FEDS verlinken

Für die Webserver-Integration müssen die Verzeichnisse noch verlinkt werden. Siehe auch Webserver Integration fedsSite Macro

cd data/publications/ruesselsheim-hoopoe.veltrup.sitepark.de/www/
ln -s /srv/sitepark/ies-webnode/feds/ruesselsheim-hoopoe-feds app
ln -s /srv/sitepark/ies-webnode/frontend/ruesselsheim-hoopoe-frontend frontend

Ausserhalb der Docker-Container sind diese Pfade nicht gültig, da /srv/sitepark/ies-webnode/ ja nicht der korrekte Pfad für den Webnode ist. Innerhalb der Container passt das so aber und kann über

veltrup@veltrup:~/ies-environments/ruesselsheim-hoopoe-neu$ docker-compose exec apache2 ls -la /var/www/ruesselsheim-hoopoe.veltrup.sitepark.de/www/app/
total 372
drwxrwxr-x  9 1000 1000   4096 Nov  7 09:42 .
drwxrwxr-x  3 1000 1000   4096 Nov  7 09:59 ..
-rw-rw-r--  1 1000 1000   1226 Nov  7 09:42 .env
drwxrwxr-x  2 1000 1000   4096 Nov  7 09:42 bin
-rw-rw-r--  1 1000 1000   4106 Nov  7 09:42 composer.json
-rw-rw-r--  1 1000 1000 325076 Nov  7 09:42 composer.lock
drwxrwxr-x  5 1000 1000   4096 Nov  7 09:42 config
-rw-rw-r--  1 1000 1000    257 Nov  7 09:42 ies-module.build.toml
drwxrwxr-x  2 1000 1000   4096 Nov  7 09:42 public
drwxrwxr-x  6 1000 1000   4096 Nov  7 09:42 src
drwxrwxr-x  2 1000 1000   4096 Nov  7 09:42 templates
drwxr-xr-x  4 1000 1000   4096 Nov  7 09:42 var
drwxrwxr-x 34 1000 1000   4096 Nov  7 09:42 vendor

und

veltrup@veltrup:~/ies-environments/ruesselsheim-hoopoe-neu$ docker-compose exec apache2 ls -la /var/www/ruesselsheim-hoopoe.veltrup.sitepark.de/www/frontend/
total 16
drwxrwxr-x  3 1000 1000 4096 Nov  7 09:59 .
drwxrwxr-x  3 1000 1000 4096 Nov  7 09:59 ..
-rw-rw-r--  1 1000 1000  215 Nov  7 09:59 ies-module.build.toml
drwxrwxr-x 12 1000 1000 4096 Nov  7 09:59 public

kontrolliert werden.

Neue Umgebung testen

Wenn alles korrekt eingerichtet ist muss der Apache einmal neu gestartet werden

docker-compose restart apache2

Anschließend ist der Publikation-Bereich mit der neuen Struktur erreichbar.

Entwicklung ohne Watcher

Für die Entwicklung und zum debuggen ist es hilfreich, wenn sich Änderungen die Projekt-Dateien direkt auswirken. Bisher haben wir einen Watcher eingesetzt der Änderungen der Dateien überwacht und diese über den IES an die entsprechende Stelle auf den Server kopiert. Mit der neuen Umgebung ist dies nicht mehr notwendig. Das Zentrale Projekt ist ja das Kunden-Projekt, in dem alle Abhängigkeiten per Composer enthalten sind. Wir können dieses Projekt direkt als Feds-Projekt in die Systemumgebung integrieren.

Dazu kann der app-Link der im Normalfall auf das FEDS-Projekt im IES-Webnode-Ordner zeigt, direkt in das Entwicklung-Projekt verweisen.

veltrup@veltrup:~/ies-environments/ruesselsheim-hoopoe-neu$ ll data/publications/ruesselsheim-hoopoe.veltrup.sitepark.de/www/
insgesamt 16
drwxr-xr-x 3 veltrup veltrup 4096 Nov 25 13:11 ./
drwxrwxr-x 3 veltrup veltrup 4096 Nov  9 10:55 ../
lrwxrwxrwx 1 veltrup veltrup   42 Nov 25 13:11 app -> /home/veltrup/git/ruesselsheim-hoopoe-feds/
lrwxrwxrwx 1 root    root      64 Nov 23 09:32 frontend -> /srv/sitepark/ies-webnode/frontend/ruesselsheim-hoopoe-frontend/
drwxrwxr-x 4 veltrup veltrup 4096 Nov  9 10:56 resources/

Das Gleiche kann auch mit dem frontend-Ordner erfolgen

veltrup@veltrup:~/ies-environments/ruesselsheim-hoopoe-neu$ ll data/publications/ruesselsheim-hoopoe.veltrup.sitepark.de/www/
insgesamt 12
drwxr-xr-x 3 veltrup veltrup 4096 Nov 25 13:13 ./
drwxrwxr-x 3 veltrup veltrup 4096 Nov  9 10:55 ../
lrwxrwxrwx 1 veltrup veltrup   42 Nov 25 13:11 app -> /home/veltrup/git/ruesselsheim-hoopoe-feds/
lrwxrwxrwx 1 veltrup veltrup   56 Nov 25 13:13 frontend -> /home/veltrup/git/ruesselsheim-hoopoe-styleguide/target//
drwxrwxr-x 4 veltrup veltrup 4096 Nov  9 10:56 resources/

Damit die Container die Entwicklung-Verzeichnisse auch erreichen können, müssen diese noch gemounted werden.

docker-compose.yaml

apache2:
       volumes:
      - /home/veltrup/git/:/home/veltrup/git/

fpm:
       volumes:
      - /home/veltrup/git/:/home/veltrup/git/

Danach wird das Entwicklung-Verzeichnis direkt ausgeführt und alle Änderungen wirken sich direkt aus.

Sollen sich auch Änderungen in abhängige Composer-Projekte direkt auswirken, kann composer link verwendet werden.

Vision

Das Kundenprojekt wird durch ein Script gebaut. Dabei werden alle abhängigkeiten installiert und Test/CI ausgeführt.

  • Bauen des Kundenprojekts
    • über Composer werden die Abhängigkeiten installiert
    • Es werden die Tests und CI ausgeführt
  • Verpacken der Anwendung mit composer git-flow plugin
    • Es werden alle für einen produktiven Einsatz der Applikation benötigten Dateien mit verpackt (keine DEV Abhängigkeiten, keine PHP Tool Configs, keine .gitignore, … )
    • Ggf. werden noch Ordner/Dateien erstellt, die für eine produktive Ausführung benötigt werden
    • Es wird alles in ein Archiv verpackt
  • Deployen des Pakets in den MCP
    • Das Archiv wird unter einer eindeutigen Versionsnummer in den MCP geschoben
      • Macht es für eine Anwendung Sinn ein anderes Version-Schema zu verwenden? Branch mit Zeitstempel? Major Version mit GIT Hash?
    • Für den MCP/IES sieht es wie ein “normales” Modul aus. Wird von dem composer gitflow plugin Erledigt
    • Im IES Admin installiert ein Admin das Update wie gewohnt
    • Das Archiv mit der Anwendung wird vom IES WEBNODE entpackt und auf den Webserver verschoben. Das Verzeichnis bekommt einen eindeutigen Zeitstempel (bsp. app.20220908072812154)
    • In dem Verzeichnis werden noch die Symlink zu den Resources angelegt. Die Styleguide-Dateien werden in das public Verzeichnis kopiert
    • Jetzt hat der IES WEBNODE noch ein mal die Möglichkeit die Anwendung für den live Betrieb vorzubereiten (bsp. Cache warm up, .env Datei ablegen, … )
    • Nun wird der app Symlink auf app.20220908072812154 geändert. Damit ist das Update abgeschlossen.

Eventuell kann der Bauprozess in einem Docker Container gekapselt werden.

  • Vorteile:
    • Einheitliche Builds auf dem Jenkins und Entwicklungsrechnern
    • ignore-platform-reqs wird nicht mehr benötigt
  • Nachteile:
    • ggf. mehr Konfigurationsdateien

Kunden-Modul umstellen

Das Kunden-Modul sollte nur noch die Quellen für die CMS-Seite enthalten. Das heißt Eingabe-Templates, Aggregatoren, JSON-Konfiguration und alles weitere was innerhalb des IES verwendet wird.

Die meisten Kunden-Module haben dafür ein Maven-Submodul [customername]-module eingerichtet. Diese Unterstruktur kann aufgelöst werden. Da sich die Module-ID aber nicht ändern darf und sich diese aus der artifactId ergibt. Muss hier die pom.xml und die [customername]-module/pom.xml Sinnvoll zusammengefasst werden. Daraus entseht dann ein neues Projekt [customername]-module.

Redirekt- und Alias-ObjectTypes anpassen

Die Redirect-Technik hat sich mit Symfony geändert. Bisher wurde diese Technik über den Apache realisiert. Hierzu waren entsprechende Konfigurationen in den Apache-Macros enthalten.

Das Redirekt übernimmt jetzt Symfony. Dazu werden die Redirekt-Regeln in einem eigenen Verzeichnis redirects parallel zu objects und media in Form eines PHP-Arrays aggregiert.

Dafür muss in dem Kunden-Modul ein anderer Object-Type für Weiterleitungen Kurz-Adressen konfiguriert werden. Dies erfolgt in der groupTypes.json.

Aus:

	"globalGroup": {
		"objectTypes": {
			"shortUrls": ":objectTypes.shortUrls",
			"redirectUrls": ":objectTypes.redirectUrls"
		}
	},

wird

	"globalGroup": {
		"objectTypes": {
			"shortUrls-symfony": ":objectTypes.shortUrls-symfony",
			"redirectUrls-symfony": ":objectTypes.redirectUrls-symfony"
		}
	},

Wenn das Modul im IES eingespielt wird müssen für die beiden Artikel die neuen Typen noch per Hand geändert werden.

TODO

  • Logging z.Z. noch in var/log des Projekt-Verzeichnisses. Soll aber nach /var/log/sitepark/fpm
  • Wrapper around autoloader to make it optional
  • Alias- und Redirect-Map durch Symfony-Routing-Technik ersetzten
  • Microsites testen und ans Laufen bringen (sollte gehen im echt-Betrieb nochmal testen, wenn es eingerichtet wird)
  • Personalisierung testen (Wird das schon benötigt?)
  • Veranstaltungskalender ist angepasst, sollte noch richtig eingerichtet werden (phpcs, phpstan, phplint, phive, …)
  • Citygov ist angepasst, sollte noch richtig eingerichtet werden (phpcs, phpstan, phplint, phive, …)
  • Verzeichnis-Modul anpassen (ca. 2 Stunden)
  • Versuchsweise haben die URLs jetzt keinen .php Suffix mehr. Siehe auch hier
  • Styleguide muss definierte JSON-Datei liefern, in der die einzubindenden Styles/Scripte angegeben werden.
  • Styleguide muss als tar.gz mit neuer Struktur (public-Verzeichnis) inklusive ies-module.build.toml gebaut werden. Jenkins mus das tar.gz ins Maven-Repository deployen (wird jetzt auch schon gemacht, andere groupId?)
  • Prüfen, ob der Styleguide die Styles für Microsites nicht über CSS-Variablen realisieren kann, damit der IES die CSS nicht über sp:sass kompilieren muss. sp:sass sollte am liebsten als deprecated definiert werden.
  • Brauchen wir Kommandos wie yarn ies-package und yarn ies-install vergleichbar mit composer?
  • Frontend- und FEDS-Module müssen über MCP installierbar sein.
  • Merge-Request runtime config plugin

Plan:

  • Mario muss den MCP soweit bringen das die Frontend- und FEDS-Module über den neuen MCP installierbar sind. Der neue MCP soll als Docker-Container auf unserem externen Docker-Host eingerichtet werden. Diese Instanz löst dann den alten MCP-Service auf ies.sitepark.com ab, wenn er stabil läuft.
  • Anfang Januar soll das System auf dem Aufbau-System umgestellt werden. Vorher wird das Test-System verwendet, um alles durchzutesten. Dies erfolgt, sobald Rene, das Frontend so weit hat.
  • Zunächst werden nur die Module Veranstaltungskalender und Verzeichnismodul umgestellt. Ob noch weitere folgend müssen, sieht man dann, wenn sie umgesetzt werden müssen.

Frontend integrieren

Hier wird es wahrscheinlich so sein, das in dem Fronten-Projekt eine JSON-Datei gibt, in der die Pfade für JavaScript und CSS enthalten sind, die eingebunden werden müssen. Das soll die einzige Stelle werden, an der das Front-End und Backend direkt miteinander gekoppelt sind.

Für Frontend-Module für Symfony-Projekte werden keine CSS mehr vom IES über SASS erzeugt. Dies war für Microsite-Styles notwendig. Dies wird jetzt über CSS-Variablen gelöst. Bestehenden Styleguides müssen dahingehend angepasst werden.

Mögliche Probleme bei der Migration

Your requirements could not be resolved to an installable set of packages.

Kommt es bei einem composer update oder composer install zu dem Fehler, kann ein Ändern der erlaubten Stabilität weiterhelfen. Dazu muss ein @dev an das Version Constrain der Library angehangen werden.

composer require --with-all-dependencies sitekit/symfony-routing sitepark/sitekit:dev-develop@dev

Es erlaubt die Konfiguration minimum-stability der composer.json zu überscheiben, und für diese Library eine develop Version zu installieren. Dies vorgehen kann für alle Libraries angewendet werden. Bevor das Projekt release wird, sollte allerdings das dev-develop@dev durch eine stabile Version ersetzt werden. Ansonsten können unvorhergesehen Seiteneffekte während der Entwicklung, wie auch auf einem produktiv System auftreten.

Ansonsten helfen noch composer why und composer why-not beim Auflösen der konflikte. Dabei helfen vor allem Erfahrungen mit composer und zu den Versionen der Libraries.

Compile Error: Cannot declare class X because the name is already in use

Es liegt noch ein Fehler beim Auto-loading vor. Eventuell ist noch ein App\ Eintrag vorhanden. Auch tritt der Fehler auf, wenn der Namespace und Ordner des Kundenprojekts nicht identisch sind.