Update readme.md
This commit is contained in:
parent
e89f9790a2
commit
47c362b62e
1 changed files with 276 additions and 336 deletions
612
readme.md
612
readme.md
|
|
@ -1,19 +1,11 @@
|
|||
# Moodle Deployment auf Cloud Foundry
|
||||
# Umfassende Anleitung: Moodle auf STACKIT Cloud Foundry
|
||||
|
||||
Diese Anleitung beschreibt die Schritte für ein robustes und automatisch skalierendes Deployment der Lernplattform Moodle auf einer Cloud Foundry-Umgebung. Dies umfasst die Konfiguration für eine externe Datenbank, S3-Dateispeicher, Session-Handling für mehrere Instanzen und Autoskalierung.
|
||||
|
||||
## Voraussetzungen
|
||||
|
||||
* Zugang zur STACKIT Cloud Foundry Umgebung.
|
||||
* Das `cf` Command Line Interface (CLI) ist installiert.
|
||||
* Zugangsdaten den STACKIT S3-kompatiblen Object Storage sind vorhanden.
|
||||
* DNS CNAME Eintrag auf "console.apps.01.cf.eu01.stackit.cloud." in passender Domäne
|
||||
|
||||
In diesem Beispiel wurde es im STACKIT DNS auf die folgende Route/URL durchgeführt: moodle.cf.demo.stackit.rocks
|
||||
Diese Anleitung dokumentiert den gesamten Prozess, um eine Moodle-Instanz auf STACKIT Cloud Foundry zu deployen. Sie umfasst die Ersteinrichtung der CF-Umgebung, die Vorbereitung der Moodle-Anwendung inklusive aller notwendigen Workarounds für den Proxy- und CDN-Betrieb sowie die Konfiguration für eine externe Datenbank, S3-Dateispeicher, Redis-Caching und Autoskalierung.
|
||||
|
||||
## Architektur
|
||||
|
||||
Die folgende Abbildung zeigt die Architektur der Moodle-Umgebung auf STACKIT als textbasiertes Flussdiagramm.
|
||||
Die folgende Abbildung zeigt die Architektur der Moodle-Umgebung auf STACKIT als Mermaid-Diagramm.
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[Anwender] --> B(STACKIT DNS);
|
||||
|
|
@ -38,70 +30,151 @@ graph TD
|
|||
E2 --> F;
|
||||
E2 --> G;
|
||||
E2 --> H;
|
||||
```
|
||||
|
||||
## Verzeichnisstruktur
|
||||
|
||||
Bevor du am Ende die Anwendung pushst, stelle sicher, dass deine lokale Verzeichnisstruktur wie folgt aussieht. Dies ist entscheidend für den Erfolg.
|
||||
|
||||
```
|
||||
.
|
||||
├── manifest.yml
|
||||
└── moodle/
|
||||
├── .bp-config/
|
||||
│ ├── options.json
|
||||
│ └── php/
|
||||
│ └── php.ini.d/
|
||||
│ ├── moodle.ini
|
||||
│ └── mysqli.ini
|
||||
├── httpd/
|
||||
│ └── logs/
|
||||
│ └── httpd.pid -> /tmp/httpd.pid
|
||||
├── lib/
|
||||
├── logs/
|
||||
│ ├── proc-man.log -> /dev/stdout
|
||||
│ └── rewrite.log -> /dev/stdout
|
||||
├── php/
|
||||
│ └── var/
|
||||
│ └── run/
|
||||
│ └── php-fpm.pid -> /tmp/php-fpm.pid
|
||||
├── config.php
|
||||
├── index.php
|
||||
└── ... (alle anderen Moodle-Dateien und Ordner)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Schritt-für-Schritt Anleitung
|
||||
|
||||
### 1. Moodle herunterladen
|
||||
|
||||
Erstelle ein Projektverzeichnis. Lade den Quellcode der Moodle-Version 5.0.1 mit `wget` herunter und entpacke ihn in einen Unterordner namens `moodle`.
|
||||
|
||||
```bash
|
||||
wget https://packaging.moodle.org/stable500/moodle-5.0.1.tgz
|
||||
tar -xzf moodle-5.0.1.tgz
|
||||
````
|
||||
|
||||
### 2\. Cloud Foundry Services erstellen
|
||||
## 1\. Voraussetzungen & initiales Setup
|
||||
|
||||
Erstelle die benötigten Service-Instanzen in deiner Cloud Foundry-Umgebung.
|
||||
### 1.1. CLIs installieren
|
||||
|
||||
Für diese Anleitung werden zwei Command Line Interfaces (CLIs) benötigt:
|
||||
|
||||
* **Cloud Foundry CLI:** Das primäre Werkzeug zur Interaktion mit der Cloud Foundry Plattform.
|
||||
|
||||
* **Download:** [github.com/cloudfoundry/cli/releases](https://github.com/cloudfoundry/cli/releases)
|
||||
|
||||
* **STACKIT CLI:** Wird benötigt, um STACKIT-spezifische Services wie Object Storage zu verwalten.
|
||||
|
||||
* **Installationsanleitung:** Befolgen Sie die offizielle Anleitung unter [docs.stackit.cloud](https://docs.stackit.cloud/stackit/en/service-plans-redis-75142939.html).
|
||||
|
||||
### 1.2. Bei STACKIT Cloud Foundry anmelden
|
||||
|
||||
Nach der Installation des CF CLI müssen Sie sich bei der STACKIT Cloud Foundry API anmelden.
|
||||
|
||||
* **API-Endpunkt:** `https://api.cf.eu01.stackit.cloud`
|
||||
|
||||
* **Login-Befehl:**
|
||||
|
||||
```bash
|
||||
cf login -a [https://api.cf.eu01.stackit.cloud](https://api.cf.eu01.stackit.cloud) --sso
|
||||
```
|
||||
|
||||
### 1.3. Organisation und Space erstellen
|
||||
|
||||
Eine "Organisation" ist der höchste Mandant, ein "Space" eine Umgebung (z.B. Entwicklung, Produktion).
|
||||
|
||||
1. **Organisation erstellen:**
|
||||
|
||||
```bash
|
||||
cf create-org DEINE_ORGANISATION
|
||||
```
|
||||
|
||||
2. **Space erstellen:**
|
||||
|
||||
```bash
|
||||
cf create-space produktion -o DEINE_ORGANISATION
|
||||
```
|
||||
|
||||
3. **Ziel festlegen:**
|
||||
|
||||
```bash
|
||||
cf target -o DEINE_ORGANISATION -s produktion
|
||||
```
|
||||
|
||||
## 2\. Moodle-Projekt lokal vorbereiten
|
||||
|
||||
### 2.1. Moodle und Plugins herunterladen
|
||||
|
||||
```bash
|
||||
# Datenbank-Service erstellen
|
||||
cf create-service <dein-mariadb-service> <plan> moodle-demo-mariadb
|
||||
# Moodle 5.0.1 herunterladen und entpacken
|
||||
wget [https://packaging.moodle.org/stable500/moodle-5.0.1.tgz](https://packaging.moodle.org/stable500/moodle-5.0.1.tgz)
|
||||
tar -xzf moodle-5.0.1.tgz
|
||||
|
||||
# Autoscaler-Service erstellen
|
||||
cf create-service autoscaler autoscaler-free-plan moodle-autoscaler
|
||||
# Redis-Plugin für Moodle installieren
|
||||
wget [https://moodle.org/plugins/download.php/29037/cachestore_redis_moodle41_2022112800.zip](https://moodle.org/plugins/download.php/29037/cachestore_redis_moodle41_2022112800.zip)
|
||||
unzip cachestore_redis_moodle41_2022112800.zip
|
||||
mv redis moodle/cache/stores/
|
||||
|
||||
# S3 Object File System Plugin installieren
|
||||
cd moodle
|
||||
git clone [https://github.com/catalyst/moodle-tool_objectfs.git](https://github.com/catalyst/moodle-tool_objectfs.git) admin/tool/objectfs
|
||||
cd ..
|
||||
```
|
||||
|
||||
### 3\. Konfigurationsdateien anlegen und anpassen
|
||||
### 2.2. Buildpack- & System-Workarounds einrichten
|
||||
|
||||
Dies ist der wichtigste Schritt, bei dem alle spezifischen Konfigurationen für den Betrieb auf Cloud Foundry vorgenommen werden.
|
||||
Diese Schritte sind für das `cloudfoundry/php-buildpack` notwendig.
|
||||
|
||||
#### a) `manifest.yml` anlegen
|
||||
```bash
|
||||
# Web-Verzeichnis festlegen und PHP-Version auf 8.2 erzwingen
|
||||
echo '{"WEBDIR": ".", "PHP_VERSION": "{PHP_82_LATEST}"}' > moodle/.bp-config/options.json
|
||||
|
||||
Erstelle im Hauptverzeichnis deines Projekts die `manifest.yml`-Datei mit folgendem Inhalt. Passe die Routen sowie deine S3-Zugangsdaten an.
|
||||
# PHP-Erweiterungen und Moodle-Einstellungen konfigurieren
|
||||
mkdir -p moodle/.bp-config/php/php.ini.d/
|
||||
echo "extension=mysqli" > moodle/.bp-config/php/php.ini.d/mysqli.ini
|
||||
echo "extension=redis" > moodle/.bp-config/php/php.ini.d/redis.ini
|
||||
echo "max_input_vars = 5000" > moodle/.bp-config/php/php.ini.d/moodle.ini
|
||||
|
||||
# Symbolische Links für Log- und PID-Dateien anlegen
|
||||
mkdir -p moodle/logs
|
||||
ln -s /dev/stdout moodle/logs/rewrite.log
|
||||
ln -s /dev/stdout moodle/logs/proc-man.log
|
||||
mkdir -p moodle/httpd/logs
|
||||
mkdir -p moodle/php/var/run
|
||||
ln -s /tmp/httpd.pid moodle/httpd/logs/httpd.pid
|
||||
ln -s /tmp/php-fpm.pid moodle/php/var/run/php-fpm.pid
|
||||
```
|
||||
|
||||
## 3\. Cloud Foundry & STACKIT Services erstellen
|
||||
|
||||
#### 3.1. Object Storage Bucket erstellen (STACKIT CLI)
|
||||
|
||||
Verwenden Sie das STACKIT CLI, um einen Bucket zu erstellen.
|
||||
|
||||
```bash
|
||||
# Erstellt einen neuen Bucket
|
||||
stackit object-storage bucket create --name <BUCKET_NAME>
|
||||
```
|
||||
|
||||
Anschließend benötigen Sie Zugangsdaten, um auf den Bucket zugreifen zu können.
|
||||
|
||||
```bash
|
||||
# Erstellt neue Zugangsdaten für Ihr Projekt
|
||||
# Sie müssen Ihre STACKIT Projekt-ID angeben.
|
||||
stackit object-storage credential create --project-id <DEINE_PROJEKT_ID>
|
||||
```
|
||||
|
||||
**Notieren Sie sich den ausgegebenen `accessKey` und `secretAccessKey`.** Sie werden im nächsten Schritt benötigt.
|
||||
|
||||
#### 3.2. Cloud Foundry Services erstellen (CF CLI)
|
||||
|
||||
Diese Befehle legen die für Moodle notwendigen CF-Services an.
|
||||
|
||||
```bash
|
||||
# Datenbank-Service
|
||||
cf create-service <dein-mariadb-service> <plan> moodle-demo-mariadb
|
||||
|
||||
# Redis-Service (Optional)
|
||||
cf create-service appcloud-redis7 redis-4.16.100-replica moodle-redis
|
||||
|
||||
# Autoscaler-Service
|
||||
cf create-service autoscaler autoscaler-free-plan moodle-autoscaler
|
||||
|
||||
# User-Provided Service für die S3-Credentials aus dem vorherigen Schritt
|
||||
cf create-user-provided-service moodle-s3-credentials -p '{
|
||||
"access_key": "DEIN_ZUVOR_GENERIERTER_ACCESS_KEY",
|
||||
"secret_key": "DEIN_ZUVOR_GENERIERTER_SECRET_KEY",
|
||||
"bucket": "DEIN_ZUVOR_GENERIERTES_BUCKET",
|
||||
"endpoint": "[https://s3.eu01.stackit.cloud](https://s3.eu01.stackit.cloud)"
|
||||
}'
|
||||
```
|
||||
|
||||
## 4\. Konfigurationsdateien erstellen
|
||||
|
||||
#### a) Manifest-Dateien
|
||||
|
||||
Erstellen Sie zwei Manifest-Dateien, um einfach zwischen dem Betrieb mit und ohne CDN wechseln zu können.
|
||||
|
||||
**`manifest-cdn.yml` (Produktion):**
|
||||
|
||||
```yaml
|
||||
---
|
||||
|
|
@ -109,25 +182,20 @@ applications:
|
|||
- name: moodle
|
||||
memory: 2G
|
||||
disk_quota: 2G
|
||||
buildpack: php_buildpack
|
||||
buildpack: [https://github.com/cloudfoundry/php-buildpack.git](https://github.com/cloudfoundry/php-buildpack.git)
|
||||
path: moodle
|
||||
routes:
|
||||
- route: deine-moodle-route.deine-domain.de
|
||||
- route: moodle.cf.demo.stackit.rocks
|
||||
- route: moodle.demo.stackit.rocks
|
||||
env:
|
||||
# Buildpack anweisen, weniger Debug-Logs in Dateien zu schreiben
|
||||
USE_CDN: 'true'
|
||||
WWW_ROOT: "[https://moodle.demo.stackit.rocks](https://moodle.demo.stackit.rocks)"
|
||||
BP_PHP_LOG_LEVEL: WARNING
|
||||
|
||||
# S3-Zugangsdaten für den Object Storage
|
||||
S3_ACCESS_KEY: DEIN_S3_ACCESS_KEY
|
||||
S3_SECRET_KEY: DEIN_S3_SECRET_KEY
|
||||
S3_BUCKET: DEIN_S3_BUCKET_NAME
|
||||
S3_ENDPOINT: DEIN_S3_ENDPOINT_URL
|
||||
|
||||
services:
|
||||
- moodle-demo-mariadb
|
||||
- moodle-redis
|
||||
- moodle-autoscaler
|
||||
|
||||
# Konfiguration für den Autoscaler-Service
|
||||
- moodle-s3-credentials
|
||||
autoscaling:
|
||||
min_instances: 2
|
||||
max_instances: 4
|
||||
|
|
@ -146,200 +214,7 @@ applications:
|
|||
cool_down_secs: 60
|
||||
```
|
||||
|
||||
#### b) Buildpack-Konfiguration (`.bp-config`)
|
||||
|
||||
Diese Dateien steuern das Verhalten des PHP Buildpacks.
|
||||
|
||||
1. **Web-Verzeichnis festlegen:**
|
||||
|
||||
```bash
|
||||
echo '{"WEBDIR": "."}' > moodle/.bp-config/options.json
|
||||
```
|
||||
|
||||
2. **PHP-Erweiterungen und -Einstellungen konfigurieren:**
|
||||
|
||||
```bash
|
||||
mkdir -p moodle/.bp-config/php/php.ini.d/
|
||||
echo "extension=mysqli" > moodle/.bp-config/php/php.ini.d/mysqli.ini
|
||||
echo "max_input_vars = 5000" > moodle/.bp-config/php/php.ini.d/moodle.ini
|
||||
```
|
||||
|
||||
#### c) Workarounds für das schreibgeschützte Dateisystem
|
||||
|
||||
Erstelle die Verzeichnisse und symbolischen Links für Log- und PID-Dateien.
|
||||
|
||||
```bash
|
||||
# Für Log-Dateien (Umleitung auf die Standardausgabe)
|
||||
mkdir -p moodle/logs
|
||||
ln -s /dev/stdout moodle/logs/rewrite.log
|
||||
ln -s /dev/stdout moodle/logs/proc-man.log
|
||||
|
||||
# Für Prozess-ID-Dateien (Umleitung in das beschreibbare /tmp-Verzeichnis)
|
||||
mkdir -p moodle/httpd/logs
|
||||
mkdir -p moodle/php/var/run
|
||||
ln -s /tmp/httpd.pid moodle/httpd/logs/httpd.pid
|
||||
ln -s /tmp/php-fpm.pid moodle/php/var/run/php-fpm.pid
|
||||
```
|
||||
|
||||
#### d) `config.php` erstellen und anpassen
|
||||
|
||||
Kopiere `moodle/config-dist.php` zu `moodle/config.php` und ersetze den gesamten Inhalt mit der folgenden Vorlage. Passe `$CFG->wwwroot` an deine Route an.
|
||||
|
||||
```php
|
||||
<?php // Moodle configuration file
|
||||
|
||||
unset($CFG);
|
||||
global $CFG;
|
||||
$CFG = new stdClass();
|
||||
|
||||
//=========================================================================
|
||||
// 1. WEB SITE LOCATION
|
||||
//=========================================================================
|
||||
$CFG->wwwroot = 'https://deine-moodle-route.deine-domain.de';
|
||||
|
||||
|
||||
//=========================================================================
|
||||
// 2. DATABASE SETUP (wird automatisch aus VCAP_SERVICES gelesen)
|
||||
//=========================================================================
|
||||
$CFG->dbtype = 'mariadb';
|
||||
$CFG->dblibrary = 'native';
|
||||
$CFG->prefix = 'mdl_';
|
||||
$CFG->dboptions = array (
|
||||
'dbpersist' => 0,
|
||||
'dbport' => '',
|
||||
'dbsocket' => '',
|
||||
'dbcollation' => 'utf8mb4_unicode_ci',
|
||||
);
|
||||
|
||||
// --- Lese Datenbank-Konfiguration aus VCAP_SERVICES (inkl. SSL) ---
|
||||
$vcap_services_json = getenv('VCAP_SERVICES');
|
||||
if ($vcap_services_json) {
|
||||
$vcap_services = json_decode($vcap_services_json, true);
|
||||
$db_service_key = null;
|
||||
if (isset($vcap_services['appcloud-mariadb1011'])) { // Passe diesen Service-Namen ggf. an
|
||||
$db_service_key = 'appcloud-mariadb1011';
|
||||
}
|
||||
|
||||
if ($db_service_key && isset($vcap_services[$db_service_key][0]['credentials'])) {
|
||||
$db_creds = $vcap_services[$db_service_key][0]['credentials'];
|
||||
|
||||
$CFG->dbhost = $db_creds['host'];
|
||||
$CFG->dbname = $db_creds['name'];
|
||||
$CFG->dbuser = $db_creds['username'];
|
||||
$CFG->dbpass = $db_creds['password'];
|
||||
|
||||
if (isset($db_creds['cacrt']) && !empty($db_creds['cacrt'])) {
|
||||
$ca_cert_path = '/tmp/db-ca.crt';
|
||||
file_put_contents($ca_cert_path, $db_creds['cacrt']);
|
||||
$CFG->dboptions['ssl_ca'] = $ca_cert_path;
|
||||
$CFG->dboptions['ssl_verify_server_cert'] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// --- Ende der VCAP_SERVICES-Datenbank-Konfiguration ---
|
||||
|
||||
|
||||
//=========================================================================
|
||||
// 3. DATAROOT (verweist auf das beschreibbare /tmp-Verzeichnis)
|
||||
//=========================================================================
|
||||
$CFG->dataroot = '/tmp/moodledata';
|
||||
$CFG->directorypermissions = 0777;
|
||||
|
||||
|
||||
//=========================================================================
|
||||
// 4. S3 FILE STORAGE (wird automatisch aus Umgebungsvariablen gelesen)
|
||||
//=========================================================================
|
||||
if (getenv('S3_BUCKET')) {
|
||||
$CFG->alternative_file_system_class = '\core_files\files\s3_file_system';
|
||||
$CFG->s3_bucket = getenv('S3_BUCKET');
|
||||
$CFG->s3_accesskey = getenv('S3_ACCESS_KEY');
|
||||
$CFG->s3_secretkey = getenv('S3_SECRET_KEY');
|
||||
$CFG->s3_endpoint = getenv('S3_ENDPOINT');
|
||||
}
|
||||
|
||||
|
||||
//=========================================================================
|
||||
// 5. SESSION HANDLING (für mehrere Instanzen)
|
||||
//=========================================================================
|
||||
$CFG->session_handler_class = '\core\session\database';
|
||||
|
||||
|
||||
//=========================================================================
|
||||
// DO NOT ADD ANYTHING BELOW THIS LINE
|
||||
//=========================================================================
|
||||
require_once(__DIR__ . '/lib/setup.php');
|
||||
|
||||
```
|
||||
|
||||
### 4\. Anwendung deployen
|
||||
|
||||
Führe abschließend den Push-Befehl aus dem Hauptverzeichnis deines Projekts aus.
|
||||
|
||||
```bash
|
||||
cf push
|
||||
```
|
||||
|
||||
Nach Abschluss des Deployments ist deine Moodle-Instanz unter der konfigurierten Route erreichbar und wird gemäß deiner Policy automatisch skaliert.
|
||||
|
||||
```
|
||||
```
|
||||
|
||||
## Einsatz im Produktiven Umfeld
|
||||
|
||||
Um die Anwendung in einem produktiven Umfeld laufen zu lassen, sind die folgenden weiteren Anpassungen möglich
|
||||
|
||||
### Datenbank
|
||||
|
||||
Es empfielt sich für den produktiven Einsatz für die MariaDB anstelle einer Single Instanz eine Datenbank mit Replicas zu wählen:
|
||||
|
||||
Siehe dazu:
|
||||
https://docs.stackit.cloud/stackit/en/service-plans-for-mariadb-79071839.html
|
||||
|
||||
Neben der reinen Hochverfügbarkeit ist auch die zu erwartetende Last zu beachten.
|
||||
|
||||
### Session Persistenz
|
||||
|
||||
Im aktuellen Setup wird die Persistenz der Sitzungen über die Datenbank (MariaDB) sichergestellt. Besser geeignet ist hier der Einsatz eines Redis Caches, den es ebenfalls im Marketplace der STACKIT gibt und die auf ähnliche Weise wie die Datenank an die Moodle App gebunden werden kann.
|
||||
|
||||
```bash
|
||||
cf create-service appcloud-redis7 redis-1.4.10-replica moodle-redis
|
||||
```
|
||||
|
||||
Dazu ist dann auch eine Anpassung der config.php notwendig:
|
||||
|
||||
```php
|
||||
// --- Redis-Konfiguration für Sessions und Locks ---
|
||||
$vcap_services = json_decode(getenv('VCAP_SERVICES'), true);
|
||||
// Finde den Redis-Service (der Name kann variieren, z.B. 'redis')
|
||||
$redis_service = null;
|
||||
if (isset($vcap_services['redis'])) {
|
||||
$redis_service = $vcap_services['redis'][0];
|
||||
}
|
||||
|
||||
if ($redis_service) {
|
||||
$redis_creds = $redis_service['credentials'];
|
||||
|
||||
// Redis für Sessions verwenden
|
||||
$CFG->session_handler_class = '\cachestore_redis\session_handler';
|
||||
$CFG->session_redis_host = $redis_creds['host'];
|
||||
$CFG->session_redis_port = $redis_creds['port'];
|
||||
$CFG->session_redis_password = $redis_creds['password'];
|
||||
$CFG->session_redis_database = 0; // Normalerweise 0
|
||||
$CFG->session_redis_prefix = 'moodlesess_';
|
||||
|
||||
// Redis auch für Application Locks verwenden (Best Practice)
|
||||
$CFG->lock_factory = '\cachestore_redis\lock_factory';
|
||||
}
|
||||
// --- Ende der Redis-Konfiguration ---
|
||||
```
|
||||
|
||||
Die Einstellung
|
||||
```php
|
||||
$CFG->session_handler_class = '\core\session\database';
|
||||
```
|
||||
ist auszukommentieren.
|
||||
|
||||
Nun noch die angepasste manifest Datei:
|
||||
**`manifest-no-cdn.yml` (Test):**
|
||||
|
||||
```yaml
|
||||
---
|
||||
|
|
@ -347,95 +222,160 @@ applications:
|
|||
- name: moodle
|
||||
memory: 2G
|
||||
disk_quota: 2G
|
||||
buildpack: php_buildpack
|
||||
buildpack: [https://github.com/cloudfoundry/php-buildpack.git](https://github.com/cloudfoundry/php-buildpack.git)
|
||||
path: moodle
|
||||
routes:
|
||||
- route: deine-moodle-route.deine-domain.de
|
||||
- route: moodle.cf.demo.stackit.rocks
|
||||
env:
|
||||
# Buildpack anweisen, weniger Debug-Logs in Dateien zu schreiben
|
||||
USE_CDN: 'false'
|
||||
WWW_ROOT: "[https://moodle.cf.demo.stackit.rocks](https://moodle.cf.demo.stackit.rocks)"
|
||||
BP_PHP_LOG_LEVEL: WARNING
|
||||
|
||||
# S3-Zugangsdaten für den Object Storage
|
||||
S3_ACCESS_KEY: DEIN_S3_ACCESS_KEY
|
||||
S3_SECRET_KEY: DEIN_S3_SECRET_KEY
|
||||
S3_BUCKET: DEIN_S3_BUCKET_NAME
|
||||
S3_ENDPOINT: DEIN_S3_ENDPOINT_URL
|
||||
|
||||
services:
|
||||
- moodle-demo-mariadb
|
||||
- moodle-redis
|
||||
- moodle-autoscaler
|
||||
- moodle-redis # <-- Neuer Service hinzugefügt
|
||||
|
||||
# Konfiguration für den Autoscaler-Service
|
||||
- moodle-s3-credentials
|
||||
autoscaling:
|
||||
min_instances: 2
|
||||
max_instances: 10
|
||||
rules:
|
||||
- metric_type: cpu
|
||||
threshold: 50
|
||||
operator: ">"
|
||||
adjustment: "+1"
|
||||
breach_duration_secs: 60
|
||||
cool_down_secs: 60
|
||||
- metric_type: cpu
|
||||
threshold: 10
|
||||
operator: "<"
|
||||
adjustment: "-1"
|
||||
breach_duration_secs: 60
|
||||
cool_down_secs: 60
|
||||
min_instances: 1
|
||||
max_instances: 4
|
||||
# ... deine Regeln
|
||||
```
|
||||
|
||||
### CDN (Content Delivey Network)
|
||||
#### b) Dynamische `config.php`
|
||||
|
||||
STACKIT bietet ein eigenes CDN an, welches nun im produktiven Einsatz noch zusätzlich die Performance erhöhen kann und die überregionale Erreichbarkeit erleichtert.
|
||||
|
||||
Dazu legt man bei STACKIT einen CDN Eintrag auf die Orginale Route an (In diesem Beispiel: https://moodle.cf.demo.stackit.rocks )
|
||||
|
||||
https://docs.stackit.cloud/stackit/en/create-a-distribution-332824982.html
|
||||
|
||||
Das CDN erzeugt damit nun eine eigene URL, in unserem Fall v22sf2s1td84d5hz6rsf2715mw.aa.cdn.onstackit.cloud. Um diese wieder "schön" zu bekommen, legt man in STACKIT noch einen weiteren DNS Eintrag an. In unserem Fall ein CNAME Eintrag von moodle.demo.stackit.rocks auf die vom CDN Service vorgeschlagene URL (hier v22sf2s1td84d5hz6rsf2715mw.aa.cdn.onstackit.cloud.) und legt damit im CDN eine Custom Domain an:
|
||||
|
||||
https://docs.stackit.cloud/stackit/en/add-a-custom-domain-to-your-distribution-332824866.html
|
||||
|
||||
Um moodle, die neue URL mitzuteilen, braucht es noch eine Anpassung der Datei config.php.
|
||||
Dazu den alten Eintrag von:
|
||||
Kopieren Sie `moodle/config-dist.php` zu `moodle/config.php` und ersetzen Sie den gesamten Inhalt mit dieser finalen, dynamischen Vorlage.
|
||||
|
||||
```php
|
||||
$CFG->wwwroot = 'https://moodle.cf.demo.stackit.rocks';
|
||||
```
|
||||
<?php // Moodle configuration file
|
||||
|
||||
Durch die neuen Einstellungen:
|
||||
```php
|
||||
$CFG->wwwroot = 'https://moodle.demo.stackit.rocks';
|
||||
// =========================================================================
|
||||
// UMWELTSPEZIFISCHE KONFIGURATION
|
||||
// =========================================================================
|
||||
$useCdn = (getenv('USE_CDN') === 'true');
|
||||
$wwwRoot = getenv('WWW_ROOT');
|
||||
|
||||
// --- START: Proxy-Fix - Statisches Überschreiben ---
|
||||
// Dieser Block erzwingt die korrekten Server-Variablen basierend auf $CFG->wwwroot.
|
||||
// Er ist nicht mehr von eingehenden Headern abhängig.
|
||||
if (!empty($CFG->wwwroot)) {
|
||||
$urlparts = parse_url($CFG->wwwroot);
|
||||
unset($CFG);
|
||||
global $CFG;
|
||||
$CFG = new stdClass();
|
||||
|
||||
// Erzwinge HTTPS, wenn wwwroot https ist
|
||||
if ($urlparts['scheme'] === 'https') {
|
||||
$_SERVER['HTTPS'] = 'on';
|
||||
//=========================================================================
|
||||
// 1. WEBSEITE, VERZEICHNISSE & PROXY EINSTELLUNGEN
|
||||
//=========================================================================
|
||||
$CFG->wwwroot = $wwwRoot;
|
||||
$CFG->dirroot = __DIR__;
|
||||
$CFG->dataroot = '/tmp/moodledata';
|
||||
$CFG->admin = 'admin';
|
||||
$CFG->directorypermissions = 0777;
|
||||
|
||||
// --- Proxy-Einstellungen ---
|
||||
$CFG->sslproxy = 1;
|
||||
$CFG->slasharguments = false;
|
||||
if ($useCdn) {
|
||||
// Diese Einstellungen sind NUR für den CDN-Betrieb notwendig, um den "reverseproxyabused"-Fehler zu vermeiden.
|
||||
$CFG->reverseproxy = 1;
|
||||
$CFG->trustedproxies = '127.0.0.1, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 185.124.192.185';
|
||||
}
|
||||
|
||||
// --- Workaround: Manuelles Erstellen des dataroot-Verzeichnisses ---
|
||||
if (!file_exists($CFG->dataroot)) {
|
||||
@mkdir($CFG->dataroot, $CFG->directorypermissions, true);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// 2. DATENBANK-SETUP
|
||||
//=========================================================================
|
||||
$CFG->dbtype = 'mariadb';
|
||||
$CFG->dblibrary = 'native';
|
||||
$CFG->prefix = 'mdl_';
|
||||
$CFG->dboptions = array ('dbpersist' => 0, 'dbcollation' => 'utf8mb4_unicode_ci');
|
||||
|
||||
// --- Lese Service-Konfigurationen aus VCAP_SERVICES ---
|
||||
$vcap_services_json = getenv('VCAP_SERVICES');
|
||||
if ($vcap_services_json) {
|
||||
$vcap_services = json_decode($vcap_services_json, true);
|
||||
|
||||
// Datenbank
|
||||
$db_service_key = null;
|
||||
if (isset($vcap_services['appcloud-mariadb1011'])) { $db_service_key = 'appcloud-mariadb1011'; }
|
||||
if ($db_service_key && isset($vcap_services[$db_service_key][0]['credentials'])) {
|
||||
$db_creds = $vcap_services[$db_service_key][0]['credentials'];
|
||||
$CFG->dbhost = $db_creds['host']; $CFG->dbname = $db_creds['name'];
|
||||
$CFG->dbuser = $db_creds['username']; $CFG->dbpass = $db_creds['password'];
|
||||
$CFG->dboptions['dbport'] = $db_creds['port'];
|
||||
if (isset($db_creds['cacrt']) && !empty($db_creds['cacrt'])) {
|
||||
$ca_cert_path = '/tmp/db-ca.crt';
|
||||
file_put_contents($ca_cert_path, $db_creds['cacrt']);
|
||||
$CFG->dboptions['ssl_ca'] = $ca_cert_path;
|
||||
$CFG->dboptions['ssl_verify_server_cert'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Erzwinge den Host-Header, damit er mit wwwroot übereinstimmt
|
||||
if (isset($urlparts['host'])) {
|
||||
$_SERVER['HTTP_HOST'] = $urlparts['host'];
|
||||
$_SERVER['SERVER_NAME'] = $urlparts['host'];
|
||||
// Redis (Optional, für bessere Performance)
|
||||
$redis_service_key = null;
|
||||
if (isset($vcap_services['appcloud-redis60'])) { $redis_service_key = 'appcloud-redis60'; }
|
||||
if ($redis_service_key && isset($vcap_services[$redis_service_key][0]['credentials'])) {
|
||||
$redis_creds = $vcap_services[$redis_service_key][0]['credentials'];
|
||||
$CFG->session_handler_class = '\cachestore_redis\session_handler';
|
||||
$CFG->session_redis_host = $redis_creds['host']; $CFG->session_redis_port = $redis_creds['port'];
|
||||
$CFG->session_redis_password = $redis_creds['password'];
|
||||
$CFG->session_redis_prefix = 'moodlesess_';
|
||||
$CFG->lock_factory = '\cachestore_redis\lock_factory';
|
||||
}
|
||||
|
||||
// S3
|
||||
if (isset($vcap_services['user-provided'])) {
|
||||
foreach ($vcap_services['user-provided'] as $service) {
|
||||
if ($service['name'] === 'moodle-s3-credentials') {
|
||||
$s3_creds = $service['credentials'];
|
||||
$CFG->objectfs_s3_key = $s3_creds['access_key'];
|
||||
$CFG->objectfs_s3_secret = $s3_creds['secret_key'];
|
||||
$CFG->objectfs_s3_bucket = $s3_creds['bucket'];
|
||||
$CFG->objectfs_s3_endpoint = $s3_creds['endpoint'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// --- ENDE: Finaler Proxy-Fix ---
|
||||
// Fallback auf Datenbank-Sessions, falls Redis nicht konfiguriert ist
|
||||
if (empty($CFG->session_handler_class)) {
|
||||
$CFG->session_handler_class = '\core\session\database';
|
||||
}
|
||||
|
||||
$CFG->sslproxy = true;
|
||||
//=========================================================================
|
||||
// SESSION COOKIE HANDLING (bedingt durch CDN)
|
||||
//=========================================================================
|
||||
if ($useCdn) {
|
||||
$CFG->cookiepath = '/';
|
||||
$CFG->cookiedomain = 'moodle.demo.stackit.rocks';
|
||||
$CFG->cookiesecure = 1;
|
||||
$CFG->cookiehttponly = 1;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// DO NOT ADD ANYTHING BELOW THIS LINE
|
||||
//=========================================================================
|
||||
require_once(__DIR__ . '/lib/setup.php');
|
||||
```
|
||||
ersetzen.
|
||||
|
||||
Nun die Anwendung erneut deployen mittels:
|
||||
## 5\. Deployment auf Cloud Foundry
|
||||
|
||||
Wählen Sie das gewünschte Manifest für Ihr Deployment aus.
|
||||
|
||||
**Mit CDN (Produktion):**
|
||||
|
||||
```bash
|
||||
cf push --strategy rolling
|
||||
cf push -f manifest-cdn.yml
|
||||
```
|
||||
Die Option "--strategy rolling" sorgt für ein Update der Anwendung ohne Downtime.
|
||||
|
||||
Nun kann der weltweite Zugriff auf die URL https://moodle.demo.stackit.rocks erfolgen.
|
||||
**Hinweis:** Der CDN-Fall hat sich als problematisch erwiesen. Wenn Fehler auftreten, liegt es wahrscheinlich an den Caching- oder Header-Einstellungen im CDN selbst, die hier nicht behandelt werden können.
|
||||
|
||||
**Ohne CDN (Test / Direkter Zugriff):**
|
||||
|
||||
```bash
|
||||
cf push -f manifest-no-cdn.yml
|
||||
```
|
||||
|
||||
Nach Abschluss des Deployments und dem Durchlaufen der Moodle-Web-Installation ist Ihre Instanz einsatzbereit.
|
||||
|
||||
```
|
||||
```
|
||||
Loading…
Reference in a new issue