Category: Uncategorised

  • How do you keep your Dockerfile FROM sha tags up to date?

    For my trusty followers who have been crying out for a technology-based post – TODAY IS THE DAY.

    Due to recent supply chain attacks; more platforms are going down the route of suggesting sha-pinning dependencies

    GitHub has a flag that ensures that all your GitHub Action dependencies are explicitly tied to a sha, instead of just a version tag (e.g. @v1)

    This helps to put you in control of version upgrades, as each time the author releases a new version.

    In the npm world, your package.json file defines the ‘range’ of dependencies that you ‘directly’ depend on, and the package-lock.json is a reference to all of the reified dependency tree versions that were pulled when you ‘built’ the package.

    This produced repeatable builds (when using `npm ci`), as it only ever downloaded the dependencies ‘pinned’ by the lockfile. As npm follows SemanticVersioning, when new packages are updated, the dependency tree is re-worked out, and dependabot can make suggestions for how to update your package-lock.json file to satisfy both generic updates, and security patches.

    It’s great for npm (SemVer), it’s great for GHA (SemVer), but it’s also capable of supporting Dockerfiles.

    FROM node:20-alpine

    An innocuous Dockerfile, build using the Official Node image, and follows Docker’s own documentation (from 2022).

    Way back in 2020, the first hit (for me) on Google is Bálint Biró‘s helpful blogpost on how to follow this approach for Docker images within the context of tools like docker-compose; and the official Dockerfile doc shows how to do this using the FROM argument in a dockerfile:

    FROM node:20-alpine@sha256:3bc9a4c4cc25cfde1e8f946341c85f333c36517aafda829b4bb7e785e9b5995c 

    Neat.

    However, the management of these images in DockerHub is kinda a different paradigm. The office ‘node’ image, of which 20-alpine is just a label, has quite a load of other labels:

    https://hub.docker.com/_/node

    There are tens of labels, and the label I’ve targeted is mutable. It automatically keeps me up to date whenever the official maintainers release a new version. However, it’s the same anti-pattern as the one that Github Actions recently fixed with their sha pinning.

    So, if I want to maintain 20-alpine, and I want to pin to a sha, so that I only get an update if the maintainer posts a new version of the 20-alpine label to docker hub, that’s possible right?

    Well, I tested it and put a Dockerfile the following:

    FROM node:20-alpine@sha256:3bc9a4c4cc25cfde1e8f946341c85f333c36517aafda829b4bb7e785e9b5995c

    and a dependabot.yml like so:

    # To get started with Dependabot version updates, you'll need to specify which
    # package ecosystems to update and where the package manifests are located.
    # Please see the documentation for all configuration options:
    # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
    
    version: 2
    updates:
      - package-ecosystem: "npm" # See documentation for possible values
        directory: "/" # Location of package manifests
        schedule:
          interval: "weekly"
      - package-ecosystem: "github-actions" # See documentation for possible values
        directory: "/" # Location of package manifests
        schedule:
          interval: "weekly"
      - package-ecosystem: "docker"
        directory: "/" # Location of package manifests
        schedule:
          interval: "daily"

    and to my (un-surprise, as I’d read the docs), it didn’t quite work as anticipated, with the next PR suggesting the following change:

    Bump node from 20-alpine to 25-alpine !

    Now, node’s own guidance is as follows:

    Major Node.js versions enter Current release status for six months, which gives library authors time to add support for them. After six months, odd-numbered releases (9, 11, etc.) become unsupported, and even-numbered releases (10, 12, etc.) move to Active LTS status and are ready for general use. LTS release status is “long-term support”, which typically guarantees that critical bugs will be fixed for a total of 30 months. Production applications should only use Active LTS or Maintenance LTS releases.

    So this PR is taking me from a current LTS release, in maintenace til April ’26, to a current version that’s never going to enter LTS and not recommended for production use.

    I think that it’s behaving like this because the implementation pattern that the official node maintains have taken to have loads of labels against a single image. Dependabot for docker isn’t particularly smart, and looks for a temporally later tag against the node image, rather than using the 20-alpine label to contextualise the sha and lock it against the label+sha as defined in my lovely Dockerfile.

    Now, no grief to the maintainers. The pattern that they support is a docker-hub image that uses SemVer in the label to contextualize their dependencies, so the nodeJS pattern is just one of many others that fall outside that paradigm.

    A little bit more research…

    After a quick Google, I went and found a few threads where people were cheering an alternative to dependabot for docker stuff, Renovate, by Mend.

    I’d come across this before, but being a Github native I’d always just deferred to dependabot.

    I had to install the app into my org, trust it with my test repo – but once it had been plumbed in and read my code.. It raised the PR that I wanted – a direct update of the sha for the node:20-alpine tag:

    I can see why Dependabot is struggling; but if renovate is ahead of the game here then I may be rethinking what else it’s picking up on that Dependabot is missing…

    What do you use to manage your dependencies? Is there another dependency bot that’s even better?

  • The Role of Open Source in Modern IT Solutions

    My career in IT began by developing open source solutions to provide licence-free services to small businesses. Working with a team of software enthusiasts from the north-west of the UK, I was a small cog in a wonderfully idyllic and optimistic consortium.

    My role initially consisted of travelling around small businesses in Manchester and offering a free ‘audit’ of their existing IT solutions. This was back in 2006, and around this time ‘Microsoft Small Business Server’ was what most small companies would use to host their ‘groupware’ – ultimately email, calendaring & file-sharing systems.

    As well as developing our own solution (the AZ1000!), we also offered local support for open source solutions. It was at the beginning of Web 2.0 (when you could start to right-click on the web) and we had got Zimbra! as one of the open source tools we’d support. We also had https://www.horde.org/ and a supported some Plone websites too.

    A few days ago, a little poem popped up on my LinkedIn, inspired by the “I met my #youngerself for coffee” trend. I found it quite a profound way of thinking about my wider life, but for the purposes of this post I wanted to reflect back on my tech career.

    The first thing I think my #youngerself would be disappointed with, is how little support the open source movement gets from the large corporates for whom it’s the lifeblood of their delivery. I doubt there are many projects running in the private sector that don’t make significant use of open source software, yet give very little back to the ecosystem – if they are even aware of it at all.

    Secondly, brought into stark focus by some of the more recent political changes – would be the re-coupling of IT to large American companies. In 2006, we were trying to avoid lock in to Microsoft, who had a significant monopoly on many aspects of commercial IT. We’ve just gone and done the same with the likes of AWS, Google, & Apple. Whilst they’ve given some back, there’s unlikely to be many commercial IT endeavours that don’t pay them some dollar.

    Looking forward, I wonder how far IT systems can be run within sovereign infrastructure? Germany and France seemed to take the ideal of open source more literally. Should we be looking to create home-based hosting; stop the transitions to the cloud of “just someone else’s server” – and work out how to stop the brain drain and commercial drain that is software licensing on European and British solutions.

    As we pick up more AI solutions that will be biased towards the status-quo; we’ve really got to make a determined and conscious effort if we want to break it – if it’s even possible.