Moodle auf einem Docker-Host

oben mein link auf den Gist. Da ist alles beschrieben.

Hallo zusammen,
ich hab ein Moodle mit PHP 8.0 dockerisiert und siehe da es läuft. Foldende Dateien sind nötig:

Dockerfile:

# Docker moodle-image
# 

FROM php:8.0-apache-buster
LABEL maintainer="Mathias Rettich <rettich@staufer-gymnasium.de>"

# Document-root ist /var/www/html/moodle

ENV APACHE_DOCUMENT_ROOT /var/www/html/moodle/

RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf && \
    sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf && \

# Installationen

    apt-get update && apt-get -y dist-upgrade && \
    apt-get install -y --no-install-recommends \
    wget \
# Lade PHP
    libxml2-dev libfreetype6-dev \
    libjpeg62-turbo-dev \
    libmcrypt-dev \
    libpng-dev \
    libpq-dev \
    libzip-dev \
    zlib1g-dev \
    libldap2-dev && \
# Konfigure Extensions
    docker-php-ext-configure gd --with-libdir=/usr/include/ --with-jpeg --with-freetype && \
    docker-php-ext-install -j$(nproc) exif ldap mysqli soap gd zip opcache intl pgsql pdo_pgsql && \
    apt-get clean && rm -rf /var/lib/apt/lists/* && \

# Moodle einrichten

    mkdir -p /moodle/data && cd /var/www/html && \
    wget -O download.tgz https://download.moodle.org/download.php/direct/stable402/moodle-4.2.tgz && \
    echo "c805bd0edbda1e4dbb3a1a94db7526fa74b2bd2d0625e739f2130bda4aca1e35 download.tgz" > download.tgz.sum && \
    sha256sum -c download.tgz.sum && \
    tar -xzf download.tgz && \
    rm download.* && \
    echo "TLS_REQCERT never" >> /etc/ldap/ldap.conf && \

    sed "s/;max_input_vars =.*/max_input_vars = 10000/" /usr/local/etc/php/php.ini-production > /usr/local/etc/php/php.ini

COPY ./docker-php-entrypoint /usr/local/bin/docker-php-entrypoint
COPY ./config.php /var/www/html/moodle/config.php

# Volumes
VOLUME /moodle/data

docker-compose.yml:

# Docker image for Moodle

version: "3"
services:
  moodle:
    build: .
    restart: always
    ports:
      - "8000:80"
    environment:
      - "MY_DBUSER=moodle"
      - "MY_DBPASS=Muster!"
      - "MY_DBNAME=moodledb"
      - "MY_WWWROOT=https://rettichmoodle.dnshome.de"
      - "MY_SSLPROXY=true"
    volumes: 
      - ./moodle-data:/moodle/data
  database:
    image: mysql:8.0
    restart: always
    command:
      - --character-set-server=utf8mb4
      - --collation-server=utf8mb4_unicode_ci
    environment:
      - "MYSQL_USER=moodle"
      - "MYSQL_PASSWORD=Muster!"
      - "MYSQL_DATABASE=moodledb"
      - "MYSQL_ROOT_PASSWORD=Muster!"
    volumes:
      - ./db:/var/lib/mysql

volumes:
  db:
  moodle-data:

config.php:

<?php  // Moodle configuration file

unset($CFG);
global $CFG;
$CFG = new stdClass();

$CFG->dbtype    = 'mysqli';
$CFG->dblibrary = 'native';
$CFG->dbhost    = 'database';
$CFG->dbname    = '__moodledb__';
$CFG->dbuser    = '__moodledbuser__';
$CFG->dbpass    = '__moodledbpass__';
$CFG->prefix    = 'mdl_';
$CFG->dboptions = array (
  'dbpersist' => 0,
  'dbport' => '',
  'dbsocket' => '',
  'dbcollation' => 'utf8mb4_unicode_ci',
);

$CFG->wwwroot   = '__WWWROOT__';
$CFG->dataroot  = '/moodle/data';
$CFG->admin     = 'admin';

$CFG->sslproxy = __SSLPROXY__;

