General developer forum

Docker images for Moodle development

 
Dan at desk in Moodle HQ, Perth
Docker images for Moodle development
Group Core developersGroup Moodle Course Creator Certificate holdersGroup Moodle HQGroup Particularly helpful MoodlersGroup Plugin developersGroup Testers

Hi All,

I'm preparing a set of docker images for Moodle development to simplify testing setups and ensure that developers can quickly setup testing environment for various aspects of Moodle core development. I'm not the first person to do this and probably won't be the last, but I want to make a solid reusable base which at least can get adoption in Moodle HQ. Now that Microsoft have Microsoft SQL Server running on Linux this is particularly compelling as we can cover all DB engines.

My goals at this stage are:

  • Focus on developers/testers, not any other use cases (i.e. production use)
  • Keep the do one thing in each docker container mantra and keep it possible for people to use the individual containers as they wish
  • Be as 'plug and play' as possible (ideally no manual configuration)

The current work in progress can be found at https://github.com/danpoltawski/docker-moodle (it's very WIP with docs out of date, sorry)

My rough plan of things to do from here:

  • Add a docker compose configuration to be able to bring up all containers communicating with each other easily
  • Script the 'make this moodle.git checkout be available'
  • Add containers for all our other optional integrations like memached, redis, ldap etc
  • Consider the multiple-php thing a bit better

But really I am posting because I have hit an impasse about the best approach and I am sure there are others in the community who have used docker in anger much more than me, so trying to solicit opinions (/experiences).

A key question is how best to expose the Moodle codebase to docker. Given an existing moodle.git checkout, my idea is that the developer can run one command and then get that codebase running with access to all services. But there are a few things causing me indecision about direction:

  1. Mounting the code directory into the php container seems the natural solution, but can cause performance issues on some platforms - particularly my platform, mac. If I want to say run automated tests, perhaps a 'copy' of the code directory is fine, to run the tests and get the result
  2. The config.php will want to be overridden for the docker environment, it might be different to the host OS. So just mounting it might not be a good solution here.
  3. Initially I was thinking of just exposing php-fpm, but perhaps its a better experience to expose php+apache
  4. If exposing php+apache, i was thinking you would run the cli tools just using docker exec into the container

Do you have any insight? Comments very welcome!

 
Average of ratings: Useful (6)
Picture of Jan Dageförde
Re: Docker images for Moodle development
Group Core developersGroup Plugin developers

Hi Dan,

this is a great idea. My entire Moodle development environment is based on docker containers for ~5 months now, which I started mostly because I frequently encountered conflicts between database state and codebases given that I had multiple instances (vanilla Moodle, our custom Moodle, and both in different versions at the same time). Separating all of them into containers resolved all these conflicts, because no two codebases ever shared the same db (they could, but why? ;) ). Also, my laptop now doesn't have to run postgres & nginx servers anymore if I am not using them. In order to facilitate all this, I created helper commands that manage multiple instances and their respective containers: https://github.com/Dagefoerde/Moodledocker . It also allows running selenium tests and phpunit tests inside the containers (undocumented, but `moodledocker startbehat INSTANCENAME` will aid smile ). These containers are still flawed in some respect, but maybe this can be of some inspiration.

Also I noticed https://moodle.org/mod/forum/discuss.php?d=349797 recently, which is another approach to this. I haven't looked into that yet.

Re your points:

- Mounting works perfectly for me (Linux), but I can't state anything about macs.
- config.php is mounted as well; of course this doesn't work if an instance is used both in docker and in regular environment. However, since you might have database mismatches here, I assumed that you wouldn't want that anyway. Therefore, in my own environment, a codebase is either for docker or for the outside world. ;)
- Why not use separate containers for 1) php-fpm and 2) nginx? Usually, in the docker world, it seems preferable to have one service per container only. 
- `docker exec`: Absolutely! In order to simplify this, we created a helper script: https://github.com/Dagefoerde/Moodledocker/blob/master/Scripts/moodledocker-exec so instead of executing `php admin/cli/...` locally, you would execute `moodledocker exec php admin/cli/...`. The script takes care of locating the correct PHP docker container and executing you command there.

Cheers
Jan

 
Average of ratings: Useful (1)
Dan at desk in Moodle HQ, Perth
Re: Docker images for Moodle development
Group Core developersGroup Moodle Course Creator Certificate holdersGroup Moodle HQGroup Particularly helpful MoodlersGroup Plugin developersGroup Testers

