Development environment using docker compose
H5P Content Type development using docker-compose
This article gives details on how to use docker-compose to spin up containers that make up a development environment for H5P Content Types.
This is a rather basic setup using only prebuilt images for drupal and mysql, and as such is surprisingly simple! The caveat is that there are a few manual steps for installation via the browser the first time we run it.
However, this setup is much more lightweight (and faster!) compared to using full VMs with VirtualBox.
Prerequisites
Install Docker Desktop for your platform. I'm using Windows 11 with WSL 2 to run the latest Ubuntu (20.04 as of this writing).
docker/getting-started
If you're completely new to using docker, I recommend going through the official Getting started guide.
Once you have docker installed, you can launch it with the following command. If you're using Docker Desktop for Windows, this exact command is thrown in your face pretty clearly when you're viewing the Docker Dashboard GUI after installing, and no containers are running.
docker run -dp 80:80 docker/getting-started
This will download the docker/getting-started image from Docker hub, and immediately start a new container with it, and will map port 80 on your machine to port 80 of the container. If you have another process using port 80 just change the port number in front of the colon to bind to another.
Once it's up and running, view it in your browser at http://localhost:80 (or whichever port you ended up mapping).
Create a docker compose file
A Compose file describes one or more services to be run together, each in their own container, but all connected via their own isolated network so that they can communicate (docker sets this up automagically).
Our Compose file will have two services: one web server (Apache with Drupal 7), and one database server (MySQL).
Each service is described and configured, and the format used is YAML. Our Compose file is rather small so the contents are probably fairly intuitive just by reading top to bottom.
But first, we'll prepare a simple folder structure that matches the volume mapping in the compose file.
code/
docker-devenv/
config/
uploads.ini
docker-compose.yml
libraries/
h5p-greetingcard/
greetingcard.css
greetingcard.js
library.json
semantics.json
The file contents for the h5p-greetingcard folder can be gotten from the Hello world tutorial.
Add the following to the config/uploads.ini file:
file_uploads = On
memory_limit = 64M
upload_max_filesize = 64M
post_max_size = 64M
max_execution_time = 600
Then add the following contents to docker-compose.yml:
version: "3.9"
services:
drupal:
image: drupal:7-apache
ports:
- "80:80"
volumes:
- ../libraries:/mnt/h5p/libraries
- drupal-storage:/var/www/html
- ./config/uploads.ini:/usr/local/etc/php/conf.d/uploads.ini
db:
image: mysql:5.7
volumes:
- db-storage:/var/lib/mysql
command: --default-authentication-plugin=mysql_native_password
restart: always
environment:
MYSQL_ROOT_PASSWORD: drupal
MYSQL_USER: drupal
MYSQL_PASSWORD: drupal
MYSQL_DATABASE: drupal
volumes:
drupal-storage: {}
db-storage: {}
Both services (drupal and db) are based on prebuilt images straight from the Docker hub.
So, as soon as we run this, docker will create a network and then run two containers that are connected to it.
Docker compose up and down
Starting the containers
No reason to wait! Start it up with this simple command from the folder containing the docker-compose.yml file.
docker compose up -d
If you can't run `docker compose`, try `docker-compose` (with a dash).
It should give output similar to this:
Creating network "docker-devenv_default" with the default driver Starting docker-devenv_drupal_1 ... done Starting docker-devenv_db_1 ... done
Remove the -d flag if you want to run in the foreground instead. Then you can stop the containers by hitting Ctrl + C.
Stopping (and removing) the containers
The "opposite" command allows you to easily tear everything down, and actually removes both containers.
docker-compose down
Stopping docker-devenv_drupal_1 ... done Stopping docker-devenv_db_1 ... done Removing docker-devenv_drupal_1 ... done Removing docker-devenv_db_1 ... done Removing network docker-devenv_default
Note that the named volumes are left intact. If you want to remove those as well, you can do so with
docker-compose down --volumes
.
You can also simply run docker-compose stop
to leave the containers intact, but just stop them.
The thing about docker is that containers are meant to be disposable and easily reproducible, and so ideally it should be safe to simply destroy a container because you should have a compose file (or a lone Dockerfile) that let's you easily recreate it.
Installing Drupal and setting up H5P content type development
Introduction
So, it's important to note that our compose file and image composition leaves room for improvement because Drupal isn't actually installed yet.
We have to run the browser based installer, and then we have to install the H5P Plugin and then enable the development folder.
Also, once this is done, we must initialize the folders under sites/default/files/h5p by adding some content and then we can create a symbolic directory link to /mnt/h5pdev where we have mapped the source code for our content type.
Installing Drupal
Ensure the containers are up and running
docker compose up -d
If they're already running, docker handles this gracefully and simply informs you that they are up-to-date.
docker-devenv_drupal_1 is up-to-date docker-devenv_db_1 is up-to-date
You should now be able to access drupal's web based installer at http://localhost.
Note that we haven't mapped any ports for the MySQL container so we cannot connect to it from the host directly, but we also shouldn't currently need to.
Proceed to the "Set up database" step of the Drupal installation. Here we provide the username and password that we have configured for our db service.
The thing to note here is that we must expand Advanced otions and supply the hostname db
instead of localhost. Docker enables us to use this as a hostname, simply referring the name we chose in our docker-compose.yml on line 11.
The rest of the installer is self-explanatory.
Installing the H5P plugin
Locate the latest Drupal 7 plugin at the bottom of the following page https://www.drupal.org/project/h5p.
Copy the URL for the tar.gz. It is https://ftp.drupal.org/files/projects/h5p-7.x-1.50.tar.gz as of Apr 20 2022.
Navigate to http://localhost/admin/modules/install and paste the URL in the "Install from URL" input, then click Install.
Upon successful installation, click "Enable newly installed modules", then scroll to the bottom of the page to enable H5P and H5P Editor.
Enabling H5P development mode and development folder
Navigate to Configuration > System > H5P (http://localhost/admin/config/system/h5p) and then check the two checkboxes labelled Enable H5P development mode and Enable library development directory.
Then, navigate to the front page and add new content > interactive content. Pick any of the available content types, and click Get.
This will initialize all the subfolders of sites/default/files/h5p including the development folder which we will now overwrite with a symbolic link.
Overwriting development folder with a symbolic link
In our docker compose file we mapped ../libraries to /mnt/h5p/libraries. We want this folder to be our development folder, and we accomplish this by simply creating a symbolic directory link to it.
This is done from inside the container, and in order to launch a shell inside a running container we can use docker compose exec drupal bash
.
Here's what we need to do in order to :
cd /var/www/html/sites/default/files/h5p
mv development development-old
ln -s /mnt/h5p/libraries development
If you added the h5p-greetingcard files then you should now be able to add new content and find the Greeting Card content type.
If you did, then we're done!
You can now hack away inside the libraries folder on your machine and the contents will be available inside the container.
Final note on volumes and persistence
We use so called named volumes to persist the contents of /var/www/html of the drupal container, and /var/lib/mysql of the mysql container. This means that the drupal installation and configuration will be persisted as long as we don't remove the volumes.
If we remove the volumes, we will have to reinstall drupal and the plugin etc all over.
Comments
Cheegiti Mahesh
Fri, 09/01/2023 - 10:56
Permalink
Problem with Editor dependices
I am using h5p cli to develop a h5p plugin but i want use the editor dependicies that is h5p-editor-radio-group but that was not loading
my file structute is
content
--h5p
-- content.json
libs
--h5p-editor-radio-group
-- radiogruop.js
-- radiogroup.css
--H5P-Skill2030
--library.json
--semantics.json
--skill2030.js
--skill2030.css
server.json
and the
library.json
{ "title": "Skill 2030", "description": "Gives the details of Pronouciation", "majorVersion": 1, "minorVersion": 0, "patchVersion": 5, "runnable": 1, "author": "Cheegiti Mahesh", "machineName": "H5P.Skill2030", "coreApi": { "majorVersion": 1, "minorVersion": 0 }, "preloadedJs": [ { "path": "skill2030.js" } ], "preloadedCss": [ {"path": "skill2030.css"} ], "editorDependencies": [ { "machineName": "H5P.RadioGroup", "majorVersion": 1, "minorVersion": 1 } ] }
can anyone explain how to use those..
Languafe
Tue, 09/05/2023 - 08:42
Permalink
Incorrect machineName in editorDependencies
It looks like the `machineName` for the radio group editor library is incorrect. It should be H5PEditor.RadioGroup.
Cheegiti Mahesh
Sat, 09/02/2023 - 12:17
Permalink
what about content.json
where can i place content.json when i developing h5p in the docker compose environnment?
Languafe
Tue, 09/05/2023 - 08:47
Permalink
What are you trying to do?The
What are you trying to do?
The `development` folder is for placing the source code for libraries during development, but there is no place for `content.json` as a file here. In order to create a new H5P with your content.json you can use the following guide for creating an .h5p package that you then upload in the editor: https://h5p.org/hello-world-h5p-package
Depending on your needs it might be even easier to just create this content using the editor and choosing your own library.