$CFG->directorypermissions = 0777;

require_once(__DIR__ . '/lib/setup.php');

// There is no php closing tag in this file,
// it is intentional because it prevents trailing whitespace probl

und docker-php-entrypoint:

#!/bin/sh

# Umgebungsvariablen eintragen
chown -R www-data:www-data /moodle
sed -ri "s/__moodledb__/$MY_DBNAME/g"     /var/www/html/moodle/config.php
sed -ri "s/__moodledbuser__/$MY_DBUSER/g" /var/www/html/moodle/config.php
sed -ri "s/__moodledbpass__/$MY_DBPASS/g" /var/www/html/moodle/config.php
sed -ri "s#__WWWROOT__#$MY_WWWROOT#g"     /var/www/html/moodle/config.php
sed -ri "s/__SSLPROXY__/$MY_SSLPROXY/g"   /var/www/html/moodle/config.php

# cp /var/www/html/moodle/config.php.sik5 /var/www/html/moodle/config.php

set -e

# first arg is `-f` or `--some-option`
if [ "${1#-}" != "$1" ]; then
	set -- apache2-foreground "$@"
fi

exec "$@"

Wenn man im Dockerfile
FROM php:8.0-apache-buster
durch
FROM php:8.1-apache-buster``
ersetzt läuft die LDAPS-Anbindung wie am Anfang beschrieben nicht mehr…
Gruß,
Mathias

Hi @rettich

Das macht so IMHO keinen Sinn.
Du definierst unten Volumes, die du nicht benutzt.
Oben in den Service-Definitionen nutzt du bind-mounts

Ich mag bind-mounts auch lieber, weil dann alles schön an einem Ort ist.

