<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Benjamin Rancourt]]></title><description><![CDATA[Thoughts, stories and ideas.]]></description><link>https://www.benjaminrancourt.ca/</link><image><url>https://www.benjaminrancourt.ca/favicon.png</url><title>Benjamin Rancourt</title><link>https://www.benjaminrancourt.ca/</link></image><generator>Ghost 5.74</generator><lastBuildDate>Thu, 28 May 2026 16:37:12 GMT</lastBuildDate><atom:link href="https://www.benjaminrancourt.ca/blog/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[How to Add GitHub Container Registry (ghcr.io) to Portainer Community Edition 🚀]]></title><description><![CDATA[Portainer CE doesn’t support GitHub natively. Here’s the quick workaround to securely pull images from ghcr.io.]]></description><link>https://www.benjaminrancourt.ca/how-to-add-github-container-registry-ghcr-io-to-portainer-community-edition/</link><guid isPermaLink="false">6936f2054034830001ad451a</guid><category><![CDATA[Docker]]></category><category><![CDATA[Portainer]]></category><dc:creator><![CDATA[Benjamin Rancourt]]></dc:creator><pubDate>Mon, 08 Dec 2025 15:59:11 GMT</pubDate><content:encoded><![CDATA[<p>If you&apos;re using <strong>Portainer Community Edition</strong> (CE), most container workflows are smooth&#x2026; until you try pulling images from <strong>GitHub Container Registry (ghcr.io)</strong>.</p><p>Since <strong>GitHub integration is only available in Portainer Business Edition</strong>, many users get stuck wondering how to authenticate with ghcr.io in CE.</p><p>The good news?<br>&#x1F449; <strong>You can easily add ghcr.io as a custom registry using a GitHub Personal Access Token.</strong></p><p>Here&#x2019;s the full step-by-step guide.</p><h2 id="1-create-a-github-personal-access-token-%F0%9F%94%91">1. Create a GitHub Personal Access Token &#x1F511;</h2><p>Portainer needs a token with permission to pull packages from GitHub.</p><h3 id="steps">Steps:</h3><ol><li>Go to: <a href="https://github.com/settings/tokens" rel="noopener">https://github.com/settings/tokens</a>.</li><li>Click <strong>Generate new token</strong> &#x2192; <strong>Generate new token (classic).</strong></li><li>Add a note, such as <em>Portainer.</em></li><li>Set an expiration date (or use <strong>No expiration</strong>, if that fits your risk tolerance).</li><li>Under <em>Scopes</em>, check: <code>read:packages   &#x2192; Allows downloading images from GitHub Container Registry</code>.</li><li>Click <strong>Generate token</strong>, and <strong>copy it immediately</strong> (GitHub won&#x2019;t show it again).</li></ol><h2 id="2-add-ghcrio-as-a-custom-registry-in-portainer-%F0%9F%93%A6">2. Add ghcr.io as a Custom Registry in Portainer &#x1F4E6; </h2><p>Now head to your Portainer instance.</p><h3 id="steps-1">Steps:</h3><ol><li>Go to your registries page, e.g.:<br>&#x1F449; <code>https://portainer.benjaminrancourt.ca/#!/registries</code><br><em>(your own Portainer URL)</em></li><li>Click <strong>+ Add registry</strong>.</li><li>Select <strong>Custom registry</strong>.</li><li>Fill in the following:<ol><li><code>Name: ghcr.io<br>Registry URL: https://ghcr.io</code></li></ol></li><li>Enable <strong>Authentication</strong>.</li><li>Fill in your credentials:<ol><li><code>Username: your GitHub username<br>Password: the token you generated earlier</code></li></ol></li><li>Save. &#x1F389;</li></ol><p>Portainer can now pull both <strong>public and private images</strong> from ghcr.io.</p><h2 id="optional-test-your-registry-%F0%9F%A7%AA">Optional: Test Your Registry &#x1F9EA;</h2><p>Try deploying a stack using a GHCR image:</p><p><code>image: ghcr.io/jonashackt/hello-world:latest</code></p><p>If everything is configured correctly, Portainer will pull the image without errors.</p><h2 id="reference-%F0%9F%93%9A">Reference &#x1F4DA; </h2><p>This tutorial is based on the discussion here:<br><a href="https://github.com/portainer/portainer/issues/12831" rel="noopener">https://github.com/portainer/portainer/issues/12831</a></p><h2 id="%F0%9F%8F%81-conclusion">&#x1F3C1; Conclusion</h2><p>Even though Portainer CE doesn&#x2019;t include built-in GitHub registry support, you can still use <strong>GitHub Container Registry</strong> seamlessly by adding it as a custom registry and authenticating with a GitHub token.</p><p>This simple setup allows you to continue deploying your applications using GHCR without needing the Business Edition.</p>]]></content:encoded></item><item><title><![CDATA[How I Used Traefik to Redirect a Domain to LinkedIn]]></title><description><![CDATA[A quick guide on how I used Traefik to redirect our new domain straight to LinkedIn. Secure, simple, and ready in minutes.]]></description><link>https://www.benjaminrancourt.ca/how-i-used-traefik-to-redirect-a-domain-to-linkedin/</link><guid isPermaLink="false">68cabfeba613620001e40cdd</guid><category><![CDATA[Traefik]]></category><dc:creator><![CDATA[Benjamin Rancourt]]></dc:creator><pubDate>Wed, 17 Sep 2025 14:07:30 GMT</pubDate><content:encoded><![CDATA[<p>Sometimes, when launching an initiative, you don&#x2019;t have a full website ready yet&#x2014;but you still want your shiny new domain name to point somewhere meaningful.</p><p>That&#x2019;s exactly the case for our new event series <strong>Pintes et pizzas pour la plan&#xE8;te</strong>. We recently acquired the domain name <a href="https://www.pintespizzasplanete.eco" rel="noreferrer"><strong>pintespizzasplanete.eco</strong></a> &#x1F30D;&#x1F355;&#x1F37A;, but while the website is still under construction, we wanted visitors to land on our LinkedIn Showcase Page instead of seeing an empty page.</p><p>With <strong>Traefik</strong>, this turned out to be a very simple task. Let me walk you through how I set up a clean redirection.</p><h2 id="the-goal">The Goal</h2><ul><li><strong>Domain:</strong> <code>pintespizzasplanete.eco</code> (and its <code>www</code> variant)</li><li><strong>Destination:</strong> Our LinkedIn Showcase page</li><li><strong>Requirement:</strong> Use HTTPS with Let&#x2019;s Encrypt and keep the redirection permanent.</li></ul><h2 id="the-traefik-setup">The Traefik Setup</h2><p>I&#x2019;m running Traefik with Docker Swarm, so the redirection was handled entirely through labels in a simple service definition.</p><p>Here&#x2019;s the full snippet from my <code>docker-compose.yml</code>:</p><pre><code class="language-yaml">version: &quot;3.8&quot;

services:
  redirect:
    deploy:
      labels:
        traefik.docker.network: &quot;traefik-net&quot;
        traefik.enable: &quot;true&quot;

        # Middleware: regex redirect to LinkedIn
        traefik.http.middlewares.linkedin-redirect.redirectregex.permanent: &quot;true&quot;
        traefik.http.middlewares.linkedin-redirect.redirectregex.regex: &quot;.*&quot;
        traefik.http.middlewares.linkedin-redirect.redirectregex.replacement: &quot;https://www.linkedin.com/showcase/3p-pintes-pizzas-planete/&quot;

        # Router: match our domain and apply middleware
        traefik.http.routers.pintespizzasplanete-redirect.entrypoints: &quot;https&quot;
        traefik.http.routers.pintespizzasplanete-redirect.middlewares: &quot;linkedin-redirect&quot;
        traefik.http.routers.pintespizzasplanete-redirect.rule: &quot;Host(`www.pintespizzasplanete.eco`) || Host(`pintespizzasplanete.eco`)&quot;
        traefik.http.routers.pintespizzasplanete-redirect.tls.certresolver: &quot;letsEncrypt&quot;
        traefik.http.routers.pintespizzasplanete-redirect.tls: &quot;true&quot;

        # Dummy service
        traefik.http.services.pintespizzasplanete-redirect.loadbalancer.server.port: &quot;80&quot;

    image: &quot;traefik/whoami:v1.7.1&quot;
    networks:
      - traefik-net

networks:
  traefik-net:
    driver: overlay
    external: true