Thanks Jan, your work on this looks like useful inspiration (part of the reason why I posted smile ), whilst I remember - Rajesh also did some work on this in https://github.com/rajeshtaneja/docker

  • config.php is mounted as well; of course this doesn't work if an instance is used both in docker and in regular environment. However, since you might have database mismatches here, I assumed that you wouldn't want that anyway. Therefore, in my own environment, a codebase is either for docker or for the outside world. ;)

This was discussed developer chat too, a point I didn't make clear enough is that I want to make these images usable without re-architecting your entire development workflow.

Darren suggested that the config.php should use environment variables. I agree that this is a sensible solution if you are changing your development workflow. But I don't want to enforce that on people using this.

A common use-case I want to solve is that a developer codes something using whatever workflow they currently use (mdk, fancy config.php), their issue gets failed for breaking on e.g. mssql and then they need to fix it. The best solution is when they can just spin up these docker instances without having to rearchitect their development setup and make use of the testing environment.

It might be that developers decide to move to an entire dockerised solution having drunk the kool-aid and I want that to be supported too, but not required.

 
Average of ratings: -
Picture of Jan Dageförde
Re: Docker images for Moodle development
Group Core developersGroup Plugin developers

Yep, I see your points re config.php. Actually I just started using mdk for core patches ~1 month ago, i.e. after I started on the docker scripts. That also means that I haven't had the chance to incorporate any mdk-related stuff, yet. So for now it is either using mdk or my docker-based workflow, which can't be the right way of doing things. 

I think the best way would be to make them aware of each other. Maybe letting mdk generate a config.php that uses docker environment variables? However that would enforce using a specific docker-based solution, which can't be the right way, either.

 
Average of ratings: -
Picture of Matteo Scaramuccia
Re: Docker images for Moodle development
Group Core developersGroup Particularly helpful MoodlersGroup Plugin developers
Also I noticed https://moodle.org/mod/forum/discuss.php?d=349797 recently, which is another approach to this. I haven't looked into that yet.

I strongly suggest to give it a read, especially https://github.com/CentOS/CentOS-Dockerfiles/pull/130 where you'll find how to get Moodle running on OpenShift since you need to keep care of the way OpenShift runs a container (i.e. random uid, gid = 0: see https://github.com/CentOS/CentOS-Dockerfiles/pull/130/commits/22f3951e6f6343fae1cbb85ed2b97179c28239ce#diff-c78e6d3b6558456f0603bf85e40bd304R1) and how to build a first manifest for Kubernetes (https://github.com/CentOS/CentOS-Dockerfiles/pull/130/commits/3b74215615d8783ad789356f3d52d2e43ee8a9a7#r109840790): this is not strictly development oriented but it gives you a clear picture of some of the security benefits when using OpenShift.

Besides there are several hints like logging on stdout/stderr: https://github.com/CentOS/CentOS-Dockerfiles/pull/130/commits/80732217d5182f990ab0f4aaabc574a62ec745bd.

That being said that image is still far from being production ready (lack of some ideas like a strong hierarchy of images starting from the base OS and several single-service based images, not to mention scheduling/backup/updates) and far from being development "ready".

HTH,
Matteo

 
Average of ratings: -
Picture of Ruslan Kabalin
Re: Docker images for Moodle development
Group Core developersGroup Plugin developers

Hi Dan,

We have a set of images for Moodle development available at https://github.com/lucisgit/docker-moodle-dev (posted on dockerhub as well) and it comes with the compose files and instruction how to override them for your requirements. At the moment the are separate images for web and cron (both php+apache based), for database I suggest using official images and link them through compose file in appropriate way (see example how I use it with postgres). The set is also clamav-friendly (running clamd in the container, but this can be disabled through env variable) and you can easily make it exposing ssl, as it comes preconfigured with snakeoil certificates, for details see https://github.com/lucisgit/docker-moodle-dev/tree/master/apache

Regarding points you made:

1. I found docker-sync is doing the right job to eliminate performance issues on mac, there are compose examples for that in our repo too, have a look at https://github.com/lucisgit/docker-moodle-dev#note-for-mac-users

2. For development purposes I just mount it as a part of moodle code.

3. I would suggest to design images for different platforms and leave user a choice which one to use.

4.  I found it perfectly fine to run `docker exec -it ...` on either of containers and run whatever you need from www-data user.

 
Average of ratings: Useful (1)
Dan at desk in Moodle HQ, Perth
Re: Docker images for Moodle development
Group Core developersGroup Moodle Course Creator Certificate holdersGroup Moodle HQGroup Particularly helpful MoodlersGroup Plugin developersGroup Testers
  1. I found docker-sync is doing the right job to eliminate performance issues on mac, there are compose examples for that in our repo too, have a look at https://github.com/lucisgit/docker-moodle-dev#note-for-mac-users