Also: entweder du machst die ./ vor dem db weg (Volumes nutzen, daten landen in /var/lib/docker/volumes, oder den volumes-block unten ersatzlos streichen. Der ist dann unmötig.

LG Jesko

Hallo Jesko,

Da hast du recht, die sind noch drin. Könnte man auch löschen…
Gruß,
Mathias

Hi.
Wir betreiben moodle auf einem vServer von HostEurope. Das Problem bei unserer Installation ist, dass der Server alle paar Jahre auf eine neue Instanz umziehen muss, da z.B. die mySQL oder PHP-Version wieder zu alt für ein aktuelles moodle geworden sind. In diesem Zshg habe ich mich auch schon öfter gefragt, ob man die moodle-Installation nicht genauso gut in das eigene Netz holen sollte. Habe ich bisher nicht gemacht … aber der Umzug von Version zu Versoin wäre mit docker oder anderen Mitteln sicher schneller zu machen als immer den gesamten Server umziehen zu lassen :thinking:
Viele Grüße,
Michael

Hallo Michael,

Bei der letzten(?) Moodle-Version wurde eine neue SQL-und php-Version vorraus gesetzt. Das passiert aber echt nur alle paar Jahre.
Bei der MariaDB-Version habe ich mir nur das neueste deb-Paket extern gezogen und installiert, das war es schon.

Was meinst Du damit genau?

Wenn ich auf einen neuen Server umgezogen bin, lief es folgenderweise ab:

  • Mit SQL-Dump die DBs sichern
  • Moodle-Data-Ordner sichern
  • Wenn gewünscht, aber nicht nötig, den Moodle-Install-Ordner bzw. die config.php sichern
    Das war es.

config.php sichern, die alte Moodle-Version löschen und durch die Neue ersetzen, als Admin in Moodle anmelden und durchlaufen lassen.
„Schwierigkeiten“ gab es nur bei externen Plugins, da diese händisch nachinstalliert werden müssen. Wir setzen ca. 10 Externe ein und das macht dann bei mehreren Moodle-Installationen schon viel Arbeit.

Ansonsten keine wirklich grosse Sache, den neuen Server einrichten war da eher die zeit-intensivste Angelegenheit.
VG Andreas

Hi. Ich meinte damit auch nicht nur moodle, sondern den gesamten Server (der auch die Schulwebseite, eMail usw hält). Daher ist der Aufwand dann immer etwas größer.
Wir nutzen da Plesk – damit geht’s dann wieder halbwegs. Trotzdem ist der Plattenplatz bei unserem Server relativ begrenzt. Zumindest in der überaus nervigen Corona-Zeit war das ein Problem. Im Moment nicht.
Viele Grüße,
Michael

Hallo Michael,

da pflichte ich Dir bei :wink:

VG Andreas

Hallo zusammen,
in der Zwischenzeit habe ich noch viele Tips und Ratschläge bekommen, die die Dockerisierung noch ein ganzes Stück verbessert haben. Und so sieht’s jetzt aus:

Dockerfile:

# Docker moodle-image
# 


FROM php:8.1-apache-bookworm
LABEL maintainer="Mathias Rettich <rettich@staufer-gymnasium.de>"

# Document-root ist /var/www/html/moodle

ENV APACHE_DOCUMENT_ROOT /var/www/html/moodle/
RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf && \
    sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf && \

# Installationen

    apt-get update && apt-get -y dist-upgrade && \
    apt-get install -y --no-install-recommends \
    wget \
    cron \
    rsync \
# Lade PHP
    libxml2-dev libfreetype6-dev \
    libjpeg62-turbo-dev \
    libmcrypt-dev \
    libpng-dev \
    libpq-dev \
    libzip-dev \
    zlib1g-dev \
    libldap2-dev && \
# Konfigure Extensions
    docker-php-ext-configure gd --with-libdir=/usr/include/ --with-jpeg --with-freetype && \
    docker-php-ext-install -j$(nproc) exif ldap mysqli soap gd zip opcache intl pgsql pdo_pgsql && \
    apt-get clean && rm -rf /var/lib/apt/lists/*

# RUN /usr/bin/systemctl start 
RUN mkdir -p /etc/ldap

# Moodle einrichten

RUN mkdir /var/www/html/moodle && \
    mkdir -p /moodle/data && cd /moodle && \
    wget -O download.tgz https://download.moodle.org/download.php/direct/stable402/moodle-4.2.1.tgz && \
    echo "19041f6865ce3c813ad7088d92f9c3f59306eeddbbb45e25468a7a9dab633efc download.tgz" > download.tgz.sum && \
    sha256sum -c download.tgz.sum && \
    tar -xzf download.tgz && \
    rm download.* && \
    chown -R root:root /moodle/moodle && \

# Cert nicht prüfen

    echo "TLS_REQCERT never" >> /etc/ldap/ldap.conf

# Maximale Upload-Größe auf 1000M setzen

RUN sed "s/;max_input_vars =.*/max_input_vars = 10000/g" /usr/local/etc/php/php.ini-production > /usr/local/etc/php/php.ini
RUN sed -i "s/post_max_size =.*M/post_max_size = 1000M/g" /usr/local/etc/php/php.ini
RUN sed -i "s/upload_max_filesize =.*M/upload_max_filesize = 1000M/g" /usr/local/etc/php/php.ini
RUN sed -i "s/max_execution_time =.*/max_execution_time = 600/g" /usr/local/etc/php/php.ini

# Cronjob einrichten

RUN echo "* * * * *  root /usr/local/bin/php /var/www/html/moodle/admin/cli/cron.php >/dev/null" > /etc/cron.d/moodle

# neue Version von docker-php-entrypoint einspielen

COPY ./docker-php-entrypoint /usr/local/bin/docker-php-entrypoint

COPY ./config.php /moodle/moodle/config.php

docker-compose.yml:

version: "3"
services:
  moodle:
    build: .
    restart: always
    ports:
      - "7781:80"
    environment:
      - "MY_DBUSER=moodle"
      - "MY_DBPASS=Muster!"
      - "MY_DBNAME=moodledb"
      - "MY_WWWROOT=https://moodle.deine-schule.de"
      - "MY_SSLPROXY=true"
    volumes: 
      - ./moodle-data:/moodle/data
      - ./moodle-www:/var/www/html/moodle
    depends_on:
      - database
  database:
    image: mysql:8.0
    restart: always
    command:
      - --character-set-server=utf8mb4
      - --collation-server=utf8mb4_unicode_ci
    environment:
      - "MYSQL_USER=moodle"
      - "MYSQL_PASSWORD=Muster!"
      - "MYSQL_DATABASE=moodledb"
      - "MYSQL_ROOT_PASSWORD=Muster!"
    volumes:
      - ./db:/var/lib/mysql

config.php

<?php  // Moodle configuration file

unset($CFG);
global $CFG;
$CFG = new stdClass();

$CFG->dbtype    = 'mysqli';
$CFG->dblibrary = 'native';
$CFG->dbhost    = 'database';
$CFG->dbname    = '__moodledb__';
$CFG->dbuser    = '__moodledbuser__';
$CFG->dbpass    = '__moodledbpass__';
$CFG->prefix    = 'mdl_';
$CFG->dboptions = array (
  'dbpersist' => 0,
  'dbport' => '',
  'dbsocket' => '',
  'dbcollation' => 'utf8mb4_unicode_ci',
);

$CFG->wwwroot   = '__WWWROOT__';
$CFG->dataroot  = '/moodle/data';
$CFG->admin     = 'admin';

$CFG->sslproxy = __SSLPROXY__;

$CFG->directorypermissions = 0777;

require_once(__DIR__ . '/lib/setup.php');

// There is no php closing tag in this file,
// it is intentional because it prevents trailing whitespace probl

docker-php-entrypoint :

#!/bin/sh

# /var/www/html/moodle leer?
cd /var/www/html/moodle
list=$(echo *)
if [ "$list" = "*" ]
    then
	rsync -av /moodle/moodle/ /var/www/html/moodle/
fi

# Umgebungsvariablen eintragen
chown -R www-data:www-data /moodle/data
sed -ri "s/__moodledb__/$MY_DBNAME/g"     /var/www/html/moodle/config.php
sed -ri "s/__moodledbuser__/$MY_DBUSER/g" /var/www/html/moodle/config.php
sed -ri "s/__moodledbpass__/$MY_DBPASS/g" /var/www/html/moodle/config.php
sed -ri "s#__WWWROOT__#$MY_WWWROOT#g"     /var/www/html/moodle/config.php
sed -ri "s/__SSLPROXY__/$MY_SSLPROXY/g"   /var/www/html/moodle/config.php



# Alter entrypoint
set -e

# first arg is `-f` or `--some-option`
if [ "${1#-}" != "$1" ]; then
	set -- apache2-foreground "$@"
fi

/usr/sbin/cron -l -L 1

exec "$@"

Und hier noch meine nginx-config-Datei:


server {
    listen [::]:80;
    listen 80;

    server_name moodle.deine-schule.de;

    location / {
      return 301 https://moodle.deine-schule.de$request_uri;
      }

    location ^~ /.well-known/acme-challenge {
      alias /var/www/dehydrated;
      }
}



server {
    listen [::]:443 ssl http2;
    listen 443 ssl http2;

    server_name moodle.deine-schule.de;

    ssl_certificate /var/lib/dehydrated/certs/moodle.deine-schule.de/fullchain.pem;
    ssl_certificate_key /var/lib/dehydrated/certs/moodle.deine-schule.de/privkey.pem;
    ssl_protocols TLSv1.2;
    ssl_prefer_server_ciphers on;

    index index.php index.html;

    client_max_body_size 1000m;


    location / {

       access_log /var/log/nginx/m2.access.log;
       error_log /var/log/nginx/m2.error.log;

       client_max_body_size 1000m;

       add_header       X-Served-By $host;
       proxy_set_header Host $host;
       proxy_set_header X-Forwarded-Scheme $scheme;
       proxy_set_header X-Forwarded-Proto  $scheme;
       proxy_set_header X-Forwarded-For    $proxy_add_x_forwarded_for;
       proxy_set_header X-Real-IP          $remote_addr;

       proxy_pass http://localhost:7781;

    }
}

Gruß,
Mathias

1 „Gefällt mir“