Darkshade Forum

General Category => General Discussion => Topic started by: diddly on May 09, 2023, 11:29:29 AM

Title: Docker Update Checker
Post by: diddly on May 09, 2023, 11:29:29 AM
Docker is what I use to run a lot of my services (including this web site!).  It keeps them contained and avoids having to clutter my host server with all sorts of dependencies needed by each service.  It also makes staying updated easier.

However.

I used to use Portainer to manage my docker images and containers.  Works great but for one of my services, rather than just downloading the updated image, it would download ALL images from all time for all architectures.  Basically, it would fill my disk if I let it.  So I moved away from Portainer.

Watchtower sounded like it did what I wanted, but I kept reading it was unsupported, then back, then deprecated, then back, then retired.  Not instilling me with confidence.

So I went wholly command line, writing scripts that would download the latest image, create the container, and update.  I still didn't know if there were updates actually available.  I just forced it every so often.

Today I found on Stack Overflow (https://stackoverflow.com/questions/26423515/how-to-automatically-update-your-docker-containers-if-base-images-are-updated) a script that lets me know if there's updates available for any of my running containers.

Code: [Select]
#!/bin/bash

DATAPATH='/data/docker/updater/data'

if [ ! -d "${DATAPATH}" ]; then
        mkdir "${DATAPATH}";
fi
IMAGES=$(docker ps --format "{{.Image}}")
for IMAGE in $IMAGES; do
        ORIGIMAGE=${IMAGE}
        if [[ "$IMAGE" != *\/* ]]; then
                IMAGE=library/${IMAGE}
        fi
        IMAGE=${IMAGE%%:*}
        echo "Checking ${IMAGE}"
        PARSED=${IMAGE//\//.}
        if [ ! -f "${DATAPATH}/${PARSED}" ]; then
                # File doesn't exist yet, make baseline
                echo "Setting baseline for ${IMAGE}"
                curl -s "https://registry.hub.docker.com/v2/repositories/${IMAGE}/tags/" > "${DATAPATH}/${PARSED}"
        else
                # File does exist, do a compare
                NEW=$(curl -s "https://registry.hub.docker.com/v2/repositories/${IMAGE}/tags/")
                OLD=$(cat "${DATAPATH}/${PARSED}")
                if [[ "${VAR1}" == "${VAR2}" ]]; then
                        echo "Image ${IMAGE} is up to date";
                else
                        echo ${NEW} > "${DATAPATH}/${PARSED}"
                        echo "Image ${IMAGE} needs to be updated";
                        H=`hostname`
                        ssh -i /data/keys/<KEYFILE> <USER>@<REMOTEHOST>.com "{ echo \"MAIL FROM: root@${H}\"; echo \"RCPT TO: <USER>@<EMAILHOST>.com\"; echo \"DATA\"; echo \"Subject: ${H} - ${IMAGE} needs update\"; echo \"\"; echo -e \"\n${IMAGE} needs update.\n\ndocker pull ${ORIGIMAGE}\"; echo \"\"; echo \".\"; echo \"quit\"; sleep 1; } | telnet <SMTPHOST> 25"
                fi

        fi
done;

Personally, I commented out the ssh line that does email notification, and will just run the script manually to check my images.  Clearly this was meant as a cron job that would run automatically, which you could do if so inclined.

I just wanted to capture this here should I need to find it again, and for anyone else who might be looking for a scripted solution.