blog/content/homelab/updates-with-watchtower.md

189 lines
5.8 KiB
Markdown
Raw Permalink Normal View History

2023-06-11 16:09:07 +02:00
---
title: "Automatics updates with WatchTower and HA notifications"
date: 2023-06-11T13:06:44+02:00
2023-06-11 16:09:58 +02:00
draft: false
2023-06-11 16:09:07 +02:00
author: "Mathieu Broillet"
cover : "img/watchtower-docker.png"
# coverAlt : "alt image"
# coverCaption : "credit of image"
description : "Tired of checking for updates every few days? Install WatchTower!"
tags : ['docker', 'watchtower']
---
With watchtower you can update the running version of your containerized app simply by pushing a new image to the Docker Hub or your own image registry. Watchtower will pull down your new image, gracefully shut down your existing container and restart it with the same options that were used when it was deployed initially.
I made a short script to automatically create the docker compose file and start it on any host (should work on debian/alpine). It also sends a notification to a webhook running on HomeAssistant.
{{< code language="BASH" title="Script to auto create a watchtower compose stack" expand="Show" collapse="Hide" isCollapsed="false" >}}
apk add docker-compose # if on alpine
docker container stop watchtower-watchtower-1
docker container rm watchtower-watchtower-1
mkdir -p /var/data/watchtower/
cat <<EOF >/var/data/watchtower/docker-compose.yml
---
version: "3"
services:
watchtower:
image: containrrr/watchtower
# command: --run-once #notify-upgrade
restart: always
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
WATCHTOWER_CLEANUP: "true"
WATCHTOWER_NOTIFICATION_REPORT: "true"
WATCHTOWER_NOTIFICATION_URL: >
generic://ha.xyz.abc/api/webhook/watchtower_notification
WATCHTOWER_NOTIFICATION_TEMPLATE: |
{{- if .Report -}}
{{- with .Report -}}
{{len .Scanned}} Scan, {{len .Updated}} Mise à jour, {{len .Failed}} Échec
{{- range .Updated}}
- {{.ImageName}}: Mis à jour
{{- end -}}
{{- range .Fresh}}
- {{.ImageName}}: OK
{{- end -}}
{{- range .Skipped}}
- {{.ImageName}}: {{.State}}: {{.Error}}
{{- end -}}
{{- range .Failed}}
- {{.ImageName}}: {{.State}}: {{.Error}}
{{- end -}}
{{- end -}}
{{- else -}}
{{range .Entries -}}{{.Message}}{{"\n"}}{{- end -}}
{{- end -}}
EOF
cd /var/data/watchtower/
docker compose up -d
{{< /code >}}
I am then using Node-RED to parse the notification and send it to my phone in a more "readable" format.
For this code to work, you need to have NodeRED and the HomeAssistant addon (node-red-contrib-home-assistant-websocket) installed.
{{< code language="JSON" title="NodeRED flow for parsing watchtower webhook" expand="Show" collapse="Hide" isCollapsed="true" >}}
[
{
"id": "cbcf3a96685a4553",
"type": "ha-webhook",
"z": "ee9d63dee39b7924",
"name": "Watchtower Notification",
"server": "f00dc31d.a2b0e",
"version": 1,
"outputs": 1,
"webhookId": "watchtower_notification",
"outputProperties": [
{
"property": "payload",
"propertyType": "msg",
"value": "",
"valueType": "data"
}
],
"payloadLocation": false,
"payloadLocationType": false,
"headersLocation": false,
"headersLocationType": false,
"x": 150,
"y": 2280,
"wires": [
[
"56ae4b8a75d63963"
]
]
},
{
"id": "56ae4b8a75d63963",
"type": "switch",
"z": "ee9d63dee39b7924",
"name": "Check if any update/skip/fail",
"property": "payload",
"propertyType": "msg",
"rules": [
{
"t": "cont",
"v": "Mis à jour",
"vt": "str"
},
{
"t": "cont",
"v": "Fail",
"vt": "str"
},
{
"t": "cont",
"v": "Skip",
"vt": "str"
}
],
"checkall": "false",
"repair": false,
"outputs": 3,
"x": 430,
"y": 2280,
"wires": [
[
"f90014bfd991bb75"
],
[
"f90014bfd991bb75"
],
[
"f90014bfd991bb75"
]
]
},
{
"id": "f90014bfd991bb75",
"type": "api-call-service",
"z": "ee9d63dee39b7924",
"name": "Send notification to mathieu",
"server": "f00dc31d.a2b0e",
"version": 5,
"debugenabled": false,
"domain": "notify",
"service": "mobile_app_oneplus_8t",
"areaId": [],
"deviceId": [],
"entityId": [],
"data": "{\t \"title\": \"WatchTower\",\t \"message\": payload,\t \"data\": {\t \"ttl\": 0,\t \"priority\": \"high\"\t }\t}\t",
"dataType": "jsonata",
"mergeContext": "",
"mustacheAltTags": false,
"outputProperties": [],
"queue": "none",
"x": 730,
"y": 2280,
"wires": [
[]
]
},
{
"id": "bfcb353047dce568",
"type": "comment",
"z": "ee9d63dee39b7924",
"name": "Watchtower notification",
"info": "",
"x": 150,
"y": 2240,
"wires": []
},
{
"id": "f00dc31d.a2b0e",
"type": "server",
"name": "Home Assistant",
"addon": false,
"rejectUnauthorizedCerts": true,
"ha_boolean": "",
"connectionDelay": false,
"cacheJson": false,
"heartbeat": false,
"heartbeatInterval": "",
"statusSeparator": "",
"enableGlobalContextStore": false
}
]
{{< /code >}}
*Import this via the NodeRED UI (Ctrl+I)*