Jekyll2024-02-07T16:56:17+01:00https://blog.dufour.xyz/feed.xmlSouvenirs of an Electric co.Florent Dufour's blogAn Example of URL Reverse Engineering2023-03-06T00:00:00+01:002023-03-06T00:00:00+01:00https://blog.dufour.xyz/2023/URL-RE<p>Slowly going up Rrose’s back catalog since her <a href="https://ra.co/events/1602724">last appearance in Munich</a>, I end up on her 2012 set for the <a href="https://ra.co/podcast/318">Resident Advisor Podcast</a>.</p>
<p>The version on Mixcloud is a shy<!--more--> 69k mp4, while SoundCloud only streams the dreaded 128k mp3.</p>
<iframe width="100%" height="166" scrolling="no" frameborder="no" allow="autoplay" src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/236925033&color=%23ff5500&auto_play=false&hide_related=false&show_comments=true&show_user=true&show_reposts=false&show_teaser=true"></iframe>
<div style="font-size: 10px; color: #cccccc;line-break: anywhere;word-break: normal;overflow: hidden;white-space: nowrap;text-overflow: ellipsis; font-family: Interstate,Lucida Grande,Lucida Sans Unicode,Lucida Sans,Garuda,Verdana,Tahoma,sans-serif;font-weight: 100;"><a href="https://soundcloud.com/resident-advisor" title="Resident Advisor" target="_blank" style="color: #cccccc; text-decoration: none;">Resident Advisor</a> · <a href="https://soundcloud.com/resident-advisor/ra318-rrose" title="RA.318 Rrose" target="_blank" style="color: #cccccc; text-decoration: none;">RA.318 Rrose</a></div>
<p>I know Resident Advisor brodcasts 320k versions on their feed. I look for the <code class="language-plaintext highlighter-rouge"><enclosure .../></code> tag of episode 318:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>~<span class="nv">$ </span>curl <span class="s2">"https://ra.co/xml/podcast.xml"</span> | xq | less <span class="nt">-R</span>
</code></pre></div></div>
<p>Unfortunately, I notice that the feed only keeps the last 400 episodes, and definitely does not include what I am looking for. I also notice that they use <code class="language-plaintext highlighter-rouge">chrt.fm</code> to resolve mp3 files. For example, last episode’s file is referenced via:</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><enclosure</span> <span class="na">type=</span><span class="s">"audio/mpeg"</span> <span class="na">url=</span><span class="s">"https://chrt.fm/track/C54868/http://feeds.soundcloud.com/stream/1455221263-resident-advisor-ra873-solid-blake.mp3"</span> <span class="na">length=</span><span class="s">"171982635"</span><span class="nt">/></span>
</code></pre></div></div>
<p>The URL structure is consistent across entries:</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://chrt.fm/track/C54868/http://feeds.soundcloud.com/stream/<span class="nt"><id></span>-resident-advisor-ra<span class="nt"><number></span>-<span class="nt"><artist></span>.mp3
</code></pre></div></div>
<p>I seem to have all the information except the SoundCloud track id. One could dig in the page source and find the api uri. I use <code class="language-plaintext highlighter-rouge">yt-dlp</code><sup id="fnref:yt-dlp" role="doc-noteref"><a href="#fn:yt-dlp" class="footnote" rel="footnote">1</a></sup> instead:</p>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>~<span class="nv">$ </span>yt-dlp <span class="nt">-F</span> <span class="s2">"https://soundcloud.com/resident-advisor/ra318-rrose"</span>
<span class="o">[</span>soundcloud] Extracting URL: https://soundcloud.com/resident-advisor/ra318-rrose
<span class="o">[</span>soundcloud] resident-advisor/ra318-rrose: Downloading info JSON
<span class="o">[</span>soundcloud] 236925033: Downloading JSON metadata
</code></pre></div></div>
<p>The id is <code class="language-plaintext highlighter-rouge">236925033</code>. We’ll need to follow a couple of redirects and save the output to a file with <code class="language-plaintext highlighter-rouge">curl</code>:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>~<span class="nv">$ </span>curl <span class="nt">-L</span> <span class="s2">"https://chrt.fm/track/C54868/http://feeds.soundcloud.com/stream/236925033-resident-advisor-ra318-rrose.mp3"</span> <span class="nt">--output</span> RA.318-Rrose.mp3
</code></pre></div></div>
<p>There you are:</p>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>exiftool RA.318-Rrose.mp3
ExifTool Version Number : 12.50
File Name : RA.318-Rrose.mp3
Directory : <span class="nb">.</span>
File Size : 138 MB
File Modification Date/Time : 2023:03:06 19:33:31+01:00
File Access Date/Time : 2023:03:06 19:33:09+01:00
File Inode Change Date/Time : 2023:03:06 19:33:31+01:00
File Permissions : <span class="nt">-rw-r--r--</span>
File Type : MP3
File Type Extension : mp3
MIME Type : audio/mpeg
MPEG Audio Version : 1
Audio Layer : 3
Audio Bitrate : 320 kbps
Sample Rate : 44100
Channel Mode : Joint Stereo
MS Stereo : Off
Intensity Stereo : Off
Copyright Flag : False
Original Media : False
Emphasis : None
ID3 Size : 387427
Encoder Settings : Logic Pro 9.1.7
Date : 2607
Time : 1825
Year : 2012
Title : RA.318 Rrose - 2012.07.02 <span class="o">[</span>320k]
Album : Resident Advisor podcast
Artist : Rrose
Initial Key : C
User Defined URL : <span class="o">(</span>URL<span class="o">)</span> http://rrose.ro http://eaux.ro
Comment : Find out more about RA.318 with Rrose on Resident Advisor: www.residentadvisor.net/podcast-episode.aspx?id<span class="o">=</span>318
Picture Format : JPG
Picture Type : Other
Picture Description :
Picture : <span class="o">(</span>Binary data 376602 bytes, use <span class="nt">-b</span> option to extract<span class="o">)</span>
Genre : Techno
Date/Time Original : 2012:26:07 18:25
Duration : 0:57:19 <span class="o">(</span>approx<span class="o">)</span>
</code></pre></div></div>
<div class="footnotes" role="doc-endnotes">
<ol>
<li id="fn:yt-dlp" role="doc-endnote">
<p><a href="https://github.com/yt-dlp/yt-dlp">yt-dlp, a youtube-dl fork with additional features and fixes</a> <a href="#fnref:yt-dlp" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
</ol>
</div>Florent DufourSlowly going up Rrose’s back catalog since her last appearance in Munich, I end up on her 2012 set for the Resident Advisor Podcast. The version on Mixcloud is a shyKarma Yoga and SSL Certificates2022-09-23T00:00:00+02:002022-09-23T00:00:00+02:00https://blog.dufour.xyz/2022/yoga-ssl<p>Even though getting enlightened while doing the dishes sounds enticing, many people are nowadays equipped with a dishwasher. Luckily enough, technical innovation does not permeate<!--more--> all aspects of one’s life at the same pace, leaving leeway for inner work<sup id="fnref:LSR" role="doc-noteref"><a href="#fn:LSR" class="footnote" rel="footnote">1</a></sup>. If you’re into IT and can relate, this blog post is for you. You don’t need to know anything about CI/CD, Kubernetes, or certbots.</p>
<p>Karma Yoga is the transformation of being that is based on one’s daily work in the world<sup id="fnref:bhn" role="doc-noteref"><a href="#fn:bhn" class="footnote" rel="footnote">2</a></sup>. Let’s see how much karma we can create and get the witness, awareness, (and patience) in action<sup id="fnref:kyia" role="doc-noteref"><a href="#fn:kyia" class="footnote" rel="footnote">3</a></sup>. We’ll use SSL certificates as an alibi and see how big of an endeavour we can make configuring <a href="https://traefik.io">Træfik</a> with custom certificates<sup id="fnref:TraefikTLSDoc" role="doc-noteref"><a href="#fn:TraefikTLSDoc" class="footnote" rel="footnote">4</a></sup> <sup id="fnref:Colding" role="doc-noteref"><a href="#fn:Colding" class="footnote" rel="footnote">5</a></sup>. We’ll expose 1 web app to a WAN via https with a database as backend.</p>
<p>I’ve been deploying containerized applications for many years now. Steps remain the same, growing on me like a mantra:</p>
<blockquote>
<p>“भण्डारं क्लोन कुर्वन्तु, docker-compose.yaml इत्यस्य अनुकूलनं कुर्वन्तु, चित्रं निर्मायन्तु तथा च पात्रं चालयन्तु, भण्डारणं/दत्तांशकोशं विन्यस्यन्तु, पात्रं प्रति DNS अभिलेखबिन्दुं कुर्वन्तु, अन्त्यबिन्दुं सुरक्षितरूपेण WAN प्रति उजागरयन्तु, सम्भवतः VPN इत्यस्य पृष्ठतः. ॐ शान्ति: शान्ति: शान्ति:॥.”</p>
</blockquote>
<!-- You got it ;) Clone the repository, adapt the docker-compose.yaml, build image and run the container, configure the storage/database, make a DNS record point to the container, securely expose the endpoint to a WAN, perhaps behind a VPN. -->
<p>This process takes me between 15 minutes and 0.5 days depending on the quality of the documentation and my level of caffeination. We are however not looking for speed or efficiency here, I’m just bragging.</p>
<hr />
<p>Let’s start the exercise. Let’s first request the resources we will need to run our 2 containers. Durations are for indicative purposes only.</p>
<table>
<thead>
<tr>
<th style="text-align: center">#</th>
<th>Task</th>
<th>Duration</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">1</td>
<td>Get compute (e.g., a Debian VM) with an IP on a WAN</td>
<td>1 day</td>
</tr>
<tr>
<td style="text-align: center">2</td>
<td>Install Docker, build and run 2 containers</td>
<td>10 minutes</td>
</tr>
<tr>
<td style="text-align: center">3</td>
<td>Get the domain name</td>
<td>4 months</td>
</tr>
<tr>
<td style="text-align: center">4</td>
<td>Get the email configuration</td>
<td>6 weeks</td>
</tr>
<tr>
<td style="text-align: center">5</td>
<td>Get SSL certificate</td>
<td>1 week</td>
</tr>
<tr>
<td style="text-align: center">6</td>
<td>Get SSL certificate again, this time without a typo</td>
<td>20 days</td>
</tr>
<tr>
<td style="text-align: center">6</td>
<td>Piece everything together</td>
<td>10 minutes</td>
</tr>
<tr>
<td style="text-align: center"> </td>
<td> </td>
<td><u>Total: ~190 days</u></td>
</tr>
</tbody>
</table>
<p>The net result is very yogic. After involving only 6 people and in less than 200 days one gets: 1 mostly idling VM (for 2 containers), no service redundancy, no backup strategy, no CI/CD, but another prospective round of emails in 1 year when certs will silently expire (you may want to put a reminder in your calendar now before you forget).</p>
<hr />
<p>All the pieces are now here. Let’s add a third container in the mix. Træfik is our reverse proxy of choice. Below, <code class="language-plaintext highlighter-rouge">docker-compose.yaml</code> is given to serve the web app (myapp in the example) using a PostgreSQL database (db in the example). You’ll need to mount the certificate and key file you got via email into the Træfik container and reference them in <code class="language-plaintext highlighter-rouge">traefik_dynamic.yaml</code>, itself referenced in <code class="language-plaintext highlighter-rouge">traefik.yaml</code>. All code snippets are provided below.</p>
<details>
<summary>docker-compose.yaml</summary>
<div>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">version</span><span class="pi">:</span> <span class="s2">"</span><span class="s">3"</span>
<span class="na">services</span><span class="pi">:</span>
<span class="c1"># ------------- #</span>
<span class="c1"># REVERSE PROXY #</span>
<span class="c1"># ------------- #</span>
<span class="na">traefik</span><span class="pi">:</span>
<span class="na">image</span><span class="pi">:</span> <span class="s">traefik:2.8.5</span>
<span class="na">container_name</span><span class="pi">:</span> <span class="s">traefik</span>
<span class="na">restart</span><span class="pi">:</span> <span class="s">always</span>
<span class="na">ports</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">80:80</span> <span class="c1"># http</span>
<span class="pi">-</span> <span class="s">443:443</span> <span class="c1"># https</span>
<span class="pi">-</span> <span class="s">8080:8080</span> <span class="c1"># dashboard</span>
<span class="na">volumes</span><span class="pi">:</span>
<span class="c1"># System mounts</span>
<span class="pi">-</span> <span class="s">/var/run/docker.sock:/var/run/docker.sock</span>
<span class="pi">-</span> <span class="s">/etc/localtime:/etc/localtime:ro</span>
<span class="c1"># Traefik config mounts</span>
<span class="pi">-</span> <span class="s">./traefik.yaml:/etc/traefik/traefik.yaml:ro</span>
<span class="pi">-</span> <span class="s">./traefik_dynamic.yaml:/etc/traefik/traefik_dynamic.yaml:ro</span>
<span class="pi">-</span> <span class="s">./ssl/certs:/etc/ssl/certs</span>
<span class="c1"># Traefik log mounts</span>
<span class="pi">-</span> <span class="s">/data/traefik/log:/var/log</span>
<span class="na">networks</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">web</span>
<span class="na">labels</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s2">"</span><span class="s">traefik.enable=true"</span>
<span class="pi">-</span> <span class="s2">"</span><span class="s">traefik.http.routers.traefik.service=api@internal"</span>
<span class="pi">-</span> <span class="s2">"</span><span class="s">traefik.http.routers.traefik.entrypoints=websecure"</span>
<span class="c1"># ------- #</span>
<span class="c1"># THE APP #</span>
<span class="c1"># ------- #</span>
<span class="na">myapp</span><span class="pi">:</span>
<span class="na">restart</span><span class="pi">:</span> <span class="s">always</span>
<span class="na">hostname</span><span class="pi">:</span> <span class="s">myapp</span>
<span class="na">container_name</span><span class="pi">:</span> <span class="s">myapp-app</span>
<span class="na">depends_on</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">db</span>
<span class="na">image</span><span class="pi">:</span> <span class="s">myapp:1</span>
<span class="na">volumes</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">/data/app/files:/usr/src/files:rw</span>
<span class="na">labels</span><span class="pi">:</span>
<span class="c1"># Enable Træfik</span>
<span class="pi">-</span> <span class="s2">"</span><span class="s">traefik.enable=true"</span>
<span class="pi">-</span> <span class="s2">"</span><span class="s">traefik.http.routers.myapp.service=myapp"</span>
<span class="pi">-</span> <span class="s2">"</span><span class="s">traefik.http.routers.myapp.entrypoints=websecure"</span>
<span class="pi">-</span> <span class="s2">"</span><span class="s">traefik.http.services.myapp.loadbalancer.server.port=3000"</span>
<span class="pi">-</span> <span class="s2">"</span><span class="s">traefik.http.routers.myapp.rule=Host(`myapp.com`,</span><span class="nv"> </span><span class="s">`www.myapp.com`)"</span>
<span class="c1"># HTTP redirect</span>
<span class="pi">-</span> <span class="s2">"</span><span class="s">traefik.http.middlewares.https_redirect.redirectscheme.scheme=https"</span>
<span class="pi">-</span> <span class="s2">"</span><span class="s">traefik.http.middlewares.https_redirect.redirectscheme.permanent=true"</span>
<span class="pi">-</span> <span class="s2">"</span><span class="s">traefik.http.routers.http_catchall.rule=HostRegexp(`{any:.+}`)"</span>
<span class="pi">-</span> <span class="s2">"</span><span class="s">traefik.http.routers.http_catchall.entrypoints=web"</span>
<span class="pi">-</span> <span class="s2">"</span><span class="s">traefik.http.routers.http_catchall.middlewares=https_redirect"</span>
<span class="na">env_file</span><span class="pi">:</span> <span class="s">.env-local</span>
<span class="na">networks</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">web</span>
<span class="pi">-</span> <span class="s">myapp</span>
<span class="c1"># ------ #</span>
<span class="c1"># THE DB #</span>
<span class="c1"># ------ #</span>
<span class="na">db</span><span class="pi">:</span>
<span class="na">restart</span><span class="pi">:</span> <span class="s">always</span>
<span class="na">container_name</span><span class="pi">:</span> <span class="s">myapp-db</span>
<span class="na">image</span><span class="pi">:</span> <span class="s">postgresql:15</span>
<span class="na">volumes</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">/data/db/pgdata:/var/lib/postgresql/data:rw</span>
<span class="na">env_file</span><span class="pi">:</span> <span class="s">.env-local-postgres</span>
<span class="na">networks</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">myapp</span>
<span class="na">networks</span><span class="pi">:</span>
<span class="na">myapp</span><span class="pi">:</span>
<span class="na">web</span><span class="pi">:</span>
<span class="na">external</span><span class="pi">:</span> <span class="no">true</span>
</code></pre></div> </div>
</div>
</details>
<details>
<summary>traefik.yaml</summary>
<div>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># REFERENCE: https://github.com/traefik/traefik/blob/master/traefik.sample.yml</span>
<span class="na">global</span><span class="pi">:</span>
<span class="na">checkNewVersion</span><span class="pi">:</span> <span class="no">true</span>
<span class="na">sendAnonymousUsage</span><span class="pi">:</span> <span class="no">false</span>
<span class="na">entryPoints</span><span class="pi">:</span>
<span class="na">web</span><span class="pi">:</span>
<span class="na">address</span><span class="pi">:</span> <span class="s">:80</span>
<span class="na">websecure</span><span class="pi">:</span>
<span class="na">address</span><span class="pi">:</span> <span class="s">:443</span>
<span class="na">http</span><span class="pi">:</span>
<span class="na">tls</span><span class="pi">:</span> <span class="pi">{}</span>
<span class="na">log</span><span class="pi">:</span>
<span class="na">level</span><span class="pi">:</span> <span class="s">INFO</span>
<span class="na">filePath</span><span class="pi">:</span> <span class="s">/var/log/traefik.json</span>
<span class="na">format</span><span class="pi">:</span> <span class="s">json</span>
<span class="na">accessLog</span><span class="pi">:</span>
<span class="na">filePath</span><span class="pi">:</span> <span class="s">/var/log/traefik-accesslog.json</span>
<span class="na">format</span><span class="pi">:</span> <span class="s">json</span>
<span class="na">api</span><span class="pi">:</span>
<span class="na">insecure</span><span class="pi">:</span> <span class="no">true</span> <span class="c1"># False when prod</span>
<span class="na">dashboard</span><span class="pi">:</span> <span class="no">true</span> <span class="c1"># False when prod</span>
<span class="na">ping</span><span class="pi">:</span>
<span class="na">entryPoint</span><span class="pi">:</span> <span class="s">traefik</span>
<span class="na">providers</span><span class="pi">:</span>
<span class="na">docker</span><span class="pi">:</span>
<span class="na">endpoint</span><span class="pi">:</span> <span class="s">unix:///var/run/docker.sock</span>
<span class="na">watch</span><span class="pi">:</span> <span class="no">true</span>
<span class="na">network</span><span class="pi">:</span> <span class="s">web</span>
<span class="na">exposedByDefault</span><span class="pi">:</span> <span class="no">false</span>
<span class="na">file</span><span class="pi">:</span>
<span class="na">filename</span><span class="pi">:</span> <span class="s2">"</span><span class="s">/etc/traefik/traefik_dynamic.yaml"</span>
<span class="na">watch</span><span class="pi">:</span> <span class="no">true</span>
</code></pre></div> </div>
</div>
</details>
<details>
<summary>traefik_dynamic.yaml</summary>
<div>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">tls</span><span class="pi">:</span>
<span class="na">certificates</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">certFile</span><span class="pi">:</span> <span class="s">/etc/ssl/certs/certificate.pem</span>
<span class="na">keyFile</span><span class="pi">:</span> <span class="s">/etc/ssl/certs/private.key</span>
</code></pre></div> </div>
</div>
</details>
<p>After issuing <code class="language-plaintext highlighter-rouge">~$ docker compose up</code>, you should be able to read Træfik’s logs. It should look like <code class="language-plaintext highlighter-rouge">traefik.json</code> provided below.</p>
<details>
<summary>traefik.json</summary>
<div>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="nl">"level"</span><span class="p">:</span><span class="s2">"info"</span><span class="p">,</span><span class="nl">"msg"</span><span class="p">:</span><span class="s2">"Traefik version 2.8.5 built on 2022-09-13T15:19:09Z"</span><span class="p">,</span><span class="nl">"time"</span><span class="p">:</span><span class="s2">"2022-09-22T17:57:17+02:00"</span><span class="p">}</span><span class="w">
</span><span class="p">{</span><span class="nl">"level"</span><span class="p">:</span><span class="s2">"info"</span><span class="p">,</span><span class="nl">"msg"</span><span class="p">:</span><span class="s2">"</span><span class="se">\n</span><span class="s2">Stats collection is disabled.</span><span class="se">\n</span><span class="s2">Help us improve Traefik by turning this feature on :)</span><span class="se">\n</span><span class="s2">More details on: https://doc.traefik.io/traefik/contributing/data-collection/</span><span class="se">\n</span><span class="s2">"</span><span class="p">,</span><span class="nl">"time"</span><span class="p">:</span><span class="s2">"2022-09-22T17:57:17+02:00"</span><span class="p">}</span><span class="w">
</span><span class="p">{</span><span class="nl">"level"</span><span class="p">:</span><span class="s2">"warning"</span><span class="p">,</span><span class="nl">"msg"</span><span class="p">:</span><span class="s2">"Traefik Pilot is deprecated and will be removed soon. Please check our Blog for migration instructions later this year."</span><span class="p">,</span><span class="nl">"time"</span><span class="p">:</span><span class="s2">"2022-09-22T17:57:17+02:00"</span><span class="p">}</span><span class="w">
</span><span class="p">{</span><span class="nl">"level"</span><span class="p">:</span><span class="s2">"info"</span><span class="p">,</span><span class="nl">"msg"</span><span class="p">:</span><span class="s2">"Starting provider aggregator aggregator.ProviderAggregator"</span><span class="p">,</span><span class="nl">"time"</span><span class="p">:</span><span class="s2">"2022-09-22T17:57:17+02:00"</span><span class="p">}</span><span class="w">
</span><span class="p">{</span><span class="nl">"level"</span><span class="p">:</span><span class="s2">"info"</span><span class="p">,</span><span class="nl">"msg"</span><span class="p">:</span><span class="s2">"Starting provider *file.Provider"</span><span class="p">,</span><span class="nl">"time"</span><span class="p">:</span><span class="s2">"2022-09-22T17:57:17+02:00"</span><span class="p">}</span><span class="w">
</span><span class="p">{</span><span class="nl">"level"</span><span class="p">:</span><span class="s2">"info"</span><span class="p">,</span><span class="nl">"msg"</span><span class="p">:</span><span class="s2">"Starting provider *traefik.Provider"</span><span class="p">,</span><span class="nl">"time"</span><span class="p">:</span><span class="s2">"2022-09-22T17:57:17+02:00"</span><span class="p">}</span><span class="w">
</span><span class="p">{</span><span class="nl">"level"</span><span class="p">:</span><span class="s2">"info"</span><span class="p">,</span><span class="nl">"msg"</span><span class="p">:</span><span class="s2">"Starting provider *acme.ChallengeTLSALPN"</span><span class="p">,</span><span class="nl">"time"</span><span class="p">:</span><span class="s2">"2022-09-22T17:57:17+02:00"</span><span class="p">}</span><span class="w">
</span><span class="p">{</span><span class="nl">"level"</span><span class="p">:</span><span class="s2">"info"</span><span class="p">,</span><span class="nl">"msg"</span><span class="p">:</span><span class="s2">"Starting provider *docker.Provider"</span><span class="p">,</span><span class="nl">"time"</span><span class="p">:</span><span class="s2">"2022-09-22T17:57:17+02:00"</span><span class="p">}</span><span class="w">
</span></code></pre></div> </div>
</div>
</details>
<hr />
<p>Here are some things you may want to check if stuff goes wrong:</p>
<ol>
<li>Are you using the right certificate and key file?
<ul>
<li>Use the <code class="language-plaintext highlighter-rouge">file</code> CLI tool to check the types of your files on the file system. You should see <code class="language-plaintext highlighter-rouge">server.pem: PEM certificate</code>, <code class="language-plaintext highlighter-rouge">private.key: ASCII text</code></li>
<li>You can <code class="language-plaintext highlighter-rouge">cat</code> the content of the files:</li>
</ul>
<ul>
<li><code class="language-plaintext highlighter-rouge">server.pem</code> is contained between <code class="language-plaintext highlighter-rouge">-----BEGIN CERTIFICATE-----</code> and <code class="language-plaintext highlighter-rouge">-----END CERTIFICATE-----</code></li>
<li><code class="language-plaintext highlighter-rouge">private.key</code> is contained between <code class="language-plaintext highlighter-rouge">-----BEGIN PRIVATE KEY-----</code> and <code class="language-plaintext highlighter-rouge">-----END PRIVATE KEY-----</code></li>
</ul>
</li>
<li>Have a look into Træfik’s logs: <code class="language-plaintext highlighter-rouge">/var/log/traefik.json</code>, not just the <code class="language-plaintext highlighter-rouge">stdout</code> provided by Docker.</li>
<li>Map port 8080 in <code class="language-plaintext highlighter-rouge">docker-compose.yaml</code> and allow api insecure and dashboard in <code class="language-plaintext highlighter-rouge">traefik.yaml</code> to peak into the services status.</li>
</ol>
<p>Namaste 🔮</p>
<div class="footnotes" role="doc-endnotes">
<ol>
<li id="fn:LSR" role="doc-endnote">
<p><a href="https://www.discogs.com/release/950213-Various-Love-Serve-Remember">Ram Dass, Love Serve Remember, vol. LSR. ZBF Foundation, 1973. [6×12” Vinyl Box Set].</a> <a href="#fnref:LSR" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:bhn" role="doc-endnote">
<p><a href="https://www.goodreads.com/book/show/41580312-be-here-now">Ram Dass, Be Here Now. New York: Harmony, 1978.</a> <a href="#fnref:bhn" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:kyia" role="doc-endnote">
<p><a href="https://www.goodreads.com/book/show/827031.Karma_Yoga">Vivekananda, Swami, Karma-yoga: The Yoga of Action. Advaita Ashrama, 2007.</a> <a href="#fnref:kyia" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:TraefikTLSDoc" role="doc-endnote">
<p><a href="https://doc.traefik.io/traefik/https/tls/">Traefik TLS Documentation - Traefik.</a> <a href="#fnref:TraefikTLSDoc" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:Colding" role="doc-endnote">
<p><a href="https://medium.com/@clintcolding/use-your-own-certificates-with-traefik-a31d785a6441">C. Colding, “Use Your Own Certificates with Traefik,” Medium, Nov. 07, 2019.</a> <a href="#fnref:Colding" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
</ol>
</div>Florent DufourEven though getting enlightened while doing the dishes sounds enticing, many people are nowadays equipped with a dishwasher. Luckily enough, technical innovation does not permeateProving That ζ(2) = π2/6 With Your Eyes Closed2022-06-16T00:00:00+02:002022-06-16T00:00:00+02:00https://blog.dufour.xyz/2022/%CE%B62<p>“Next time you go clubbing, ask around what’s the sum over k of 1 / k<sup>2</sup>” once said my math teacher. “You’ll see who’s worth partying with”.<!--more--></p>
<p>Here’s what you need to know:</p>
\[\zeta(2) = \sum_{k=1}^{\infty} \frac{1}{k^2} = \frac{\pi^2}{6}\]
<p>While Euler was the first to prove the identity in 1740<sup id="fnref:euler_1740" role="doc-noteref"><a href="#fn:euler_1740" class="footnote" rel="footnote">1</a></sup>, a handful of other modern approaches have been proposed since then<sup id="fnref:chapman_2003" role="doc-noteref"><a href="#fn:chapman_2003" class="footnote" rel="footnote">2</a></sup>:</p>
<ol>
<li>Using a monotone convergence<sup id="fnref:apostol_1983" role="doc-noteref"><a href="#fn:apostol_1983" class="footnote" rel="footnote">3</a></sup></li>
<li>Using the Jacobian Matrix<sup id="fnref:chapman_2003:1" role="doc-noteref"><a href="#fn:chapman_2003" class="footnote" rel="footnote">2</a></sup></li>
<li>Using the power series for the inverse sine function<sup id="fnref:choe_1987" role="doc-noteref"><a href="#fn:choe_1987" class="footnote" rel="footnote">4</a></sup></li>
<li>Using the L<sup>2</sup>-completeness of the trigonometric functions<sup id="fnref:chapman_2003:2" role="doc-noteref"><a href="#fn:chapman_2003" class="footnote" rel="footnote">2</a></sup></li>
<li>Using the convergence of Fourier series<sup id="fnref:chapman_2003:3" role="doc-noteref"><a href="#fn:chapman_2003" class="footnote" rel="footnote">2</a></sup></li>
<li>Using uniform convergence of a power series on the real line<sup id="fnref:chapman_2003:4" role="doc-noteref"><a href="#fn:chapman_2003" class="footnote" rel="footnote">2</a></sup></li>
<li>Using an infinite product for the sine function<sup id="fnref:euler_1740:1" role="doc-noteref"><a href="#fn:euler_1740" class="footnote" rel="footnote">1</a></sup></li>
<li>Using the calculus of residues<sup id="fnref:chapman_2003:5" role="doc-noteref"><a href="#fn:chapman_2003" class="footnote" rel="footnote">2</a></sup></li>
<li>Using cotangente inequalities<sup id="fnref:apostol_1974" role="doc-noteref"><a href="#fn:apostol_1974" class="footnote" rel="footnote">5</a></sup></li>
<li>Using the MacLaurin expansion<sup id="fnref:kortram_1996" role="doc-noteref"><a href="#fn:kortram_1996" class="footnote" rel="footnote">6</a></sup></li>
<li>Using the reduction of integral<sup id="fnref:matsuoka_1961" role="doc-noteref"><a href="#fn:matsuoka_1961" class="footnote" rel="footnote">7</a></sup></li>
<li>Using the identity for the Fejér kernel<sup id="fnref:stark_1969" role="doc-noteref"><a href="#fn:stark_1969" class="footnote" rel="footnote">8</a></sup></li>
<li>Using Gregory’s formula and infinite limits<sup id="fnref:borwein_1987" role="doc-noteref"><a href="#fn:borwein_1987" class="footnote" rel="footnote">9</a></sup></li>
<li>Using the formula for the number of representations of a positive integer as a sum of four squares<sup id="fnref:hua_2012" role="doc-noteref"><a href="#fn:hua_2012" class="footnote" rel="footnote">10</a></sup></li>
</ol>
<p>I was recently reminded of the Jacobian Matrix, let’s use this method for example.</p>
<hr />
<p><em>Before beginning</em></p>
<p>We know that<sup id="fnref:chapman_2003:6" role="doc-noteref"><a href="#fn:chapman_2003" class="footnote" rel="footnote">2</a></sup></p>
\[\frac{3}{4} \zeta(2) = \sum_{n=1}^{\infty} \frac{1}{n^2} - \sum_{m=1}^{\infty}\frac{1}{(2m)^2} = \sum_{r=0}^{\infty} \frac{1}{(2r + 1)^2},\]
<p>and that</p>
\[\sum_{r=0}^{\infty} \frac{1}{(2r + 1)^2} = \frac{\pi^2}{8}.\]
<p>We also note that</p>
\[\frac{1}{n^2} = \int_{0}^{1}\int_{0}^{1} x^{n-1} y^{n-1} dx\:dy,\]
<p>gives</p>
\[\sum_{n=1}^{\infty} \frac{1}{n^2} = \int_{0}^{1}\int_{0}^{1} \frac{dx\:dy}{1-xy}\]
<p>by monotonous convergence<sup id="fnref:apostol_1983:1" role="doc-noteref"><a href="#fn:apostol_1983" class="footnote" rel="footnote">3</a></sup>.</p>
<hr />
<p><em>Off we go</em></p>
<p>We start considering the monotonous convergence:</p>
\[\sum_{r=0}^{\infty} \frac{1}{(2r + 1)^2} = \int_{0}^{1}\int_{0}^{1} \frac{dx\:dy}{1-x^2y^2}.\]
<p>Let’s use the substitution</p>
\[(u, v) = \left( \tan^{-1} x \sqrt{\frac{1-y^2}{1-x^2}}, \tan^{-1} y \sqrt{\frac{1-x^2}{1-y^2}} \right),\]
<p>so that</p>
\[(x, y) = \left( \frac{\sin u}{\cos v}, \frac{\sin v}{\cos u} \right).\]
<p>The Jacobian matrix is:</p>
\[\begin{align*}
\frac{\partial(x, y)}{\partial(u, v)}
&= \begin{vmatrix}
\cos u / \cos v & \sin u \sin v / \cos^2 v\\
\sin u \sin v / \cos^2u & \cos v / \cos u
\end{vmatrix} \\
&= 1- \frac{\sin^2 u \sin^2 v}{\cos^2 u \cos^2 v} \\
&= 1-x^2y^2.
\end{align*}\]
<p>We get:</p>
\[\frac{3}{4} \zeta(2) = \int\int_{A} du\:dv,\]
<p>where</p>
\[A = \{ (u, v) : u \gt 0, \: v \gt 0, \: u+v \lt \pi/2 \}\]
<p>
has area \( \pi^2/8 \), giving <em>\( \zeta(2) = \pi^2 / 6 \)</em>.
</p>
<div class="footnotes" role="doc-endnotes">
<ol>
<li id="fn:euler_1740" role="doc-endnote">
<p><a href="https://scholarlycommons.pacific.edu/euler-works/41/">Euler, Leonhard. “De summis serierum reciprocarum.” Commentarii academiae scientiarum Petropolitanae (1740): 123-134.</a> <a href="#fnref:euler_1740" class="reversefootnote" role="doc-backlink">↩</a> <a href="#fnref:euler_1740:1" class="reversefootnote" role="doc-backlink">↩<sup>2</sup></a></p>
</li>
<li id="fn:chapman_2003" role="doc-endnote">
<p><a href="http://secamlocal.ex.ac.uk/people/staff/rjchapma/etc/zeta2.pdf">Evaluating ζ(2), Robin Chapman, Department of Mathematics University of Exeter (2003)</a> <a href="#fnref:chapman_2003" class="reversefootnote" role="doc-backlink">↩</a> <a href="#fnref:chapman_2003:1" class="reversefootnote" role="doc-backlink">↩<sup>2</sup></a> <a href="#fnref:chapman_2003:2" class="reversefootnote" role="doc-backlink">↩<sup>3</sup></a> <a href="#fnref:chapman_2003:3" class="reversefootnote" role="doc-backlink">↩<sup>4</sup></a> <a href="#fnref:chapman_2003:4" class="reversefootnote" role="doc-backlink">↩<sup>5</sup></a> <a href="#fnref:chapman_2003:5" class="reversefootnote" role="doc-backlink">↩<sup>6</sup></a> <a href="#fnref:chapman_2003:6" class="reversefootnote" role="doc-backlink">↩<sup>7</sup></a></p>
</li>
<li id="fn:apostol_1983" role="doc-endnote">
<p><a href="https://link.springer.com/article/10.1007/BF03026576">Apostol, Tom M. “A proof that Euler missed: evaluating ζ (2) the easy way.” The Mathematical Intelligencer 5.3 (1983): 59-60.</a> <a href="#fnref:apostol_1983" class="reversefootnote" role="doc-backlink">↩</a> <a href="#fnref:apostol_1983:1" class="reversefootnote" role="doc-backlink">↩<sup>2</sup></a></p>
</li>
<li id="fn:choe_1987" role="doc-endnote">
<p><a href="https://dl.acm.org/doi/abs/10.2307/2322220">Choe, Boo Rim. “An Elementary Proof of Σn=1 1/n2 = π2/6.” The American Mathematical Monthly 94.7 (1987): 662-663.</a> <a href="#fnref:choe_1987" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:apostol_1974" role="doc-endnote">
<p><a href="http://www.ru.ac.bd/wp-content/uploads/sites/25/2019/03/205_04_Apostol-Mathematical-Analysis-1973.pdf">Apostol, T. “Mathematical Analysis, Addison-Welsey.” Reading, MA 2 (1974).</a> <a href="#fnref:apostol_1974" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:kortram_1996" role="doc-endnote">
<p><a href="">Kortram, R. A. (1996). Simple Proofs for and sin. Mathematics Magazine, 69(2), 122-125.</a> <a href="#fnref:kortram_1996" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:matsuoka_1961" role="doc-endnote">
<p><a href="https://www.jstor.org/stable/2311110">Matsuoka, Yoshio. “An Elementary Proof of the Formula Σk=1 1/k2 = π2/6.” The American Mathematical Monthly 68.5 (1961): 485-487.</a> <a href="#fnref:matsuoka_1961" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:stark_1969" role="doc-endnote">
<p><a href="">Stark, E. L. (1969). Another Proof of the Formula Σk=1 1/k2=π2/6. The American Mathematical Monthly, 76(5), 552-553.</a> <a href="#fnref:stark_1969" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:borwein_1987" role="doc-endnote">
<p><a href="https://dl.acm.org/doi/abs/10.5555/40700">Borwein, J. M., & Borwein, P. B. (1987). Pi and the AGM: a study in the analytic number theory and computational complexity. Wiley-Interscience.</a> <a href="#fnref:borwein_1987" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:hua_2012" role="doc-endnote">
<p><a href="http://math.fau.edu/yiu/PSRM2015/yiu/Oldwebsites/NT2002/NT2002notes.pdf">Hua, L. K. (2012). Introduction to number theory. Springer Science & Business Media.</a> <a href="#fnref:hua_2012" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
</ol>
</div>Florent Dufour“Next time you go clubbing, ask around what’s the sum over k of 1 / k2” once said my math teacher. “You’ll see who’s worth partying with”.Isn’t Music the Art of Shaking Air?2022-05-21T00:00:00+02:002022-05-21T00:00:00+02:00https://blog.dufour.xyz/2022/audiophile-playlist<p>Being an audiophile is as much about the gear as it is about the art of music. I had an offbeat feeling this year, as if air was shaking while missing out on the art component. Luckily<!--more-->, sticking long enough with the <a href="https://admireaudio.com/aa4/">Admire Audio AA4</a> led me to re-discover <em>“Volver volver”, Buika (2008)</em>. There’s definitely something magical about horns, especially when they’re lifting voices like Buika’s (wait for the trumpet to enter). Other time, other horns, the <a href="https://avantgarde-acoustic.de/trio/">Avantgarde Trio G3</a> is playing <em>“Two Thousand and Seventeen”, Four Tet (2017)</em>. I like how they got people silent, meditative, with unabashed basses, and ultra-wide and sharp soundscapes.</p>
<p>The rest of the show unfortunately remained musically underwhelming. Why does everyone seem to be playing Norah Jones and Katie Melua<sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote" rel="footnote">1</a></sup>?</p>
<p>Finally, some kicks permeate a closed door. The <em>Adriatique Remix of “Atlas”, Marc Romboy (2015)</em> is playing on the impressive <a href="https://www.credo-audio.ch/cinema-ltm-eng.html">Credo Cinema LTM</a>. Did we really have to wait for the Swiss to come and play German house — loud — in Germany?</p>
<p>Anyway, here are two hours of unordered tracks I think make sense for my taste when listening to a new system:</p>
<iframe allow="autoplay *; encrypted-media *; fullscreen *; clipboard-write" frameborder="0" height="500" style="width:100%;max-width:800px;overflow:hidden;background:transparent;" sandbox="allow-forms allow-popups allow-same-origin allow-scripts allow-storage-access-by-user-activation allow-top-navigation-by-user-activation" src="https://embed.music.apple.com/fr/playlist/audiophile-playlist/pl.u-RRbVNM7TygoeWG?l=en"></iframe>
<div class="footnotes" role="doc-endnotes">
<ol>
<li id="fn:1" role="doc-endnote">
<p><a href="https://darko.audio/2022/05/audiophile-starter-kit/.">Would it be true? (link to darko.audio)</a> <a href="#fnref:1" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
</ol>
</div>Florent DufourBeing an audiophile is as much about the gear as it is about the art of music. I had an offbeat feeling this year, as if air was shaking while missing out on the art component. LuckilyHow to Get Any Extension to Work With VSCodium2022-02-20T00:00:00+01:002022-02-20T00:00:00+01:00https://blog.dufour.xyz/2022/extensions-vscodium<p>A student recently asked me how I managed to get the “Remote Development Extension Pack” provided by Microsoft to work with the open source software <a href="https://vscodium.com">VSCodium</a><!--more--><sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote" rel="footnote">1</a></sup>. The trick is underwhelming.</p>
<p>I have both Visual Studio Code (VS Code) and VSCodium installed on my machine. From the terminal:</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>~<span class="nv">$ </span><span class="nb">cd</span> ~/.vscode-oss
~<span class="nv">$ </span><span class="nb">ln</span> <span class="nt">-s</span> ../.vscode/extensions extensions
</code></pre></div></div>
<p>creates a symbolic link VSCodium will follow to initialize the extensions from the VS Code folder. This is much easier than compiling extensions into <code class="language-plaintext highlighter-rouge">.vsix</code> archives (when it is even possible). VS Code is now relegated to a mere store front I use to install extensions.</p>
<div class="footnotes" role="doc-endnotes">
<ol>
<li id="fn:1" role="doc-endnote">
<p>While VSCodium is point to point VS Code (except the Microsoft telemetry and branding), it does not tap into the Microsoft license protected store. Instead, only a limited set of extensions are made available via the <a href="https://open-vsx.org">Open VSX Registry</a>. <a href="#fnref:1" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
</ol>
</div>Florent DufourA student recently asked me how I managed to get the “Remote Development Extension Pack” provided by Microsoft to work with the open source software VSCodiumShower Idea: Build a URL Shortener With Jekyll2021-12-15T00:00:00+01:002021-12-15T00:00:00+01:00https://blog.dufour.xyz/2021/du4.link<p>I wanted to self-host a URL shortener for a long time in order to easily share blog posts, lecture material, files etc. Surprisingly,<!--more--> none of the solutions listed on <a href="https://github.com/awesome-selfhosted/awesome-selfhosted#url-shorteners">Awesome-Selfhosted</a> were really fitting me. They usually require a frontend, a database, and sometimes don’t run in ARM docker containers without a bit of hacking. Besides, I’m not interested in fancy features like analytics, access control, and co.</p>
<p>KISS<sup id="fnref:KISS" role="doc-noteref"><a href="#fn:KISS" class="footnote" rel="footnote">1</a></sup>! I just need a set of HTML pages with a <code class="language-plaintext highlighter-rouge">http-equiv="refresh"</code> tag that points to my target!</p>
<p>I take a shower and realize I can repurpose <a href="https://jekyllrb.com">Jekyll</a> very much like I did to generate <a href="https://podcast.dufour.xyz">podcast RSS feeds</a>, but this time with HTTP redirects. A couple of commits later, the first prototype is working. I feel refreshed, smell like a coconut, and the project is available on Github: <a href="https://github.com/f-dufour/du4.link">du4.link</a>.</p>
<div class="footnotes" role="doc-endnotes">
<ol>
<li id="fn:KISS" role="doc-endnote">
<p><a href="https://en.wikipedia.org/wiki/KISS_principle">Keep it Simple Stupid.</a> <a href="#fnref:KISS" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
</ol>
</div>Florent DufourI wanted to self-host a URL shortener for a long time in order to easily share blog posts, lecture material, files etc. Surprisingly,Loksins Erum Við Engin2021-08-19T00:00:00+02:002021-08-19T00:00:00+02:00https://blog.dufour.xyz/2021/Loksins%20erum%20vi%C3%B0%20engin<p>The kids loved it more than anything. They never missed a chance to ask me to play the record. Múm became our companion in nap. I loved<!--more--> to see their breath and mind finally getting some rest after hours of running and jumping around. Nap time was as much a precious and mindful moment for me as it was for them. I know they got it.</p>
<p>Still, Múm is not composing kids lullabies. Instead, they are the Icelandic band that embodies what the island is all about in delicate, fragile, and organic tunes. Since the late 90’s, they released 6 full length albums and played live on several occasions. “Loksins erum við engin” or “finally we are no one” in English most certainly stands at the pinnacle of their creativity and remains one of their most polished work. I remember offering the record to those I love. I hope it sill brings peace to their home today.</p>
<center>
<figure>
<img class="cover" src="/assets/img/posts/2021-08-19-mum/mum-thumb.jpg" alt="Album cover of the Icelandic version of finally we are no one" />
<figcaption>Album cover of the Icelandic version of “finally we are no one”.</figcaption>
</figure>
</center>
<p>“finally we are no one” has become rare to find. Slowly vanishing from streaming platforms, it has also shown to be impossible to find in record stores. I am glad I have a copy safe in my collection, I am also glad it is coming with me on this occasion.</p>
<p>The plane leans on its side, I open my eyes and see Iceland from above. I see clouds hugging the mountains, green freckles on a volcanic skin, and a pale blue sky stretching beyond the horizon. The closing song “The Land Between Solar Systems” starts playing and I can finally feel my body getting closer to the ground.</p>Florent DufourThe kids loved it more than anything. They never missed a chance to ask me to play the record. Múm became our companion in nap. I lovedJean-Luc Is Still Dead2021-05-05T00:00:00+02:002021-05-05T00:00:00+02:00https://blog.dufour.xyz/2021/Jean-Luc<p>As I am writing these lines, Jean-Luc le Ténia was taking his own life in his mother town, Le Mans - France, 10 years ago. I can feel<!--more--> my skin getting closer. Why would someone this talented, <a href="https://www.flickr.com/photos/jeanlucletenia/">well surrounded</a>, and <a href="http://aurorebagarry.com/index.php/jean-luc-le-tenia/">such fun</a> commit suicide at the age 35?</p>
<blockquote>
<p>“Écoutez mes chansons, en souvenir de moi<br />
Moi j’étais beau garçon, mais j’étais seul chez moi<br />
Mes chansons sont en vous, elles grandissent chaque jour<br />
Mes chansons sont les ténias de l’amour!”<br />
- L’âme du Mans (L’âme du Mans, 2002)</p>
</blockquote>
<p>Jean-Luc le Ténia wrote and self produced more than 2’000 songs and hundreds of video clips. They feature everything that make life what it is: happiness, humor, friends, sex, but also pain, sorrow, regrets, love and the lack thereof.</p>
<center>
<figure>
<img src="/assets/img/posts/2021-05-03-JLLT/JLLT.jpg" class="cover" alt="Album cover of Le Meilleur chanteur français du monde" />
<figcaption>Album cover of “Le meilleur chanteur français du monde”: him during his 25<sup>th</sup> birthday in front of the wardrobe in his apartment, Le Mans.</figcaption>
</figure>
</center>
<p>Unique figure of French anti-folk, his songs vacillate between humor and anxiety, providing a raw, deep, and fragile glimpse into a mind afflicted by depression. He openly sang about suicide, as in “Tous les matins”, “Je chante la nuit”, or even “La vie sans toi”:</p>
<blockquote>
<p>“La vie sans toi, tout est froid<br />
La vie avec toi, tout me plait<br />
Je ne peux plus supporter d’attendre sans savoir<br />
Ne m’aimes-tu plus ou es-tu empêchée ?<br />
Tu ne veux pas ou bien tu ne peux pas ?<br />
Je veux savoir, je ne peux plus attendre<br />
Je ne peux plus attendre, espérer pour rien, enfermé dans un lit qui me guette<br />
Marchant le long du canal qui me lèche<br />
Sur le pont, la tentation<br />
Sur le pont, la tentation<br />
La tentation, la tentation”<br />
- La vie sans toi (L’amour et/ou la poésie, 2005)</p>
</blockquote>
<p>In addition to his musical legacy, Jean-Luc left his diary behind. A methodical daily log he started in 1995 available for everyone to dive in<sup id="fnref:diary" role="doc-noteref"><a href="#fn:diary" class="footnote" rel="footnote">1</a></sup>. Later in 2016, the diary was published <a href="https://www.goodreads.com/book/show/58310126-le-meilleur-chanteur-fran-ais-du-monde">as a book</a> under (Book is) Conspiration. His last entry, 18 words, 2 days before killing himself:</p>
<blockquote>
<p>“Crevé, je suis allé boire trois bières au Lézard en début de soirée, puis suis rentré chez moi.”<br />
- Tenia Diary, entry log May 3<sup>rd</sup>, 2011.</p>
</blockquote>
<div class="footnotes" role="doc-endnotes">
<ol>
<li id="fn:diary" role="doc-endnote">
<p>The online diary, provided by Tony Papin: <a href="http://teniadiary.fr/category/diary/">link</a> <a href="#fnref:diary" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
</ol>
</div>Florent DufourAs I am writing these lines, Jean-Luc le Ténia was taking his own life in his mother town, Le Mans - France, 10 years ago. I can feelWe Finally Cancelled Pint of Science 20202020-08-18T00:00:00+02:002020-08-18T00:00:00+02:00https://blog.dufour.xyz/2020/POS-cancelled<p>While there have been some back and forths on whether Pint of Science 2020 should take place or not, we decided it is safer, easier, and wiser to simply cancel this edition. Still, you shouldn’t worry much, we are intensively working on the brew for 2021<!--more-->! <em>You can already save the three evenings from the 17<sup>th</sup> to the 19<sup>th</sup> of May 2021</em>! We’ll be happy to see you there and finally be able to share science (as it should be)!</p>
<p><img src="https://media.idownloadblog.com/wp-content/uploads/2015/08/Steve-Jobs-One-More-Thing.jpg" alt="one more thing steve jobs" /></p>
<p>Oh, one more thing, the French board has been working hard to set up a virtual event at the end of September. This will help us wait until next May! You can find information <a href="https://pintofscience.com">here</a>.</p>
<p>Do not hesitate to support the organization by <a href="https://pintofscience.com/donate/">donating</a>.</p>
<p>Stay safe !</p>Florent DufourWhile there have been some back and forths on whether Pint of Science 2020 should take place or not, we decided it is safer, easier, and wiser to simply cancel this edition. Still, you shouldn’t worry much, we are intensively working on the brew for 2021We Simply Postponed Pint of Science!2020-05-01T00:00:00+02:002020-05-01T00:00:00+02:00https://blog.dufour.xyz/2020/POS-postponed<p>Pint of Science 2020 was expected to take place on the three evenings of the 11<sup>th</sup>, 12<sup>th</sup>, and 13<sup>th</sup> of May 2020 worldwide.</p>
<p>However, as you may have learned from elsewhere, the global COVID-19 situation and the extended containment period made us reconsider these dates. <!--more--> The situation has taken such an important and dramatic dimension that we decided it is safer for the event not to take place this early.</p>
<center>
<blockquote class="twitter-tweet" data-dnt="true" data-theme="light"><p lang="fr" dir="ltr"><a href="https://twitter.com/hashtag/pint20?src=hash&ref_src=twsrc%5Etfw">#pint20</a> est reporté du 7 au 9 septembre 😢<br /><br />Ce n'est pas une décision prise à la légère, mais nous pensons que c'est la bonne chose à faire.<br />Merci à nos merveilleux bénévoles et à vous qui nous suivez dans cette aventure ❤️<br /><br />Nous espérons vous voir en septembre pour <a href="https://twitter.com/hashtag/pint20?src=hash&ref_src=twsrc%5Etfw">#pint20</a> ! <a href="https://t.co/VnNgYc1mvv">pic.twitter.com/VnNgYc1mvv</a></p>— Pint of Science FR (@pintofscienceFR) <a href="https://twitter.com/pintofscienceFR/status/1239506926267961344?ref_src=twsrc%5Etfw">March 16, 2020</a></blockquote> <script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</center>
<p>We want Pint of Science to happen in the best conditions, as it has always had. Even though it requires a lot of rethink for the organizing teams and speakers, <em>the event will still take place in 2020, but on the evenings of the 7<sup>th</sup>, 8<sup>th</sup>, and 9<sup>th</sup> of September 2020!</em> Tickets sales are expected to start in early July! Yaaay!</p>
<p>We hope that everyone will recover until then and that we will be able to meet in bars to share science. However, if it happens not to be possible still, no worries ! We anticipate live streaming the talks on the internet. Therefore, we encourage you to safely keep a beer in your refrigerator!</p>
<p>Do not hesitate to support the organization by <a href="https://pintofscience.com/donate/">donating</a>.</p>
<p>Stay safe !</p>Florent DufourPint of Science 2020 was expected to take place on the three evenings of the 11th, 12th, and 13th of May 2020 worldwide. However, as you may have learned from elsewhere, the global COVID-19 situation and the extended containment period made us reconsider these dates.