Search code examples
dockerdocker-swarm

Docker stack deploy doesn't pull images from ghcr


EDIT: Nevermind, see answer below


There seems to be a ton of noise about this across the internet (yes, I've read all the stack overflows and github issues), but not much signal for my particular problem. Also, I'm new to docker, so possibly user error, but none of the obvious....

Here's what's happening:

  • I've created a single node swarm for a pet project and have successfully logged in to both ghcr and docker hub.
  • I've created a simple docker image based on the standard mysql image and published it as a private ghcr package
  • I've created a docker context on my local machine pointing to the docker socket that I'm forwarding from the swarm node.
  • Using that context, when I run docker image pull ghcr.io/my-name/my-image:latest, it works fine and pulls the image down to the swarm node.
  • I then remove the image and run docker stack deploy -c test.yml test (test.yml included below) and it fails with "No such image: ghcr.io/my-name...."

It does appear to have something to do with authentication, but unclear exactly what.... I also tested with a public ghcr package and it worked fine, so the difference seems to be public vs private.

Here's what test.yml looks like (sub my-name/my-image in for any private ghcr package you have access to):

version: "3.9"

services:
    test-db:
        image: ghcr.io/my-name/my-image:latest
        networks:
            - test-backend
        labels:
            test.app: test

networks:
    test-backend:
        driver: overlay

Again, the problem is that when I run docker swarm deploy, it does not automatically pull the images, even though I can successfull pull the images manually.


Solution

  • Total embarrassing facepalm - I seem to have gotten stuck in a web of false-negatives. In the end, it was as simple as adding --with-registry-auth to my deploy command, which many people on the internet have said before. I had done that several times and it hadn't worked, so I thought it wasn't that, but for whatever reason, I tried it again and it seems to work now. My bad for cluttering up SO with duplicates.

    For others, as @Chris Becke notes in the comment above, the full command would be:

    docker stack deploy --with-registry-auth -c test.yml test
    

    And something that I learned about this (from Bret Fisher) is that login is only a client concept, and it is always the client that sends auth info to the engine, so running docker login on the remote machine where the swarm is is not necessary if you access the swarm via your local docker client.