Sensor for new docker image versions available

Meanwhile I run about 10 docker container.
Does someone know a sensor or other easy method, do be informed about new versions of installed images?

Yes

There are the automated options like Watchtower; I don’t use this anymore since it bit me more than once with breaking changes that were just installed and I had to wait till I got home so I could fix, so I stopped using it.

I created a script that runs every hour (how often is your choice) that actually pulls the latest docker image (only pull, not recreated). Then I count how many images I have of any certain container, if I have more than 1 of each then I have a binary sensor indicate there is an update. The script publishes to MQTT and I have MQTT sensors, with template sensors to get my binary sensors.

There is also a docker API, I never got it to work right. I had problems with the tags such as latest or 1.3.6, it would only ever return what ever had the latest publish date regardless of tag.

Do you use Portainer?
Portainer is a docker management tool. I have Portainer running as a docker container. The easiest thing to do is click on a container in Portainer and say recreate, which will pull the latest image and recreate it with the exact parameters that it had when initially created.

I utilize Portainer like this, I just only recreate the ones I know I have new images for. If the image is already downloaded, it won’t download again (unless an even newer one exist) it will create the container off the newer image.

Might you share that script?

Yes, but you will have to wait a few hours until I get home.

Also, should look at this thread:
https://community.home-assistant.io/t/sensor-for-latest-docker-image-versions/48745/24

1 Like

Modify as you need. This seems convoluted, but it works for me.
Feel free to ask questions.
As you can see in the python script that I baked debugging into the script from the beginning. If something does not work just change the Debug variable to True. If you need more info change Debug2 to True.
You will have to modify for your purposes.
If you decide to go this route, I can post the binary sensor config.

Cron Job

0 * * * * /home/user/DockerUpdate.sh

DockerUpdate.sh

echo Starting Docker Pulls
sudo docker pull homeassistant/home-assistant:stable && sudo docker pull portainer/portainer-ce && sudo docker pull linuxserver/grocy && sudo docker pull linuxserver/jellyfin && sudo docker pull linuxserver/swag && sudo docker pull syne>
sudo python3 /home/user/DockerMQTT.py

DockerMQTT.py

# Revision Date 12/28/2020 2047

# Requires paho-mqtt for MQTT intergration; if not using MQTT, then ignore
# sudo python3 -m pip install paho-mqtt

import datetime, time
import paho.mqtt.client as mqtt # Allow publishing to MQTT Server
import subprocess

# MQTT Configuration:
MQTT_enable     = True          # Enable MQTT
Broker_IP = "10.74.1.224"       # MQTT Broker IP
Broker_Port = "1883"            # MQTT Broker Port

now = datetime.datetime.now()
ETime = str(now.strftime(" %H:%M:%S on %m-%d-%Y"))

''' Only comment out the Debug = True below to turn off Degub '''
Debug = False
Debug2 = False

#Debug = True           # Uncomment and Comment out this line for Debug
if Debug is True:       # Debug Level 2
  Debug2 = False
  #Debug2 = True        # Uncomment and Comment out this line for Debug Level 2

#########

def MQTT(MQ_Topic,MQ_Payload):
  # Send to the MQTT Broker
  try:
    if MQTT_enable is True:
      if Debug2 is True:
        print ("MQTT pre Client")
      mqttc = mqtt.Client("python_pub")
      if Debug2 is True:
        print ("MQTT pre Connect")
      mqttc.connect(Broker_IP)
      if Debug2 is True:
        print ("MQTT pre Publish")
      mqttc.publish(MQ_Topic, MQ_Payload, retain = True)
      if Debug is True:
        print ("MQTT Publish Complete for " + MQ_Topic)
      if MQTT_enable is False:
        if Debug is True:
          print ("MQTT is not enabled")
  except:
    # Prevent crashing if Broker is disconnected
    if Debug is True:
      print ("MQTT Failed to publish All")

#########

# Main program:
try:
  if __name__ == '__main__':
    #time.sleep(MainWait) # Pause between Docker Image DownloadsChecks and MQTT Updates
    MQTT("docker/Time",ETime)
    time.sleep (10)
    Dock_MQTT = int(subprocess.check_output('docker image ls -a | wc -l', shell=True, text=True)) - 1
    MQTT("docker/Image",Dock_MQTT)
    time.sleep (10)
    Dock_MQTT = int(subprocess.check_output('docker container ls | wc -l', shell=True, text=True)) - 1
    MQTT("docker/ContRun",Dock_MQTT)
    time.sleep (10)
    Dock_MQTT = int(subprocess.check_output('docker ps -a | wc -l', shell=True, text=True)) - 1
    MQTT("docker/ContLoad",Dock_MQTT)
    time.sleep (10)
    Dock_MQTT = int(subprocess.check_output('docker images -f dangling=true | wc -l', shell=True, text=True)) - 1
    MQTT("docker/ImageUnused",Dock_MQTT)
    time.sleep (10)
    Dock_MQTT = int(subprocess.check_output('docker image ls -a | grep "portainer" | wc -l', shell=True, text=True))
    MQTT("docker/Image/Portainer",Dock_MQTT)
    time.sleep (10)
    Dock_MQTT = int(subprocess.check_output('docker image ls -a | grep "home-assistant" | wc -l', shell=True, text=True))
    MQTT("docker/Image/HA",Dock_MQTT)
    time.sleep (10)
    Dock_MQTT = int(subprocess.check_output('docker image ls -a | grep "swag" | wc -l', shell=True, text=True))
    MQTT("docker/Image/Swag",Dock_MQTT)
    time.sleep (10)
    Dock_MQTT = int(subprocess.check_output('docker image ls -a | grep "marytts" | wc -l', shell=True, text=True))
    MQTT("docker/Image/MaryTTS",Dock_MQTT)
    time.sleep (10)
    Dock_MQTT = int(subprocess.check_output('docker image ls -a | grep "grocy" | wc -l', shell=True, text=True))
    MQTT("docker/Image/Grocy",Dock_MQTT)
    time.sleep (10)
    Dock_MQTT = int(subprocess.check_output('docker image ls -a | grep "jellyfin" | wc -l', shell=True, text=True))
    MQTT("docker/Image/Jellyfin",Dock_MQTT)
    time.sleep (10)
    Dock_MQTT = int(subprocess.check_output('docker image ls -a | grep "mosquitto" | wc -l', shell=True, text=True))
    MQTT("docker/Image/Mosquitto",Dock_MQTT)
    time.sleep (10)
    Dock_MQTT = int(subprocess.check_output('docker image ls -a | grep "zwave2mqtt" | wc -l', shell=True, text=True))
    MQTT("docker/Image/Zwave2MQTT",Dock_MQTT)
    time.sleep (10)

except KeyboardInterrupt:
  print ('Interrupted by User at keyboard')
  quit()