</code></pre><h2 id="how-it-works">How It Works</h2><ol><li><strong>The middleware</strong> (<code>linkedin-redirect</code>) catches all requests (<code>.*</code>) and rewrites them to our LinkedIn URL.</li><li><strong>The router</strong> listens for <code>pintespizzasplanete.eco</code> or <code>www.pintespizzasplanete.eco</code>, applies the middleware, and ensures TLS certificates are handled by Let&#x2019;s Encrypt.</li><li><strong>The dummy service (<code>whoami</code>)</strong> doesn&#x2019;t actually serve traffic. It just satisfies Docker&apos;s requirement to have a backend service defined.</li></ol><p>That&#x2019;s it. Now anyone typing our <code>.eco</code> domain will land directly on our LinkedIn Showcase page, until we&#x2019;re ready to launch the real site.</p><h2 id="why-i-like-this-approach">Why I Like This Approach</h2><ul><li><strong>Fast to set up</strong>: Just a few lines of configuration.</li><li><strong>Secure by default</strong>: HTTPS with Let&#x2019;s Encrypt handled automatically.</li><li><strong>Flexible</strong>: When the website is ready, I&#x2019;ll only need to update the router rule to point to the new service instead of LinkedIn.</li></ul><p>&#x1F449; If you&#x2019;re running Traefik already, this is probably the simplest way to make sure your domain name always points somewhere useful&#x2014;even before your website is live.</p>]]></content:encoded></item><item><title><![CDATA[Changing User Language Settings in Microsoft 365 via PowerShell]]></title><description><![CDATA[Managing mailbox language and regional settings in Microsoft 365 is much faster with PowerShell than through the admin portal. This guide walks through installing PowerShell 7, connecting to Exchange Online, and applying consistent language settings for one or all users.]]></description><link>https://www.benjaminrancourt.ca/changing-user-language-settings-in-microsoft-365-via-powershell/</link><guid isPermaLink="false">68c03edea613620001e40cad</guid><category><![CDATA[PowerShell]]></category><dc:creator><![CDATA[Benjamin Rancourt]]></dc:creator><pubDate>Tue, 09 Sep 2025 14:57:18 GMT</pubDate><content:encoded><![CDATA[<p>Recently, I had to help a client who needed all their Microsoft 365 mailboxes switched from French to English (United States), with the correct date and time format for their region (Chicago, Central Standard Time). Since I don&#x2019;t want to reinvent the wheel next time this comes up, I&#x2019;m documenting the steps here for my own future reference, and hopefully, this can also help others.</p><h2 id="step-0-%E2%80%93-make-sure-powershell-7-is-installed">Step 0 &#x2013; Make Sure PowerShell 7 is Installed</h2><p>Although Windows includes PowerShell 5.1 by default, it is strongly recommended to use <strong>PowerShell 7 (PowerShell Core)</strong> when managing Microsoft 365. The newer version provides better module support, security, and compatibility with Microsoft&#x2019;s modern APIs.</p><h3 id="check-your-version">Check your version</h3><p>Run this command in a PowerShell window:</p><pre><code class="language-powershell">$PSVersionTable.PSVersion</code></pre><p>If the <strong>Major</strong> version is less than 7, you should install PowerShell 7.</p><h3 id="install-powershell-7">Install PowerShell 7</h3><ul><li>Download the latest installer from the <a href="https://github.com/PowerShell/PowerShell/releases" rel="noopener">official GitHub releases page</a></li><li>Choose the <strong>MSI package</strong> for Windows (x64 is most common).</li><li>Run the installer, and make sure to check the option <em>&#x201C;Add to PATH&#x201D;</em> so you can easily launch it.</li></ul><p>Once installed, open <strong>PowerShell 7</strong> (you&#x2019;ll see <code>PS C:\&gt;</code> instead of <code>Windows PowerShell</code>) and run the version check again:</p><pre><code class="language-powershell">$PSVersionTable.PSVersion</code></pre><p>You should now see version <strong>7.x</strong> or higher.</p><h2 id="step-1-%E2%80%93-install-the-required-powershell-module">Step 1 &#x2013; Install the Required PowerShell Module</h2><p>Microsoft 365 Exchange Online requires the <strong>Exchange Online PowerShell V2 module</strong> (<code>ExchangeOnlineManagement</code>). If you don&#x2019;t already have it installed, open PowerShell <strong>as Administrator</strong> and run:</p><pre><code class="language-powershell"># Install the Exchange Online Management module
Install-Module ExchangeOnlineManagement</code></pre><h2 id="step-2-%E2%80%93-connect-to-exchange-online">Step 2 &#x2013; Connect to Exchange Online</h2><p>Once the module is installed, connect to your tenant:</p><pre><code class="language-powershell">Connect-ExchangeOnline</code></pre><p>A Microsoft login window will appear. Sign in with an <strong>administrator account</strong> that has the <strong>Exchange Administrator</strong> or <strong>Global Administrator</strong> role.</p><h2 id="step-3-%E2%80%93-change-language-and-regional-settings-for-all-users">Step 3 &#x2013; Change Language and Regional Settings for All Users</h2><p>Now you can update the regional settings for every mailbox. For example, to set the interface language to <strong>English (United States)</strong>, time zone to <strong>Central Standard Time (Chicago)</strong>, and apply US-style date and time formats:</p><pre><code class="language-powershell">Get-Mailbox -ResultSize Unlimited | Set-MailboxRegionalConfiguration `
  -Language en-US `
  -TimeZone &quot;Central Standard Time&quot; `
  -DateFormat &quot;MM/dd/yyyy&quot; `
  -TimeFormat &quot;hh:mm tt&quot;</code></pre><p>This command loops through every mailbox in the tenant and applies the same configuration.</p><h2 id="step-4-%E2%80%93-change-language-for-a-single-user">Step 4 &#x2013; Change Language for a Single User</h2><p>If you only need to update one user, use the <code>-Identity</code> parameter:</p><pre><code class="language-powershell">Set-MailboxRegionalConfiguration -Identity user@domain.com `
  -Language en-US `
  -TimeZone &quot;Central Standard Time&quot; `
  -DateFormat &quot;MM/dd/yyyy&quot; `
  -TimeFormat &quot;hh:mm tt&quot;</code></pre><p>This is useful if only one user has the wrong settings, or if you want to test before applying changes to everyone.</p><h2 id="step-5-%E2%80%93-verify-the-configuration">Step 5 &#x2013; Verify the Configuration</h2><p>You can confirm the settings for a specific user:</p><pre><code class="language-powershell">Get-MailboxRegionalConfiguration -Identity user@domain.com | Format-List</code></pre><p>This will display the current <strong>Language</strong>, <strong>TimeZone</strong>, <strong>DateFormat</strong>, and <strong>TimeFormat</strong> values.</p><h2 id="notes-and-best-practices">Notes and Best Practices</h2><ul><li>These changes apply to <strong>existing users only</strong>. New accounts will need to be configured either manually when created, or by re-running the script.</li><li>Users can still change their own language/time zone in Outlook on the web, unless you enforce policies.</li><li>Always test on one mailbox first before applying changes tenant-wide.</li></ul><h2 id="conclusion">Conclusion</h2><p>By connecting to Exchange Online with PowerShell, you can quickly enforce consistent language and regional settings across all mailboxes in Microsoft 365. This saves a lot of time compared to asking each user to change their own preferences manually, and ensures consistency in date/time formats for your organization.</p>]]></content:encoded></item><item><title><![CDATA[How to Clear DNS Cache and Propagate Changes Quickly]]></title><description><![CDATA[Clear outdated DNS records and accelerate propagation with these simple tools to refresh major DNS caches instantly.]]></description><link>https://www.benjaminrancourt.ca/clear-dns-cache-faster/</link><guid isPermaLink="false">677d4a37a613620001e40c91</guid><dc:creator><![CDATA[Benjamin Rancourt]]></dc:creator><pubDate>Wed, 15 Jan 2025 13:15:56 GMT</pubDate><media:content url="https://www.benjaminrancourt.ca/content/images/2025/01/pexels-sebastiaan9977-1480690.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://www.benjaminrancourt.ca/content/images/2025/01/pexels-sebastiaan9977-1480690.jpg" alt="How to Clear DNS Cache and Propagate Changes Quickly"><p>When updating DNS records for your domain, one common frustration is the delay caused by cached DNS entries. These cached records can cause outdated information to persist, leading to inaccessible websites or incorrect routing. Clearing or forcing a refresh of DNS cache is crucial to ensure that DNS changes propagate swiftly across the internet.</p><h3 id="the-problem">The Problem</h3><p>DNS changes, such as updating an A record, modifying a CNAME, or adjusting MX records, can take time to propagate fully. This delay often stems from DNS resolvers and major name servers holding onto cached data for a specified time (TTL &#x2013; Time to Live). While waiting for these caches to expire naturally, users and visitors might experience disruptions or fail to see the updated records.</p><h3 id="the-solution">The Solution</h3><p>To accelerate the propagation of DNS changes, you can directly force major DNS resolvers to refresh their caches for your domain. This action ensures that updated records are recognized sooner, reducing downtime or access issues. Below are a few key tools for clearing DNS cache with major DNS providers:</p><ol><li><strong>Cloudflare -</strong> <a href="https://1.1.1.1/purge-cache/">https://1.1.1.1/purge-cache/</a></li><li><strong>Google Public DNS </strong>- <a href="https://dns.google/cache">https://dns.google/cache</a></li><li><strong>OpenDNS -</strong> <a href="https://cachecheck.opendns.com/">https://cachecheck.opendns.com/</a></li></ol><h3 id="final-steps">Final Steps</h3><p>After submitting your domain through these tools, DNS changes should propagate more quickly for users relying on these resolvers. Additionally, encourage visitors experiencing issues to clear their local DNS cache by running commands like <code>ipconfig /flushdns</code> (Windows) or <code>sudo dscacheutil -flushcache</code> (macOS).</p><p>By proactively refreshing DNS caches on major resolvers, you can minimize disruptions and ensure a smoother transition when making DNS updates.</p>]]></content:encoded></item><item><title><![CDATA[Quick and Efficient Way to Backup a Remote Folder using Rsync]]></title><description><![CDATA[Rsync stands as a formidable utility. However, to harness its full potential, it's essential to recall the specific arguments that it needs. Herein lies my personal aide-memoire to address this very concern.]]></description><link>https://www.benjaminrancourt.ca/backup-remote-folder-rsync/</link><guid isPermaLink="false">64ef5860428dc70001de7f16</guid><category><![CDATA[bash]]></category><dc:creator><![CDATA[Benjamin Rancourt]]></dc:creator><pubDate>Tue, 05 Sep 2023 11:15:32 GMT</pubDate><media:content url="https://www.benjaminrancourt.ca/content/images/2023/08/pexels-sergei-starostin-6429127.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://www.benjaminrancourt.ca/content/images/2023/08/pexels-sergei-starostin-6429127.jpg" alt="Quick and Efficient Way to Backup a Remote Folder using Rsync"><p>Occasionally, there arises a need for me to download directories stored on my remote server, often for backup purposes. Yet, on each occasion, I find myself scouring the Internet to determine the precise arguments required for the <strong>rsync</strong> utility.</p><p>Those days are now relegated to history, as I have chosen today to write down a future-oriented reminder right here. &#x1F605;</p><p>Without further ado, here is the definitive command to download a remote directory on your computer:</p><figure class="kg-card kg-code-card"><pre><code># Adapt the variables below
SSH_PORT=22
SSH_USER=root
SSH_SERVER=138.197.142.29
REMOTE_SOURCE_DIRECTORY=/var/opt/mealie
LOCAL_DESTINATION_DIRECTORY=.

# From your local machine
rsync \
  --archive \
  --compress \
  --human-readable \
  --partial \
  --progress \
  --rsh &quot;ssh -p ${SSH_PORT}&quot; \
  --stats \
  --verbose \
  &quot;${SSH_USER}@${SSH_SERVER}:${REMOTE_SOURCE_DIRECTORY}&quot; \
  &quot;${LOCAL_DESTINATION_DIRECTORY}&quot;</code></pre><figcaption>An example of the rsync command to download a remote directory.</figcaption></figure><p><strong>Explanation of the arguments</strong></p><ol><li><code>--archive</code>: Preserves file permissions, ownership, timestamps, and more.</li><li><code>--compress</code>: Enables compression of data during transfer, reducing the amount of data transmitted.</li><li><code>--human-readable</code>: File sizes are displayed in a human-readable format (e.g., kB, Mb or gB).</li><li><code>--partial</code>: If the transfer is interrupted, partially transferred files are keep instead of discarding them.</li><li><code>--progress</code>: Displays a progress indicator.</li><li><code>--rsh &quot;ssh -p ${SSH_PORT}&quot;</code>: The communication should be done over SSH using port 22. It is useful if your server use another port for SSH.</li><li><code>--stats</code>: Provides a summary of the transfer statistics once the process is completed.</li><li><code>--verbose</code>: Increases the verbosity of the output, offering more detailed information.</li><li><code>&quot;${SSH_USER}@${SSH_SERVER}:${REMOTE_SOURCE_DIRECTORY}:</code>: The source directory on the remote server that you wish to back up.</li><li><code>&quot;${LOCAL_DESTINATION_DIRECTORY}&quot;</code>: The destination directory on your local machine where the backup will be saved.</li></ol>]]></content:encoded></item><item><title><![CDATA[How to Find the Largest Files and Directories on Debian]]></title><description><![CDATA[Ever experienced the frustration of a server running out of storage space? It can be difficult to locate the problem, unless you have THE command to investigate. 😎]]></description><link>https://www.benjaminrancourt.ca/largest-files-directories/</link><guid isPermaLink="false">64dcd323b4003f0001dede02</guid><category><![CDATA[bash]]></category><dc:creator><![CDATA[Benjamin Rancourt]]></dc:creator><pubDate>Tue, 29 Aug 2023 11:15:22 GMT</pubDate><media:content url="https://www.benjaminrancourt.ca/content/images/2023/08/pexels-tima-miroshnichenko-6549919.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://www.benjaminrancourt.ca/content/images/2023/08/pexels-tima-miroshnichenko-6549919.jpg" alt="How to Find the Largest Files and Directories on Debian"><p>Running out of <strong>server space</strong> can be a real headache, often requiring thorough investigation to pinpoint the issue. In this quick guide, I&apos;ll show you an <strong>invaluable command</strong> that can help you identify the culprits behind <strong>excessive storage consumption</strong> on your Debian server.</p><p>To uncover the largest files and directories eating up your server&apos;s precious space, you can employ the following command:</p><pre><code class="language-bash">sudo du --all / | sort --numeric-sort --reverse | head --lines 15</code></pre><p>Or alternatively:</p><pre><code class="language-bash">sudo du -a / | sort -n -r | head -n 15</code></pre><p>The output of this command provides a list of the <strong>largest files</strong> and <strong>directories</strong>, accompanied by the space they occupy:</p><figure class="kg-card kg-code-card"><pre><code>25072264  /
20175684  /var
8949680   /var/lib
8783876   /var/lib/docker
8629384   /var/lib/docker/overlay2
6131060   /var/log
[...]</code></pre><figcaption>An example of the output of the previous command.</figcaption></figure><p>This resulted list helped me to swiftly identify the storage-intensive elements on my server. Armed with this knowledge, I implemented measures to mitigate their impact and free up valuable space.</p><p>Should you need to delve into a specific directory for a more thorough investigation, the command can be tailored accordingly. For instance, if you want to focus on the <code>/var/log</code> directory:</p><pre><code class="language-bash">sudo du -a /var/log | sort -n -r | head -n 15</code></pre><p>By integrating this command into your diagnostic toolkit, you can confidently tackle storage issues and prevent future space shortages on your server. The satisfaction of maintaining an organized and efficient server environment awaits&#x2014;enjoy the journey! &#x1F60E;</p>]]></content:encoded></item><item><title><![CDATA[Streamlining LinkedIn Verification for Quebec Businesses]]></title><description><![CDATA[In this blog post, I share the documents I provided to LinkedIn to prove that my business was legitimate.]]></description><link>https://www.benjaminrancourt.ca/linkedin-verification-quebec-businesses/</link><guid isPermaLink="false">64da4022ffe2530001626341</guid><dc:creator><![CDATA[Benjamin Rancourt]]></dc:creator><pubDate>Tue, 15 Aug 2023 11:15:45 GMT</pubDate><media:content url="https://www.benjaminrancourt.ca/content/images/2023/08/pexels-airam-datoon-16450744.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://www.benjaminrancourt.ca/content/images/2023/08/pexels-airam-datoon-16450744.jpg" alt="Streamlining LinkedIn Verification for Quebec Businesses"><p>A few weeks ago, I embarked on the journey of obtaining access to the LinkedIn <a href="https://developer.linkedin.com/product-catalog/marketing/community-management-api"><strong>Community Management API</strong></a><strong> </strong>for one of my application. However, I soon discovered that this privilege was exclusively reserved for <strong>verified companies</strong>. &#x1F648;</p><p>As the automatic verification failed for my business, I had to provide some documentation that prove that <strong><a href="https://www.merisia.ca/">Merisia</a></strong> was a <strong>legal business</strong>. And today, I&apos;m excited to share my experience and the key documents I submitted, in case you find yourself in a similar situation:</p><ul><li><strong>Business Registration</strong>: I provided a meticulous screenshot displaying <a href="https://www.registreentreprises.gouv.qc.ca/RQAnonymeGR/GR/GR03/GR03A2_19A_PIU_RechEnt_PC/PageRechSimple.aspx?T1.CodeService=S00436&amp;NEQ=1178573383">Merisia&apos;s entry on the <em>Registraire des entreprises</em></a>.</li><li><strong>Domain Ownership Validation</strong>: I submitted an invoice confirming our ownership of the domain <a href="merisia.ca">merisia.ca</a>.</li><li><strong>Business Tax Identification</strong>: I also included a screenshot detailing our business tax numbers, sourced from <a href="https://www.revenuquebec.ca/fr/entreprises/mon-dossier-pour-les-entreprises/"><em>Mon dossier - Entreprise</em></a>.</li><li><strong>Inclusion in Business Registries</strong>: and to further substantiating our legitimacy, I included a screenshot affirming <a href="https://beta.canadasbusinessregistries.ca/search/results?search=%7BMerisia%7D&amp;status=Active">Merisia&apos;s inclusion in the public Canada&apos;s Business Registries</a>.</li></ul><p>With these meticulously gathered documents, I submitted them to the LinkedIn support team, who then channelled them to their legal department. The subsequent weeks were a waiting game, filled with anticipation. The culmination of this process was the exhilarating moment when <strong>I received confirmation of the granted access</strong>! &#x1F924;</p><p>This experience stands as a testament to the efficacy of providing <strong>comprehensive documentation</strong> to establish the authenticity of a business. If you find yourself navigating the intricacies of verification, take heart from my journey &#x2013; it truly works! &#x1F60E;</p>]]></content:encoded></item><item><title><![CDATA[How to List All Changed Files Inside Docker Containers]]></title><description><![CDATA[Discover how to use the "docker container diff" command to effortlessly identify added, changed, and deleted files within your Docker containers' file systems.]]></description><link>https://www.benjaminrancourt.ca/how-to-list-all-changed-files-inside-docker-containers/</link><guid isPermaLink="false">64779af211087b0001a05daa</guid><category><![CDATA[Docker]]></category><category><![CDATA[bash]]></category><dc:creator><![CDATA[Benjamin Rancourt]]></dc:creator><pubDate>Tue, 20 Jun 2023 11:15:29 GMT</pubDate><media:content url="https://www.benjaminrancourt.ca/content/images/2023/05/pexels-david-dibert-1117210.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://www.benjaminrancourt.ca/content/images/2023/05/pexels-david-dibert-1117210.jpg" alt="How to List All Changed Files Inside Docker Containers"><p>Did you know that you can <strong>easily identify</strong> the <strong>files</strong> that have been <strong>changed</strong> within a <strong><a href="https://www.docker.com/">Docker</a> container&apos;s file system</strong>? This information can be valuable, especially when you want to ensure that all necessary files are backed up and <strong>aren&apos;t lost</strong> when the container restarts. &#x1F644;</p><p>In this article, we will explore how to use the command made available by Docker effectively and even automate the process for multiple containers.</p><h2 id="listing-changed-files-and-directories">Listing changed files and directories</h2><p>To list all the files and directories that have been <strong>added</strong>, <strong>changed</strong>, or <strong>deleted </strong>within a Docker container, you can use the &quot;<strong><a href="https://docs.docker.com/engine/reference/commandline/container_diff/">docker container diff</a></strong>&quot; command. Here is the syntax:</p><figure class="kg-card kg-code-card"><pre><code class="language-bash">docker container diff &lt;CONTAINER_NAME_OR_ID&gt;</code></pre><figcaption>Make sure to replace <code>&lt;CONTAINER_NAME_OR_ID&gt;</code> with the container&apos;s name or ID!</figcaption></figure><p>Here is an example of its output for a <a href="https://mariadb.org/">MariaDB</a> container that I use:</p><figure class="kg-card kg-code-card"><pre><code>C /run
C /run/mysqld
A /run/mysqld/mysqld.pid
A /run/mysqld/mysqld.sock</code></pre><figcaption>Example of the result of a <em>docker container diff</em> command.</figcaption></figure><p>This command will output a list of files and directories that fall into the following categories:</p><ul><li><strong>A</strong>: <em>added</em></li><li><strong>C</strong>: <em>changed</em></li><li><strong>D</strong>: <em>deleted</em></li></ul><h2 id="automating-the-process">Automating the process</h2><p>If you need to perform this check for multiple containers, <em>manually</em> finding and pasting each container&apos;s name or ID can be <strong>time-consuming</strong>. However, you can <strong>automate this process</strong> using the following script:</p><figure class="kg-card kg-code-card"><pre><code class="language-bash">#!/bin/bash

# Get the names of all containers
container_names=$(docker container ls --format &apos;{{.Names}}&apos;)

# Iterate over all container names
for container_name in $container_names
do
    # Execute `docker container diff` on the container
    docker container diff ${container_name}

    # Check if the command was successful or not 
    if [ $? -eq 0 ]
    then
        echo &quot;The command &apos;docker container diff&apos; has been executed with success on container ${container_name}.&quot;
    else
        echo &quot;The command &apos;docker container diff&apos; has failed on container ${container_name}.&quot;
    fi
done</code></pre><figcaption>The Bash script that you can use to list all changed files and directories for all your containers.</figcaption></figure><p>By running this script, you will get the results for <em>all your containers</em>. The output will appear on the standard output, but you can easily modify the script to <em>redirect</em> the results to a <strong>file</strong> or <strong>multiple files</strong> according to your needs. &#x1F609;</p><h2 id="conclusion">Conclusion</h2><p>By utilizing the <code>docker container diff</code> command and the provided script, you now have the ability to identify all the changed files within your Docker containers. This knowledge is crucial for ensuring that all necessary files are appropriately preserved, especially when working with container volumes. &#x1F917;</p>]]></content:encoded></item><item><title><![CDATA[How to Resolve “Pull Access Denied for registry.gitlab.com” Error]]></title><description><![CDATA[Resolving the 'Pull access denied for registry.gitlab.com' error is crucial when migrating private GitLab repositories to a group. Follow these steps to overcome the issue and get your CI/CD pipeline back on track. 🤗]]></description><link>https://www.benjaminrancourt.ca/pull-access-denied-for-registry-gitlab-com/</link><guid isPermaLink="false">6466649f47dd0b0001e71ce3</guid><category><![CDATA[GitLab]]></category><dc:creator><![CDATA[Benjamin Rancourt]]></dc:creator><pubDate>Tue, 13 Jun 2023 11:15:40 GMT</pubDate><media:content url="https://www.benjaminrancourt.ca/content/images/2023/05/pexels-sarah-chai-7262478.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://www.benjaminrancourt.ca/content/images/2023/05/pexels-sarah-chai-7262478.jpg" alt="How to Resolve &#x201C;Pull Access Denied for registry.gitlab.com&#x201D; Error"><p>If you&apos;re migrating your <strong>private GitLab repositories</strong> to a <strong>group</strong>, like I did for my <a href="https://www.merisia.ca/">personal business</a>, you may encounter an error message like this in your pipelines:</p><pre><code>WARNING: Failed to pull image with policy &quot;always&quot;: Error response from daemon: pull access denied for registry.gitlab.com/merisia/tools/git-rsync, repository does not exist or may require &apos;docker login&apos;: denied: requested access to the resource is denied (manager.go:237:0s)

ERROR: Job failed: failed to pull image &quot;registry.gitlab.com/merisia-inc/outils/git-rsync:1.2.0&quot; with specified policies [always]: Error response from daemon: pull access denied for registry.gitlab.com/merisia/tools/git-rsync, repository does not exist or may require &apos;docker login&apos;: denied: requested access to the resource is denied (manager.go:237:0s)</code></pre><p>Despite confirming that the URL and tag exist in the repository&apos;s Container Registry, the problem persists. &#x1F613;</p><p>After conducting some research, I discovered a related <a href="https://stackoverflow.com/questions/65097315/pull-access-denied-for-registry-gitlab-com-when-the-project-is-transfered-to-a-g">StackOverflow question</a> where another user faced a similar issue. Although no solution was provided, I stumbled upon a <strong>helpful clue</strong>. The user encountered the same issue when <strong>moving a private repository to a group</strong>. &#x1F914;</p><p>The thread mention the <code>DOCKER_AUTH_CONFIG</code> variable, which picked my curiosity. So I began to look on it and I found <a href="https://microfluidics.utoronto.ca/gitlab/help/ci/docker/using_docker_images.md#define-an-image-from-a-private-container-registry">this documentation</a> from a team of UToronto that helped me solve my problem. &#x1F929;</p><p>As it&apos;s not impossible that I encountered again this problem in a distant future,I decided to <strong>share the solution I used</strong> through this blog post. I&apos;ll skip the detailed explanations, since the UToronto team has already covered the necessary commands. &#x1F917;</p><h2 id="solution">Solution</h2><h3 id="encode-your-gitlab-credentials-in-base64">Encode your GitLab credentials in base64</h3><pre><code class="language-bash"># The use of &quot;-n&quot; - prevents encoding a newline in the password.
echo -n &apos;GITLAB_USERNAME:GITLAB_PASSWORD&apos; | base64</code></pre><p></p><h3 id="create-the-dockerauthconfig-variable-in-your-cicd-group-settings">Create the DOCKER_AUTH_CONFIG variable in your CI/CD group settings</h3><ul><li>Go to your GitLab group (or project).</li><li>Under <code>Settings</code> &gt; <code>CI/CD</code> &gt; <code>Variable</code>, click the <code>Add variable</code> button.</li><li>Set the key as <code>DOCKER_AUTH_CONFIG</code> and set the content with the following JSON:</li></ul><pre><code class="language-json">{
    &quot;auths&quot;: {
        &quot;registry.gitlab.com&quot;: {
            &quot;auth&quot;: &quot;(Base64 content from above)&quot;
        }
    }
}
</code></pre><ul><li>Make sure to uncheck the <code>Protect variable</code> and <code>Expand variable reference</code> options as they are optionals.</li><li>Click the <code>Add variable</code> button to create this new variable.</li></ul><h2 id="rerun-your-previously-failed-cicd-pipeline">Rerun your previously failed CI/CD pipeline</h2><p>By following the previous steps, your pipeline should now be back on track! &#x1F973;</p><p>If the issue persists, you can <strong>retry</strong> the previous steps or <strong>continue searching</strong> for an <strong>alternative solution</strong>! &#x1F605;</p>]]></content:encoded></item><item><title><![CDATA[How to Update Ubuntu in WSL from 18.04 to 22.04]]></title><description><![CDATA[Are you stuck with Ubuntu 18.04 for your WSL distribution? In this article, I finally managed to upgrade to the latest LTS version! 😎]]></description><link>https://www.benjaminrancourt.ca/how-to-update-ubuntu-in-wsl-from-18-04-to-22-04/</link><guid isPermaLink="false">64188a457e8210000134ec76</guid><category><![CDATA[bash]]></category><dc:creator><![CDATA[Benjamin Rancourt]]></dc:creator><pubDate>Tue, 02 May 2023 11:15:56 GMT</pubDate><media:content url="https://www.benjaminrancourt.ca/content/images/2023/03/pexels-monica-silvestre-3562689.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://www.benjaminrancourt.ca/content/images/2023/03/pexels-monica-silvestre-3562689.jpg" alt="How to Update Ubuntu in WSL from 18.04 to 22.04"><p>For a long time, I was <strong>not able to run </strong><a href="https://nodejs.org/en"><strong>Node.js</strong></a><strong> 18</strong> on my desktop. When I choose one of its version with <a href="https://github.com/nvm-sh/nvm">nvm</a>, I always ran into an error stating that a library was missing: <code>node: /lib/x86_64-linux-gnu/libc.so.6: version &apos;GLIBC_2.28&apos; not found (required by node)</code>. I was stuck with the latest Node.js 16 version available... &#x1F625;</p><p>But, it was something that was bothered me. I couldn&apos;t use the <strong>new features</strong> of Node.js LTS version, and I hopped that somehow, it would resolve by itself. <em>Disclaimer</em>: it hasn&apos;t. I tried from time to time to upgrade, but my attempts have been unsuccessful. Until now. &#x1F62E;</p><p>I&apos;m now happy to says that I manage <strong>to install</strong> and <strong>to use</strong> Node.js 18. How? By <strong>upgrading my <a href="https://ubuntu.com/">Ubuntu</a> version</strong> of <a href="https://learn.microsoft.com/en-us/windows/wsl/install">Windows Subsystem for Linux</a> (WSL) from 18.04 to 22.04. After a new search, I stumbled on <a href="https://stackoverflow.com/a/74586477">this answer on StackOverflow</a> from <a href="https://stackoverflow.com/users/20609953/hallexcosta">hallexcosta</a> and it worked for me! I was able to <strong>update to Ubuntu 20.04</strong> and with <a href="https://askubuntu.com/questions/1428423/upgrade-ubuntu-in-wsl2-from-20-04-to-22-04">another answer</a> by <a href="https://askubuntu.com/users/1165986/notthedr01ds">NotTheDr01ds</a>, I updated to <strong>Ubuntu 22.04</strong> as well. So, thanks a lot to these people! &#x1F970;</p><p>As it&apos;s possible that I would need to update my WSL distribution on another computer, I decided to <strong>write here</strong> the commands I used <em>for posterity</em>. It could also be useful for you if you aren&apos;t either on the latest version of Ubuntu. &#x1F609;</p><p>Without further ado, here is the <strong>complete procedure</strong>. &#x1F917;</p><h2 id="from-1804-to-2004">From 18.04 to 20.04</h2><p>Before continuing, make sure that <strong>you aren&apos;t</strong> on the <a href="https://ubuntu.com/download/desktop">latest version of Ubuntu</a> by running the following command in your WSL terminal:</p><figure class="kg-card kg-code-card"><pre><code class="language-bash">lsb_release -a

# No LSB modules are available.     
# Distributor ID: Ubuntu
# Description:    Ubuntu 18.04.6 LTS
# Release:        18.04
# Codename:       bionic</code></pre><figcaption>Make sure that you&apos;re using Ubuntu 18 with the <code>lsb_release</code> command.</figcaption></figure><div class="kg-card kg-callout-card kg-callout-card-red"><div class="kg-callout-emoji">&#x1F4A3;</div><div class="kg-callout-text">Sometimes, I&apos;m a little bit reckless, so I <strong>didn&apos;t do a backup</strong>. But if you don&apos;t want to take the same risks that I took, hallexcosta also provide the steps to <strong>create </strong>and <strong>restore </strong>a backup. &#x1F609;</div></div><h3 id="remove-the-snapd-package">Remove the Snapd package</h3><blockquote>&quot;For me it was necessary to remove the <code>snapd</code> package, because ubuntu was not allowing me to upgrade to 20.04 LTS version.&quot; &#x2013; hallexcosta</blockquote><p>As I didn&apos;t want to take any chances, I <strong>uninstall </strong>as well the <strong>Snapd package</strong>. I don&apos;t know if it would have made a difference for me, but just to be sure... &#x1F60B;</p><figure class="kg-card kg-code-card"><pre><code class="language-bash">sudo apt purge snapd</code></pre><figcaption>This command remove and delete the snapd package, along with its configuration files.</figcaption></figure><p>According to <a href="https://en.wikipedia.org/wiki/Snap_(software)">its Wikipedia page</a>, <strong>snapd </strong>is a tool used to package and to deploy applications. The procedure doesn&apos;t reinstall it, but at least, it is noted here that it has been removed. To add it back should be simple <strong>if it is needed</strong>. &#x1F643;</p><h3 id="update-and-upgrade-packages">Update and upgrade packages</h3><p>Always make sure that the operating system is <strong>up-to-date</strong> before taking a major upgrade! &#x1F604;</p><figure class="kg-card kg-code-card"><pre><code class="language-bash"># Get updated software list for Ubuntu
sudo apt update

# Apply updates and patches
sudo apt upgrade</code></pre><figcaption>The default commands to update all packages.</figcaption></figure><h3 id="install-the-update-manger-core-package">Install the update-manger-core package</h3><blockquote>&quot;It&#x2019;s essential to install this update manager core package this will trick the system into thinking there is a new LTS available and allow you to do an in-place upgrade.&quot; &#x2013; hallexcosta</blockquote><p>Again, I proceed exactly as I&apos;ve been told. I wanted to quickly see if the procedure would work for me. &#x1F605;</p><pre><code class="language-bash">sudo apt install update-manager-core</code></pre><p><a href="https://packages.ubuntu.com/bionic/admin/update-manager-core">update-manager-core</a> seems to be a simple package that manage release upgrades...</p><h3 id="install-the-new-version">Install the new version</h3><figure class="kg-card kg-code-card"><pre><code class="language-bash"># Update Ubuntu
sudo do-release-upgrade</code></pre><figcaption>This command will check if there is a new version and will proceed to install it.</figcaption></figure><p>The command should take a <strong>couple of minutes</strong> to run. In my case, it has more than 600 MB to download. Go take a walk or grab a drink; once it&apos;s finished it will ask for a confirmation. &#x1F609;</p><h3 id="restart">Restart</h3><p><strong>Restart your computer</strong> to make sure everything has been updated and <strong>check</strong> if Ubuntu has been updated by typing the following command:</p><figure class="kg-card kg-code-card"><pre><code class="language-bash">lsb_release -a

# No LSB modules are available.     
# Distributor ID: Ubuntu
# Description:    Ubuntu 20.04.5 LTS
# Release:        20.04
# Codename:       focal</code></pre><figcaption>You should now see that Ubuntu has been updated to 20.04, the next major LTS version after 18.04.</figcaption></figure><p>Unfortunately, at the time of writing this article, Ubuntu 20.04 <em>is not</em> the latest LTS version. But the steps from passing to Ubuntu 22.04 are smaller than those before. Let&apos;s see them. &#x1F917;</p><h2 id="from-2004-to-2204">From 20.04 to 22.04</h2><p>With the <strong>three following commands</strong>, you should be able to upgrade to the latest LTS version:</p><figure class="kg-card kg-code-card"><pre><code class="language-bash"># Get updated software list for Ubuntu
sudo apt update

# Apply updates and patches
sudo apt upgrade

# Update Ubuntu
sudo do-release-upgrade</code></pre><figcaption>You may recognize some commands that we have used to install Ubuntu 20.04.</figcaption></figure><p>Again, <strong>restart your computer</strong> and check if your Ubuntu distribution has been upgraded:</p><figure class="kg-card kg-code-card"><pre><code class="language-bash">lsb_release -a

# No LSB modules are available.     
# Distributor ID: Ubuntu
# Description:    Ubuntu 22.04.2 LTS
# Release:        22.04
# Codename:       jammy</code></pre><figcaption>We are now on the latest LTS version of Ubuntu! &#x1F973;</figcaption></figure><p>When Ubuntu 24.04 will be released, I hope that the previous procedure remains the same, as it&apos;s really simple. &#x1F91E;</p><h2 id="conclusion">Conclusion</h2><p>After <strong>upgrading to Ubuntu 22.04</strong>, you should now be able to <strong>use Node.js 18</strong> on your computer. Install it if it&apos;s not already done and run a simple command to check if the error about the missing library is gone.</p><pre><code class="language-bash"># Install the Node.js latest version available
nvm install 18.15.0

# Check if Node.js is able to run without errors
node --version
# v18.15.0</code></pre><p><strong>Thanks </strong>again to <a href="https://stackoverflow.com/users/20609953/hallexcosta">hallexcosta</a> and <a href="https://askubuntu.com/users/1165986/notthedr01ds">NotTheDr01ds</a>! &#x1F970;</p>]]></content:encoded></item><item><title><![CDATA[How to Redirect a Domain to Another Domain with Traefik]]></title><description><![CDATA[In this blog post, you will learn how to use Traefik to redirect traffic from one domain to another temporarily.]]></description><link>https://www.benjaminrancourt.ca/how-to-redirect-a-domain-to-another-domain-with-traefik/</link><guid isPermaLink="false">641e0878b7496b000104a985</guid><category><![CDATA[Traefik]]></category><dc:creator><![CDATA[Benjamin Rancourt]]></dc:creator><pubDate>Tue, 11 Apr 2023 11:15:53 GMT</pubDate><media:content url="https://www.benjaminrancourt.ca/content/images/2023/03/pexels-yevhen-sukhenko-11921224.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://www.benjaminrancourt.ca/content/images/2023/03/pexels-yevhen-sukhenko-11921224.jpg" alt="How to Redirect a Domain to Another Domain with Traefik"><p>One month ago, I submitted a <strong>business plan</strong> as part of the <a href="https://www.osentreprendre.quebec/defi-osentreprendre/"><strong>Defi OSEntreprendre</strong></a>, using a <strong>new domain</strong> that I had not yet created a website for. I was worried that if a member of the jury clicked on one of my links, they would encounter a <strong>404 error page</strong>, which would not be great for my project&apos;s credibility. &#x1F643;</p><p>To buy myself some time, I decided to <strong>redirect the whole website</strong> to my <strong>existing website</strong>, where I could temporarily host the content for the challenge. </p><p>Initially, I tried to create a solution that would allow me to create multiple redirects, but it didn&apos;t work out. Instead, I created a <strong>quick proof-of-concept</strong> using <a href="https://doc.traefik.io/traefik/"><strong>Traefik</strong></a>, a tool I often use in my infrastructure. &#x1F60E;</p><h2 id="solution">Solution</h2><p>Here is the final solution I came up with using Traefik:</p><pre><code class="language-yaml">version: &quot;3.8&quot;

services:
  merisia:
    # As we are using Docker Swarm, labels need to be set inside deploy
    deploy:
      labels:
        traefik.docker.network: &quot;traefik-net&quot;
        traefik.enable: &quot;true&quot;
        traefik.http.routers.merisia.entrypoints: &quot;https&quot;
        traefik.http.routers.merisia.middlewares: &quot;redirect-merisia-benjaminrancourt,default@file&quot;
        traefik.http.routers.merisia.rule: &quot;Host(`merisia.ca`,`www.merisia.ca`)&quot;
        traefik.http.routers.merisia.tls.certresolver: &quot;letsEncrypt&quot;
        traefik.http.routers.merisia.tls.options: &quot;intermediate@file&quot;
        traefik.http.routers.merisia.tls: &quot;true&quot;
        traefik.http.services.merisia.loadbalancer.server.port: 80
        traefik.http.services.merisia.loadbalancer.sticky.cookie.httpOnly: &quot;true&quot;
        traefik.http.services.merisia.loadbalancer.sticky.cookie.secure: &quot;true&quot;
        traefik.http.middlewares.redirect-merisia-benjaminrancourt.redirectregex.regex: &quot;^https?://(www\\.)?merisia\\.ca/(.*)&quot;
        traefik.http.middlewares.redirect-merisia-benjaminrancourt.redirectregex.replacement: &quot;https://www.benjaminrancourt.ca/$${2}&quot;
        traefik.http.middlewares.redirect-merisia-benjaminrancourt.redirectregex.permanent: &quot;false&quot;
      resources:
        limits:
          cpus: &apos;0.750&apos;
          memory: 16M
        reservations:
          cpus: &apos;0.001&apos;
          memory: 6M
    # https://hub.docker.com/r/traefik/whoami/tags?page=1&amp;ordering=last_updated
    image: &quot;traefik/whoami:v1.8.7&quot;
    networks:
      - traefik-net

networks:
  traefik-net:
    driver: overlay
    external: true
</code></pre><p>Let me explain how this solution works below. &#x1F609;</p><h2 id="explanations">Explanations</h2><div class="kg-card kg-callout-card kg-callout-card-yellow"><div class="kg-callout-emoji">&#x1F4A3;</div><div class="kg-callout-text"><strong>Note</strong>: to improve the readability of the code, I removed the <strong>indentation </strong>and renamed the <strong>middleware </strong>as <code>redirection</code>. Because of that, the excerpts below would not work with the solution above without modification.</div></div><h3 id="1-%E2%80%93-router-rule">1 &#x2013; Router rule</h3><pre><code class="language-yaml">traefik.http.routers.merisia.rule: &quot;Host(`merisia.ca`,`www.merisia.ca`)&quot;</code></pre><p>This rule tells Traefik the <strong>original domain</strong> to redirect from. In this case, the domain is <a href="https://merisia.ca/">merisia.ca</a> and its subdomain is <a href="https://www.merisia.ca/">www</a>. </p><h3 id="2-%E2%80%93-redirect-regex-middleware">2 &#x2013; Redirect regex middleware</h3><pre><code class="language-yaml"> traefik.http.middlewares.redirection.redirectregex.regex: &quot;^https?://(www\\.)?merisia\\.ca/(.*)&quot;
 traefik.http.middlewares.redirection.redirectregex.replacement: &quot;https://www.benjaminrancourt.ca/$${2}&quot;
 traefik.http.middlewares.redirection.redirectregex.permanent: &quot;false&quot;</code></pre><p>The regex <strong>redirects </strong>the original traffic to the <strong>replacement domain</strong>. It captures the original traffic using a <strong>regular expression</strong> (in <code>regex</code>) and redirects it to the replacement domain using a replacement pattern (in <code>replacement</code>).</p><p>The regex is designed to work with both <strong>HTTP </strong>and <strong>HTTPS </strong>(<code>^https?://</code>) and to capture all traffic that come from its <code>www</code> <strong>subdomain</strong> and its <strong>bare domain</strong> (<code>(www\\.)?</code>). All dots were also escaped accordingly (<code>\\.</code>).</p><p>The <strong>pathname </strong>is captured in the <strong>second </strong>and last <strong>capture group</strong> (<code>$${2}</code>).</p><h3 id="3-%E2%80%93-middlewares">3 &#x2013; Middlewares</h3><p>This label tells Traefik to use the <strong>previous <a href="https://doc.traefik.io/traefik/middlewares/overview/">middleware</a></strong>.</p><figure class="kg-card kg-code-card"><pre><code class="language-yaml">traefik.http.routers.merisia.middlewares: &quot;redirection,default@file&quot;</code></pre><figcaption>Two middlewares is used here: our redirect middleware and the unknown <code>default</code> from the configuration file.</figcaption></figure><h3 id="4-%E2%80%93-image">4 &#x2013; Image</h3><p>And finally, we also need to have a container that simply exists, as I don&apos;t think it&apos;s possible to have a docker-compose stack <strong>without a container</strong>! &#x1F605;</p><pre><code class="language-yaml">image: &quot;traefik/whoami:v1.8.7&quot;</code></pre><p>The <a href="https://hub.docker.com/r/traefik/whoami">traefik/whoami</a> image is a <strong>tiny web server</strong> that prints OS information and HTTP request to output. But, if you have configured everything correctly, you should never see its output, as you should be redirected to your second domain! &#x1F609;</p><h2 id="conclusion">Conclusion</h2><p>In my case, the previous solution has helped me to have <a href="https://www.merisia.ca/linkedin">www.merisia.ca/linkedin</a> temporarily redirect to <a href="https://www.benjaminrancourt.ca/linkedin">www.benjaminrancourt.ca/linkedin</a>, which finally redirect to my personal LinkedIn profile. I also had some others links, but I&apos;m not able to disclosure yet. &#x1F605;</p><p>So, if you use <strong>Traefik</strong>, you now have a solution to <strong>temporarily redirect traffic from one domain to another</strong>. &#x1F609;</p><p>Good luck! &#x1F60E;</p>]]></content:encoded></item><item><title><![CDATA[How to Completely Uninstall Docker]]></title><description><![CDATA[In this article, you'll learn step-by-step on how to completely remove Docker from a Debian-based Linux system.]]></description><link>https://www.benjaminrancourt.ca/how-to-completely-uninstall-docker/</link><guid isPermaLink="false">64121188adebd10001b50e85</guid><category><![CDATA[Docker]]></category><dc:creator><![CDATA[Benjamin Rancourt]]></dc:creator><pubDate>Tue, 21 Mar 2023 11:15:46 GMT</pubDate><media:content url="https://www.benjaminrancourt.ca/content/images/2023/03/pexels-karolina-grabowska-4239146.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://www.benjaminrancourt.ca/content/images/2023/03/pexels-karolina-grabowska-4239146.jpg" alt="How to Completely Uninstall Docker"><p>Last week, I was looking to recreate my <strong>personal infrastructure</strong> on a new server, but somehow, I <em>screwed</em> something in the process and was left with a Docker container that I could not delete... &#x1F648;</p><p>Something similar had already happened to me in the past, and the fix that I had found in that time was to <strong>completely remove</strong> and <strong>reinstall Docker</strong>. &#x1F92F;</p><p>As I was only at the beginning of my process and didn&apos;t want to lose any more time, I decided to <strong>choose again</strong> this solution. But, my previous notes were a little bit <em>scrambled</em>, so I decided to improve them and to <strong>share them with you</strong>. Just in case you need it! &#x1F609;</p><p>So, without further ado, here is the <strong>complete procedure</strong> with some explanations if you want to learn more! &#x1F60E;</p><div class="kg-card kg-callout-card kg-callout-card-yellow"><div class="kg-callout-emoji">&#x1F4A1;</div><div class="kg-callout-text">In this procedure, my <strong>Linux distribution</strong> is <a href="https://www.debian.org/index.en.html"><strong>Debian</strong></a>. If you use another distribution, you may need to <strong>modify </strong>the commands as they could be not suitable for you distribution.<br><br>And to remove the need of <code>sudo</code> before each command, I suggest that you run these command as <code>root</code> (with <code>sudo su -</code>). &#x1F609;</div></div><h2 id="step-1-%E2%80%93-remove-docker-images-containers-and-volumes">Step 1 &#x2013; Remove Docker images, containers, and volumes</h2><p>To completely remove Docker from your system, you&apos;ll need to remove any <strong>images</strong>, <strong>containers</strong>, and <strong>volumes </strong>that were created. To do this, use the following commands:</p><figure class="kg-card kg-code-card"><pre><code class="language-bash"># Remove unused data
docker system prune --all --volumes

# Remove all services
docker service rm $(docker service ls -q)

# Remove all containers
docker rm -f $(docker ps -aq)

# Remove all images
docker rmi -f $(docker images -aq)

# Remove all volumes
docker volume rm $(docker volume ls -q)</code></pre><figcaption>Remove all data created and managed by Docker.</figcaption></figure><h2 id="step-2-%E2%80%93-stop-docker-service">Step 2 &#x2013; Stop Docker service</h2><p>Before removing Docker from your system, you should <strong>stop the Docker service</strong> by running the following command:</p><figure class="kg-card kg-code-card"><pre><code class="language-bash">systemctl stop docker</code></pre><figcaption>Shut down Docker.</figcaption></figure><p>This will ensure that Docker is <strong>not running</strong> in the <strong>background </strong>while you&apos;re removing it. &#x1F609;</p><h2 id="step-3-%E2%80%93-uninstall-docker">Step 3 &#x2013; Uninstall Docker</h2><p>It&apos;s now time to <strong>remove Docker</strong> from the operating system. Run the followings commands:</p><figure class="kg-card kg-code-card"><pre><code class="language-bash"># Uninstalls the Docker Community Edition (docker-ce) package from your Debian system
apt-get purge docker-ce -y

# Removes any remaining Docker packages and their dependencies that were not automatically removed by the previous command
apt-get autoremove --purge docker-ce -y</code></pre><figcaption>Uninstall Docker without prompts.</figcaption></figure><p>This will remove any packages that were installed as <strong>dependencies of Docker</strong> but are no longer needed.</p><h2 id="step-5-%E2%80%93-remove-docker-group-optional">Step 5 &#x2013; Remove Docker group (optional)</h2><p>If you had previously added users to the <a href="https://docs.docker.com/engine/install/linux-postinstall/#manage-docker-as-a-non-root-user"><strong>Docker users group</strong></a> to allow them to run Docker commands without <code>sudo</code>, you may want to remove the Docker group as well. Use the following command:</p><figure class="kg-card kg-code-card"><pre><code class="language-bash">groupdel docker</code></pre><figcaption>This command will also remove the <code>docker</code> group from all users.</figcaption></figure><h2 id="step-4-%E2%80%93-remove-docker-directories">Step 4 &#x2013; Remove Docker directories </h2><p>Next, you&apos;ll need to <strong>remove </strong>any <strong>directories associated</strong> with Docker, including its configuration files and its <a href="https://docs.docker.com/storage/storagedriver/">storage location</a>. Use the following commands:</p><figure class="kg-card kg-code-card"><pre><code class="language-bash"># Remove the Docker configuration files
rm -rf /etc/docker

# Remove the Docker Daemon&apos;s storage location
rm -rf /var/lib/docker</code></pre><figcaption>Remove all directories created and used by Docker.</figcaption></figure><h2 id="conclusion">Conclusion</h2><p>And that&apos;s it! You&apos;ve now <strong>completely removed Docker</strong> from your system, along with any associated files and directories. &#x1F60E;</p><p>If you want to <strong>reinstall</strong> Docker, you may now run the same commands as you typed when you installed it before! &#x1F609;</p>]]></content:encoded></item><item><title><![CDATA[Sustainable Acceptance Criteria 🌳]]></title><description><![CDATA[Do you write acceptance criteria for your user stories? Do you have any that relate to the environment and performance of your website?]]></description><link>https://www.benjaminrancourt.ca/sustainable-acceptance-criteria/</link><guid isPermaLink="false">6397d3490d0cf600019751cd</guid><dc:creator><![CDATA[Benjamin Rancourt]]></dc:creator><pubDate>Tue, 13 Dec 2022 12:15:54 GMT</pubDate><media:content url="https://www.benjaminrancourt.ca/content/images/2022/10/pexels-pixabay-45863.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://www.benjaminrancourt.ca/content/images/2022/10/pexels-pixabay-45863.jpg" alt="Sustainable Acceptance Criteria &#x1F333;"><p>I write many <strong>user stories</strong> as part of my work and my entrepreneurial project. For each of them, I list all the <strong>acceptance criteria</strong> that will allow us to determine if the features have been <strong>successfully</strong> implemented. &#x2611;&#xFE0F;</p><p>To <strong>reduce</strong> the <strong>carbon footprint</strong> of the products that are developed, I have started to integrate more and more <strong>eco-responsible acceptance criteria</strong>. &#x1F343;</p><p>These acceptance criteria stand out from the others because they focus on the <strong>environment</strong>. Specifically, they are intended to <strong>reduce the data needed</strong> to <strong>operate</strong> the website (or web application).</p><p>By <strong>minimizing this data</strong>, all the infrastructures on which they transact use <strong>less memory</strong> and <strong>electricity</strong>. &#x26A1;</p><p>Did I pique your curiosity? &#x1F61C;</p><h2 id="examples-of-sustainable-acceptance-criteria"><strong>Examples of s</strong>ustainable<strong> acceptance criteria</strong></h2><p>If you are wondering <strong>what</strong> these famous criteria might look like, here are some <strong>real examples</strong> that I regularly put in my user stories:</p><ul><li>Only the data necessary for the application operation are <strong>transmitted</strong> between the different computer systems. &#x1F5A5;</li><li><strong>Data</strong> is <strong>cached</strong> for as <strong>long as</strong> possible. &#x1F648;</li><li>All <strong>caches</strong> are <strong>invalidated</strong> at the appropriate time, such as when updating data or computer systems.</li><li><strong><a href="https://en.wikipedia.org/wiki/SVG">SVG vector images</a></strong> are <a href="https://www.benjaminrancourt.ca/how-to-optimize-your-svgs-with-svgomg/"><strong>optimized</strong> with <strong>SVGOMG</strong></a><strong> </strong>so there is no perceptible difference to the naked eye. &#x1F441;&#xFE0F;</li><li>Images<strong> are available in more compressed</strong> formats than traditional ones, such as <a href="https://en.wikipedia.org/wiki/WebP">WebP</a> and <a href="https://en.wikipedia.org/wiki/AVIF">AVIF</a>. &#x1F5BC;</li><li><strong>Resources</strong> are <strong>compressed in <a href="https://en.wikipedia.org/wiki/Gzip">gzip</a> </strong>and <strong><a href="https://en.wikipedia.org/wiki/Brotli">Brotli</a></strong> formats. &#x1F5DC;&#xFE0F;</li><li>JavaScript, HTML and CSS <strong>files are minified</strong> and <em><strong><a href="https://www.quora.com/What-does-uglify-mean">uglified</a></strong></em>.</li></ul><p>Of course, these acceptance criteria are not <strong>always applicable</strong> to all user stories. Some of them are mainly intended for the <strong>design of the product</strong> itself. &#x1F609;</p><h2 id="conclusion"><strong>Conclusion</strong></h2><p>Now that you know that it is possible to write <strong>eco-responsible acceptance criteria</strong>, do you plan to add them to your next user stories? &#x1F917;</p>]]></content:encoded></item><item><title><![CDATA[How to Optimize Your SVGs with SVGOMG]]></title><description><![CDATA[Just like any image on the web, we need to compress and optimize our SVGs to deliver as few bytes as possible to our users. Let's see here how to optimize them with SVGOMG.]]></description><link>https://www.benjaminrancourt.ca/how-to-optimize-your-svgs-with-svgomg/</link><guid isPermaLink="false">6342d698048eb70001aca9ec</guid><dc:creator><![CDATA[Benjamin Rancourt]]></dc:creator><pubDate>Tue, 08 Nov 2022 12:15:43 GMT</pubDate><media:content url="https://www.benjaminrancourt.ca/content/images/2022/03/pexels-amar-preciado-9969537.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://www.benjaminrancourt.ca/content/images/2022/03/pexels-amar-preciado-9969537.jpg" alt="How to Optimize Your SVGs with SVGOMG"><p>Are you able to determine the difference between the two images below? Is it the same picture?</p><figure class="kg-card kg-gallery-card kg-width-wide kg-card-hascaption"><div class="kg-gallery-container"><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="https://www.benjaminrancourt.ca/content/images/2022/03/favicon-1.svg" width="48" height="48" loading="lazy" alt="How to Optimize Your SVGs with SVGOMG"></div><div class="kg-gallery-image"><img src="https://www.benjaminrancourt.ca/content/images/2022/03/favicon.min.svg" width="48" height="48" loading="lazy" alt="How to Optimize Your SVGs with SVGOMG"></div></div></div><figcaption>Take a close look at these two images. Do you see any differences? &#x1F914;</figcaption></figure><p>You probably guessed it, but it&apos;s not the same picture! The image on the right is actually an <strong>optimized version</strong> of the original image on the left.</p><p>This improvement was made manually using a tool I discovered this year in on of the latest <a href="https://frontendfoc.us/issues/534"><em>Frontend Focus</em></a> newsletter: <strong><a href="https://jakearchibald.github.io/svgomg/">SVGOMG</a></strong>.</p><p>SVGOMG is the <strong>M</strong>issing <strong>Graphical user interface </strong><em>of</em> a Node.js tool specialized in <strong>optimizing SVG</strong> files, named <strong><em><a href="https://www.npmjs.com/package/svgo">SVGO</a></em></strong>.</p><p>SVGOMG&apos;s interface is straightforward to use and can be summarized in three steps:</p><ul><li>Upload your SVG image</li><li>Play with the different controls offered to have an almost identical image, but with a lower weight than the original image</li><li>Download the resulting SVG image</li></ul><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.benjaminrancourt.ca/content/images/2022/03/svgomg.jpg" class="kg-image" alt="How to Optimize Your SVGs with SVGOMG" loading="lazy" width="1916" height="949" srcset="https://www.benjaminrancourt.ca/content/images/size/w600/2022/03/svgomg.jpg 600w, https://www.benjaminrancourt.ca/content/images/size/w1000/2022/03/svgomg.jpg 1000w, https://www.benjaminrancourt.ca/content/images/size/w1600/2022/03/svgomg.jpg 1600w, https://www.benjaminrancourt.ca/content/images/2022/03/svgomg.jpg 1916w" sizes="(min-width: 720px) 720px"><figcaption><font style="border-color: var(--gray-200); border-style: solid; border-width: 0px; box-sizing: border-box; --tw-border-spacing-x:0; --tw-border-spacing-y:0; --tw-translate-x:0; --tw-translate-y:0; --tw-rotate:0; --tw-skew-x:0; --tw-skew-y:0; --tw-scale-x:1; --tw-scale-y:1; --tw-pan-x:; --tw-pan-y:; --tw-pinch-zoom:; --tw-scroll-snap-strictness:proximity; --tw-ordinal:; --tw-slashed-zero:; --tw-numeric-figure:; --tw-numeric-spacing:; --tw-numeric-fraction:; --tw-ring-inset:; --tw-ring-offset-width:0px; --tw-ring-offset-color:#fff; --tw-ring-color:rgba(59,130,246,0.5); --tw-ring-offset-shadow:0 0 #0000; --tw-ring-shadow:0 0 #0000; --tw-shadow:0 0 #0000; --tw-shadow-colored:0 0 #0000; --tw-blur:; --tw-brightness:; --tw-contrast:; --tw-grayscale:; --tw-hue-rotate:; --tw-invert:; --tw-saturate:; --tw-sepia:; --tw-drop-shadow:; --tw-backdrop-blur:; --tw-backdrop-brightness:; --tw-backdrop-contrast:; --tw-backdrop-grayscale:; --tw-backdrop-hue-rotate:; --tw-backdrop-invert:; --tw-backdrop-opacity:; --tw-backdrop-saturate:; --tw-backdrop-sepia:; vertical-align: inherit;"><font style="border-color: var(--gray-200); border-style: solid; border-width: 0px; box-sizing: border-box; --tw-border-spacing-x:0; --tw-border-spacing-y:0; --tw-translate-x:0; --tw-translate-y:0; --tw-rotate:0; --tw-skew-x:0; --tw-skew-y:0; --tw-scale-x:1; --tw-scale-y:1; --tw-pan-x:; --tw-pan-y:; --tw-pinch-zoom:; --tw-scroll-snap-strictness:proximity; --tw-ordinal:; --tw-slashed-zero:; --tw-numeric-figure:; --tw-numeric-spacing:; --tw-numeric-fraction:; --tw-ring-inset:; --tw-ring-offset-width:0px; --tw-ring-offset-color:#fff; --tw-ring-color:rgba(59,130,246,0.5); --tw-ring-offset-shadow:0 0 #0000; --tw-ring-shadow:0 0 #0000; --tw-shadow:0 0 #0000; --tw-shadow-colored:0 0 #0000; --tw-blur:; --tw-brightness:; --tw-contrast:; --tw-grayscale:; --tw-hue-rotate:; --tw-invert:; --tw-saturate:; --tw-sepia:; --tw-drop-shadow:; --tw-backdrop-blur:; --tw-backdrop-brightness:; --tw-backdrop-contrast:; --tw-backdrop-grayscale:; --tw-backdrop-hue-rotate:; --tw-backdrop-invert:; --tw-backdrop-opacity:; --tw-backdrop-saturate:; --tw-backdrop-sepia:; vertical-align: inherit;">Screenshot from SVGOMG, dated March 23, 2022.</font></font></figcaption></figure><p>One of the advantages of using a GUI and going about it with a <strong>manual process</strong> is that we can more easily ensure the <strong>quality</strong> of the resulting image.</p><p>My favicon&apos;s image size went from 73,728 bytes to 20,480 bytes! This represents a <strong>saving of approximately 72%</strong> of the original image! Impressive, right?&#x1F62E;</p><div class="kg-card kg-callout-card kg-callout-card-blue"><div class="kg-callout-emoji">&#x1F4A1;</div><div class="kg-callout-text">Although the interface shows different sizes in the lower right corner, this is due to the fact that I left the &quot;<em>Compare gzipped</em> &quot; option activated.<br><br>Indeed, it compares the size of files compressed with <a href="https://fr.wikipedia.org/wiki/Gzip">gzip</a>! &#x1F609;</div></div><p>You will now have one more tool in your toolbox! &#x1F60B;</p>]]></content:encoded></item><item><title><![CDATA[Frequently Asked Questions About Open Data in Sherbrooke]]></title><description><![CDATA[Would you like to know more about the open data published by the Ville de Sherbrooke and its partners? This FAQ may answer all your questions! 🤗]]></description><link>https://www.benjaminrancourt.ca/open-data-in-sherbrooke/</link><guid isPermaLink="false">631a843ab652ad0001cb85a7</guid><dc:creator><![CDATA[Benjamin Rancourt]]></dc:creator><pubDate>Tue, 04 Oct 2022 11:15:27 GMT</pubDate><media:content url="https://www.benjaminrancourt.ca/content/images/2022/08/pexels-thisisengineering-3861969.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://www.benjaminrancourt.ca/content/images/2022/08/pexels-thisisengineering-3861969.jpg" alt="Frequently Asked Questions About Open Data in Sherbrooke"><p>Last year, on December 6, 2021, the <em><a href="https://www.sherbrooke.ca/en">Ville de Sherbrooke</a></em> adopted its <a href="https://www.sherbrooke.ca/Fichiers/3337a882-4a53-e611-80ea-00155d09650f/Sites/333dd3d3-915d-e611-80ea-00155d09650f/Documents/Politiques/2021-politique-administrative-donnees_ouvertes.pdf"><strong>Open Data Policy</strong></a> at its <a href="https://www.sherbrooke.ca/fr/vie-municipale/seances-du-conseil/281/comite-plenier-public-et-seance-ordinaire">regular council meeting</a>.</p><p>To celebrate its first anniversary, I decided to create this reference article on open data in Sherbrooke. &#x1F973;</p><p>This article may also help the participants of the next <a href="https://hackqc.ca/">HackQC</a>, an IT competition using open data, whose theme will be &quot;<em>Data at the service of the <strong>ecological transition</strong></em>&quot;. &#x1F60E;</p><p>Are you ready to dig deeper into open data in Sherbrooke? &#x1F609;</p><h2 id="frequently-asked-questions">Frequently Asked Questions</h2><h3 id="what-is-open-data">What is Open Data?</h3><p>Although I have already mentioned the term several times in this article, I have never defined this one. But what exactly is open data? See the <a href="https://vitrinelinguistique.oqlf.gouv.qc.ca/fiche-gdt/fiche/26519745/donnees-ouvertes">definition</a> on the <a href="https://vitrinelinguistique.oqlf.gouv.qc.ca/">linguistic showcase</a> of the <a href="https://www.oqlf.gouv.qc.ca/"><em>Office qu&#xE9;b&#xE9;cois de la langue fran&#xE7;aise</em></a> (OQLF):</p><blockquote class="kg-blockquote-alt">Non-personal <strong>raw data</strong> <strong>free of rights</strong>, produced or collected by a public or private organization, and <strong>accessible to citizens</strong> via the <strong>Internet</strong>.</blockquote><p>These data are generally delivered in one or more open formats (not requiring proprietary software), to facilitate their <strong>reuse</strong>.</p><h3 id="why-does-the-ville-de-sherbrooke-publish-open-data">Why does the Ville de Sherbrooke publish open data?</h3><p>As part of its open data policy, the <em>Ville de Sherbrooke</em> has identified several advantages to publishing open data:</p><ul><li>data can be <strong>enriched</strong> and its potential increased;</li><li>the citizens can <strong>obtain</strong> the desired information <strong>themselves</strong>;</li><li><strong>useful applications</strong> for the community or research can be established;</li><li>and it encourages <strong>innovation</strong> and sustainable economic growth.<br></li></ul><h3 id="where-can-i-find-the-ville-de-sherbrookes-open-data">Where can I find the Ville de Sherbrooke&apos;s open data?</h3><p>The data can be found on the <em><a href="https://www.donneesquebec.ca/">Partenariat Donn&#xE9;es Qu&#xE9;bec</a> website</em>. As of this writing, <strong>34 datasets</strong> have been released.</p><figure class="kg-card kg-bookmark-card kg-card-hascaption"><a class="kg-bookmark-container" href="https://www.donneesquebec.ca/recherche/dataset?q=&amp;extras_organisation_principale=ville-de-sherbrooke"><div class="kg-bookmark-content"><div class="kg-bookmark-title">Jeu de donn&#xE9;es - Donn&#xE9;es Qu&#xE9;bec</div><div class="kg-bookmark-description"></div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://www.donneesquebec.ca/recherche/images/favicon.ico" alt="Frequently Asked Questions About Open Data in Sherbrooke"><span class="kg-bookmark-author">ville-de-sherbrooke</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://www.donneesquebec.ca/recherche/uploads/group/2016-01-22-204608.163487eee.jpg" alt="Frequently Asked Questions About Open Data in Sherbrooke"></div></a><figcaption>Datasets published by the Ville de Sherbrooke.</figcaption></figure><p>The open data produced by the geomatics team can also be consulted via a dedicated site linked to <a href="https://www.arcgis.com/index.html">ArcGIS</a>, a suite of geomatics software used by the <em>Ville de Sherbrooke</em>.</p><figure class="kg-card kg-bookmark-card kg-card-hascaption"><a class="kg-bookmark-container" href="https://donneesouvertes-sherbrooke.opendata.arcgis.com/"><div class="kg-bookmark-content"><div class="kg-bookmark-title">Donn&#xE9;es ouvertes de la Ville de Sherbrooke</div><div class="kg-bookmark-description">Portail de donn&#xE9;es ouvertes de la Ville de Sherbrooke</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://arcgis.com/favicon.ico" alt="Frequently Asked Questions About Open Data in Sherbrooke"></div></div><div class="kg-bookmark-thumbnail"><img src="https://cartes.ville.sherbrooke.qc.ca/Hyperliens/Logo/logoSherbrooke.png" alt="Frequently Asked Questions About Open Data in Sherbrooke"></div></a><figcaption>Map data portal.</figcaption></figure><h2 id="what-open-data-does-the-ville-de-sherbrooke-offer">What open data does the Ville de Sherbrooke offer?</h2><p>By combining the two previous sources, I was able to list the following 34 datasets:</p><ol><li>&#x1F30E; Developed areas</li><li>&#x1F30E; Boroughs</li><li>&#x1F30E; Buildings</li><li>&#x26A0;&#xFE0F;&#x1F30E; Municipal buildings and services</li><li>Real-time event calendar</li><li>&#x1F30E; Contours and Digital Elevation Model (DEM)</li><li>Dataset requests</li><li>&#x1F30E; Electoral districts</li><li>Defibrillators</li><li>Ecocentres - list and schedules</li><li>Events - <em>Soci&#xE9;TIC</em></li><li>Events in the Sherbrooke region (What to do - GVQ standardization)</li><li>&#x1F30E; Parking meters</li><li>&#x1F30E; Public Safety Incidents</li><li>Login information</li><li>Residual materials - Materials accepted</li><li>Walls dedicated to temporary and permanent graffiti</li><li>Where to eat?</li><li>&#x26A0;&#xFE0F;&#x1F30E; Road works</li><li>&#x1F30E; Parking signs</li><li>&#x26A0;&#xFE0F;&#x1F30E; Pools and beaches</li><li>Cycle paths</li><li>&#x1F30E; Street snow removal priorities</li><li>Urban perimeter</li><li>What to do?</li><li>Directory of businesses in the Sherbrooke region</li><li>&#x1F30E; Waste collection channels</li><li>&#x1F30E; Street Segments</li><li>&#x1F30E; Walking trails</li><li>&#x1F30E; Landmarks</li><li>&#x1F30E; Public car parks</li><li>Park Recreational Structures</li><li>Public transport</li><li>&#x1F30E; Work in progress</li><li>ZAP: access points</li><li>&#x1F30E; Landslide areas</li><li>&#x1F30E; Flood zones<br></li></ol><p>The datasets identified by a globe (&#x1F30E;) are the datasets from the geomatics software ArcGIS.</p><p>As for those identified by an exclamation mark (&#x26A0;&#xFE0F;), these datasets do not seem to be present on the <em>Donn&#xE9;es Qu&#xE9;bec</em> website yet.</p><h2 id="which-sherbrooke-organizations-participate-in-open-data">Which Sherbrooke organizations participate in open data?</h2><p>According to <em>Donn&#xE9;es Qu&#xE9;bec</em>, the main organizations and paramunicipal organizations are, in alphabetical order:</p><ul><li><a href="https://www.destinationsherbrooke.com/fr"><em>Destination Sherbrooke</em></a></li><li><a href="https://www.entreprendresherbrooke.com/"><em>Entreprendre Sherbrooke</em></a></li><li><a href="https://societic.ca/"><em>Soci&#xE9;TIC</em></a></li><li><a href="https://www.sts.qc.ca/"><em>Soci&#xE9;t&#xE9; de transport de Sherbrooke</em></a> (STS)</li><li><a href="https://www.sherbrooke.ca/en"><em>Ville de Sherbrooke</em></a></li><li><a href="https://www.zapsherbrooke.org/"><em>ZAP Sherbrooke</em></a></li></ul><h3 id="who-to-contact-to-request-the-release-of-new-datasets">Who to contact to request the release of new datasets?</h3><p>According to the Open Data Policy, the Communications Department is responsible for receiving requests for new datasets. This service can <a href="https://www.sherbrooke.ca/en/contact-us">be reached</a> by email at <a href="mailto:communications@sherbrooke.ca">communications@sherbrooke.ca</a>.</p><h2 id="under-what-license-is-the-ville-de-sherbrookes-open-data-published">Under what license is the Ville de Sherbrooke&apos;s open data published?</h2><p>All open data is released under the <em>Attribution 4.0 International License (CC BY 4.0)</em>.</p><figure class="kg-card kg-bookmark-card kg-card-hascaption"><a class="kg-bookmark-container" href="https://creativecommons.org/licenses/by/4.0/deed.en"><div class="kg-bookmark-content"><div class="kg-bookmark-title">Creative Commons &#x2014; Attribution 4.0 International &#x2014; CC BY 4.0</div><div class="kg-bookmark-description"></div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://creativecommons.org/favicon.ico" alt="Frequently Asked Questions About Open Data in Sherbrooke"><span class="kg-bookmark-author">cc.logo.white</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://creativecommons.org/images/language_icon_x2.png" alt="Frequently Asked Questions About Open Data in Sherbrooke"></div></a><figcaption>CC BY 4.0 License Summary.</figcaption></figure><p>Under the terms of the license, it is therefore permitted to:</p><ul><li><strong>Share </strong>&#x2014; copy, distribute and communicate the material in any format and by any means</li><li><strong>Adapt </strong>&#x2014; transform and create from the material for any use, including commercial</li></ul><p>under the following conditions:</p><ul><li><strong>Attribution</strong> &#x2014; The dataset must be <strong>credited</strong> and a link to its license must be embedded. In addition, all changes made to the data must be indicated. This information should appear, by all reasonable means, without suggesting that the dataset owner supports you in how you use their dataset.</li><li><strong>No Additional Restrictions</strong> &#x2014; No legal requirement or technical measure can prevent others from using the same dataset.</li></ul><h3 id="how-do-i-know-when-the-ville-de-sherbrooke-publishes-or-updates-datasets">How do I know when the Ville de Sherbrooke publishes or updates datasets?</h3><p>Those interested can subscribe to the <a href="https://en.wikipedia.org/wiki/Atom_(web_standard)">Atom</a> feed below with their favourite feed reader, such as <a href="https://feedly.com/">Feedly</a>.</p><figure class="kg-card kg-bookmark-card kg-card-hascaption"><a class="kg-bookmark-container" href="https://www.donneesquebec.ca/recherche/feeds/custom.atom?q=&amp;q=&amp;extras_organisation_principale=ville-de-sherbrooke"><div class="kg-bookmark-content"><div class="kg-bookmark-title">Donn&#xE9;es Qu&#xE9;bec - Custom query</div><div class="kg-bookmark-description"></div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://www.donneesquebec.ca/favicon.ico" alt="Frequently Asked Questions About Open Data in Sherbrooke"><span class="kg-bookmark-author">Custom query</span></div></div></a><figcaption>Atom feed to follow <em>Ville de Sherbrooke</em> datasets, recently created or updated on the <em>Donn&#xE9;es Qu&#xE9;bec</em> website.</figcaption></figure><h3 id="where-can-i-find-examples-of-research-papers-using-open-data-on-sherbrooke">Where can I find examples of research papers using open data on Sherbrooke?</h3><p>I don&apos;t know if the Ville de Sherbrooke maintains such a registry, but here is a non-exhaustive list of research reports that I found while writing this article:</p><ul><li><strong>[French]</strong> <a href="https://contenu.maruche.ca/Fichiers/3337a882-4a53-e611-80ea-00155d09650f/Sites/333ceda8-915d-e611-80ea-00155d09650f/Documents/Routes%20et%20transport/Projet_rues_conviviales_Rapport%20final_2020-12-29.pdf"><em>&#xC9;valuation du potentiel des rues de la Ville de Sherbrooke &#xE0; &#xEA;tre transform&#xE9;es en rues partag&#xE9;es</em></a>, by Alexandre Cailhier (December 29, 2020)</li></ul><h2 id="references">References</h2><ul><li><strong>[French] </strong><a href="https://www.sherbrooke.ca/Fichiers/3337a882-4a53-e611-80ea-00155d09650f/Sites/333dd3d3-915d-e611-80ea-00155d09650f/Documents/Politiques/2021-politique-administrative-donnees_ouvertes.pdf">Politique de donn&#xE9;es ouvertes (ADM-2115)</a>, on the <em>Ville de Sherbrooke</em> website</li></ul>]]></content:encoded></item></channel></rss>