<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Renovate on Jug.lol</title><link>https://jug.lol/tags/renovate/</link><description>Guides and reflections from Jug.lol</description><language>en-CA</language><copyright>CC BY-NC-SA 4.0 🇵🇸 🍉 JS-free</copyright><lastBuildDate>Sun, 07 Jun 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://jug.lol/tags/renovate/index.xml" rel="self" type="application/rss+xml"/><item><title>Automating Komodo Installation with Ansible, Forgejo Actions, and Renovate</title><link>https://jug.lol/posts/komodo-ansible-playbook/</link><pubDate>Sun, 07 Jun 2026 00:00:00 +0000</pubDate><guid>https://jug.lol/posts/komodo-ansible-playbook/</guid><description>&lt;p&gt;&lt;img loading="lazy" src="komodo-stack.png"
alt="Komodo stack"/&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve been gearing up for the release of &lt;a href="https://github.com/moghtech/komodo/releases/tag/v2.0.0"target="_blank" rel="noopener noreferrer"&gt;Komodo v2&lt;/a&gt; with a complete overhaul on how I manage the Periphery binary on my homelab nodes. By using Ansible and Forgejo Actions, I can install and update Periphery with a click of a button!&lt;/p&gt;
&lt;p&gt;In this guide, I&amp;rsquo;ll explain what Komodo is, and I&amp;rsquo;ll go through installing Komodo Core, creating an Ansible playbook to install Komodo Periphery across your fleet, running that playbook with Forgejo Actions, and automating updates with Renovate Bot. Getting to this point took some trial and error, but hopefully this post can guide you through the steps to achieve some neat deployment automation.&lt;/p&gt;
&lt;p&gt;Before starting, I recommend having the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Familiarity with Docker and compose files&lt;/li&gt;
&lt;li&gt;Forgejo and Forgejo Actions (Nick Cunningham has a &lt;a href="https://nickcunningh.am/blog/how-to-setup-and-configure-forgejo-with-support-for-forgejo-actions-and-more"target="_blank" rel="noopener noreferrer"&gt;great guide&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Renovate Bot (covered in another one of &lt;a href="https://nickcunningh.am/blog/how-to-automate-version-updates-for-your-self-hosted-docker-containers-with-gitea-renovate-and-komodo"target="_blank" rel="noopener noreferrer"&gt;Nick&amp;rsquo;s guides&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Traefik (Optional)&lt;/li&gt;
&lt;li&gt;OAuth/OIDC (like &lt;a href="https://docs.goauthentik.io/"target="_blank" rel="noopener noreferrer"&gt;Authentik&lt;/a&gt; or &lt;a href="https://kanidm.com/"target="_blank" rel="noopener noreferrer"&gt;Kanidm&lt;/a&gt; - Optional)&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="the-lizard-wizard"&gt;The Lizard Wizard&lt;/h1&gt;
&lt;p&gt;Komodo is a declarative orchestrator for Docker containers in your homelab. First, you define resources like &lt;strong&gt;servers&lt;/strong&gt;, &lt;strong&gt;stacks&lt;/strong&gt;, and &lt;strong&gt;repos&lt;/strong&gt;. Then, you define the relationships between them, like which &lt;strong&gt;stack&lt;/strong&gt; from which &lt;strong&gt;repo&lt;/strong&gt; deploys on which &lt;strong&gt;server&lt;/strong&gt;. This is quite powerful, as Komodo can then be configured to deploy any stacks that have changes committed, like a version update, or deploy newly created stacks all through Git!&lt;/p&gt;
&lt;p&gt;For example, let&amp;rsquo;s say that you&amp;rsquo;ve committed a compose file to your homelab repository for a bookmark manager, &lt;a href="https://linkding.link/"target="_blank" rel="noopener noreferrer"&gt;Linkding&lt;/a&gt;. You would simply create a new &lt;strong&gt;stack&lt;/strong&gt; and define some necessary options like where it is and where it goes. Komodo will then clone the repository to the target machine, run &lt;code&gt;docker compose up -d&lt;/code&gt;, and report container status and logs to the UI. Paired with Renovate Bot, a Pull Request updating the image version can be opened, merged, and deployed automatically!&lt;/p&gt;
&lt;p&gt;Komodo also handles all my variables and secrets, passing them to containers via the &lt;strong&gt;stack&lt;/strong&gt; definition. Simply add the variable in the WebUI, add the variable to the &lt;strong&gt;stack&lt;/strong&gt;, and add the variable to the compose. Komodo will then interpolate the value into the compose file upon deployment.&lt;/p&gt;
&lt;p&gt;This may be a bit confusing, so here&amp;rsquo;s an example of how Komodo sees a &lt;strong&gt;stack&lt;/strong&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#b0c4de;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-toml" data-lang="toml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[[&lt;span style="color:#c1abea"&gt;stack&lt;/span&gt;]]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c1abea"&gt;name&lt;/span&gt; = &lt;span style="color:#63c381"&gt;&amp;#34;linkding&amp;#34;&lt;/span&gt; &lt;span style="color:#8a93a5;font-style:italic"&gt;# The name of the stack in the Komodo UI&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c1abea"&gt;description&lt;/span&gt; = &lt;span style="color:#63c381"&gt;&amp;#34;Simple bookmark manager&amp;#34;&lt;/span&gt; &lt;span style="color:#8a93a5;font-style:italic"&gt;# The description of the stack in the Komodo UI&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c1abea"&gt;tags&lt;/span&gt; = [&lt;span style="color:#63c381"&gt;&amp;#34;internal&amp;#34;&lt;/span&gt;, &lt;span style="color:#63c381"&gt;&amp;#34;tools&amp;#34;&lt;/span&gt;] &lt;span style="color:#8a93a5;font-style:italic"&gt;# Relevant tags for UI organization&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[&lt;span style="color:#c1abea"&gt;stack&lt;/span&gt;.&lt;span style="color:#c1abea"&gt;config&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c1abea"&gt;server&lt;/span&gt; = &lt;span style="color:#63c381"&gt;&amp;#34;node-01&amp;#34;&lt;/span&gt; &lt;span style="color:#8a93a5;font-style:italic"&gt;# Which server to deploy the stack to&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c1abea"&gt;links&lt;/span&gt; = [&lt;span style="color:#63c381"&gt;&amp;#34;https://linkding.domain.tld&amp;#34;&lt;/span&gt;] &lt;span style="color:#8a93a5;font-style:italic"&gt;# A link to the service in the Komodo UI&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c1abea"&gt;linked_repo&lt;/span&gt; = &lt;span style="color:#63c381"&gt;&amp;#34;homelab&amp;#34;&lt;/span&gt; &lt;span style="color:#8a93a5;font-style:italic"&gt;# Which Git repository the compose file resides&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c1abea"&gt;run_directory&lt;/span&gt; = &lt;span style="color:#63c381"&gt;&amp;#34;linkding&amp;#34;&lt;/span&gt; &lt;span style="color:#8a93a5;font-style:italic"&gt;# Which folder the `compose.yaml` file resides&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c1abea"&gt;environment&lt;/span&gt; = &lt;span style="color:#63c381"&gt;&amp;#34;&amp;#34;&amp;#34; # Komodo will replace ${SOME_SECRET} in the compose file
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#63c381"&gt;SOME_SECRET=[[SOME_SECRET]] # with the value defined in the WebUI
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#63c381"&gt;&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Komodo&amp;rsquo;s configuration can live within a Git repository as well. This works best especially if you have a lot of stacks to create, which is done faster with copy-and-paste compared to ClickOps. You can even define them in the WebUI and Komodo will commit them directly to the repository on your behalf! I highly recommend storing your Komodo configuration in Git, as you essentially have a versioned backup of changes you make to Komodo.&lt;/p&gt;
&lt;p&gt;Komodo can do a whole lot more than just manage compose files. To name a few, it can build and push images to registries, alert you on high resource usage, display logs, exec into containers. To learn more about what it can offer, give their &lt;a href="https://komo.do/docs/intro"target="_blank" rel="noopener noreferrer"&gt;docs&lt;/a&gt; a read!&lt;/p&gt;
&lt;h2 id="the-anatomy-of-komodo"&gt;The anatomy of Komodo&lt;/h2&gt;
&lt;p&gt;Komodo is built with two major components, &lt;strong&gt;Core&lt;/strong&gt; and &lt;strong&gt;Periphery&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Core&lt;/strong&gt; is the WebUI you use to interact with your homelab. When I say Komodo, I&amp;rsquo;m usually talking about Komodo &lt;strong&gt;Core&lt;/strong&gt;. You only require one instance of &lt;strong&gt;Core&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Periphery&lt;/strong&gt; is the agent that reports to &lt;strong&gt;Core&lt;/strong&gt; and it must be installed on each node you want to control through &lt;strong&gt;Core&lt;/strong&gt;. There are a couple ways to install &lt;strong&gt;Periphery&lt;/strong&gt;, either via container or systemd. I highly recommend going the systemd route, as it will allow Komodo to update itself without hitches.&lt;/p&gt;
&lt;p&gt;Initially, communication between the two components was only inbound to &lt;strong&gt;Periphery&lt;/strong&gt;. However, with v2 &lt;strong&gt;Periphery&lt;/strong&gt; can send outbound communication to &lt;strong&gt;Core&lt;/strong&gt;. Having this flexibility can simplify your deployment depending on your network topology. This guide uses the new outbound method. This communication is secured via automatically generated public/private key pairs.&lt;/p&gt;
&lt;h2 id="installing-komodo-core"&gt;Installing Komodo Core&lt;/h2&gt;
&lt;p&gt;All right, this is gonna be a pretty hefty compose file, but most of it is just environment variables. You can view all the variables and their definitions in the docs &lt;a href="https://komo.do/docs/setup/advanced"target="_blank" rel="noopener noreferrer"&gt;here&lt;/a&gt;, but I left some comments to describe some of the more obscure ones. The &lt;code&gt;.env&lt;/code&gt; file for secrets comes right after, which you&amp;rsquo;ll have to fill.&lt;/p&gt;
&lt;p&gt;I use Traefik as my reverse proxy, so delete those labels if you do not. I have also externally created a Docker network, &lt;code&gt;frontend&lt;/code&gt;, which connects Traefik to the service. Change that according to your setup, or create a network using &lt;code&gt;docker network create frontend&lt;/code&gt;. I use Kanidm as my OIDC provider, delete that as well if you do not.&lt;/p&gt;
&lt;p&gt;One last note, the compose file below will create two services, &lt;strong&gt;Core&lt;/strong&gt; and &lt;strong&gt;MongoDB&lt;/strong&gt;. &lt;strong&gt;Core&lt;/strong&gt; is connected to both networks, &lt;code&gt;frontend&lt;/code&gt; and &lt;code&gt;komodo&lt;/code&gt;, while MongoDB is only connected to the &lt;code&gt;komodo&lt;/code&gt; network. Because &lt;strong&gt;MongoDB&lt;/strong&gt; doesn&amp;rsquo;t have to interact with Traefik, we can place it on its own separate network. This is simply a good security practice.&lt;/p&gt;
&lt;h4 id="composeyaml"&gt;compose.yaml&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#b0c4de;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#76a9f9"&gt;---&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;services&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;core&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;image&lt;/span&gt;: &lt;span style="color:#98c379"&gt;ghcr.io/moghtech/komodo-core:2.2.0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;container_name&lt;/span&gt;: &lt;span style="color:#98c379"&gt;komodo&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;restart&lt;/span&gt;: &lt;span style="color:#98c379"&gt;always&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;init&lt;/span&gt;: &lt;span style="color:#b756ff;font-weight:bold"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;depends_on&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#98c379"&gt;komodo-db&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;networks&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;frontend&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;komodo&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;volumes&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#98c379"&gt;path/to/komodo/core/config/keys:/config/keys&lt;/span&gt; &lt;span style="color:#8a93a5;font-style:italic"&gt;# CHANGE ME&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;environment&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#98c379"&gt;KOMODO_DATABASE_ADDRESS=komodo-db:27017&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#98c379"&gt;KOMODO_DATABASE_USERNAME=komodo&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#98c379"&gt;KOMODO_DATABASE_PASSWORD=${KOMODO_DB_PASSWORD}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#98c379"&gt;KOMODO_HOST=https://komodo.domain.tld&lt;/span&gt; &lt;span style="color:#8a93a5;font-style:italic"&gt;# CHANGE ME&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#98c379"&gt;KOMODO_TITLE=Komodo&lt;/span&gt; &lt;span style="color:#8a93a5;font-style:italic"&gt;# Displayed in the browser tab.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#98c379"&gt;KOMODO_WEBHOOK_SECRET=${KOMODO_WEBHOOK_SECRET}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#98c379"&gt;KOMODO_JWT_SECRET=${KOMODO_JWT_SECRET}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#98c379"&gt;KOMODO_DISABLE_CONFIRM_DIALOG=true&lt;/span&gt; &lt;span style="color:#8a93a5;font-style:italic"&gt;# Replaces the confirm dialog with a double-click&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#98c379"&gt;KOMODO_DISABLE_NON_ADMIN_CREATE=true&lt;/span&gt; &lt;span style="color:#8a93a5;font-style:italic"&gt;# Only admins can create resources&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#98c379"&gt;KOMODO_DISABLE_USER_REGISTRATION=true&lt;/span&gt; &lt;span style="color:#8a93a5;font-style:italic"&gt;# Only the first user to log in will be registered as a user&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#8a93a5;font-style:italic"&gt;# Optional OIDC&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#98c379"&gt;KOMODO_LOCAL_AUTH=false&lt;/span&gt; &lt;span style="color:#8a93a5;font-style:italic"&gt;# Disables user login with a username &amp;amp; password&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#98c379"&gt;KOMODO_OIDC_ENABLED=true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#98c379"&gt;KOMODO_OIDC_AUTO_REDIRECT=true&lt;/span&gt; &lt;span style="color:#8a93a5;font-style:italic"&gt;# Automatically redirects login page to the OIDC provider&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#98c379"&gt;KOMODO_OIDC_PROVIDER=https://auth.domain.tld/application/o/komodo/&lt;/span&gt; &lt;span style="color:#8a93a5;font-style:italic"&gt;# CHANGE ME&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#98c379"&gt;KOMODO_OIDC_CLIENT_ID=XXX&lt;/span&gt; &lt;span style="color:#8a93a5;font-style:italic"&gt;# CHANGE ME&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#98c379"&gt;KOMODO_OIDC_CLIENT_SECRET=${KOMODO_OIDC_CLIENT_SECRET}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#98c379"&gt;KOMODO_OIDC_USE_FULL_EMAIL=false&lt;/span&gt; &lt;span style="color:#8a93a5;font-style:italic"&gt;# Makes usernames more concise&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;logging&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;driver&lt;/span&gt;: &lt;span style="color:#98c379"&gt;local&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;labels&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#98c379"&gt;komodo.skip&lt;/span&gt; &lt;span style="color:#8a93a5;font-style:italic"&gt;# Prevents Komodo from stopping itself with StopAllContainers&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#98c379"&gt;traefik.enable=true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#98c379"&gt;traefik.http.routers.komodo.rule=Host(`komodo.domain.tld`)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#98c379"&gt;traefik.http.services.komodo.loadbalancer.server.port=9120&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#98c379"&gt;traefik.docker.network=frontend&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;komodo-db&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;image&lt;/span&gt;: &lt;span style="color:#98c379"&gt;mongo:6&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;container_name&lt;/span&gt;: &lt;span style="color:#98c379"&gt;komobo-db&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;restart&lt;/span&gt;: &lt;span style="color:#98c379"&gt;always&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;command&lt;/span&gt;: --&lt;span style="color:#98c379"&gt;quiet --wiredTigerCacheSizeGB 0.25&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;networks&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#98c379"&gt;komodo&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;volumes&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#98c379"&gt;path/to/komodo/data/db:/data/db&lt;/span&gt; &lt;span style="color:#8a93a5;font-style:italic"&gt;# CHANGE ME&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#98c379"&gt;path/to/komodo/data/configdb:/data/configdb&lt;/span&gt; &lt;span style="color:#8a93a5;font-style:italic"&gt;# CHANGE ME&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;environment&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#98c379"&gt;MONGO_INITDB_ROOT_USERNAME=komodo&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#98c379"&gt;MONGO_INITDB_ROOT_PASSWORD=${KOMODO_DB_PASSWORD}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;logging&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;driver&lt;/span&gt;: &lt;span style="color:#98c379"&gt;local&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;labels&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#98c379"&gt;komodo.skip&lt;/span&gt; &lt;span style="color:#8a93a5;font-style:italic"&gt;# Prevents Komodo from stopping itself with StopAllContainers&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;networks&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;frontend&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;external&lt;/span&gt;: &lt;span style="color:#b756ff;font-weight:bold"&gt;true&lt;/span&gt; &lt;span style="color:#8a93a5;font-style:italic"&gt;# Only if you created the network via `docker network create`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;komodo&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="env"&gt;.env&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#b0c4de;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#dcaeea"&gt;KOMODO_DB_PASSWORD&lt;/span&gt;&lt;span style="color:#c7bf54"&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#dcaeea"&gt;KOMODO_WEBHOOK_SECRET&lt;/span&gt;&lt;span style="color:#c7bf54"&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#dcaeea"&gt;KOMODO_JWT_SECRET&lt;/span&gt;&lt;span style="color:#c7bf54"&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#dcaeea"&gt;KOMODO_OIDC_CLIENT_SECRET&lt;/span&gt;&lt;span style="color:#c7bf54"&gt;=&lt;/span&gt; &lt;span style="color:#8a93a5;font-style:italic"&gt;# Optional if you&amp;#39;re not using OIDC&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="admonition tip"&gt;
&lt;div class="admonition-header"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"&gt;&lt;path d="M272 384c9.6-31.9 29.5-59.1 49.2-86.2c0 0 0 0 0 0c5.2-7.1 10.4-14.2 15.4-21.4c19.8-28.5 31.4-63 31.4-100.3C368 78.8 289.2 0 192 0S16 78.8 16 176c0 37.3 11.6 71.9 31.4 100.3c5 7.2 10.2 14.3 15.4 21.4c0 0 0 0 0 0c19.8 27.1 39.7 54.4 49.2 86.2l160 0zM192 512c44.2 0 80-35.8 80-80l0-16-160 0 0 16c0 44.2 35.8 80 80 80zM112 176c0 8.8-7.2 16-16 16s-16-7.2-16-16c0-61.9 50.1-112 112-112c8.8 0 16 7.2 16 16s-7.2 16-16 16c-44.2 0-80 35.8-80 80z"/&gt;&lt;/svg&gt;
&lt;span&gt;Tip&lt;/span&gt;
&lt;/div&gt;
&lt;div class="admonition-content"&gt;
&lt;p&gt;You can easily generate an alphanumeric secret in Linux with &lt;code&gt;openssl rand -hex 40&lt;/code&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Once that&amp;rsquo;s done, you can save it on a machine and run &lt;code&gt;docker compose up -d&lt;/code&gt;. Savour it, because this might be the last time you have to run that command!&lt;/p&gt;
&lt;h2 id="setting-up-ansible"&gt;Setting up Ansible&lt;/h2&gt;
&lt;p&gt;Ansible lets you automate virtually any task (yeah, I took that from &lt;a href="https://docs.ansible.com/ansible/latest/getting_started/introduction.html"target="_blank" rel="noopener noreferrer"&gt;their docs&lt;/a&gt;) across as many hosts as you want over SSH. I initially wrote a playbook to install and update Komodo, but have since switched to &lt;a href="https://github.com/bpbradley/ansible-role-komodo"target="_blank" rel="noopener noreferrer"&gt;bpbradley&amp;rsquo;s Komodo role&lt;/a&gt;. This role is a marvel, and huge props to bpbradley for their efforts. I&amp;rsquo;ll walk you through how I set it up for my Periphery installation and upgrades.&lt;/p&gt;
&lt;p&gt;First thing&amp;rsquo;s first, make the following directory structure in your homelab Git repository. The inventory file contains a list of hosts we want to target with a playbook. Under the &lt;code&gt;[komodo]&lt;/code&gt; group, list the IP address or hostname of the nodes you want to install Periphery on. Then in &lt;code&gt;[komodo:vars]&lt;/code&gt;, define the user that Ansible will SSH as.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s also the &lt;code&gt;ansible_python_interpreter&lt;/code&gt; variable that silences the &amp;ldquo;automatically discovered Python&amp;rdquo; warning. Alternatively, you can replace &lt;code&gt;auto_silent&lt;/code&gt; with the Python interpreter&amp;rsquo;s path (e.g., &lt;code&gt;/usr/bin/python3.12&lt;/code&gt;), but I trust Ansible to find it.&lt;/p&gt;
&lt;h4 id="directory-structure"&gt;Directory structure&lt;/h4&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;.
└── ansible/
├── inventory/
│ └── inventory
└── playbooks/
└── install_komodo.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="inventory"&gt;inventory&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#b0c4de;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;[komodo]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#b3d23c"&gt;10.0.0.2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#b3d23c"&gt;example-node.lan&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#b3d23c"&gt;10.0.0.3 ansible_user&lt;/span&gt;&lt;span style="color:#c7bf54"&gt;=&lt;/span&gt;&lt;span style="color:#98c379"&gt;some_other_user_if_required&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;[komodo:vars]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#b3d23c"&gt;ansible_user&lt;/span&gt;&lt;span style="color:#c7bf54"&gt;=&lt;/span&gt;&lt;span style="color:#98c379"&gt;ansible&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#b3d23c"&gt;ansible_python_interpreter&lt;/span&gt;&lt;span style="color:#c7bf54"&gt;=&lt;/span&gt;&lt;span style="color:#98c379"&gt;auto_silent&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="creating-the-user"&gt;Creating the user&lt;/h3&gt;
&lt;p&gt;For this, I&amp;rsquo;ve opted to create a new user, ansible, on each machine instead of using my regular user. It&amp;rsquo;s good practice to separate users by service, and it&amp;rsquo;s easy to disable those that you no longer need. You can either create the user manually, or use another Ansible playbook to create the user across the fleet. Then, create an SSH keypair for the ansible user and add the public key to its &lt;code&gt;authorized_keys&lt;/code&gt; file in &lt;code&gt;/home/ansible/.ssh/authorized_keys&lt;/code&gt;. Copy the contents of the private key to Forgejo secrets as &lt;code&gt;ANSIBLE_SSH_PRIVATE_KEY&lt;/code&gt; in Settings &amp;gt; Actions &amp;gt; Secrets &amp;gt; Add secret.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#b0c4de;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo adduser ansible sudo
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ssh-keygen -t ed25519 -C ansible -f ~/.ssh/ansible
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo mkdir /home/ansible/.ssh
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ef8383"&gt;echo&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;ssh-ed25519 AAAA... ansible&amp;#39;&lt;/span&gt; | sudo tee /home/ansible/.ssh/authorized_keys
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#8a93a5;font-style:italic"&gt;# Set correct permissions&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo chown -R ansible:ansible /home/ansible/.ssh
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo chmod &lt;span style="color:#d19a66"&gt;700&lt;/span&gt; /home/ansible/.ssh
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo chmod &lt;span style="color:#d19a66"&gt;600&lt;/span&gt; /home/ansible/.ssh/authorized_keys
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="admonition important"&gt;
&lt;div class="admonition-header"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"&gt;&lt;path d="M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zm0-384c13.3 0 24 10.7 24 24l0 112c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-112c0-13.3 10.7-24 24-24zM224 352a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z"/&gt;&lt;/svg&gt;
&lt;span&gt;Important&lt;/span&gt;
&lt;/div&gt;
&lt;div class="admonition-content"&gt;
&lt;p&gt;The ansible user must be able to escalate to root privileges. The above command adds the new ansible user to the sudo group. I highly recommend forcing password authentication for privilege escalation. Test the user out and edit sudoers if necessary.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="admonition caution"&gt;
&lt;div class="admonition-header"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"&gt;&lt;path d="M256 32c14.2 0 27.3 7.5 34.5 19.8l216 368c7.3 12.4 7.3 27.7 .2 40.1S486.3 480 472 480L40 480c-14.3 0-27.6-7.7-34.7-20.1s-7-27.8 .2-40.1l216-368C228.7 39.5 241.8 32 256 32zm0 128c-13.3 0-24 10.7-24 24l0 112c0 13.3 10.7 24 24 24s24-10.7 24-24l0-112c0-13.3-10.7-24-24-24zm32 224a32 32 0 1 0 -64 0 32 32 0 1 0 64 0z"/&gt;&lt;/svg&gt;
&lt;span&gt;Caution&lt;/span&gt;
&lt;/div&gt;
&lt;div class="admonition-content"&gt;
&lt;p&gt;It is best practice to use different SSH keys for each host. By using one key for all hosts, an adversary can login to all of them from only one leaked key. This guide uses one universal key for the ansible user, so make an informed decision on the security of your infrastructure.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Once you&amp;rsquo;ve created an ansible user, we have to add its password to the Ansible Vault, an encryption/decryption tool for secrets in Ansible. You&amp;rsquo;ll need Ansible installed to use it, or you can use the Ansible Docker container. First, generate a password for the Vault. After running the commands below, save the output which we&amp;rsquo;ll add to the &lt;code&gt;install_komodo.yaml&lt;/code&gt; playbook in a bit, and create another secret in Forgejo called &lt;code&gt;ANSIBLE_VAULT_PASSWORD&lt;/code&gt; with the same output.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#b0c4de;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;docker run -it --rm alpine/ansible /bin/sh &lt;span style="color:#8a93a5;font-style:italic"&gt;# to enter an Ansible container if you don&amp;#39;t have Ansible installed locally&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;vi password_file &lt;span style="color:#8a93a5;font-style:italic"&gt;# press i to enter insert mode, paste your password, then enter :wq to save and exit&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ansible-vault encrypt_string --vault-password-file password_file &lt;span style="color:#98c379"&gt;&amp;#39;change_me_to_ansible_user_password&amp;#39;&lt;/span&gt; --name &lt;span style="color:#98c379"&gt;&amp;#39;ansible_become_pass&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="writing-the-playbook"&gt;Writing the playbook&lt;/h3&gt;
&lt;p&gt;Now, onto the good stuff. The following &lt;code&gt;install_komodo.yaml&lt;/code&gt; playbook, as mentioned previously, uses &lt;a href="https://github.com/bpbradley/ansible-role-komodo"target="_blank" rel="noopener noreferrer"&gt;bpbradley&amp;rsquo;s Komodo role&lt;/a&gt;. We&amp;rsquo;re targetting all hosts in the &lt;code&gt;komodo&lt;/code&gt; group, and escalating to root privileges (&lt;code&gt;become: true&lt;/code&gt;). This means that the ansible user you created must be able to use &lt;code&gt;sudo&lt;/code&gt;. The user&amp;rsquo;s password is stored in Ansible Vault and passed to the playbook by the &lt;code&gt;ansible_become_pass&lt;/code&gt; variable.&lt;/p&gt;
&lt;div class="admonition warning"&gt;
&lt;div class="admonition-header"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"&gt;&lt;path d="M256 32c14.2 0 27.3 7.5 34.5 19.8l216 368c7.3 12.4 7.3 27.7 .2 40.1S486.3 480 472 480L40 480c-14.3 0-27.6-7.7-34.7-20.1s-7-27.8 .2-40.1l216-368C228.7 39.5 241.8 32 256 32zm0 128c-13.3 0-24 10.7-24 24l0 112c0 13.3 10.7 24 24 24s24-10.7 24-24l0-112c0-13.3-10.7-24-24-24zm32 224a32 32 0 1 0 -64 0 32 32 0 1 0 64 0z"/&gt;&lt;/svg&gt;
&lt;span&gt;Warning&lt;/span&gt;
&lt;/div&gt;
&lt;div class="admonition-content"&gt;
&lt;p&gt;Ensure you have any existing Komodo Periphery agents removed&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Moving onto the role configuration, we&amp;rsquo;re installing Periphery under its own user, komodo (visit &lt;a href="https://github.com/bpbradley/ansible-role-komodo?tab=readme-ov-file#systemd-user-vs-system-units"target="_blank" rel="noopener noreferrer"&gt;user manager vs system manager&lt;/a&gt; for a comparison). The &lt;code&gt;komodo_version&lt;/code&gt; variable will be automatically updated by Renovate Bot after we configure a custom manager (covered at the end).&lt;/p&gt;
&lt;h4 id="install_komodoyaml"&gt;install_komodo.yaml&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#b0c4de;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#76a9f9"&gt;---&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;- &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;: &lt;span style="color:#98c379"&gt;Manage Komodo Periphery Service&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;hosts&lt;/span&gt;: &lt;span style="color:#98c379"&gt;komodo&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;become&lt;/span&gt;: &lt;span style="color:#b756ff;font-weight:bold"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;vars&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;ansible_become_pass&lt;/span&gt;: !&lt;span style="color:#98c379"&gt;vault |&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#98c379"&gt;$ANSIBLE_VAULT;1.1;AES256&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#d19a66"&gt;35643532663130386236386563396534323433306238356339386565306661316239636535613234&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#98c379"&gt;3265316162356338623963636437386236333561356539340a633162303266313064663566383163&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#d19a66"&gt;63383138636631343736353635646364326334623131323961323537656561313831326134353333&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#98c379"&gt;6365383934616230340a363566366230386365396364333064326132616232613338376337386333&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#d19a66"&gt;66303265653364333635636335646364343232363132663539636437626361613530&lt;/span&gt; &lt;span style="color:#8a93a5;font-style:italic"&gt;# CHANGE ME&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;roles&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#e06c75"&gt;role&lt;/span&gt;: &lt;span style="color:#98c379"&gt;bpbradley.komodo&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;komodo_action&lt;/span&gt;: &lt;span style="color:#63c381"&gt;&amp;#34;install&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;komodo_service_scope&lt;/span&gt;: &lt;span style="color:#63c381"&gt;&amp;#34;user&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;komodo_version&lt;/span&gt;: &lt;span style="color:#63c381"&gt;&amp;#34;v2.2.0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;komodo_core_address&lt;/span&gt;: &lt;span style="color:#63c381"&gt;&amp;#34;wss://komodo.domain.tld&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;komodo_connect_as&lt;/span&gt;: &lt;span style="color:#63c381"&gt;&amp;#34;{{ ansible_hostname }}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The above playbook will create a new user, komodo, and add it to the docker group. Then, it will create the Periphery configuration file in &lt;code&gt;/home/komodo/.config/komodo&lt;/code&gt;. Then, it will create a unit file in &lt;code&gt;/home/komodo/.config/systemd&lt;/code&gt; to start the non-root Periphery service and enable linger so the Periphery process stays alive. By default, the komodo user cannot be logged into which is more secure but can make troubleshooting a little tricky. Here are a couple commands to manage the Periphery service and view its logs.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#b0c4de;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo -u komodo &lt;span style="color:#dcaeea"&gt;XDG_RUNTIME_DIR&lt;/span&gt;&lt;span style="color:#c7bf54"&gt;=&lt;/span&gt;&lt;span style="color:#63c381"&gt;&amp;#34;/run/user/&lt;/span&gt;&lt;span style="color:#c678dd"&gt;$(&lt;/span&gt;id -u komodo&lt;span style="color:#c678dd"&gt;)&lt;/span&gt;&lt;span style="color:#63c381"&gt;&amp;#34;&lt;/span&gt; systemctl status --user periphery
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo -u komodo journalctl --user -u periphery
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="creating-the-workflow"&gt;Creating the workflow&lt;/h2&gt;
&lt;p&gt;With that out of the way, we can set up a workflow with Forgejo Actions that will run our playbook. Forgejo&amp;rsquo;s &lt;a href="https://forgejo.org/docs/next/user/actions/reference/"target="_blank" rel="noopener noreferrer"&gt;documentation on Actions&lt;/a&gt; is a great resource that I recommend reviewing. Otherwise, create the following directory structure in your homelab Git repository.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;.
└── .forgejo/
└── workflows/
└── run_komodo_playbook.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Let&amp;rsquo;s break down the workflow file below. First, we define when we want the workflow to run, both automatically on any changes to the &lt;code&gt;install_komodo.yaml&lt;/code&gt; playbook, and manually with &lt;code&gt;workflow_dispatch&lt;/code&gt;. When running manually via the Forgejo UI, we can limit the targets to a single host by typing in its inventory name (e.g., &lt;code&gt;node-02.lan&lt;/code&gt;, &lt;code&gt;10.0.0.2&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Then, we define on which runner the workflow will use, and which container it will execute the tasks on. The Ansible container cannot clone our homelab Git repository without NodeJS, so there&amp;rsquo;s a task that installs it. Then, it sets up the authentication credentials by copying &lt;code&gt;ANSIBLE_SSH_PRIVATE_KEY&lt;/code&gt; and &lt;code&gt;ANSIBLE_VAULT_PASSWORD&lt;/code&gt; from Forgejo&amp;rsquo;s secrets into the Ansible container. After that, it installs the Komodo Ansible role and moves on to executing the playbook.&lt;/p&gt;
&lt;p&gt;The Ansible playbook task enters the ansible directory from our cloned homelab Git repository, then executes the playbook with the following arguments.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--private-key&lt;/code&gt; defines the path to our ansible user&amp;rsquo;s SSH key&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-i&lt;/code&gt; defines the path to the inventory file&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--limit&lt;/code&gt; uses any target limit defined in a manual execution&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--ssh-extra-args&lt;/code&gt; disables the known_hosts SSH requirement&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--vault-password-file&lt;/code&gt; defines the path to our Ansible Vault password&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#b0c4de;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;name&lt;/span&gt;: &lt;span style="color:#98c379"&gt;Run the Komodo playbook&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;on&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;push&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;branches&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#63c381"&gt;&amp;#34;main&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;paths&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#63c381"&gt;&amp;#34;**/install_komodo.yaml&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;workflow_dispatch&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;inputs&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;ansible_host_target_limit&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;description&lt;/span&gt;: &lt;span style="color:#63c381"&gt;&amp;#34;Limit the targets&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;type&lt;/span&gt;: &lt;span style="color:#98c379"&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;default&lt;/span&gt;: &lt;span style="color:#63c381"&gt;&amp;#34;komodo&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;jobs&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;run-playbooks&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;runs-on&lt;/span&gt;: &lt;span style="color:#98c379"&gt;your_runner_label&lt;/span&gt; &lt;span style="color:#8a93a5;font-style:italic"&gt;# CHANGE ME&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;container&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;image&lt;/span&gt;: &lt;span style="color:#98c379"&gt;alpine/ansible:latest&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;steps&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;: &lt;span style="color:#98c379"&gt;Install Node&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;run&lt;/span&gt;: &lt;span style="color:#98c379"&gt;apk add --update nodejs&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;: &lt;span style="color:#98c379"&gt;Checkout code&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;uses&lt;/span&gt;: &lt;span style="color:#98c379"&gt;https://code.forgejo.org/actions/checkout@v6&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;: &lt;span style="color:#98c379"&gt;Set up credentials&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;run&lt;/span&gt;: |&lt;span style="color:#7e97c3"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7e97c3"&gt; mkdir -p $HOME/.ssh/
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7e97c3"&gt; echo &amp;#34;${{secrets.ANSIBLE_SSH_PRIVATE_KEY}}&amp;#34; &amp;gt; $HOME/.ssh/ansible_key
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7e97c3"&gt; chmod 700 $HOME/.ssh/ansible_key
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7e97c3"&gt; echo &amp;#34;${{secrets.ANSIBLE_VAULT_PASSWORD}}&amp;#34; &amp;gt; $HOME/.vault_pass.txt&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;: &lt;span style="color:#98c379"&gt;Install Ansible role&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;run&lt;/span&gt;: &lt;span style="color:#98c379"&gt;ansible-galaxy role install bpbradley.komodo&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#e06c75"&gt;name&lt;/span&gt;: &lt;span style="color:#98c379"&gt;Run Ansible playbook&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;run&lt;/span&gt;: |&lt;span style="color:#7e97c3"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7e97c3"&gt; cd ${{ forgejo.workspace }}/ansible
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7e97c3"&gt; ansible-playbook --private-key $HOME/.ssh/ansible_key \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7e97c3"&gt; -i inventory playbooks/install_komodo.yaml \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7e97c3"&gt; --limit=${{ inputs.ansible_host_target_limit }} \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7e97c3"&gt; --ssh-extra-args=&amp;#34;-o StrictHostKeyChecking=no&amp;#34; \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7e97c3"&gt; --vault-password-file $HOME/.vault_pass.txt&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;After committing this to your homelab Git repository, it&amp;rsquo;s ready to execute!&lt;/p&gt;
&lt;h2 id="updating-with-renovate-bot"&gt;Updating with Renovate Bot&lt;/h2&gt;
&lt;p&gt;Although this guide won&amp;rsquo;t cover setting up Renovate Bot in Forgejo, you can follow &lt;a href="https://nickcunningh.am/blog/how-to-automate-version-updates-for-your-self-hosted-docker-containers-with-gitea-renovate-and-komodo"target="_blank" rel="noopener noreferrer"&gt;Nick Cunningham&amp;rsquo;s guide&lt;/a&gt; as a reference.&lt;/p&gt;
&lt;p&gt;In your &lt;code&gt;.renovaterc.json&lt;/code&gt; (or whatever you named your Renovate configuration), add the following manager. To group Periphery and Core upgrades into one Pull Request, you can also add the package rule.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#b0c4de;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#63c381"&gt;&amp;#34;customManagers&amp;#34;&lt;/span&gt;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;&amp;#34;customType&amp;#34;&lt;/span&gt;: &lt;span style="color:#63c381"&gt;&amp;#34;regex&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;&amp;#34;managerFilePatterns&amp;#34;&lt;/span&gt;: [&lt;span style="color:#63c381"&gt;&amp;#34;ansible/playbooks/install_komodo.yaml&amp;#34;&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;&amp;#34;matchStrings&amp;#34;&lt;/span&gt;: [&lt;span style="color:#63c381"&gt;&amp;#34;komodo_version: [\&amp;#34;&amp;#39;]v?(?&amp;lt;currentValue&amp;gt;.+?)[\&amp;#34;&amp;#39;]&amp;#34;&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;&amp;#34;datasourceTemplate&amp;#34;&lt;/span&gt;: &lt;span style="color:#63c381"&gt;&amp;#34;docker&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;&amp;#34;depNameTemplate&amp;#34;&lt;/span&gt;: &lt;span style="color:#63c381"&gt;&amp;#34;ghcr.io/moghtech/komodo-periphery&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#63c381"&gt;&amp;#34;packageRules&amp;#34;&lt;/span&gt;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;&amp;#34;matchPackageNames&amp;#34;&lt;/span&gt;: [&lt;span style="color:#63c381"&gt;&amp;#34;ghcr.io/moghtech/komodo*&amp;#34;&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;&amp;#34;groupName&amp;#34;&lt;/span&gt;: &lt;span style="color:#63c381"&gt;&amp;#34;moghtech/komodo&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;With everything properly configured, Renovate will announce new releases of Komodo with a Pull Request in your forge. All you have to do is merge the branch, which will kick off the Ansible playbook to upgrade your fleet to the newest Periphery binary as well as upgrade your Core version.&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="renovate-pr.png"
alt="Pull Request by Renovate"/&gt;&lt;/p&gt;
&lt;h2 id="afterword"&gt;Afterword&lt;/h2&gt;
&lt;p&gt;Congratulations on making it to the end! If you haven&amp;rsquo;t used Ansible or Forgejo Actions much before, I hope you learned a bit about these tools and how to better incorporate them into your homelab. It&amp;rsquo;s a great way to run playbooks across any number of hosts, even those in the cloud.&lt;/p&gt;</description></item></channel></rss>