<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Posts on JEROENDEV</title>
        <link>https://jeroendev.one/posts/</link>
        <description>Recent content in Posts on JEROENDEV</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>en</language>
        <copyright>&lt;a href=&#34;https://creativecommons.org/licenses/by-nc/4.0/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;CC BY-NC 4.0&lt;/a&gt;</copyright>
        <lastBuildDate>Fri, 04 Oct 2024 00:00:00 +0000</lastBuildDate>
        <atom:link href="https://jeroendev.one/posts/index.xml" rel="self" type="application/rss+xml" />
        
        <item>
            <title>Apache: Disable HTTP/2 per domain base</title>
            <link>https://jeroendev.one/posts/apache-disable-http/2-per-domain-base/</link>
            <pubDate>Fri, 04 Oct 2024 00:00:00 +0000</pubDate>
            
            <guid>https://jeroendev.one/posts/apache-disable-http/2-per-domain-base/</guid>
            <description>Disabling through .htaccess Append the following to your HTTP conf for the specific Virtualhost you want to disable HTTP/2 for:
Protocols http/1.1 </description>
            <content type="html"><![CDATA[<h1 id="disabling-through-htaccess">Disabling through .htaccess</h1>
<p>Append the following to your HTTP conf for the specific Virtualhost you want to disable HTTP/2 for:</p>
<pre tabindex="0"><code>Protocols http/1.1
</code></pre>]]></content>
        </item>
        
        <item>
            <title>Docker Compose: Auto update containers using only Bash</title>
            <link>https://jeroendev.one/posts/docker-compose-auto-update-containers-using-only-bash/</link>
            <pubDate>Sat, 06 Apr 2024 00:00:00 +0000</pubDate>
            
            <guid>https://jeroendev.one/posts/docker-compose-auto-update-containers-using-only-bash/</guid>
            <description>Setting up the structure If you&amp;rsquo;re using Docker compose for having a declarative way to run your containers you might have found out that updating it requires some manual work. In this example we automate it using the following structure:
Folder: /opt/docker-compose Container folders: /opt/docker-compose/&amp;laquo;container&amp;raquo; Below is an example of my structure:
[root] docker-compose# ls -ld /opt/docker-compose/* -rw-r--r-- 1 root root 0 Sep 11 2023 /opt/docker-compose/README.md drwxr-xr-x 2 root root 4096 Sep 13 2023 /opt/docker-compose/bazarr drwxr-xr-x 2 root root 4096 Sep 11 2023 /opt/docker-compose/deluge drwxr-xr-x 2 root root 4096 Sep 16 15:51 /opt/docker-compose/homeassistant drwxr-xr-x 2 root root 4096 Jul 26 10:04 /opt/docker-compose/jellyfin drwxr-xr-x 2 root root 4096 Sep 13 2023 /opt/docker-compose/jenkins drwxr-xr-x 2 root root 4096 Oct 1 10:14 /opt/docker-compose/openvpn drwxr-xr-x 4 root root 4096 Sep 13 2023 /opt/docker-compose/pihole drwxr-xr-x 2 root root 4096 Sep 11 2023 /opt/docker-compose/radarr drwxr-xr-x 2 root root 4096 Dec 4 2023 /opt/docker-compose/ring-mqtt drwxr-xr-x 2 root root 4096 Sep 11 2023 /opt/docker-compose/sonarr -rwxr-xr-x 1 root root 349 Sep 11 2023 /opt/docker-compose/update.</description>
            <content type="html"><![CDATA[<h2 id="setting-up-the-structure">Setting up the structure</h2>
<p>If you&rsquo;re using Docker compose for having a declarative way to run your containers you might have found out that updating it requires some manual work. In this example we automate it using the following structure:</p>
<ul>
<li>Folder: /opt/docker-compose</li>
<li>Container folders: /opt/docker-compose/&laquo;container&raquo;</li>
</ul>
<p>Below is an example of my structure:</p>
<div class="highlight"><pre tabindex="0" style="color:#ccc;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#39c">[</span>root<span style="color:#39c">]</span> docker-compose# ls -ld /opt/docker-compose/*
</span></span><span style="display:flex;"><span>-rw-r--r-- <span style="color:#cd00cd">1</span> root root    <span style="color:#cd00cd">0</span> Sep <span style="color:#cd00cd">11</span>  <span style="color:#cd00cd">2023</span> /opt/docker-compose/README.md
</span></span><span style="display:flex;"><span>drwxr-xr-x <span style="color:#cd00cd">2</span> root root <span style="color:#cd00cd">4096</span> Sep <span style="color:#cd00cd">13</span>  <span style="color:#cd00cd">2023</span> /opt/docker-compose/bazarr
</span></span><span style="display:flex;"><span>drwxr-xr-x <span style="color:#cd00cd">2</span> root root <span style="color:#cd00cd">4096</span> Sep <span style="color:#cd00cd">11</span>  <span style="color:#cd00cd">2023</span> /opt/docker-compose/deluge
</span></span><span style="display:flex;"><span>drwxr-xr-x <span style="color:#cd00cd">2</span> root root <span style="color:#cd00cd">4096</span> Sep <span style="color:#cd00cd">16</span> 15:51 /opt/docker-compose/homeassistant
</span></span><span style="display:flex;"><span>drwxr-xr-x <span style="color:#cd00cd">2</span> root root <span style="color:#cd00cd">4096</span> Jul <span style="color:#cd00cd">26</span> 10:04 /opt/docker-compose/jellyfin
</span></span><span style="display:flex;"><span>drwxr-xr-x <span style="color:#cd00cd">2</span> root root <span style="color:#cd00cd">4096</span> Sep <span style="color:#cd00cd">13</span>  <span style="color:#cd00cd">2023</span> /opt/docker-compose/jenkins
</span></span><span style="display:flex;"><span>drwxr-xr-x <span style="color:#cd00cd">2</span> root root <span style="color:#cd00cd">4096</span> Oct  <span style="color:#cd00cd">1</span> 10:14 /opt/docker-compose/openvpn
</span></span><span style="display:flex;"><span>drwxr-xr-x <span style="color:#cd00cd">4</span> root root <span style="color:#cd00cd">4096</span> Sep <span style="color:#cd00cd">13</span>  <span style="color:#cd00cd">2023</span> /opt/docker-compose/pihole
</span></span><span style="display:flex;"><span>drwxr-xr-x <span style="color:#cd00cd">2</span> root root <span style="color:#cd00cd">4096</span> Sep <span style="color:#cd00cd">11</span>  <span style="color:#cd00cd">2023</span> /opt/docker-compose/radarr
</span></span><span style="display:flex;"><span>drwxr-xr-x <span style="color:#cd00cd">2</span> root root <span style="color:#cd00cd">4096</span> Dec  <span style="color:#cd00cd">4</span>  <span style="color:#cd00cd">2023</span> /opt/docker-compose/ring-mqtt
</span></span><span style="display:flex;"><span>drwxr-xr-x <span style="color:#cd00cd">2</span> root root <span style="color:#cd00cd">4096</span> Sep <span style="color:#cd00cd">11</span>  <span style="color:#cd00cd">2023</span> /opt/docker-compose/sonarr
</span></span><span style="display:flex;"><span>-rwxr-xr-x <span style="color:#cd00cd">1</span> root root  <span style="color:#cd00cd">349</span> Sep <span style="color:#cd00cd">11</span>  <span style="color:#cd00cd">2023</span> /opt/docker-compose/update.sh
</span></span><span style="display:flex;"><span>drwxr-xr-x <span style="color:#cd00cd">2</span> root root <span style="color:#cd00cd">4096</span> Sep <span style="color:#cd00cd">13</span>  <span style="color:#cd00cd">2023</span> /opt/docker-compose/vaultwarden
</span></span><span style="display:flex;"><span>drwxr-xr-x <span style="color:#cd00cd">3</span> root root <span style="color:#cd00cd">4096</span> Oct  <span style="color:#cd00cd">1</span> 10:33 /opt/docker-compose/your_spotify
</span></span></code></pre></div><p>All these folders contain a <code>docker-compose.yaml</code> or <code>compose.yaml</code> file which the <code>docker-compose</code> command will look for when executing commands like <code>docker-compose up -d</code>.</p>
<h2 id="the-update-script">The update script</h2>
<p>Place the update script in <code>/opt/docker-compose/update.sh</code>:</p>
<div class="highlight"><pre tabindex="0" style="color:#ccc;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#000080">#!/bin/bash
</span></span></span><span style="display:flex;"><span><span style="color:#000080"></span>
</span></span><span style="display:flex;"><span><span style="color:#000080">## Variables</span>
</span></span><span style="display:flex;"><span><span style="color:#00cdcd">SCRIPT_DIR</span><span style="color:#39c">=</span><span style="color:#cd0000">&#34;</span><span style="color:#cdcd00">$(</span> <span style="color:#cd00cd">cd</span> <span style="color:#cd0000">&#34;</span><span style="color:#cdcd00">$(</span> dirname <span style="color:#cd0000">&#34;</span><span style="color:#cd0000">${</span><span style="color:#00cdcd">BASH_SOURCE</span>[0]<span style="color:#cd0000">}</span><span style="color:#cd0000">&#34;</span> <span style="color:#cdcd00">)</span><span style="color:#cd0000">&#34;</span> &amp;&gt; /dev/null <span style="color:#39c">&amp;&amp;</span> <span style="color:#cd00cd">pwd</span> <span style="color:#cdcd00">)</span><span style="color:#cd0000">&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#00cdcd">RED</span><span style="color:#39c">=</span><span style="color:#cd0000">&#34;\e[31m&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#00cdcd">ENDCOLOR</span><span style="color:#39c">=</span><span style="color:#cd0000">&#34;\e[0m&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#00cdcd">DIRS</span><span style="color:#39c">=</span><span style="color:#cdcd00">$(</span>find <span style="color:#00cdcd">$SCRIPT_DIR</span>/* -type d<span style="color:#cdcd00">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#000080">## Update</span>
</span></span><span style="display:flex;"><span><span style="color:#cdcd00">for</span> DIR in <span style="color:#00cdcd">$DIRS</span>
</span></span><span style="display:flex;"><span><span style="color:#cdcd00">do</span>
</span></span><span style="display:flex;"><span>        <span style="color:#cd00cd">echo</span> -e <span style="color:#cd0000">&#34;</span><span style="color:#cd0000">${</span><span style="color:#00cdcd">RED</span><span style="color:#cd0000">}</span><span style="color:#cd0000">Checking update for </span><span style="color:#cd0000">${</span><span style="color:#00cdcd">DIR</span><span style="color:#cd0000">}</span><span style="color:#cd0000">...</span><span style="color:#cd0000">${</span><span style="color:#00cdcd">ENDCOLOR</span><span style="color:#cd0000">}</span><span style="color:#cd0000">\n&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#cd00cd">cd</span> <span style="color:#00cdcd">$DIR</span>
</span></span><span style="display:flex;"><span>        docker-compose pull
</span></span><span style="display:flex;"><span>        docker-compose up -d --remove-orphans
</span></span><span style="display:flex;"><span>        <span style="color:#cd00cd">cd</span> <span style="color:#00cdcd">$SCRIPT_DIR</span>
</span></span><span style="display:flex;"><span><span style="color:#cdcd00">done</span>
</span></span></code></pre></div><p>Make it executable by setting the X bit on the script:</p>
<div class="highlight"><pre tabindex="0" style="color:#ccc;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>chmod <span style="color:#cd00cd">750</span> /opt/docker-compose/update.sh
</span></span></code></pre></div><p>You can now run the script manually from any directory to check if it works correctly. Notice the <code>SCRIPT_DIR</code> variable which will automatically look in the folders where the script is located and thus check it&rsquo;s subdirectories.</p>
<div class="highlight"><pre tabindex="0" style="color:#ccc;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#00cdcd">SCRIPT_DIR</span><span style="color:#39c">=</span><span style="color:#cd0000">&#34;</span><span style="color:#cdcd00">$(</span> <span style="color:#cd00cd">cd</span> <span style="color:#cd0000">&#34;</span><span style="color:#cdcd00">$(</span> dirname <span style="color:#cd0000">&#34;</span><span style="color:#cd0000">${</span><span style="color:#00cdcd">BASH_SOURCE</span>[0]<span style="color:#cd0000">}</span><span style="color:#cd0000">&#34;</span> <span style="color:#cdcd00">)</span><span style="color:#cd0000">&#34;</span> &amp;&gt; /dev/null <span style="color:#39c">&amp;&amp;</span> <span style="color:#cd00cd">pwd</span> <span style="color:#cdcd00">)</span><span style="color:#cd0000">&#34;</span>
</span></span></code></pre></div><h2 id="example-script-output">Example script output</h2>
<p>Below a screenshot of how the output will look (screenshot, not text because of the colours.)
<img alt="Docker compose autoupdate output" src="/images/docker-autoupdate/autoupdate-output.png"></p>
<h2 id="setting-up-a-cronjob">Setting up a cronjob</h2>
<p>Place a cronjob as following to execute script periodically. In this case I placed it in <code>/etc/crontab</code> hence why you see the user (root) argument after the time.</p>
<p>Below example will run it every day at 1 AM:</p>
<div class="highlight"><pre tabindex="0" style="color:#ccc;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#cd00cd">0</span> <span style="color:#cd00cd">1</span> * * * root bash /opt/docker-compose/update.sh
</span></span></code></pre></div>]]></content>
        </item>
        
        <item>
            <title>Python: Blind poule generator</title>
            <link>https://jeroendev.one/posts/python-blind-poule-generator/</link>
            <pubDate>Sun, 24 Mar 2024 00:00:00 +0000</pubDate>
            
            <guid>https://jeroendev.one/posts/python-blind-poule-generator/</guid>
            <description>What is it? A blind poule is a list of randomly generated soccer score outcomes. The script I made favours the lower numbers first (because this is more likely to happen) but it can generate scores where one team scores 6 or 7 goals.
Requirements weasyprint numpy jinja2 Weasyprint can be installed using your distro&amp;rsquo;s package manager. The remaining Python modules can be installed using pip:
pip install numpy jinja2 The script import random import numpy as np import datetime from jinja2 import Template # Set generated_scores = set() # Generate random scores def generate_score(): global generated_scores while True: # Generate random scores favoring towards lower values team1_score = max(0, int(np.</description>
            <content type="html"><![CDATA[<h2 id="what-is-it">What is it?</h2>
<p>A blind poule is a list of randomly generated soccer score outcomes. The script I made favours the lower numbers first (because this is more likely to happen) but it can generate scores where one team scores 6 or 7 goals.</p>
<h3 id="requirements">Requirements</h3>
<ul>
<li>weasyprint</li>
<li>numpy</li>
<li>jinja2</li>
</ul>
<p>Weasyprint can be installed using your distro&rsquo;s package manager. The remaining Python modules can be installed using <code>pip</code>:</p>
<div class="highlight"><pre tabindex="0" style="color:#ccc;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>pip install numpy jinja2
</span></span></code></pre></div><h3 id="the-script">The script</h3>
<div class="highlight"><pre tabindex="0" style="color:#ccc;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#cd00cd">import</span> random
</span></span><span style="display:flex;"><span><span style="color:#cd00cd">import</span> numpy <span style="color:#cdcd00">as</span> np
</span></span><span style="display:flex;"><span><span style="color:#cd00cd">import</span> datetime
</span></span><span style="display:flex;"><span><span style="color:#cd00cd">from</span> jinja2 <span style="color:#cd00cd">import</span> Template
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#000080"># Set</span>
</span></span><span style="display:flex;"><span>generated_scores <span style="color:#39c">=</span> <span style="color:#cd00cd">set</span>()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#000080"># Generate random scores</span>
</span></span><span style="display:flex;"><span><span style="color:#cdcd00">def</span> generate_score():
</span></span><span style="display:flex;"><span>    <span style="color:#cdcd00">global</span> generated_scores
</span></span><span style="display:flex;"><span>    <span style="color:#cdcd00">while</span> <span style="color:#cdcd00">True</span>:
</span></span><span style="display:flex;"><span>        <span style="color:#000080"># Generate random scores favoring towards lower values</span>
</span></span><span style="display:flex;"><span>        team1_score <span style="color:#39c">=</span> <span style="color:#cd00cd">max</span>(<span style="color:#cd00cd">0</span>, <span style="color:#cd00cd">int</span>(np<span style="color:#39c">.</span>random<span style="color:#39c">.</span>normal(<span style="color:#cd00cd">2</span>, <span style="color:#cd00cd">1.5</span>)))
</span></span><span style="display:flex;"><span>        team2_score <span style="color:#39c">=</span> <span style="color:#cd00cd">max</span>(<span style="color:#cd00cd">0</span>, <span style="color:#cd00cd">int</span>(np<span style="color:#39c">.</span>random<span style="color:#39c">.</span>normal(<span style="color:#cd00cd">2</span>, <span style="color:#cd00cd">1.5</span>)))
</span></span><span style="display:flex;"><span>        score <span style="color:#39c">=</span> <span style="color:#cd0000">f</span><span style="color:#cd0000">&#34;</span><span style="color:#cd0000">{</span>team1_score<span style="color:#cd0000">}</span><span style="color:#cd0000">-</span><span style="color:#cd0000">{</span>team2_score<span style="color:#cd0000">}</span><span style="color:#cd0000">&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#cdcd00">if</span> score <span style="color:#cdcd00">not</span> <span style="color:#cdcd00">in</span> generated_scores:
</span></span><span style="display:flex;"><span>            generated_scores<span style="color:#39c">.</span>add(score)
</span></span><span style="display:flex;"><span>            <span style="color:#cdcd00">return</span> score
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#000080"># Reset the set</span>
</span></span><span style="display:flex;"><span><span style="color:#cdcd00">def</span> reset_generated_scores():
</span></span><span style="display:flex;"><span>    <span style="color:#cdcd00">global</span> generated_scores
</span></span><span style="display:flex;"><span>    generated_scores <span style="color:#39c">=</span> <span style="color:#cd00cd">set</span>()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#000080"># Render the Jinja2 template</span>
</span></span><span style="display:flex;"><span><span style="color:#cdcd00">def</span> render_template(template_path, num_scores):
</span></span><span style="display:flex;"><span>    <span style="color:#cdcd00">with</span> <span style="color:#cd00cd">open</span>(template_path, <span style="color:#cd0000">&#39;r&#39;</span>) <span style="color:#cdcd00">as</span> f:
</span></span><span style="display:flex;"><span>        template_content <span style="color:#39c">=</span> f<span style="color:#39c">.</span>read()
</span></span><span style="display:flex;"><span>    
</span></span><span style="display:flex;"><span>    template <span style="color:#39c">=</span> Template(template_content)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    rendered_content <span style="color:#39c">=</span> template<span style="color:#39c">.</span>render(
</span></span><span style="display:flex;"><span>        generate_score<span style="color:#39c">=</span>generate_score,
</span></span><span style="display:flex;"><span>        num_scores<span style="color:#39c">=</span>num_scores,
</span></span><span style="display:flex;"><span>    )
</span></span><span style="display:flex;"><span>    
</span></span><span style="display:flex;"><span>    <span style="color:#cdcd00">return</span> rendered_content
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#000080"># Generate and save the template</span>
</span></span><span style="display:flex;"><span><span style="color:#cdcd00">def</span> generate_markdown_file(template_path, output_path, num_scores):
</span></span><span style="display:flex;"><span>    reset_generated_scores()  <span style="color:#000080"># Reset!</span>
</span></span><span style="display:flex;"><span>    rendered_content <span style="color:#39c">=</span> render_template(template_path, num_scores)
</span></span><span style="display:flex;"><span>    <span style="color:#cdcd00">with</span> <span style="color:#cd00cd">open</span>(output_path, <span style="color:#cd0000">&#39;w&#39;</span>) <span style="color:#cdcd00">as</span> f:
</span></span><span style="display:flex;"><span>        f<span style="color:#39c">.</span>write(rendered_content)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#000080"># Call it</span>
</span></span><span style="display:flex;"><span>generate_markdown_file(<span style="color:#cd0000">&#34;pool-template.html&#34;</span>, <span style="color:#cd0000">&#34;pool.html&#34;</span>, <span style="color:#cd00cd">50</span>)
</span></span></code></pre></div><h3 id="jinja2-template-for-scores-save-as-pool-templatehtml">Jinja2 template for scores (save as pool-template.html)</h3>
<div class="highlight"><pre tabindex="0" style="color:#ccc;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-html" data-lang="html"><span style="display:flex;"><span><span style="color:#000080">&lt;!DOCTYPE html&gt;</span>
</span></span><span style="display:flex;"><span>&lt;html lang<span style="color:#39c">=</span><span style="color:#cd0000">&#34;en&#34;</span>&gt;
</span></span><span style="display:flex;"><span>&lt;head&gt;
</span></span><span style="display:flex;"><span>&lt;meta charset<span style="color:#39c">=</span><span style="color:#cd0000">&#34;UTF-8&#34;</span>&gt;
</span></span><span style="display:flex;"><span>&lt;meta name<span style="color:#39c">=</span><span style="color:#cd0000">&#34;viewport&#34;</span> content<span style="color:#39c">=</span><span style="color:#cd0000">&#34;width=device-width, initial-scale=1.0&#34;</span>&gt;
</span></span><span style="display:flex;"><span>&lt;title&gt;Blinde voetbalpoule&lt;/title&gt;
</span></span><span style="display:flex;"><span>&lt;style&gt;
</span></span><span style="display:flex;"><span>  @<span style="color:#cdcd00">page</span> {
</span></span><span style="display:flex;"><span>    size<span style="color:#39c">:</span> A4<span style="color:#39c">;</span>
</span></span><span style="display:flex;"><span>    margin<span style="color:#39c">:</span> 0<span style="color:#39c">;</span>
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  table {
</span></span><span style="display:flex;"><span>    <span style="color:#cdcd00">width</span>: <span style="color:#cd00cd">100</span><span style="color:#00cd00">%</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#cdcd00">font-size</span>: <span style="color:#cd00cd">9</span><span style="color:#00cd00">px</span>; <span style="color:#000080">/* Smaller font size */</span>
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  th<span style="color:#39c">,</span> td {
</span></span><span style="display:flex;"><span>    <span style="color:#cdcd00">padding</span>: <span style="color:#cd00cd">2.2</span><span style="color:#00cd00">px</span>; <span style="color:#000080">/* Smaller padding */</span>
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>&lt;/style&gt;
</span></span><span style="display:flex;"><span>&lt;/head&gt;
</span></span><span style="display:flex;"><span>&lt;body&gt;
</span></span><span style="display:flex;"><span>&lt;h3 style<span style="color:#39c">=</span><span style="color:#cd0000">&#34;text-align: center;&#34;</span>&gt;Blinde voetbalpoule&lt;/h3&gt;
</span></span><span style="display:flex;"><span>&lt;h5 style<span style="color:#39c">=</span><span style="color:#cd0000">&#34;text-align:center;&#34;</span>&gt;____________ tegen ____________ &lt;/h5&gt;
</span></span><span style="display:flex;"><span>&lt;h6&gt;Inleg: €1 per nummer, prijs bij goede uitslag: €25&lt;/h6&gt;
</span></span><span style="display:flex;"><span>&lt;table&gt;
</span></span><span style="display:flex;"><span>  &lt;thead&gt;
</span></span><span style="display:flex;"><span>    &lt;tr&gt;
</span></span><span style="display:flex;"><span>      &lt;th style<span style="color:#39c">=</span><span style="color:#cd0000">&#34;width: 5%;&#34;</span>&gt;Nr.&lt;/th&gt;
</span></span><span style="display:flex;"><span>      &lt;th style<span style="color:#39c">=</span><span style="color:#cd0000">&#34;width: 70%;&#34;</span>&gt;Naam deelnemer:&lt;/th&gt;
</span></span><span style="display:flex;"><span>      &lt;th style<span style="color:#39c">=</span><span style="color:#cd0000">&#34;width: 20%;&#34;</span>&gt;&lt;/th&gt;
</span></span><span style="display:flex;"><span>      &lt;th style<span style="color:#39c">=</span><span style="color:#cd0000">&#34;text-align:center; width: 30%;&#34;</span>&gt;Score&lt;/th&gt;
</span></span><span style="display:flex;"><span>    &lt;/tr&gt;
</span></span><span style="display:flex;"><span>  &lt;/thead&gt;
</span></span><span style="display:flex;"><span>  &lt;tbody&gt;
</span></span><span style="display:flex;"><span>    {% for x in range(1, num_scores + 1) %}
</span></span><span style="display:flex;"><span>    &lt;tr&gt;
</span></span><span style="display:flex;"><span>      &lt;td style<span style="color:#39c">=</span><span style="color:#cd0000">&#34;border: 1px solid black;&#34;</span>&gt;{{ x }}&lt;/td&gt;
</span></span><span style="display:flex;"><span>      &lt;td style<span style="color:#39c">=</span><span style="color:#cd0000">&#34;border: 1px solid black;&#34;</span>&gt;&lt;/td&gt;
</span></span><span style="display:flex;"><span>      &lt;td style<span style="color:#39c">=</span><span style="color:#cd0000">&#34;width: 20%;&#34;</span>&gt;&lt;/td&gt;
</span></span><span style="display:flex;"><span>      &lt;td style<span style="color:#39c">=</span><span style="color:#cd0000">&#34;text-align:center;border: 1px solid black;&#34;</span>&gt;{{ generate_score() }}&lt;/td&gt;
</span></span><span style="display:flex;"><span>    &lt;/tr&gt;
</span></span><span style="display:flex;"><span>    {% endfor %}
</span></span><span style="display:flex;"><span>  &lt;/tbody&gt;
</span></span><span style="display:flex;"><span>&lt;/table&gt;
</span></span><span style="display:flex;"><span>&lt;/body&gt;
</span></span><span style="display:flex;"><span>&lt;/html&gt;
</span></span></code></pre></div><h3 id="automating-it-and-mailing-the-pdfs">Automating it and mailing the PDF&rsquo;s</h3>
<p>To make it easy I made a simple Bash script which runs the script and mails it to me as a attachment.</p>
<div class="highlight"><pre tabindex="0" style="color:#ccc;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#000080">#!/bin/bash
</span></span></span><span style="display:flex;"><span><span style="color:#000080"></span><span style="color:#00cdcd">TO_EMAIL</span><span style="color:#39c">=</span>nobody@example.com
</span></span><span style="display:flex;"><span>python3 main.py
</span></span><span style="display:flex;"><span>weasyprint pool.html voetbalpoule.pdf
</span></span><span style="display:flex;"><span><span style="color:#cd00cd">echo</span> <span style="color:#cd0000">&#34;Voetbalpoule&#34;</span> | mutt -s <span style="color:#cd0000">&#34;Voetbalpoule </span><span style="color:#cdcd00">$(</span>date +<span style="color:#cd0000">&#39;%d-%m&#39;</span><span style="color:#cdcd00">)</span><span style="color:#cd0000">&#34;</span> -a <span style="color:#cd0000">&#34;voetbalpoule.pdf&#34;</span> -- <span style="color:#00cdcd">$TO_EMAIL</span>
</span></span></code></pre></div>]]></content>
        </item>
        
        <item>
            <title>PS5: Setting up Discord RPC client</title>
            <link>https://jeroendev.one/posts/ps5-setting-up-discord-rpc-client/</link>
            <pubDate>Mon, 12 Feb 2024 00:00:00 +0000</pubDate>
            
            <guid>https://jeroendev.one/posts/ps5-setting-up-discord-rpc-client/</guid>
            <description>What is it? PS5 RPC Client is an client I made using Python3 which will update your Discord Rich Presence with the game you&amp;rsquo;re playing on your jailbroken PS5. Requires Discord Desktop App
It requires etaHEN &amp;gt;= 1.4b to be running and have the following entry enabled in the /data/etaHEN/config.ini:
[Settings] discord_rpc=1 Advised to have an static IP for your PS5.
Getting started 1. Setting up Discord Go to the Discord Developers page.</description>
            <content type="html"><![CDATA[<div style="display: flex; gap: 30px; justify-content: align-left; flex-wrap: wrap;">
    <img src="/images/rpc-client/discord_example_buttons.png" alt="Rich Presence example game with button" style="width: 400px; height: auto;">
    <img src="/images/rpc-client/discord_example_game.png" alt="Rich Presence example game" style="width: 400px; height: auto;">
    <img src="/images/rpc-client/discord_example_hb.png" alt="Rich Presence example homebrew" style="width: 400px; height: auto;">
    <img src="/images/rpc-client/discord_example_idle.png" alt="Rich Presence example idle" style="width: 400px; height: auto;">
</div>
<h2 id="what-is-it">What is it?</h2>
<p>PS5 RPC Client is an client I made using Python3 which will update your Discord Rich Presence with the game you&rsquo;re playing on your jailbroken PS5. <em>Requires Discord Desktop App</em></p>
<p>It requires <a href="https://github.com/LightningMods/etaHEN">etaHEN &gt;= 1.4b</a> to be running and have the following entry enabled in the <code>/data/etaHEN/config.ini</code>:</p>
<div class="highlight"><pre tabindex="0" style="color:#ccc;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-ini" data-lang="ini"><span style="display:flex;"><span><span style="color:#cdcd00">[Settings]</span>
</span></span><span style="display:flex;"><span>discord_rpc<span style="color:#39c">=</span><span style="color:#cd0000">1</span>
</span></span></code></pre></div><p>Advised to have an static IP for your PS5.</p>
<h2 id="getting-started">Getting started</h2>
<h3 id="1-setting-up-discord">1. Setting up Discord</h3>
<ol>
<li>Go to the <a href="https://discord.com/developers">Discord Developers</a> page.</li>
<li>On the top right side click &lsquo;New Application&rsquo;. Name it &lsquo;Playstation&rsquo; or how ever you like.</li>
<li>Select the application and copy the value named &lsquo;Application ID&rsquo; and note it down.</li>
</ol>
<h3 id="2-running-the-client">2. Running the client</h3>
<p>The client will ask for the Discord Application ID and PS5 IP address upon first startup. It will write those values to a <code>config.ini</code></p>
<p>Config values:</p>
<div class="highlight"><pre tabindex="0" style="color:#ccc;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-ini" data-lang="ini"><span style="display:flex;"><span><span style="color:#cdcd00">[settings]</span>
</span></span><span style="display:flex;"><span>client_id <span style="color:#39c">=</span> <span style="color:#cd0000">&#39;&lt;application ID&#39;</span>
</span></span><span style="display:flex;"><span>ps5_ip <span style="color:#39c">=</span> <span style="color:#cd0000">&#39;xxx.xxx.x.xxx&#39;</span>
</span></span><span style="display:flex;"><span>buttons_enabled <span style="color:#39c">=</span> <span style="color:#cd0000">&#39;1 or 0&#39; (1 = enabled, 0 = disabled)</span>
</span></span></code></pre></div><h3 id="windows">Windows</h3>
<ol>
<li>Download the latest exe release from the <a href="https://github.com/jeroendev-one/ps5-rpc-client/releases">releases</a> page.</li>
<li>Unzip the directory to a location of your choice.</li>
<li>Run the exe.</li>
</ol>
<h2 id="linux--macos">Linux / MacOS</h2>
<ol>
<li>Clone this repo</li>
<li>Install dependencies with <code>pip3 install -r requirements.txt</code></li>
<li>Run <code>python3 client.py</code> or <code>python client.py</code></li>
</ol>
<h2 id="docker">Docker</h2>
<ol>
<li>Clone this repo, and inside the directory create a <code>config.ini</code>:</li>
</ol>
<div class="highlight"><pre tabindex="0" style="color:#ccc;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-ini" data-lang="ini"><span style="display:flex;"><span><span style="color:#cdcd00">[settings]</span>
</span></span><span style="display:flex;"><span>client_id <span style="color:#39c">=</span> <span style="color:#cd0000">&#39;xxxxxx&#39;</span>
</span></span><span style="display:flex;"><span>ps5_ip <span style="color:#39c">=</span> <span style="color:#cd0000">&#39;xxx.xxx.xxx&#39;</span>
</span></span><span style="display:flex;"><span>buttons_enabled <span style="color:#39c">=</span> <span style="color:#cd0000">1 (enabled) or 0 (disabled)</span>
</span></span></code></pre></div><ol>
<li>Build and run the container using <code>docker compose up -d</code></li>
</ol>
]]></content>
        </item>
        
        <item>
            <title>Ansible: Secret management</title>
            <link>https://jeroendev.one/posts/ansible-secret-management/</link>
            <pubDate>Sun, 07 Jan 2024 00:00:00 +0000</pubDate>
            
            <guid>https://jeroendev.one/posts/ansible-secret-management/</guid>
            <description>Vault / secrets Ansible has a good way of storing passwords / secrets and still keeping your source code in Git. The tool is called ansible-vault and can be used to encrypt/decrypt secrets.
Creating a secret file This is for demonstration purposes only. Use/edit our vault in case you need secrets.
Let&amp;rsquo;s say we have this Yaml file secret.yml containing a password which we want to use in our playbooks:</description>
            <content type="html"><![CDATA[<h1 id="vault--secrets">Vault / secrets</h1>
<p>Ansible has a good way of storing passwords / secrets and still keeping your source code in Git. The tool is called <code>ansible-vault</code> and can be used to encrypt/decrypt secrets.</p>
<h2 id="creating-a-secret-file">Creating a secret file</h2>
<p>This is for demonstration purposes only. Use/edit our vault in case you need secrets.</p>
<p>Let&rsquo;s say we have this Yaml file <code>secret.yml</code> containing a password which we want to use in our playbooks:</p>
<div class="highlight"><pre tabindex="0" style="color:#ccc;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span>---
</span></span><span style="display:flex;"><span>install_password: <span style="color:#cd0000">&#39;superPassword&#39;</span>
</span></span></code></pre></div><p>Use this command to encrypt the secret:</p>
<div class="highlight"><pre tabindex="0" style="color:#ccc;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>ansible-vault encrypt secret.yml 
</span></span><span style="display:flex;"><span>New Vault password: 
</span></span><span style="display:flex;"><span>Confirm New Vault password: 
</span></span><span style="display:flex;"><span>Encryption successful
</span></span></code></pre></div><p>After this command it&rsquo;s safe to share / upload it to a repository. Save the password in a password manager and you&rsquo;re done.</p>
<h2 id="decrypting--viewing-secrets">Decrypting / viewing secrets</h2>
<p>To view the secrets in the vault file, use the following command:</p>
<pre tabindex="0"><code>ansible-vault view &lt;&lt;secret file&gt;&gt;
Vault password: 
</code></pre><p>To decrypt it (<strong>Never upload it when you have it decrypted!</strong>):</p>
<pre tabindex="0"><code>ansible-vault decrypt &lt;&lt;secret file&gt;&gt;
Vault password: 
Decryption successful
</code></pre><h2 id="automatically-unlocking-vault">Automatically unlocking vault</h2>
<h3 id="1-command-line">1. Command line</h3>
<p>To prevent having to type a password every time you want to see secrets, execute the following steps:</p>
<ol>
<li>
<p>Write your password to a file <code>~/.ansible/vault</code> for example.</p>
</li>
<li>
<p>Set the proper permissions (600)</p>
<div class="highlight"><pre tabindex="0" style="color:#ccc;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>chmod <span style="color:#cd00cd">600</span> ~/.ansible/vault
</span></span></code></pre></div></li>
<li>
<p>Set the following environment variable in your <code>.bashrc</code></p>
<div class="highlight"><pre tabindex="0" style="color:#ccc;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#cd00cd">export</span> <span style="color:#00cdcd">ANSIBLE_VAULT_PASSWORD_FILE</span><span style="color:#39c">=</span>~/.ansible/vault
</span></span></code></pre></div></li>
<li>
<p>Now you can automatically unlock the vault without having the password prompt.</p>
</li>
</ol>
<h3 id="2-in-ansible-playbooks--roles-system-wide">2. In Ansible playbooks / roles (system wide)</h3>
<ol>
<li>Write the password to a file <code>/home/ansible-user/.vault</code> for example.</li>
<li>Set the proper permissions (600)
<div class="highlight"><pre tabindex="0" style="color:#ccc;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>chmod <span style="color:#cd00cd">600</span> /home/ansible-user/.vault
</span></span></code></pre></div></li>
<li>In your ansible.cfg (located in <code>/etc/ansible/ansible.cfg</code>) set the following config value:
<div class="highlight"><pre tabindex="0" style="color:#ccc;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-ini" data-lang="ini"><span style="display:flex;"><span><span style="color:#cdcd00">[defaults]</span>
</span></span><span style="display:flex;"><span>vault_password_file <span style="color:#39c">=</span> <span style="color:#cd0000">/home/ansible-user/.vault</span>
</span></span></code></pre></div></li>
</ol>
]]></content>
        </item>
        
        <item>
            <title>Kubernetes: Fix stuck &#39;terminating namespace</title>
            <link>https://jeroendev.one/posts/kubernetes-fix-stuck-terminating-namespace/</link>
            <pubDate>Sat, 05 Aug 2023 00:00:00 +0000</pubDate>
            
            <guid>https://jeroendev.one/posts/kubernetes-fix-stuck-terminating-namespace/</guid>
            <description>If a namespace on Kubernetes is stuck on the &amp;rsquo;terminating&amp;rsquo; / finalizer state. You can try to run the following to delete it.
read -p &amp;#34;Namespace: &amp;#34; NAMESPACE kubectl proxy &amp;amp; kubectl get namespace $NAMESPACE -o json |jq &amp;#39;.spec = {&amp;#34;finalizers&amp;#34;:[]}&amp;#39; &amp;gt;temp.json curl -k -H &amp;#34;Content-Type: application/json&amp;#34; -X PUT --data-binary @temp.json 127.0.0.1:8001/api/v1/namespaces/$NAMESPACE/finalize This should fix your stuck namespace.</description>
            <content type="html"><![CDATA[<p>If a namespace on Kubernetes is stuck on the &rsquo;terminating&rsquo; / finalizer state. You can try to run the following to delete it.</p>
<div class="highlight"><pre tabindex="0" style="color:#ccc;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#cd00cd">read</span> -p <span style="color:#cd0000">&#34;Namespace: &#34;</span> NAMESPACE
</span></span><span style="display:flex;"><span>kubectl proxy &amp;
</span></span><span style="display:flex;"><span>kubectl get namespace <span style="color:#00cdcd">$NAMESPACE</span> -o json |jq <span style="color:#cd0000">&#39;.spec = {&#34;finalizers&#34;:[]}&#39;</span> &gt;temp.json
</span></span><span style="display:flex;"><span>curl -k -H <span style="color:#cd0000">&#34;Content-Type: application/json&#34;</span> -X PUT --data-binary @temp.json 127.0.0.1:8001/api/v1/namespaces/<span style="color:#00cdcd">$NAMESPACE</span>/finalize
</span></span></code></pre></div><p>This should fix your stuck namespace.</p>
]]></content>
        </item>
        
        <item>
            <title>DirectAdmin: Configure to use mail relay for specific domains</title>
            <link>https://jeroendev.one/posts/directadmin-configure-to-use-mail-relay-for-specific-domains/</link>
            <pubDate>Sun, 02 Apr 2023 00:00:00 +0000</pubDate>
            
            <guid>https://jeroendev.one/posts/directadmin-configure-to-use-mail-relay-for-specific-domains/</guid>
            <description>I discovered my server was on a blacklist from Microsoft, probably because of the provider. I couldn&amp;rsquo;t get it whitelisted as fast as I would, so I configured an SMTP relay for these specific domains. The error message from Exim:
F=&amp;lt;***@domain.com&amp;gt; R=lookuphost T=remote_smtp H=hotmail-com.olc.protection.outlook.com [104.47.14.33] X=TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256 CV=yes: SMTP error from remote mail server after pipelined MAIL FROM:&amp;lt;***@domain.com&amp;gt; SIZE=165698: 550 5.7.1 Unfortunately, messages from [XX.XX.XX.XXX] weren&amp;#39;t sent. Please contact your Internet service provider since part of their network is on our block list (S3140).</description>
            <content type="html"><![CDATA[<p>I discovered my server was on a blacklist from Microsoft, probably because of the provider. I couldn&rsquo;t get it whitelisted as fast as I would, so I configured an SMTP relay for these specific domains. The error message from Exim:</p>
<pre tabindex="0"><code>F=&lt;***@domain.com&gt; R=lookuphost T=remote_smtp H=hotmail-com.olc.protection.outlook.com [104.47.14.33] X=TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256 CV=yes: SMTP error from remote mail server after pipelined MAIL FROM:&lt;***@domain.com&gt; SIZE=165698: 550 5.7.1 Unfortunately, messages from [XX.XX.XX.XXX] weren&#39;t sent. Please contact your Internet service provider since part of their network is on our block list (S3140). You can also refer your provider to http://mail.live.com/mail/troubleshooting.aspx#errors. [VI1EUR04FT004.eop-eur04.prod.protection.outlook.com]
</code></pre><p>To relay the mail to an Exim SMTP server I had setup for this, allowing only access to the SMTP ports (25,465,587) by IP whitelisting, I configured the following config for Exim:</p>
<p>Create a new file called <code>/etc/exim.routers.pre.conf</code></p>
<p>And configure it as following:</p>
<p>NOTE: If you don&rsquo;t want to forward specific domains to the relay, but all, then replace domains = xxx with:</p>
<pre tabindex="0"><code>domains = ! +local_domains
</code></pre><p>This will forward all domains to your SMTP relay.</p>
<div class="highlight"><pre tabindex="0" style="color:#ccc;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>smart_route_forward:
</span></span><span style="display:flex;"><span>    <span style="color:#00cdcd">driver</span> <span style="color:#39c">=</span> manualroute
</span></span><span style="display:flex;"><span>    <span style="color:#00cdcd">domains</span> <span style="color:#39c">=</span> hotmail.com:live.nl:live.com:outlook.com:hotmail.nl
</span></span><span style="display:flex;"><span>    <span style="color:#00cdcd">ignore_target_hosts</span> <span style="color:#39c">=</span> 127.0.0.0/8
</span></span><span style="display:flex;"><span>    <span style="color:#00cdcd">condition</span> <span style="color:#39c">=</span> <span style="color:#cd0000">${</span><span style="color:#00cdcd">if</span> !eq{<span style="color:#00cdcd">$original_domain</span><span style="color:#cd0000">}</span><span style="color:#39c">{</span><span style="color:#00cdcd">$domain</span><span style="color:#39c">}}</span>
</span></span><span style="display:flex;"><span>    <span style="color:#00cdcd">condition</span> <span style="color:#39c">=</span> <span style="color:#cd0000">${</span><span style="color:#00cdcd">if</span> !eq{<span style="color:#00cdcd">$original_domain</span><span style="color:#cd0000">}</span><span style="color:#39c">{}}</span>
</span></span><span style="display:flex;"><span>    <span style="color:#00cdcd">condition</span> <span style="color:#39c">=</span> <span style="color:#cd0000">&#34;</span><span style="color:#cd0000">${</span><span style="color:#00cdcd">perl</span>{check_limits<span style="color:#cd0000">}</span><span style="color:#cd0000">}&#34;</span>
</span></span><span style="display:flex;"><span>    
</span></span><span style="display:flex;"><span>    <span style="color:#00cdcd">transport</span> <span style="color:#39c">=</span> remote_smtp_forward_transport
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#00cdcd">route_list</span> <span style="color:#39c">=</span> * smtprelay.domain.com::587
</span></span><span style="display:flex;"><span>    no_more
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>smart_route:
</span></span><span style="display:flex;"><span>    <span style="color:#00cdcd">driver</span> <span style="color:#39c">=</span> manualroute
</span></span><span style="display:flex;"><span>    <span style="color:#00cdcd">domains</span> <span style="color:#39c">=</span> hotmail.com:live.nl:live.com:outlook.com:hotmail.nl
</span></span><span style="display:flex;"><span>    <span style="color:#00cdcd">ignore_target_hosts</span> <span style="color:#39c">=</span> 127.0.0.0/8
</span></span><span style="display:flex;"><span>    <span style="color:#00cdcd">condition</span> <span style="color:#39c">=</span> <span style="color:#cd0000">&#34;</span><span style="color:#cd0000">${</span><span style="color:#00cdcd">perl</span>{check_limits<span style="color:#cd0000">}</span><span style="color:#cd0000">}&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#00cdcd">transport</span> <span style="color:#39c">=</span> remote_smtp
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#00cdcd">route_list</span> <span style="color:#39c">=</span> * smtprelay.domain.com::587
</span></span><span style="display:flex;"><span>    no_more
</span></span></code></pre></div><p>After this, restart the Exim service:</p>
<div class="highlight"><pre tabindex="0" style="color:#ccc;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>service exim restart
</span></span></code></pre></div>]]></content>
        </item>
        
    </channel>
</rss>
