1

******EDIT

I've boiled this down to the following:

  • I am moving my composer require commands to image build time rather than run time. I am not sure if this is ideal but it feels better.
  • The composer commands need to update files in a mounted volume, which isn't done at run time. It should update files at /bitnami/drupal/modules/contrib
  • This thread discusses my problem: Add a volume to Docker, but exclude a sub-folder

Relevant line from docker-compose

volumes:
        - /docker/drupal9/template/site-files:/bitnami/drupal

I mount the /bitnami/drupal directory because, per the documentation on https://hub.docker.com/r/bitnami/drupal/, it is required for persistence.

Not sure how to best proceed but I'm going to troubleshoot "excluding sub-folders" so I can continue to mount the /bitnami/drupal volume while excluding the /bitnami/drupal/modules/contrib directory.

******END EDIT

I'm fairly new to Docker and confused on the best way to handle module installation and updates using composer on containerized Drupal 9 websites (at scale).

Background We manage ~50 websites. Some are unique enough that multi-site isn't appropriate for us. Most of them share the same tools. Regardless, we decided to containerize and each site is running from it's own codebase. We have persistent file storage and database in place.

What we're doing now: The custom Dockerfile is FROM bitnami/drupal but has a few overrides, including a custom ENTRYPOINT file it runs every time the container starts. The ENTRYPOINT file contains a list of "composer require" commands which install necessary contrib modules.

This works OK, as it's easy to push a new image with updates and reboot every container to make sure they're all applied.

The problem: Any time we reboot the container or want to add a new module to this list, the ENTRYPOINT file runs through all "composer require" statements. This causes strain on our internal dev machine and takes a fair bit of time.

We've tried removing the composer statements from the ENTRYPOINT file, but then we aren't sure how to update all websites at once.

What we're thinking: Do we need to maintain multiple images? One with all composer require statements used for standing up new sites, and one with no composer require statements, used for production hosting, container rebooting, etc... Then a third for running composer update at scale?

Is there an easy drush solution I'm missing here? Some workflow for pulling in a controlled composer.json? Are we overthinking this?

I was hoping to avoid any sort of ecs-exec looping.

To summarize, I cannot wrap my head around best implementation given the following criteria:

  • Push button updates (of core and contrib modules) at scale
  • Push button addition of new contrib module at scale
  • Not having to reinstall every module every time
  • Supports creating new websites with all required modules and composer.json

Thank you!

Jordan
  • 13
  • 4
  • Why not do the composer installs/updates in the Dockerfile (during the image build) instead of in the running container? – Mark B May 11 '23 at 14:36
  • @MarkB great question... I think nothing. This is likely the simple answer I was looking for. This stems from my misunderstanding of ENTRYPOINT. I moved my commands to a shell script that is referenced via RUN. Now, the image takes a long time to build, but sites stand up instantly. If I need to update all sites, I'm guessing I build a new image which RUNs "composer update". So far so good! doing a bit more edge-case testing. – Jordan May 11 '23 at 18:10
  • Any `RUN` command in the Dockerfile is a command to run as part of building the image. Those are build-time commands. The `ENTRYPOINT` is the command to run when the container is started. That is a run-time command. Doing something like this once, during the image build, instead of every single time a container is created from the image, is going to be much more efficient and result in much faster container startups (at the expense of slower image builds). – Mark B May 11 '23 at 18:26
  • I added a new module via the RUN command using 'composer require 'drupal/honeypot:^2.1''. Then I rebuilt that image. During the image build, I saw it run through those commands, so I know they are happening. Then I stopped and removed an existing container, updated the associated docker-compose file to look at my freshly built image, and stood it back up. The new module (and other updates) were not applied. Any idea where I'm going wrong? I tried commands such as 'docker-compose build --no-cache' to no success. – Jordan May 11 '23 at 19:10
  • I exec'd into the container and can see that the composer command was successfully added to the composer.json file, but the actual module file itself does not exist. So the statement ran... but didn't actually download anything? – Jordan May 11 '23 at 19:30
  • This could be an issue with the order in which I mount volumes. I am going to try what is being discussed here: https://stackoverflow.com/questions/46786589/running-composer-install-within-a-dockerfile – Jordan May 11 '23 at 19:35
  • If the compose command is suppose to update files that are in a mounted volume, then you can't do that in the Dockerfile at build time, you would have to go back to doing that during run-time. The volumes are not available inside the Dockerfile during the image build. Or you would have to stop mounting that path as a volume. – Mark B May 11 '23 at 19:47
  • Thanks Mark, I've updated my original post with current status and my new plan. I appreciate your help. – Jordan May 11 '23 at 21:29
  • I see your (updated) problem, there are a couple possible solutions. 1. Look at what is under the `/bitnami/drupal` folder in the mounted volume and see if there are just some other subfolders there you could mount as volumes, instead of mounting the entire folder. 2. Inside the Dockerfile, after everything else is done, zip up the contents of the `/bitnami/drupal/modules` folder and store it somewhere like `/tmp`. Then in the script that you use for the `ENTRYPOINT` unzip that file into the `/bitnami/drupal/modules` folder (which will copy the updated module files into the mounted volume). – Mark B May 12 '23 at 00:22
  • If either of those sound like something you would want me to expand upon more, let me know and I'll type up a full answer tomorrow. – Mark B May 12 '23 at 00:24
  • 1
    @MarkB I ended up going with a version of #1 and it appears to be working. I'm now mounting several necessary directories, but leaving out the modules directory. So far so good. A little more testing needed tomorrow! – Jordan May 12 '23 at 00:54

0 Answers0