Our Moodle Dev Workflow
Docker, Git and Submodules (14.06.2023)
Förderjahr / Projekt Call #17 / ProjektID: 6384 / Projekt: GigapixelTutor

As part of the NetIdee 2022 call we develop a moodle plugin to view gigapixel/deepzoom images in moodle. When developing Moodle plugins it can easily become confusing since they are nested in their respective Moodle subdirectories.

Moodle proposes to use git submodules to load the modules. We additionally use softlinks to manage the various plugins in our IDE.

First we created an empty directory and initialized git (init git). Moodle is loaded via Git Submodules, the moodledata directory we create manually.

mkdir gigapixel
cd gigapixel
git init
git submodule add -b MOODLE_401_STABLE https://github.com/moodle/moodle.git moodle 
mkdir moodledata
sudo chown -R www-data:root moodledata
sudo chmod -R 770 moodledata/
# Don´t use 777 in production
sudo chmod -R 777 moodle

To deploy our Moodle instance and to develop we use Docker and Docker-Compose with currently only two Docker Images (i.e. mariadb:10.5.8 and PHP:8.0-apache). For PHP we created an additional Dockerfile to install some dependencies (e.g. mysqli, pdo_mysql, zip, exif, pcntl, pspell, soap, gd, opcache) and use the PHP image with apache already preconfigured. We currently did not need the JavaScript ESM modules, if needed we add an additional Docker Node Image to our Docker-Compose file. We use some variables in our Docker-Compose loaded via an environmental file. Since we run multiple Docker containers we assign every one a separate fixed IP.

gigapixel/.gitignore

/.env
/moodledata/
/moodle/
.idea/*
/mariadb/
/plugins/

gigapixel/.env

#changeme
MYSQL_PASSWORD=secret
#changeme
MYSQL_ROOT_PASSWORD=secret
APP=gigapixel
IP=174

gigapixel/docker-compose.yml

version: '3'
networks:
  network:
    ipam:
      driver: default
      config:
        - subnet: 192.168.${IP}.0/24

services:
  php:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: ${APP}-php
    ports:
      - "80:80"
    volumes:
      - ./moodle:/var/www/html
      - ./moodledata:/var/www/moodledata
    depends_on:
      - mariadb
    networks:
      network:
        ipv4_address: 192.168.${IP}.8

  mariadb:
    image: mariadb:10.5.8
    container_name: ${APP}-mariadb
    ports:
      - "3306:3306"
    volumes:
      - ./mariadb:/var/lib/mysql
    environment:
      MYSQL_DATABASE: ${APP}
      MYSQL_USER: ${APP}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      SERVICE_TAGS: dev
      SERVICE_NAME: mysql
    command: mysqld --innodb-large-prefix --innodb-file-format=barracuda --innodb-file-per-table
    networks:
      network:
        ipv4_address: 192.168.${IP}.6

gigapixel/Dockerfile

FROM php:8.0-apache

WORKDIR /var/www/html

# Install dependencies
RUN apt-get update \
     && apt-get install -y libzip-dev libicu-dev libpspell-dev libxml2-dev libfreetype6-dev \
        libjpeg62-turbo-dev \
        libpng-dev
RUN apt-get install -y aspell-en
RUN apt-get install -y aspell-de

RUN docker-php-ext-install opcache pdo intl pspell soap gd mysqli pdo_mysql zip exif pcntl
RUN docker-php-ext-enable pdo_mysql
# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*

RUN sed -E -i -e 's/post_max_size = 8M/post_max_size = 64M/' /usr/local/etc/php/php.ini-production \
 && sed -E -i -e 's/upload_max_filesize = 2M/upload_max_filesize = 64M/' /usr/local/etc/php/php.ini-production \
 && sed -E -i -e 's/;max_input_vars = 1000/max_input_vars = 5000/' /usr/local/etc/php/php.ini-production

RUN sed -E -i -e 's/post_max_size = 8M/post_max_size = 64M/' /usr/local/etc/php/php.ini-development \
 && sed -E -i -e 's/upload_max_filesize = 2M/upload_max_filesize = 64M/' /usr/local/etc/php/php.ini-development \
 && sed -E -i -e 's/;max_input_vars = 1000/max_input_vars = 5000/' /usr/local/etc/php/php.ini-development

RUN cp /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini

RUN a2enmod rewrite

# Expose port 9000 and start php-fpm server
EXPOSE 80

Everything should be ready to start now.

docker-compose up

Open http://localhost

Start Moodle Installation

Be sure to use 'mariadb' as Database type and later as host, the APP name from the .env file as database name and database user and the MYSQL_PASSWORD as password. Port is 3306.

Additional Plugins can now easily be installed with git submodules. Via command line the moodle install can be triggered as well.

cd moodle 
git submodule add -b main https://github.com/mudrd8mz/moodle-tool_pluginskel.git admin/tool/pluginskel
cd ..
docker compose exec php php admin/cli/upgrade.php --non-interactive

To manage Plugins in the local Development environment we create a local folder with symbolic links to the imported submodules. This way we can easily create a project in our IDE and changes are automatically deployed in our local Moodle instance. The softlink also ensures that all plugins have a unique name and could be imported into the same IDE Project.

mkdir plugins
cd plugins
ln -s /gigapixel/moodle/admin/tool/pluginskel moodle-tool_pluginskel

With this workflow all our changes to plugins are automatically tracked and we don´t have to navigate multiple subdirectories in the moodle installation folder during development.

Hope this helps you in your moodle development!

CAPTCHA
Diese Frage dient der Überprüfung, ob Sie ein menschlicher Besucher sind und um automatisierten SPAM zu verhindern.
    Datenschutzinformation
    Der datenschutzrechtliche Verantwortliche (Internet Privatstiftung Austria - Internet Foundation Austria, Österreich würde gerne mit folgenden Diensten Ihre personenbezogenen Daten verarbeiten. Zur Personalisierung können Technologien wie Cookies, LocalStorage usw. verwendet werden. Dies ist für die Nutzung der Website nicht notwendig, ermöglicht aber eine noch engere Interaktion mit Ihnen. Falls gewünscht, treffen Sie bitte eine Auswahl: