erseco / alpine-moodle

Moodle docker image based on Alpine Linux
https://hub.docker.com/r/erseco/alpine-moodle
MIT License
44 stars 34 forks source link

Better HA setup #40

Closed erseco closed 1 year ago

erseco commented 1 year ago

Import some ideas from @jimsihk fork jimsihk/alpine-moodle to better support HA setup (allow disabling auto-update)

jimsihk commented 1 year ago

Here are some changes I made to support HA and the corresponding commit in my fork, I would be more than happy to submit PR if you think the feature would be helpful:

Database

  1. Support database pooling in Postgres (e.g. PGBouncer): https://github.com/jimsihk/alpine-moodle/commit/726858f3795f40b6d85de23c6111cff1c8dd26ff
  2. Support database read replica: https://github.com/jimsihk/alpine-moodle/commit/f60261f270957e5b0bbbccc2c100696137c0593d

Caching

  1. Support Redis Sentinel: https://github.com/jimsihk/alpine-moodle/commit/3b9361bdde18f311ee71efdb4bc52f680669fdd5

Note that memcached has been removed since Moodle 4.2 (see https://tracker.moodle.org/browse/MDL-77161)

Moodle

  1. Support disabling auto update to avoid start with maintainence mode: https://github.com/jimsihk/alpine-moodle/commit/d8640edd9236c11bcbd52944cd4ba47801e2538d
erseco commented 1 year ago

Apologies for the delayed response; I've been tied up with work commitments.

I am genuinely impressed with the changes you've made for High Availability support; they add substantial value, and I'm more than happy to integrate these into the main branch.

With regards to using the "Redis Sentinel" cache plugin instead of the cache store provided by Moodle, I appreciate its benefits. It certainly offers some compelling features. However, to keep our codebase accessible and straightforward for all users, I prefer not to incorporate external plugins directly.

But this shouldn't hinder the benefits from reaching the users who need them. We could potentially document the configuration steps for Redis Sentinel in our README file. Alternatively, we could consider introducing a "High Availability (HA)" configuration setting. This setting could facilitate the use of Redis Sentinel or similar plugins when required, ensuring the main codebase remains uncomplicated for general users.

I'm keen to hear your thoughts on this approach.

jimsihk commented 1 year ago

It's understandable and thanks for the detail comments.

Given that Moodle by default supports Redis (and Redis Cluster, a type of HA of Redis) which is useful on scaling the Moodle instance and it is commonly used, we could first stick to to keep it simple out-of-the-box.

Regarding the configurations, I think more on listing some options for achieving a higher availability setup? What if we also provide a sample docker-compose.yaml with also Redis as part of the containers? I am trying to consolidate my k8s setup for reference as well.

Another challenge is we will need to think of a good way to properly support plugin installation (which installs to /var/www/html). Since the image is assuming one volume per container, we cannot install from web UI since it could not sync between replicas without modification. I have thought of some ways:

  1. only install plugin when build the DockerFile
    • pros: keeping the container as immutable
    • cons: giving up the flexibility to install plugin from web UI
  2. change the moodle code volume to support mounting a shared directory (e.g. NFS)
    • pros: easy to maintain, transparent to users
    • cons: potential performance issue and currently the 02-configure-moodle.sh does not really support mounting an existing external drive
  3. separate the admin module from the normal pool of containers (see https://github.com/Azure/Moodle)
    • pros: may not need IT to support installing new plugins
    • cons: need extra setup and a bit complex

Personally, I have taken approach 1, assuming plugin installation will always be performed by IT member to avoid corrupting the live site but shifting the burden to me (haha).

erseco commented 1 year ago

I fully support the idea of incorporating Redis into the provided docker-compose.yml file. Additionally, I believe that adopting the first approach would be more convenient. By installing plugins during the build phase or initial setup, anyone can utilize the image as a source and effortlessly enhance its functionality by adding their desired plugins. However, I am uncertain whether it is feasible to restrict plugin installations for users, similar to how WordPress operates.

jimsihk commented 1 year ago

Yes, it's possible to disable installing plugin at web UI by setting the $CFG->disableupdateautodeploy parameter, see https://github.com/moodle/moodle/blob/MOODLE_402_STABLE/config-dist.php#L549.

I implemented a container parameter DISABLE_WEB_INSTALL_PLUGIN to control it: https://github.com/jimsihk/alpine-moodle/blob/dev/rootfs/docker-entrypoint-init.d/02-configure-moodle.sh#L197

Besides, I just discover we could also limit the plugin uninstallation with $CFG->uninstallclionly, see https://github.com/moodle/moodle/blob/MOODLE_402_STABLE/config-dist.php#L717. But then I think will need to have an uninstallation script as well (maybe wrap the official admin/cli/uninstall_plugins.php?).

erseco commented 1 year ago

Hey there,

This looks amazing! The updates you've made to your fork are a really neat feature. Thanks for taking the time to detail the additions and provide the links.

I'm going to have some free time in the next few weeks, and I look forward to diving in and cherrypicking your changes. This includes looking into the $CFG->disableupdateautodeploy parameter and the new container parameter you've implemented.

Thanks for your incredible work!

Best, Ernesto