Thanks Ruslan, and I saw they added a new :cached flag on the latest OSX beta, so perhaps I should ignore this consideration for now.

 
Average of ratings: -
Picture of Matteo Scaramuccia
Re: Docker images for Moodle development
Group Core developersGroup Particularly helpful MoodlersGroup Plugin developers

Hi Dan,
that's a great idea: I started months ago (Jul 2016 but left on Aug!) a similar project but still pending a first public release.

Based on docker compose (still v2) and 1 service<=> 1 container approach, the goal was to have multiple environments quite easy, based on a "production ready" OS (first, "my" lovely CentOS, 7 and different compositions, and then different OSes) to give a nice way to describe how to deploy the things even in a VM and not only through containers.

The file system hierarchy was something similar to:

├───config
│   └───centos7
│       ├───appcode // <= trying to play with permissions issues with VOLUME (no way as also described
│ │ // in https://github.com/CentOS/CentOS-Dockerfiles/pull/130/files#diff-2f7a31c9e648aff543a099083dff59e4R21)
│       ├───appdata // <= ^^^ Same as above. ^^^
│       ├───httpd
│       │   └───image
│       ├───mailcatcher
│       │   └───image
│       ├───php70
│       ├───php70-mod
│       │   └───image
│       └───unoconv
│           └───image
├───data
│   ├───maria55db
│   ├───moodle
│   └───solr60
└───logs
    ├───maria55db
    └───solr60

but I never finished it (and never give up to finish it wink).

Different PHP versions, different PHP way of loading (e.g. module vs fpm), different web servers were part of the target too (still one OS for the initial release, including a syslog server to collect the logs from each container in plain files). At that time part of my future plans was also to provide a Dockerfile for each service including the ones that could be already available in the docker registry like e.g. solr 6.0 via image: solr:6.0.

Moodle code files should be external to the container - another potential difference w/ a production ready approach (still not sure about the right one for Moodle and its weeklies) - as well as all data files for persistence: I was not aware of issues on Mac.

One thing I noticed at that time is that naming the things like docker* should be avoided wide eyes: https://github.com/moby/moby/issues/26556.

HTH,
Matteo

 
Average of ratings: Useful (1)
Mark Nielsen in Prague, Czech Republic - 2006
Re: Docker images for Moodle development
Group Core developers

Hey Dan, just wanted to give you a thumbs up on this initiative, would be very helpful for contributing to Moodle and hopefully re-usable for partner development environments (your comments on mixing and matching sound like a good fit for this).

Do you plan to include MDK in this to make it easier to contribute changes to Moodle?

Cheers, looking forward to updates.

 
Average of ratings: -
Picture of Avi Levy
Re: Docker images for Moodle development
Group Core developers

Hi Dan,

In The last few month all ouer Dev env moved to containers, We are work with docker and docker-compose to run different env for moodle. The solution we implimented to solve the problem of container user and OS user is to change the UID of the PHP docker to the UID of the developer user. then the www-data user have the same UID as the developer so the developer and php-fpm have the full access to the files. 

You can find the php container by pull sysbind/php deocker


here is example of yaml of docker compose:

version: '2'


services:

  db:

    image: mariadb:10.0.26

    volumes: 

      - /your/workspaces/mysql/10.0.26:/var/lib/mysql

      - ./mariadb.cnf:/etc/mysql/conf.d/mariadb.cnf

    restart: always

    environment:

      MYSQL_ROOT_PASSWORD: moodleroot

      MYSQL_USER: moodleuser

      MYSQL_PASSWORD: realpassword

      MYSQL_DATABASE: moodle

    security_opt:

      - label:disable

    # DB ports need only if you want to debug DB from your host
    ports:

      - "3306:3306"

  webserver:

    image: nginx:1.10.1

    volumes:

      - ../nginx.conf:/etc/nginx/nginx.conf

      - ../virtualhost.conf:/etc/nginx/conf.d/virtualhost.conf

      - /your/workspaces/PHP:/var/www/html

      - /your/workspaces/moodledata:/var/www/moodledata

      - ../../ssl:/etc/nginx/ssl

    links:

      - db

      - php

    ports:

      - "80:80"

      - "443:443"

    security_opt:

      - label:disable

  php:

    image: sysbind/php:7.0-fpm

    volumes:

      - /your/workspaces/PHP:/var/www/html

      - /your/workspaces/moodledata:/var/www/moodledata

      - ../../php.ini:/usr/local/etc/php/php.ini

    security_opt:

      - label:disable

    links:

      - db

      - memcached

      - redis

    environment:

      # You can find it by echo $UID

      - UID=XXXX

  memcached:

    image: memcached

  redis:

    image: redis


 
Average of ratings: -