{"id":167500,"date":"2025-05-18T12:45:11","date_gmt":"2025-05-18T12:45:11","guid":{"rendered":"https:\/\/linuxiac.com\/?p=167500"},"modified":"2025-05-18T12:46:24","modified_gmt":"2025-05-18T12:46:24","slug":"how-to-keep-containers-up-to-date-with-whats-up-docker-wud","status":"publish","type":"post","link":"https:\/\/linuxiac.com\/how-to-keep-containers-up-to-date-with-whats-up-docker-wud\/","title":{"rendered":"How to Keep Containers Up-to-Date with What\u2019s Up Docker (WUD)"},"content":{"rendered":"\n<div class=\"wp-block-ultimate-post-table-of-content ultp-block-be402a\"><div class=\"ultp-block-wrapper\"><div class=\"ultp-block-toc\"><div class=\"ultp-toc-header\"><div class=\"ultp-toc-heading\">Table of Contents<\/div><div class=\"ultp-collapsible-toggle  ultp-collapsible-right\"><a class=\"ultp-collapsible-text ultp-collapsible-open\" href=\"javascript:;\">[Open]<\/a><a class=\"ultp-collapsible-text ultp-collapsible-hide\" href=\"javascript:;\">[Close]<\/a><\/div><\/div><div class=\"ultp-block-toc-style1 ultp-block-toc-body\" style=\"display:block;\"><ul class=\"ultp-toc-lists\"><li><a href=\"#A_Brief_Introduction_to_What\u2019s_Up_Docker_WUD\">A Brief Introduction to What\u2019s Up Docker (WUD)<\/a><\/li><li><a href=\"#Install_What\u2019s_Up_Docker_with_Docker_Compose\">Install What\u2019s Up Docker with Docker Compose<\/a><\/li><li><a href=\"#Open_the_WUD_Web_UI\">Open the WUD Web UI<\/a><\/li><li><a href=\"#Configure_WUD\">Configure WUD<\/a><ul class=\"ultp-toc-lists\"><li><a href=\"#WUD_Notification_Setup\">WUD Notification Setup<\/a><\/li><li><a href=\"#Container_Update_or_Just_Notifications?\">Container Update or Just Notifications?<\/a><\/li><li><a href=\"#Dealing_with_Docker_Compose_Files\">Dealing with Docker Compose Files<\/a><\/li><li><a href=\"#Include_amp;_Exclude_Triggers\">Include &amp; Exclude Triggers<\/a><\/li><li><a href=\"#Launching_Triggers_from_the_WUD_Dashboard\">Launching Triggers from the WUD Dashboard<\/a><\/li><li><a href=\"#Exclude_Container_from_Monitoring\">Exclude Container from Monitoring<\/a><\/li><li><a href=\"#Docker_Images_Tag_Handling_in_WUD\">Docker Images Tag Handling in WUD<\/a><\/li><\/ul><\/li><li><a href=\"#Conclusion\">Conclusion<\/a><\/li><\/ul><\/div><\/div><\/div><\/div>\n\n\n\n<p>Containers\u2014especially Docker\u2014have completely transformed the tech world. But as powerful as Docker is, one thing it doesn\u2019t offer out of the box is a way to monitor the images you\u2019re using, particularly when it comes to knowing if updates are available.<\/p>\n\n\n\n<p>Of course, that\u2019s not a big deal if you only manage a couple of them. In that case, it&#8217;s easy enough to stop them, delete the old images, pull the new ones, and restart everything manually, just like the good old days.<\/p>\n\n\n\n<p>But what if you&#8217;re running a home lab with dozens of containers? Or maybe your day job involves managing hundreds of them in a production environment? In that case, manually updating everything quickly becomes a nightmare.<\/p>\n\n\n\n<p>That\u2019s where a centralized monitoring system comes in\u2014a tool that keeps an eye on all your containers, notifies you when updates are available, or even updates them automatically in the background.<\/p>\n\n\n\n<p>For years, I relied on <a href=\"https:\/\/containrrr.dev\/watchtower\/\" target=\"_blank\" rel=\"noreferrer noopener\">Watchtower<\/a> to handle this task (<a href=\"https:\/\/linuxiac.com\/watchtower-automatically-update-docker-container-images\/\">here&#8217;s our guide<\/a>), and it did a fantastic job. Unfortunately, it hasn\u2019t seen any updates <a href=\"https:\/\/github.com\/containrrr\/watchtower\/releases\" target=\"_blank\" rel=\"noreferrer noopener\">since November 2023<\/a>. That got me looking for a new solution\u2014and that\u2019s when I discovered What\u2019s Up Docker (WUD).<\/p>\n\n\n\n<p>In this guide, I\u2019ll walk you through installing and setting it up so you\u2019ll have a reliable way to stay informed about the Docker images you\u2019re running. But before we dive into the setup, let\u2019s take a quick look at what WUD is all about.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"A_Brief_Introduction_to_What\u2019s_Up_Docker_WUD\">A Brief Introduction to What\u2019s Up Docker (WUD)<\/h2>\n\n\n\n<p><a href=\"https:\/\/getwud.github.io\/wud\/#\/\" target=\"_blank\" rel=\"noreferrer noopener\">What&#8217;s Up Docker<\/a> (WUD) is a free, open-source, self-hostable tool designed to simplify Docker container maintenance by monitoring image updates.<\/p>\n\n\n\n<p>The way it works is pretty straightforward: WUD regularly checks running containers against Docker registries to detect newer image versions. It accomplishes this by periodically pulling metadata about the latest available tags and comparing it against your deployed containers.<\/p>\n\n\n\n<p>When updates are identified, WUD can automatically trigger notifications through various communication channels, including email, Slack, Discord, webhook integrations, etc.<\/p>\n\n\n\n<p>One of the things I personally love about WUD is its flexibility\u2014you can set it up to run in two different modes.<\/p>\n\n\n\n<p>The first is a notification-only mode. When WUD detects that a new version of a Docker image is available, it simply lets you know. That way, you stay in full control of when and how to update your containers.<\/p>\n\n\n\n<p>The second mode\u2014let\u2019s call it fully automated\u2014takes things a step further. When an update is available, WUD will automatically stop the running container, pull the updated image, and restart the container using the new version. It all happens quietly in the background and usually takes just a few seconds.<\/p>\n\n\n\n<p>Also, WUD can automatically update your &#8220;<em>docker-compose.yml<\/em>&#8221; file to point to the new image. Pretty handy, right?<\/p>\n\n\n\n<p>And now, here comes the cherry on top: WUD lets you fine-tune this behavior on a per-container basis. For example, you might want to keep full control over critical containers and only receive update notifications for those, with no automatic actions. At the same time, less critical containers can be set to update automatically without any manual intervention.<\/p>\n\n\n\n<p>Which mode you use is totally up to you. All of this is controlled through environment variables in the WUD container itself and by assigning specific labels to the containers you want it to watch. I&#8217;ll walk you through exactly how to set this up a bit further down. But now, let\u2019s do some work.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"Install_What\u2019s_Up_Docker_with_Docker_Compose\">Install What\u2019s Up Docker with Docker Compose<\/h2>\n\n\n\n<p>The first step is to create the project directory in which our Docker Compose deployment file will be placed. Then switch to it.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"Bash\" data-shcb-language-slug=\"bash\"><span><code class=\"hljs language-bash\">mkdir wud\n<span class=\"hljs-built_in\">cd<\/span> wud<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Bash<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">bash<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Next, open your favorite terminal text editor, create a \u201c<em><strong>docker-compose.yml<\/strong><\/em>\u201d file, paste the content below into it, save the file, and then exit the editor.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"YAML\" data-shcb-language-slug=\"yaml\"><span><code class=\"hljs language-yaml\"><span class=\"hljs-attr\">services:<\/span>\n  <span class=\"hljs-attr\">whatsupdocker:<\/span>\n    <span class=\"hljs-attr\">image:<\/span> <span class=\"hljs-string\">getwud\/wud<\/span>\n    <span class=\"hljs-attr\">container_name:<\/span> <span class=\"hljs-string\">wud<\/span>\n    <span class=\"hljs-attr\">environment:<\/span>\n      <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">WUD_WATCHER_LOCAL_CRON=0<\/span> <span class=\"hljs-number\">6<\/span> <span class=\"hljs-string\">*<\/span> <span class=\"hljs-string\">*<\/span> <span class=\"hljs-string\">*<\/span>\n      <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">WUD_AUTH_BASIC_MY_USER=&lt;YOUR_USERNAME&gt;<\/span>\n      <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">WUD_AUTH_BASIC_MY_HASH=&lt;YOUR_PASSWORD&gt;<\/span>\n    <span class=\"hljs-attr\">ports:<\/span>\n      <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-number\">3000<\/span><span class=\"hljs-string\">:3000<\/span>\n    <span class=\"hljs-attr\">volumes:<\/span>\n      <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">\/var\/run\/docker.sock:\/var\/run\/docker.sock<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">YAML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">yaml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>As you can see, the deployment setup is pretty simple. The key part is the &#8220;<em>environment<\/em>&#8221; section. The &#8220;<em>WUD_WATCHER_LOCAL_CRON<\/em>&#8221; variable <a href=\"https:\/\/linuxiac.com\/how-to-use-cron-and-crontab-on-linux\/\">uses standard CRON syntax<\/a> to define how often WUD should check your Docker containers for updates. In this example, it&#8217;s set to run every day at 6:00 AM\u2014but of course, you can adjust that to fit your own schedule.<\/p>\n\n\n\n<p>But before we go any further, let\u2019s take a moment to talk about one of the WUD&#8217;s core pieces \u2014 the so-called &#8220;<strong>watchers<\/strong>.&#8221; In simple terms, watchers define how WUD scans containers.<\/p>\n\n\n\n<p>They follow this pattern (for CRON, specifically): &#8220;<em>WUD_WATCHER_{watcher_name}_CRON<\/em>,&#8221; where &#8220;<em>{watcher_name}<\/em>&#8221; can be any name you like. For example, I used &#8220;<em>LOCAL<\/em>&#8221; in my setup, but feel free to choose something else\u2014it\u2019s totally up to you.<\/p>\n\n\n\n<p>WUD actually supports several types of watchers, which you can check out&nbsp;<a href=\"https:\/\/getwud.github.io\/wud\/#\/configuration\/watchers\/\" target=\"_blank\" rel=\"noopener\">at this link<\/a>. I highly recommend taking a look since understanding these is important for the next steps, where I\u2019ll walk you through specific examples using them. Now, back to our deployment.<\/p>\n\n\n\n<p>The next two variables, &#8220;<em>WUD_AUTH_BASIC_MY_USER<\/em>&#8221; and &#8220;<em>WUD_AUTH_BASIC_MY_HASH<\/em>,&#8221; are used to set a username and password for accessing the WUD web interface. After all, we don\u2019t want just anyone poking around and seeing which containers we\u2019re running, right?<\/p>\n\n\n\n<p>You can use whatever you like for the username\u2014totally up to you. The fun begins when it comes to setting the password. The &#8220;<em>WUD_AUTH_BASIC_MY_HASH<\/em>&#8221; environment variable expects a value using the Apache-style MD5 hashing algorithm, so we must generate that first.<\/p>\n\n\n\n<p>Now, if your system already has the &#8220;<em>apache<\/em>&#8221; package installed (which includes the <code>htpasswd<\/code> tool), this is super easy. But installing the whole Apache just to create a password hash? Yeah\u2026 that\u2019s overkill, to put it mildly. Luckily, there\u2019s another way to do it.<\/p>\n\n\n\n<p>We will use the command below, which generates a hashed password using the Apache MD5-based password algorithm, also known as APR1.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"Bash\" data-shcb-language-slug=\"bash\"><span><code class=\"hljs language-bash\">openssl passwd -apr1<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Bash<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">bash<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>You\u2019ll be prompted to enter a password, then repeat it, and finally, the command will output a string like this:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">$apr1$zv6vdUFS$g0mH9DjK7ON4FGtps1Xpt0<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-01.jpg\"><img decoding=\"async\" width=\"914\" height=\"142\" src=\"https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-01.jpg\" alt=\"Generate an Apache-style MD5 hashing password.\" class=\"wp-image-168074\" srcset=\"https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-01.jpg 914w, https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-01-380x59.jpg 380w, https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-01-768x119.jpg 768w\" sizes=\"(max-width: 914px) 100vw, 914px\" \/><\/a><figcaption class=\"wp-element-caption\">Generate an Apache-style MD5 hashing password.<\/figcaption><\/figure>\n\n\n\n<p>Now here\u2019s the tricky part: you need to take this string and, every time you see a &#8220;<em>$<\/em>&#8221; symbol (which usually shows up in three spots), add another &#8220;<em>$<\/em>&#8221; right next to it. So, the original string:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">$apr1$zv6vdUFS$g0mH9DjK7ON4FGtps1Xpt0<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Turns into this:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">$$apr1$$zv6vdUFS$$g0mH9DjK7ON4FGtps1Xpt0<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Now that we\u2019ve got our password, let\u2019s update the &#8220;<em>docker-compose.yml<\/em>&#8221; file by replacing &#8220;<em>&lt;YOUR_USERNAME&gt;<\/em>&#8221; and &#8220;<em>&lt;YOUR_PASSWORD&gt;<\/em>&#8221; with the actual username and the password we just created. In the end, it should look something like this:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"YAML\" data-shcb-language-slug=\"yaml\"><span><code class=\"hljs language-yaml\"><span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">WUD_AUTH_BASIC_MY_USER=bobby<\/span>\n<span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">WUD_AUTH_BASIC_MY_HASH=$$apr1$$zv6vdUFS$$g0mH9DjK7ON4FGtps1Xpt0<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">YAML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">yaml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Finally, save the changes and run the container in the background (detached mode):<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"Bash\" data-shcb-language-slug=\"bash\"><span><code class=\"hljs language-bash\">docker compose up -d<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Bash<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">bash<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-02.jpg\"><img decoding=\"async\" width=\"1014\" height=\"520\" src=\"https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-02.jpg\" alt=\"Deploying What's Up Docker with Docker Compose.\" class=\"wp-image-168095\" srcset=\"https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-02.jpg 1014w, https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-02-380x195.jpg 380w, https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-02-768x394.jpg 768w\" sizes=\"(max-width: 1014px) 100vw, 1014px\" \/><\/a><figcaption class=\"wp-element-caption\">Deploying What&#8217;s Up Docker with Docker Compose.<\/figcaption><\/figure>\n\n\n\n<p>If, for some reason, something goes wrong, you can easily figure out what happened by checking the container log with this simple Docker command:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"Bash\" data-shcb-language-slug=\"bash\"><span><code class=\"hljs language-bash\">docker logs wud -f<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Bash<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">bash<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\" id=\"Open_the_WUD_Web_UI\">Open the WUD Web UI<\/h2>\n\n\n\n<p>Just a quick heads-up: As you can see below, I&#8217;m using an unencrypted HTTP connection here\u2014this is only for the sake of the demo. In a real production setup, always put WUD behind a reverse proxy (like <a href=\"https:\/\/linuxiac.com\/reverse-proxy-with-nginx\/\">Nginx<\/a>, <a href=\"https:\/\/linuxiac.com\/how-to-set-up-reverse-proxy-with-nginx-proxy-manager\/\">Nginx Proxy Manager<\/a>, <a href=\"https:\/\/linuxiac.com\/how-to-set-up-caddy-as-reverse-proxy\/\">Caddy<\/a>, Traefik, HAProxy, or any other option you prefer) and <strong>serve it over a secure HTTPS connection<\/strong>. Now, back to the guide.<\/p>\n\n\n\n<p>Open your browser and navigate to \u201c<strong><em>http:\/\/localhost:3000<\/em><\/strong>\u201d (if you access WUD from the same host) or \u201c<strong><em>http:\/\/&lt;server-ip-address&gt;:3000<\/em><\/strong>\u201c (if you access it remotely). Of course, replace the \u201c<em>&lt;server-ip-address&gt;<\/em>\u201d part with your actual server\u2019s IP address. The WUD login page will welcome you.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-03.jpg\"><img decoding=\"async\" width=\"1024\" height=\"590\" src=\"https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-03-1024x590.jpg\" alt=\"WUD login page\" class=\"wp-image-168107\" srcset=\"https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-03-1024x590.jpg 1024w, https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-03-380x219.jpg 380w, https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-03-768x443.jpg 768w, https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-03.jpg 1298w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">WUD login page<\/figcaption><\/figure>\n\n\n\n<p>Enter your username and password and hit the &#8220;<em>LOGIN<\/em>&#8221; button.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-04.jpg\"><img decoding=\"async\" width=\"1024\" height=\"588\" src=\"https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-04-1024x588.jpg\" alt=\"WUD UI\" class=\"wp-image-168110\" srcset=\"https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-04-1024x588.jpg 1024w, https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-04-380x218.jpg 380w, https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-04-768x441.jpg 768w, https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-04.jpg 1311w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">WUD UI<\/figcaption><\/figure>\n\n\n\n<p>And before you get too excited, let me pump the brakes a little. Honestly, we haven\u2019t really done much yet\u2014the real work is just getting started.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"Configure_WUD\">Configure WUD<\/h2>\n\n\n\n<p>As I mentioned, we\u2019ve successfully set up WUD, and it\u2019s running fine in the background. But here\u2019s the thing\u2014we haven\u2019t actually told it how we want it to do its job yet. Most importantly, we haven\u2019t set up any way to get notified when there are container updates, which is the main reason we installed it in the first place.<\/p>\n\n\n\n<p>Now\u2019s also a good time to mention something else: The settings we need aren\u2019t configurable through the WUD web interface &#8211; <strong>think of it more as a dashboard than a control panel<\/strong>. Instead, all the configurations are done by setting the right environment variables on the WUD container itself or by adding labels to the containers it watches.<\/p>\n\n\n\n<p>So, let\u2019s review several strategies and you decide which ones to use for your needs.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"WUD_Notification_Setup\">WUD Notification Setup<\/h3>\n\n\n\n<p><span style=\"box-sizing: border-box; margin: 0px; padding: 0px;\">Of course, we first want to<\/span> set up notifications to let us know when a container update is available. This is handled through what WUD calls&nbsp;triggers, which are mechanisms that kick in and perform actions when a new version of a container is detected.<\/p>\n\n\n\n<p>WUD supports almost every notification method you can think of: Apprise, Discord, Gotify, Ntfy, Pushover, Slack, SMTP, Telegram\u2014you name it. In this example, I\u2019ll walk you through setting up notifications the old-school way (yep, I\u2019m that kind of guy): by email, <a href=\"https:\/\/getwud.github.io\/wud\/#\/configuration\/triggers\/smtp\/\" target=\"_blank\" rel=\"noreferrer noopener\">using SMTP<\/a>. Of course, if you\u2019d rather use something else, <a href=\"https:\/\/getwud.github.io\/wud\/#\/configuration\/triggers\/\" target=\"_blank\" rel=\"noreferrer noopener\">check out the documentation<\/a> for the trigger that fits your needs.<\/p>\n\n\n\n<p>However, if you want to use Gmail in this case, you\u2019ll first need to create an app-specific password. To be clear, this isn\u2019t the same as your regular Gmail password. It\u2019s a separate one, a special 16-character password that Google generates for use with third-party apps (like WUD), made just for this purpose. Creating one is super easy &#8211; just <a href=\"https:\/\/security.google.com\/settings\/security\/apppasswords\" target=\"_blank\" rel=\"noreferrer noopener\">click on this link<\/a> and follow the instructions.<\/p>\n\n\n\n<p>Now that you&#8217;ve generated the application password, open your &#8220;<em>docker-compose.yml<\/em>&#8221; file. Then, add the following under the &#8220;<em>environment<\/em>&#8221; section:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"YAML\" data-shcb-language-slug=\"yaml\"><span><code class=\"hljs language-yaml\"><span class=\"hljs-attr\">services:<\/span>\n  <span class=\"hljs-attr\">whatsupdocker:<\/span>\n    <span class=\"hljs-attr\">image:<\/span> <span class=\"hljs-string\">getwud\/wud<\/span>\n    <span class=\"hljs-string\">...<\/span>\n    <span class=\"hljs-attr\">environment:<\/span>\n      <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">WUD_TRIGGER_SMTP_GMAIL_HOST=smtp.gmail.com<\/span>\n      <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">WUD_TRIGGER_SMTP_GMAIL_PORT=465<\/span>\n      <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">WUD_TRIGGER_SMTP_GMAIL_USER=&lt;YOUR-GMAIL-ACCOUNT&gt;<\/span>\n      <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">WUD_TRIGGER_SMTP_GMAIL_PASS=&lt;THE-APP-PASSWORD&gt;<\/span>\n      <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">WUD_TRIGGER_SMTP_GMAIL_FROM=&lt;YOUR-GMAIL-ACCOUNT&gt;<\/span>\n      <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">WUD_TRIGGER_SMTP_GMAIL_TO=&lt;YOUR-GMAIL-ACCOUNT&gt;<\/span>\n      <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">WUD_TRIGGER_SMTP_GMAIL_TLS_ENABLED=true<\/span> <\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">YAML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">yaml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Just make sure to replace &#8220;<em>&lt;YOUR-GMAIL-ACCOUNT&gt;<\/em>&#8221; with your actual Gmail address in all three spots, and swap out &#8220;<em>&lt;THE-APP-PASSWORD&gt;<\/em>&#8221; with the app password you just generated.<\/p>\n\n\n\n<p>Finally, if the WUD container is already running, run the two commands below to redeploy it and apply the changes:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"Bash\" data-shcb-language-slug=\"bash\"><span><code class=\"hljs language-bash\">docker compose down\ndocker compose up -d<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Bash<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">bash<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Head back to the WUD web interface to check if notifications are working properly. In the left-hand menu, go to &#8220;<em>Configuration<\/em>&#8221; &gt; &#8220;<em>Triggers<\/em>.&#8221; Next, click on the &#8220;<em>smtp\/gmail<\/em>&#8221; trigger, click the &#8220;<em>TEST<\/em>&#8221; button, and then confirm by selecting &#8220;<em>RUN TRIGGER<\/em>.&#8221; You should receive a test email confirming that your SMTP notification settings are all set up correctly.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-05.jpg\"><img decoding=\"async\" width=\"1024\" height=\"597\" src=\"https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-05-1024x597.jpg\" alt=\"Testing if the notifications work correctly.\" class=\"wp-image-168281\" srcset=\"https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-05-1024x597.jpg 1024w, https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-05-380x222.jpg 380w, https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-05-768x448.jpg 768w, https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-05.jpg 1394w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Testing if the notifications work correctly.<\/figcaption><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"Container_Update_or_Just_Notifications?\">Container Update or Just Notifications?<\/h3>\n\n\n\n<p>The next big decision you need to make is how you want WUD to behave\u2014should it just notify you when updates are available for your Docker containers, or should it automatically update them, too?<\/p>\n\n\n\n<p><span style=\"box-sizing: border-box; margin: 0px; padding: 0px;\">This is where the &#8220;<em>WUD_TRIGGER_DOCKER_{trigger_name}_PRUNE<\/em>&#8221; setting, whose defa<\/span>ult value is &#8220;<em>false<\/em>,&#8221; comes into play, and it&#8217;s crucial to understand how it works.<\/p>\n\n\n\n<p>If you <strong>don\u2019t<\/strong> include &#8220;<em>WUD_TRIGGER_DOCKER_{trigger_name}_PRUNE=true<\/em>&#8221; in the &#8220;<em>environment<\/em>&#8221; section of your &#8220;<em>docker-compose.yml<\/em>&#8221; file, WUD will run in notification-only mode.<\/p>\n\n\n\n<p>But if you <strong>do<\/strong> include it with the &#8220;<em>true<\/em>&#8221; value set, WUD will not only notify you\u2014it&#8217;ll take care of the entire update process: it will pull the new Docker image, stop the running container, remove the old image, and start the container again with the updated image\u2014full automatic updates mode.<\/p>\n\n\n\n<p>So, if you only want to be notified, you can skip adding that line\u2014there&#8217;s nothing more to say here. But if you\u2019d like to enable automatic updates, add &#8220;<em>WUD_TRIGGER_DOCKER_{trigger_name}_PRUNE=true<\/em>&#8221; under the &#8220;<em>environment<\/em>&#8221; section in your &#8220;<em>docker-compose.yml<\/em>&#8221; file.<\/p>\n\n\n\n<p>For example, if you want to name this trigger \u201c<em>LOCAL<\/em>,\u201d the line you need to include would look like this:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"YAML\" data-shcb-language-slug=\"yaml\"><span><code class=\"hljs language-yaml\"><span class=\"hljs-attr\">environment:<\/span>\n  <span class=\"hljs-string\">...<\/span>\n  <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">WUD_TRIGGER_DOCKER_LOCAL_PRUNE=true<\/span>\n  <span class=\"hljs-string\">...<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">YAML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">yaml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>And just like that, you&#8217;re all set for a fully automated process that keeps your containers running the latest Docker images.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"Dealing_with_Docker_Compose_Files\">Dealing with Docker Compose Files<\/h3>\n\n\n\n<p>But what if your Docker Compose deployments use hardcoded image versions and you have instructed WUD to update your containers automatically? Let me show you a really simple example to illustrate the point:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-13\" data-shcb-language-name=\"YAML\" data-shcb-language-slug=\"yaml\"><span><code class=\"hljs language-yaml shcb-code-table\"><span class='shcb-loc'><span><span class=\"hljs-attr\">services:<\/span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attr\">web:<\/span>\n<\/span><\/span><mark class='shcb-loc'><span>    <span class=\"hljs-attr\">image:<\/span> <span class=\"hljs-string\">nginx:1.27<\/span>\n<\/span><\/mark><span class='shcb-loc'><span>    <span class=\"hljs-attr\">ports:<\/span>\n<\/span><\/span><span class='shcb-loc'><span>      <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">\"80:80\"<\/span>\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-13\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">YAML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">yaml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Let&#8217;s say, Nginx version 1.28 just dropped. WUD will detect the update, pull the new image, and automatically restart the container using it. But here\u2019s where things can get a little tricky: the next time you manually reload your deployment using something like:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-14\" data-shcb-language-name=\"Bash\" data-shcb-language-slug=\"bash\"><span><code class=\"hljs language-bash\">docker compose down  \ndocker compose up -d<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-14\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Bash<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">bash<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Docker will proceed with your &#8220;docker-compose.yml&#8221; file, pointing to image version 1.27, and spin up the container with the&nbsp;<em>older<\/em>&nbsp;version. Not exactly what we want, right?<\/p>\n\n\n\n<p>Thankfully, WUD has a smart way to handle this. The&nbsp;<a href=\"https:\/\/getwud.github.io\/wud\/#\/configuration\/triggers\/docker-compose\/\" target=\"_blank\" rel=\"noreferrer noopener\">Docker Compose trigger<\/a>&nbsp;can automatically update your &#8220;<em>docker-compose.yml<\/em>&#8221; file on the fly, simply by swapping out the image tag with the latest&nbsp;WUD discovered. That way, when you redeploy, everything\u2019s in sync and your setup ends up looking just like this:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-15\" data-shcb-language-name=\"YAML\" data-shcb-language-slug=\"yaml\"><span><code class=\"hljs language-yaml shcb-code-table\"><span class='shcb-loc'><span><span class=\"hljs-attr\">services:<\/span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attr\">web:<\/span>\n<\/span><\/span><mark class='shcb-loc'><span>    <span class=\"hljs-attr\">image:<\/span> <span class=\"hljs-string\">nginx:1.28<\/span>\n<\/span><\/mark><span class='shcb-loc'><span>    <span class=\"hljs-attr\">ports:<\/span>\n<\/span><\/span><span class='shcb-loc'><span>      <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">\"80:80\"<\/span>\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-15\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">YAML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">yaml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>To make this work, you\u2019ll need to mount the correct &#8220;<em>docker-compose.yml<\/em>&#8221; file into your WUD deployment and use the &#8220;<em>WUD_TRIGGER_DOCKERCOMPOSE_{trigger_name}_FILE<\/em>&#8221; trigger. For example, if you name your trigger \u201c<em>NGINX<\/em>,\u201d here\u2019s what that would look like in practice.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-16\" data-shcb-language-name=\"YAML\" data-shcb-language-slug=\"yaml\"><span><code class=\"hljs language-yaml shcb-code-table\"><span class='shcb-loc'><span><span class=\"hljs-attr\">services:<\/span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attr\">whatsupdocker:<\/span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attr\">image:<\/span> <span class=\"hljs-string\">getwud\/wud<\/span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-string\">...<\/span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attr\">environment:<\/span>\n<\/span><\/span><span class='shcb-loc'><span>      <span class=\"hljs-string\">...<\/span>\n<\/span><\/span><mark class='shcb-loc'><span>      <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">WUD_TRIGGER_DOCKERCOMPOSE_NGINX_FILE=\/wud\/nginx\/docker-compose.yml<\/span>\n<\/span><\/mark><mark class='shcb-loc'><span>      <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">WUD_TRIGGER_DOCKERCOMPOSE_NGINX_PRUNE=true<\/span>\n<\/span><\/mark><span class='shcb-loc'><span>      <span class=\"hljs-string\">...<\/span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attr\">volumes:<\/span>\n<\/span><\/span><span class='shcb-loc'><span>      <span class=\"hljs-string\">...<\/span>\n<\/span><\/span><mark class='shcb-loc'><span>      <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">\/compose\/file\/location\/docker-compose.yml:\/wud\/nginx\/docker-compose.yml<\/span>\n<\/span><\/mark><span class='shcb-loc'><span>      <span class=\"hljs-string\">...<\/span>\n<\/span><\/span><span class='shcb-loc'><span>      \n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-16\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">YAML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">yaml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>As you can see, in the &#8220;<em>volumes<\/em>&#8221; section, we\u2019re mounting our actual &#8220;<em>docker-compose.yml<\/em>&#8221; file into the WUD container at our chosen location. Then, in the &#8220;<em>environment<\/em>&#8221; section, we tell WUD where to look for that file by setting the &#8220;<em>WUD_TRIGGER_DOCKERCOMPOSE_NGINX_FILE<\/em>&#8221; variable to its path inside the container.<\/p>\n\n\n\n<p>I can already hear your next question: What if I have two, three, or ten Docker Compose deployments? No worries\u2014just create a separate trigger for each one, following the pattern below.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-17\" data-shcb-language-name=\"YAML\" data-shcb-language-slug=\"yaml\"><span><code class=\"hljs language-yaml\"><span class=\"hljs-attr\">services:<\/span>\n  <span class=\"hljs-attr\">whatsupdocker:<\/span>\n    <span class=\"hljs-attr\">image:<\/span> <span class=\"hljs-string\">getwud\/wud<\/span>\n    <span class=\"hljs-string\">...<\/span>\n    <span class=\"hljs-attr\">environment:<\/span>\n      <span class=\"hljs-string\">...<\/span>\n      <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">WUD_TRIGGER_DOCKERCOMPOSE_ONE_FILE=\/wud\/one\/docker-compose.yml<\/span>\n      <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">WUD_TRIGGER_DOCKERCOMPOSE_ONE_PRUNE=true<\/span>\n      <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">WUD_TRIGGER_DOCKERCOMPOSE_TWO_FILE=\/wud\/two\/docker-compose.yml<\/span>\n      <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">WUD_TRIGGER_DOCKERCOMPOSE_TWO_PRUNE=true<\/span>\n      <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">WUD_TRIGGER_DOCKERCOMPOSE_THREE_FILE=\/wud\/three\/docker-compose.yml<\/span>\n      <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">WUD_TRIGGER_DOCKERCOMPOSE_THREE_PRUNE=true<\/span>\n      <span class=\"hljs-string\">...<\/span>\n    <span class=\"hljs-attr\">volumes:<\/span>\n      <span class=\"hljs-string\">...<\/span>\n      <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">\/compose\/file\/location\/one\/docker-compose.yml:\/wud\/one\/docker-compose.yml<\/span>\n      <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">\/compose\/file\/location\/two\/docker-compose.yml:\/wud\/two\/docker-compose.yml<\/span>\n      <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">\/compose\/file\/location\/three\/docker-compose.yml:\/wud\/three\/docker-compose.yml<\/span>\n      <span class=\"hljs-string\">...<\/span>\n      <\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-17\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">YAML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">yaml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Of course, none of the above needs to be applied if you&#8217;re using the &#8220;<em>latest<\/em>&#8221; image tag for your Compose deployments. In that case, there&#8217;s no need to modify the &#8220;<em>docker-compose.yml<\/em>&#8221; file since you&#8217;re always pulling the most current version of the image anyway.<\/p>\n\n\n\n<p>However, once again, here\u2019s the moment where things get a little tricky. If you open up the WUD UI and look at the triggers for each container, you might be unpleasantly surprised\u2014they\u2019ve all been automatically applied to <em>every<\/em> container.<\/p>\n\n\n\n<p>Yep, the Nginx trigger we created earlier shows up across the board, which definitely isn\u2019t what we had in mind.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-07.jpg\"><img decoding=\"async\" width=\"1024\" height=\"597\" src=\"https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-07-1024x597.jpg\" alt=\"WUD triggers\" class=\"wp-image-168347\" srcset=\"https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-07-1024x597.jpg 1024w, https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-07-380x222.jpg 380w, https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-07-768x448.jpg 768w, https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-07.jpg 1394w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">WUD triggers<\/figcaption><\/figure>\n\n\n\n<p>This brings us to an important concept in WUD: <strong>by default, all triggers are global<\/strong>. That means any trigger you create gets applied to all containers, unless you explicitly tell WUD otherwise.<\/p>\n\n\n\n<p>Thankfully, there <em>is<\/em> a way to control this, and that\u2019s where WUD watcher&#8217;s <strong>labels<\/strong> come into play. Keep reading, I\u2019ll walk you through the solution in the next section.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"Include_amp;_Exclude_Triggers\">Include &amp; Exclude Triggers<\/h3>\n\n\n\n<p>The solution to the problem above lies in using labels in your containers\u2014something WUD understands and uses to let you fine-tune watchers&#8217; actions more precisely on a per-container basis. Around <a href=\"https:\/\/getwud.github.io\/wud\/#\/configuration\/watchers\/?id=labels\" target=\"_blank\" rel=\"noreferrer noopener\">a dozen labels are available<\/a>, but we&#8217;re mostly interested in &#8220;<em>wud.trigger.include<\/em>&#8221; and &#8220;<em>wud.trigger.exclude<\/em>.&#8221;<\/p>\n\n\n\n<p>When neither of the two above-mentioned is explicitly defined to a container, all triggers apply to every container by default. This is important to understand.<\/p>\n\n\n\n<p>So, what are we trying to do? We want our notification trigger to stay active for all containers, but we only want the Nginx-specific trigger to run for the Nginx container. The best way to handle this is by using the &#8220;<em>wud.trigger.include<\/em>&#8221; label. This tells WUD to apply only the triggers you explicitly list for that particular container, and nothing else.<\/p>\n\n\n\n<p>So, we will open the deployment file (&#8220;<em>docker-compose.yml<\/em>&#8220;) for the Nginx container, add the label we need, and list the triggers as values to this label we want to apply to it.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-18\" data-shcb-language-name=\"YAML\" data-shcb-language-slug=\"yaml\"><span><code class=\"hljs language-yaml shcb-code-table\"><span class='shcb-loc'><span><span class=\"hljs-attr\">services:<\/span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attr\">web:<\/span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attr\">labels:<\/span>\n<\/span><\/span><mark class='shcb-loc'><span>      <span class=\"hljs-attr\">wud.trigger.include:<\/span> <span class=\"hljs-string\">smtp.gmail,dockercompose.nginx<\/span>\n<\/span><\/mark><span class='shcb-loc'><span>    <span class=\"hljs-attr\">image:<\/span> <span class=\"hljs-string\">nginx:stable-alpine3.21-slim<\/span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attr\">container_name:<\/span> <span class=\"hljs-string\">nginx<\/span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attr\">ports:<\/span>\n<\/span><\/span><span class='shcb-loc'><span>      <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">\"80:80\"<\/span>\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-18\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">YAML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">yaml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Of course, you\u2019ll need to do the same for all your other containers. But the difference is that in each one, the line should include only &#8220;<em>wud.trigger.include: smtp.gmail<\/em>&#8221; along with any container-specific triggers you\u2019ve set up in WUD\u2014if there are any.<\/p>\n\n\n\n<p>Remember to restart your containers after making any changes. There\u2019s no need to restart WUD itself\u2014<strong>it automatically picks up changes<\/strong>&nbsp;to the containers it\u2019s watching on the fly.<\/p>\n\n\n\n<p>Now, if we head back to the WUD UI and take a quick look, we\u2019ll see that the Nginx trigger (&#8220;<em>dockercompose.nginx<\/em>&#8220;) is now applied only to that specific container, while our Gmail (&#8220;<em>smtp.gmail<\/em>&#8220;) notification trigger is available to all others.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-08.jpg\"><img decoding=\"async\" width=\"1024\" height=\"597\" src=\"https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-08-1024x597.jpg\" alt=\"Apply WUD triggers only to a specific container.\" class=\"wp-image-168362\" srcset=\"https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-08-1024x597.jpg 1024w, https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-08-380x222.jpg 380w, https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-08-768x448.jpg 768w, https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-08.jpg 1394w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Apply WUD triggers only to a specific container.<\/figcaption><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"Launching_Triggers_from_the_WUD_Dashboard\">Launching Triggers from the WUD Dashboard<\/h3>\n\n\n\n<p>By default, WUD runs quietly in the background unless you tell it otherwise. But in many cases, I\u2019ve found it most convenient to let WUD notify me when there\u2019s a new version of a container, have it set to auto-update, but only apply the update after I give the green light through the UI.<\/p>\n\n\n\n<p>This way, you get the best of both worlds: first, you can check out what\u2019s new in the updated image before applying it, so you don\u2019t get hit with any unexpected changes. And second, you skip the hassle of jumping into the terminal to stop and redeploy the container manually.<\/p>\n\n\n\n<p>To do this, just set the &#8220;<em>WUD_TRIGGER_{trigger_type}_{trigger_name}_AUTO<\/em>&#8221; option to &#8220;<em>false<\/em>&#8221; (it\u2019s &#8220;<em>true<\/em>&#8221; by default). This turns off the automatic execution of the corresponding trigger.<\/p>\n\n\n\n<p>To clarify, let\u2019s use our Nginx deployment as an example. In your WUD &#8220;<em>docker-compose.yml<\/em>&#8221; file, add the following line to disable the automatic trigger execution\u2014so you can run it manually through the WUD web UI whenever you see fit:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-19\" data-shcb-language-name=\"YAML\" data-shcb-language-slug=\"yaml\"><span><code class=\"hljs language-yaml shcb-code-table\"><span class='shcb-loc'><span><span class=\"hljs-attr\">services:<\/span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attr\">whatsupdocker:<\/span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attr\">image:<\/span> <span class=\"hljs-string\">getwud\/wud<\/span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-string\">...<\/span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attr\">environment:<\/span>\n<\/span><\/span><span class='shcb-loc'><span>      <span class=\"hljs-string\">...<\/span>\n<\/span><\/span><span class='shcb-loc'><span>      <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">WUD_TRIGGER_DOCKERCOMPOSE_NGINX_FILE=\/wud\/nginx\/docker-compose.yml<\/span>\n<\/span><\/span><span class='shcb-loc'><span>      <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">WUD_TRIGGER_DOCKERCOMPOSE_NGINX_PRUNE=true<\/span>\n<\/span><\/span><mark class='shcb-loc'><span>      <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">WUD_TRIGGER_DOCKERCOMPOSE_NGINX_AUTO=false<\/span>\n<\/span><\/mark><span class='shcb-loc'><span>      <span class=\"hljs-string\">...<\/span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attr\">volumes:<\/span>\n<\/span><\/span><span class='shcb-loc'><span>      <span class=\"hljs-string\">...<\/span>\n<\/span><\/span><span class='shcb-loc'><span>      <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">\/compose\/file\/location\/docker-compose.yml:\/wud\/nginx\/docker-compose.yml<\/span>\n<\/span><\/span><span class='shcb-loc'><span>      <span class=\"hljs-string\">...<\/span>\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-19\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">YAML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">yaml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>From now on, if updates are available, the WUD dashboard will show them, and the &#8220;<em>RUN<\/em>&#8221; button will be active. Just click it, and WUD will update the Docker image and automatically start the container with the new version.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-09.jpg\"><img decoding=\"async\" width=\"1024\" height=\"597\" src=\"https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-09-1024x597.jpg\" alt=\"Launching triggers from the WUD dashboard.\" class=\"wp-image-168494\" srcset=\"https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-09-1024x597.jpg 1024w, https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-09-380x222.jpg 380w, https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-09-768x448.jpg 768w, https:\/\/linuxiac.com\/wp-content\/uploads\/2025\/05\/wud-howto-09.jpg 1394w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Launching triggers from the WUD dashboard.<\/figcaption><\/figure>\n\n\n\n<p>Then, click the blue &#8220;<em>WATCH NOW<\/em>&#8221; button in the top-right corner to refresh the screen and see the changes take effect.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"Exclude_Container_from_Monitoring\">Exclude Container from Monitoring<\/h3>\n\n\n\n<p>WUD lets you exclude specific containers from monitoring, meaning it will completely ignore them and take no action. It\u2019s super easy to set up\u2014add the label &#8220;<em>wud.watch: false<\/em>&#8221; to the container\u2019s deployment. For example, if you&#8217;re using Nginx, it would look like this:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-20\" data-shcb-language-name=\"YAML\" data-shcb-language-slug=\"yaml\"><span><code class=\"hljs language-yaml shcb-code-table\"><span class='shcb-loc'><span><span class=\"hljs-attr\">services:<\/span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attr\">web:<\/span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attr\">labels:<\/span>\n<\/span><\/span><mark class='shcb-loc'><span>      <span class=\"hljs-attr\">wud.watch:<\/span> <span class=\"hljs-literal\">false<\/span>\n<\/span><\/mark><span class='shcb-loc'><span>    <span class=\"hljs-attr\">image:<\/span> <span class=\"hljs-string\">nginx:1.27<\/span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attr\">container_name:<\/span> <span class=\"hljs-string\">nginx<\/span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attr\">ports:<\/span>\n<\/span><\/span><span class='shcb-loc'><span>      <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">\"80:80\"<\/span>\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-20\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">YAML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">yaml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The opposite setup is also possible \u2014 you can tell WUD not to monitor any containers by default. Just set &#8220;<em>WUD_WATCHER_LOCAL_WATCHBYDEFAULT=false<\/em>&#8221; in the WUD&#8217;s &#8220;<em>docker-compose.yml<\/em>&#8221; file. Then, for each container you <em>do<\/em> want WUD to keep an eye on, add the label &#8220;<em>wud.watch=true<\/em>.&#8221;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"Docker_Images_Tag_Handling_in_WUD\">Docker Images Tag Handling in WUD<\/h3>\n\n\n\n<p>The last \u2014 but definitely one of the most important \u2014 cases I want to cover when setting up WUD is how to handle Docker image tags. Chances are, many of you use deployments that look something like this:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-21\" data-shcb-language-name=\"YAML\" data-shcb-language-slug=\"yaml\"><span><code class=\"hljs language-yaml shcb-code-table\"><span class='shcb-loc'><span><span class=\"hljs-attr\">services:<\/span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attr\">web:<\/span>\n<\/span><\/span><mark class='shcb-loc'><span>    <span class=\"hljs-attr\">image:<\/span> <span class=\"hljs-string\">nginx:latest<\/span>\n<\/span><\/mark><span class='shcb-loc'><span>    <span class=\"hljs-attr\">container_name:<\/span> <span class=\"hljs-string\">nginx<\/span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-string\">...<\/span>\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-21\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">YAML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">yaml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In this case, when you&#8217;re using the &#8220;<em>latest<\/em>&#8221; tag, WUD checks Docker images based on their digest. The problem is that it does this by sending an extensive number of requests to Docker Hub, <a href=\"https:\/\/docs.docker.com\/docker-hub\/usage\/\" target=\"_blank\" rel=\"noreferrer noopener\">which can quickly hit their rate limits<\/a>.<\/p>\n\n\n\n<p>Beyond that, though, it&#8217;s generally a better idea to monitor a specific image version for updates. WUD makes this easier by offering two tags\u2014&#8221;<em>wud.tag.include<\/em>&#8221; and &#8220;<em>wud.tag.exclude<\/em>&#8220;\u2014that you can apply directly to your deployment to control which tags WUD should consider or ignore.<\/p>\n\n\n\n<p>The values these labels take are <strong>regular expressions<\/strong>. The key thing to keep in mind is that different software projects use different versioning schemes for their images. So, you\u2019ll need to tailor each deployment to match the specific versioning style used by that image.<\/p>\n\n\n\n<p>For instance, you might see the classic &#8220;<em>major.minor.patch<\/em>&#8221; (semver) format, like &#8220;<em>1.27.2<\/em>.&#8221; But in other cases, it could be something like &#8220;<em>2025.04.2<\/em>,&#8221; or &#8220;<em>1.27.2-alpine<\/em>&#8220;\u2014there\u2019s a lot of variation out there.<\/p>\n\n\n\n<p>The point is, you\u2019ll need to write a regex that matches the format used in your specific case. I highly recommend testing your expression with an online regex validator, like <a href=\"https:\/\/regex101.com\" target=\"_blank\" rel=\"noreferrer noopener\">Regex101<\/a>, to ensure it works as expected before adding it to your deployments.<\/p>\n\n\n\n<p>Here&#8217;s a real-world example. Let\u2019s say we\u2019re watching Nginx Docker images that follow the &#8220;<em><em>major.minor.patch<\/em><\/em>&#8221; (&#8220;<em>1.27.2<\/em>,&#8221; for example) version pattern. In that case, the regular expression in our Docker deployment would look something like this:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-22\" data-shcb-language-name=\"YAML\" data-shcb-language-slug=\"yaml\"><span><code class=\"hljs language-yaml shcb-code-table\"><span class='shcb-loc'><span><span class=\"hljs-attr\">services:<\/span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attr\">web:<\/span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attr\">image:<\/span> <span class=\"hljs-string\">nginx:latest<\/span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attr\">container_name:<\/span> <span class=\"hljs-string\">nginx<\/span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attr\">labels:<\/span>\n<\/span><\/span><mark class='shcb-loc'><span>      <span class=\"hljs-string\">'wud.tag.include=^\\d+\\.\\d+\\.\\d+$'<\/span>\n<\/span><\/mark><span class='shcb-loc'><span>    <span class=\"hljs-string\">...<\/span>\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-22\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">YAML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">yaml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In simple words, this regex means: only watching tags that look like semantic versions (e.g., &#8220;<em>1.27.2<\/em>&#8220;). However, if the image we want to monitor is something like &#8220;<em>1.27.2-alpine<\/em>,&#8221; then our regex should already look like this:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-23\" data-shcb-language-name=\"YAML\" data-shcb-language-slug=\"yaml\"><span><code class=\"hljs language-yaml shcb-code-table\"><span class='shcb-loc'><span><span class=\"hljs-attr\">services:<\/span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-attr\">web:<\/span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attr\">image:<\/span> <span class=\"hljs-string\">nginx:latest<\/span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attr\">container_name:<\/span> <span class=\"hljs-string\">nginx<\/span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-attr\">labels:<\/span>\n<\/span><\/span><mark class='shcb-loc'><span>      <span class=\"hljs-string\">'wud.tag.include=^\\d+\\.\\d+\\.\\d+-alpine$'<\/span>\n<\/span><\/mark><span class='shcb-loc'><span>    <span class=\"hljs-string\">...<\/span>\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-23\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">YAML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">yaml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>You get the idea\u2014the same goes for the &#8220;<em>wud.tag.exclude<\/em>&#8221; label. It lets you clearly list specific image versions WUD should skip when checking for updates.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"Conclusion\">Conclusion<\/h2>\n\n\n\n<p>Yeah, I know\u2014configuring WUD can seem a little confusing at first. But once you get the hang of how it all works, it starts to make sense, and everything clicks into place pretty quickly. It is a great piece of software, probably the best in its class at the moment.<\/p>\n\n\n\n<p>Of course, WUD offers plenty of other features, such as monitoring remote Docker instances via &#8220;<em>WUD_WATCHER_{watcher_name}_HOST<\/em>&#8221; watcher. Remember that if you decide to use this capability, you should expose the Docker daemon to the outside world only <a href=\"https:\/\/linuxiac.com\/how-to-set-up-wireguard-vpn-with-docker\/\">over a secure VPN connection<\/a>. Otherwise, you could leave your containers wide open to unauthorized access.<\/p>\n\n\n\n<p>WUD\u2019s configuration options give you a ton of flexibility when monitoring updates for your Docker images. In this guide, I\u2019ve walked through the main use cases, but if you\u2019re looking for more in-depth details, check out the official <a href=\"https:\/\/getwud.github.io\/wud\/#\/?id=introduction\" target=\"_blank\" rel=\"noreferrer noopener\">WUD documentation<\/a>.<\/p>\n\n\n\n<p>Thanks for your time and for using this tutorial. As always, your feedback and comments are most welcome. Happy monitoring!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Learn how to automate Docker container updates using What\u2019s Up Docker (WUD) to get notified and keep your images fresh.<\/p>\n","protected":false},"author":10,"featured_media":167503,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9,4417],"tags":[1439,6169,6186],"class_list":["post-167500","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tutorials","category-linux-knowledge","tag-docker","tag-monitoring","tag-wud"],"blocksy_meta":[],"_links":{"self":[{"href":"https:\/\/linuxiac.com\/wp-json\/wp\/v2\/posts\/167500","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/linuxiac.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/linuxiac.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/linuxiac.com\/wp-json\/wp\/v2\/users\/10"}],"replies":[{"embeddable":true,"href":"https:\/\/linuxiac.com\/wp-json\/wp\/v2\/comments?post=167500"}],"version-history":[{"count":0,"href":"https:\/\/linuxiac.com\/wp-json\/wp\/v2\/posts\/167500\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/linuxiac.com\/wp-json\/wp\/v2\/media\/167503"}],"wp:attachment":[{"href":"https:\/\/linuxiac.com\/wp-json\/wp\/v2\/media?parent=167500"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/linuxiac.com\/wp-json\/wp\/v2\/categories?post=167500"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/linuxiac.com\/wp-json\/wp\/v2\/tags?post=167500"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}