Fishing boats at dock

Docked Libraries and DNSMasque

I use Docker at work because it’s what we have to use to build sites on specific servers (like WordPress VIP). Honestly, I like it because everything is nicely isolated, but it has been known to have some … let’s call them ‘quirks’ with the newer M1 and M2 chip Macs.

You know what I have.

And I had some drama on a Friday afternoon, because why the hell not.

Drama 1: libc-bin

After working just fine all day, I quit out of Docker to run something else that likes to use a lot of processing power. When I popped back in and started my container, it blew a gasket on me:

21.39 Setting up npm (9.2.0~ds1-1) ...
21.40 Processing triggers for libc-bin (2.36-9+deb12u1) ...
22.74 npm ERR! code EBADENGINE
22.74 npm ERR! engine Unsupported engine
22.74 npm ERR! engine Not compatible with your version of node/npm: npm@10.1.0
22.74 npm ERR! notsup Not compatible with your version of node/npm: npm@10.1.0
22.74 npm ERR! notsup Required: {"node":"^18.17.0 || >=20.5.0"}
22.74 npm ERR! notsup Actual:   {"npm":"9.2.0"}

I was using Node 16 as a holdover from some work I was doing back at DreamHost. Of course the first thing I did was update Node to 18, but no matter what I tried, Docker would not run the right version!

I looked at the Dockerfile and saw this section:

# Development tooling dependencies
RUN apt-get update \
	&& apt-get install -y --no-install-recommends \
		bash less default-mysql-client git zip unzip \
		nodejs npm curl pv \
		msmtp libz-dev libmemcached-dev \
	&& npm install --global npm@latest \
	&& rm -rf /var/lib/apt/lists/*

When I broke it apart, it was clear than apt-get install was installing the wrong version of Node!

Maddening. I wrestled around, and finally I added FROM node:18 to the top of my Dockerfile to see if that declare would work (after all, Docker supports multiple FROM calls since 2017).

To my surprise, it did! Almost…

Drama 2: PHP

It broke PHP.

While you can have multiple FROM calls in modern Docker, you have to make sure that you place them properly. Since node was the new thing, I put it as the second FROM call. In doing so, it overrode the PHP call a few lines down, causing the build to fail on PHP.

Our Dockerfile is using something like the older version of the default file (I know I know, but I can only update a few things at a time, I have 4 tickets out there to modernize things, including PHPCS), I had to move the call for FROM wordpress:php8.1-fpm to right above the line where we call PHP.

You may not have that. But if you add in that from node and it breaks PHP telling you it can’t run? That’s probably why.

Huzzah, the build works! PHP and Node are happy … but then …

Drama 3: UDP Ports

Guess what happened next?

Error response from daemon: Ports are not available: exposing port 
UDP -> listen udp bind: address 
already in use

I shouted “FOR FUCKS SAKE!”

I did not want to edit the compose.yml file. Not one bit. If it works for everyone else, it should be that way.

Thankfully, Docker has a way to override with compose.override.yml (we have a docker-compose.override.yml file, old school name, old school project). I was already using that because, for some dumb reason, the only way to get the database working was to add in this:

    platform: linux/amd64

It’s not a super dumb reason, it’s a Docker vs M1 chipset reason. Still, it was annoying as all get out.

Naturally, I assumed override meant anything I put in there would override the default. So I tossed this in:

      - "54:54/udp"

Turns out, override doesn’t mean override when it comes to ports. I went to the documentation, and there is no mention of how to override ports. On to the Googles! A lot of searching finally landed me on an old, closed ticket that implied I could do exactly what I wanted.

After reading that whole long ass ticket I determined the syntax is this:

    ports: !reset
      - "54:54/udp"

Finally I could get my site up and running! No idea why that isn’t documented, since the dnsmasq issue is a known compat issue with MacOS.

Drama 4: Update All The Things

Then I did the dumbest thing on the planet.

I updated the following:

  • Docker
  • Everything I use from HomeBrew
  • Mac OS (only the minor – I’m not jumping to the next major release on a Friday afternoon!)

But I have good news this time.

Everything worked.

Final Drama…

The thing was, I didn’t really want to have to edit the Dockerfile. It’s a tetchy beast, and we all use different OSes (I’m M1, one person is older Mac, one is Windows). Cross compatibility is a bit issue. I did test a number of alternatives (like defining engine in package.json and even mimicking our other setups).

At the end of the day, nothing worked except the above. No matter what, libc-bin was certain I was using NPM 10, which I wasn’t. I wish I’d found a better solution, but so far, this is the only way I could convince my Dockerfile that when you install via apt, you really want to use the latest.