<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Convalesco|notes</title>
  <subtitle>Ipsa scientia potestas est</subtitle>
  <id>http://www.convalesco.org/notes</id>
  <link href="http://www.convalesco.org/notes"/>
  <link href="http://www.convalesco.org/feed-notes.xml" rel="self"/>
  <updated>2025-08-10T09:11:00+03:00</updated>
  <author>
    <name>atmosx</name>
  </author>
  <entry>
    <title>ζ, η, θ Ο ξένος πρόσφυγας</title>
    <link rel="alternate" href="http://www.convalesco.org/notes/2025/08/10/zita-hta-thita-o-ksenos.html"/>
    <id>http://www.convalesco.org/notes/2025/08/10/zita-hta-thita-o-ksenos.html</id>
    <published>2025-08-10T09:11:00+03:00</published>
    <updated>2026-03-05T10:34:30+00:00</updated>
    <author>
      <name>atmosx</name>
    </author>
    <content type="html">&lt;h2 id="part-bacd3384a79e7b46"&gt;Εισαγωγή &amp;amp; Προσφυγικό&lt;/h2&gt;

&lt;p&gt;Στην παράσταση &amp;ldquo;&lt;a href="https://www.lifo.gr/guide/theater/news/z-i-th-o-xenos-mia-symparagogi-toy-kthbe-kai-toy-thok"&gt;ζ, η, θ Ο ξένος&lt;/a&gt;&amp;rdquo; ο &lt;a href="https://www.onassis.org/el/people/michail-marmarinos"&gt;Μιχαήλ Μαρμαρινός&lt;/a&gt; μας συστήνει τον Οδυσσέα, ως πανανθρώπινη, παγκόσμια νοητική εποπτεία στον ρόλο του &lt;strong&gt;ξένου&lt;/strong&gt;. Εγχείρημα φιλόδοξο, απαιτητικό και σύνθετο.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;[&amp;hellip;] Το έργο είναι μια ευκαιρία να συναντήσουμε την ενσυναίσθηση, μέσα από την περιπέτεια ενός άλλου [&amp;hellip;]&amp;rdquo; - Μιχαήλ Μαρμαρίνος, &lt;a href="https://youtu.be/v7zIClrGJNg?t=174"&gt;Euronews | YouTube&lt;/a&gt;, 03 Ιουλίου 2025.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Σύμφωνα με τον σκηνοθέτη, πρόκειται για μια ευκαιρία να μιλήσουμε για ενσυναίσθηση απέναντι στον ξένο με αφορμή το πρόβλημα των προσφυγικών ροών. Άλλωστε η χώρα μας δέχεται κατά μέσο όρο εκατό χιλιάδες πρόσφυγες ανά έτος τα τελευταία χρόνια&lt;sup id="fnref1"&gt;&lt;a href="#fn1"&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;h2 id="part-b36e76c5566383c8"&gt;Ο &amp;ldquo;ξένος&amp;rdquo; Οδυσσέας&lt;/h2&gt;

&lt;p&gt;Παρότι ο Οδυσσέας είναι ξένος, κατέχει &lt;em&gt;το όμαιμον, το ομόγλωσσον, το ομότροπον&lt;/em&gt; (ίδιο αίμα, γλώσσα &amp;amp; θρησκεία). Κατέχει τον ίδιο πολιτισμό με τους Φαίακες.&lt;/p&gt;

&lt;p&gt;Ο πολιτισμός του ανθρώπου, συμπεριλαμβάνει το πως και τι τρώει, πως σχετίζεται με τους γύρω του. Τι κάνει στον ελεύθερο του χρόνο, τι θαυμάζει και τι απεχθάνεται. Η γεωγραφική απόσταση μπορεί κάλλιστα να μετατρέψει τον έπαινο σε προσβολή, την ευχή σε κατάρα.&lt;/p&gt;

&lt;p&gt;Ο Οδυσσεάς είναι δίχως άλλο ο εξυπνότερος άνθρωπος της εποχής του.
Άλλωστε, ο Σοφοκλής θα τον παρουσιάσει ως γιο του &lt;a href="https://el.wikipedia.org/wiki/%CE%A3%CE%AF%CF%83%CF%85%CF%86%CE%BF%CF%82"&gt;Σισύφου&lt;/a&gt;, για να τονίσει την τέχνη του στη ρητορεία και την εξαπάτηση.&lt;/p&gt;

&lt;p&gt;Ο Οδυσσέας είναι ικανότατος ναυτικός αφού έχει γυρίσει όλη την μεσόγειο, μυθικού επιπέδου πολεμιστής ως &amp;ldquo;πορθητής&amp;rdquo; της Τροίας. Έχει αντιμετωπίσει την οργή του Ποσειδόνα κι είναι ακόμη ζωντανός. Μόνο θνητός με την εύνοια των θεών θα μπορούσε να το καταφέρει.&lt;/p&gt;

&lt;p&gt;Όταν φτάνει καταβεβλημένος στο νησί των Φαιάκων είναι εξαθλιωμένος.
Ταυτόχρονα είναι εμφανίσιμος με τα δεδομένα των κατοίκων. Η Ναυσικά βλέπει την ομορφιά πίσω από την εξαθλίωση κι εντυπωσιάζεται από τους τρόπους του. Ο ξένος μιλάει σε κάθε έναν που θα συναντήσει με τον βέλτιστο τρόπο. Με φράσεις, τρόπους και συμπεριφορές που κατανοούν.&lt;/p&gt;

&lt;p&gt;Θα γοητεύσει την Ναυσικά αλλά δεν θα την συνοδεύσει στο παλάτι για να μην την προσβάλει. Θα δείξει τον σεβασμό που απαιτείται στην Αρήτη πριν στραφεί προς τον Αλκίνοο, γιατί αντιλαμβάνεται ότι επηρεάζει την γνώμη του άρχοντα της πόλης και συζύγου της.&lt;/p&gt;

&lt;p&gt;Η γοητεία που ασκεί στους γύρο του είναι τόση που ο Αλκίνοος θα του προσφέρει το χέρι της
όμορφης κόρης του, πριν μάθει το όνομα του. Ο Αλκίνοος δεν είναι αφελής. Έχει αντιληφθεί πως αυτός ο &amp;ldquo;ξένος&amp;rdquo;, είναι από σπάνιο μέταλλο φτιαγμένος. Ανήκει στο παλάτι, κατέχει σοφία, μπορεί να σταθεί δίπλα σε άρχοντες, αν όχι να τους ξεπεράσει. Κι όλα αυτά, συνεχίζει να τα πιστεύει ακόμη κι όταν ο &amp;ldquo;ξένος&amp;rdquo; θα του μηνύσει πως δεν είναι Θεός. Γιατί με τέτοιο λόγο, για Θεό τον έκαναν. Αργότερα, θα ξεπεράσει στην δισκοβολία όλο το νησί. &lt;/p&gt;

&lt;p&gt;Κι έπειτα έρχεται η αποκάλυψη. Ο ξένος αποκτά όνομα, είναι &lt;strong&gt;ο Οδυσσέας&lt;/strong&gt;. Πριν λίγο τον παίνευε ο &lt;a href="https://el.wikipedia.org/wiki/%CE%94%CE%B7%CE%BC%CF%8C%CE%B4%CE%BF%CE%BA%CE%BF%CF%82_(%CE%A6%CE%B1%CE%AF%CE%B1%CE%BA%CE%B1%CF%82_%CE%B1%CE%BF%CE%B9%CE%B4%CF%8C%CF%82)"&gt;Δημόδοκος&lt;/a&gt;. Δημόδοκος σημαίνει &lt;em&gt;o ευπρόσδεκτος από τον λαό&lt;/em&gt;. Σαν να λέμε πως ο Οδυσσέας και οι πράξεις του, αποτελούν πράμα του μύθου για τους Φαίακες. Κατορθώματα που τραγουδά ο λαοφιλής αοιδός. Τα παιδιά ξέρουν τ&amp;rsquo; όνομα του, οι άρχοντες της πόλης γνωρίζουν για τα καμώματα του στην Τροία.&lt;/p&gt;

&lt;p&gt;Καλά το &amp;lsquo;χε καταλάβει ο Αλκίνοος και η Αρήτη πως δεν είναι τυχαίος αυτός ο &amp;ldquo;ξένος&amp;rdquo;. Τον έχει  προικίσει η μοίρα όσο λίγους. Είναι ζωντανός θρύλος. &lt;strong&gt;Δεν είναι ξένος&lt;/strong&gt;.&lt;/p&gt;

&lt;h2 id="part-c05f053ddfd2557c"&gt;Ο σύγχρονος πρόσφυγας ως ξένος&lt;/h2&gt;

&lt;p&gt;Πως να συγκρίνεις έναν ημίθεο, με έναν πρόσφυγα από την Συρία, το Αφγανιστάν ή την Σομαλία&lt;sup id="fnref2"&gt;&lt;a href="#fn2"&gt;2&lt;/a&gt;&lt;/sup&gt;;&lt;/p&gt;

&lt;p&gt;Ο άνθρωπος φοβάται τον ξένο που δεν μιλάει την γλώσσα του και δεν λατρεύει τους ίδιους Θεούς. Η προσπάθεια που απαιτείται είναι πολύ μεγαλύτερη από τον Αλκίνοο και τους Φαίακες που είχαν απέναντι τους έναν ημίθεο.&lt;/p&gt;

&lt;p&gt;Δημιουργήσαμε την &lt;a href="https://unric.org/el/%CE%BF%CE%B9%CE%BA%CE%BF%CF%85%CE%BC%CE%B5%CE%BD%CE%B9%CE%BA%CE%B7-%CE%B4%CE%B9%CE%B1%CE%BA%CE%B7%CF%81%CF%85%CE%BE%CE%B7-%CE%B3%CE%B9%CE%B1-%CF%84%CE%B1-%CE%B1%CE%BD%CE%B8%CF%81%CF%89%CF%80%CE%B9-2/"&gt;οικουμενική διακήρυξη για τα ανθρώπινα δικαιώματα&lt;/a&gt;. Αλλά τι μπορούν τα πολλά ωραία λόγια μπροστά στο φόβο που δημιουργεί η παρουσία του ξένου στις ακτές μας; Κι όμως, υπάρχουν φορές που καταφέραμε να φανούμε άνθρωποι. Γιατί αν ο βιολογικός άνθρωπος είναι απλό πράγμα, ο φιλοσοφικός είναι δύσκολο πολύ. Κι εμείς βαδίζουμε σαν τα καβούρια, προς τα πίσω, τα τελευταία δεκαπέντε χρόνια.&lt;/p&gt;

&lt;p&gt;Εν κατακλείδι, αντιλαμβάνομαι την αναλογία, αλλά παραμένει δύσπεπτη, σχεδόν άδικη στο δικό μου άντερο.&lt;/p&gt;

&lt;h2 id="h"&gt;H παράσταση&lt;/h2&gt;

&lt;p&gt;Όλα τα παραπάνω καθόλου δεν μειώνουν την αξία και την ανάγκη για εγχειρήματα σαν ετούτο.&lt;/p&gt;

&lt;p&gt;Η Όλγα Σέλλα έχει γράψει μια συγκροτημένη κριτική της παράστασης στην σελίδα &lt;a href="https://www.oanagnostis.gr/z-i-th-o-xenos-odysseia-m-marmarinos-mia-empneysmeni-stigmi-stin-epidayro-tis-olgas-sella/"&gt;oanagnostis&lt;/a&gt;. Έχει υπερθεματίσει την δυσκολία του εγχειρήματος, τα θετικά και τα αδύναμα σημεία της παράστασης. Τυχαίνει να συμφωνώ σε όλα, ένα προς ένα. Δεν έχει νόημα να ξαναγραφτούν, διαβάστε τα εκεί.&lt;/p&gt;

&lt;p&gt;Κάποιες από τις αμφιλεγόμενες επιλογές του σκηνοθέτη γίνονται αντιληπτές διαβάζοντας το ένθετο της παράστασης. Το συγκεκριμένο ένθετο, είναι θησαυρός για όποιον αγαπά την ανάλυση, τους συμβολισμούς και τις αναφορές. Η τιμή είναι πολύ χαμηλή για την ποιότητα του. Δεν γνωρίζω αν πωλείται στο διαδίκτυο, αν μπορέσετε να το διαβάσετε &lt;em&gt;πριν&lt;/em&gt; την παράσταση θα την απολαύσετε παραπάνω.&lt;/p&gt;

&lt;p&gt;Αν μπορούσα να πήγαινα και δεύτερη φορά να δω την παράσταση. Αλλιώς περιμένουμε με αγωνία την επόμενη παράσταση του Μιχαήλ Μαρμαρινού, κι εύχομαι να είναι κάτι παρόμοιο. Θα ήθελα πολύ για παράδειγμα να τον δω να μεταφέρει το &lt;a href="https://el.wikipedia.org/wiki/%CE%A3%CF%85%CE%BC%CF%80%CF%8C%CF%83%CE%B9%CE%BF_(%CE%A0%CE%BB%CE%B1%CF%84%CF%89%CE%BD%CE%B9%CE%BA%CF%8C%CF%82_%CE%B4%CE%B9%CE%AC%CE%BB%CE%BF%CE%B3%CE%BF%CF%82)"&gt;Πλατωνικό συμπόσιο&lt;/a&gt;. Θα είχε μεγάλο ενδιαφέρον η ματιά του Μαρμαρινού στο ομορφότερο, βαθύτερο και ειλικρινέστερο έργο στην ιστορία της ανθρωπότητας για την φύση του έρωτα. &lt;/p&gt;

&lt;div class="footnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;ΕΛΣΤΑΤ: Άλμα των μεταναστευτικών ροών το 2023 σε επίπεδα 2016, capital.gr - &lt;a href="https://www.capital.gr/epikairotita/3893781/elstat-alma-ton-metanasteutikon-roon-to-2023-se-epipeda-2016/"&gt;σύνδεσμος&lt;/a&gt;&amp;nbsp;&lt;a href="#fnref1"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn2"&gt;
&lt;p&gt;Οι κύριες εθνικότητες των αιτούντων άσυλο στην Ελλάδα είναι αυτές οι τρεις, rsaegean.org - &lt;a href="https://rsaegean.org/en/asylum-procedure-statistics-in-greece-2024/"&gt;σύνδεσμος&lt;/a&gt;&amp;nbsp;&lt;a href="#fnref2"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;
&lt;/div&gt;
</content>
  </entry>
  <entry>
    <title>Courchevel, France</title>
    <link rel="alternate" href="http://www.convalesco.org/notes/2025/06/26/courchevel.html"/>
    <id>http://www.convalesco.org/notes/2025/06/26/courchevel.html</id>
    <published>2025-06-26T11:55:00+03:00</published>
    <updated>2026-03-05T10:34:30+00:00</updated>
    <author>
      <name>atmosx</name>
    </author>
    <content type="html">&lt;h2 id="the-place"&gt;The Place&lt;/h2&gt;

&lt;p&gt;This year, I visited Courchevel for a &lt;a href="https://it.wikipedia.org/wiki/Settimana_bianca"&gt;settimana bianca&lt;/a&gt;. Courchevel is a ski resort nestled in the French Alps. We stayed in &lt;em&gt;Le Praz&lt;/em&gt;, a small, scenic village located at the lower end of the mountain.&lt;/p&gt;

&lt;p&gt;Courchevel is part of the &lt;em&gt;Three Valleys&lt;/em&gt; alongside Méribel and Val Thorens. These are three neighboring mountain areas, each leading to different villages, yet seamlessly connected by lifts and gondolas.&lt;/p&gt;

&lt;p&gt;Courchevel is composed by several villages, the most luxurious and internationally renowned being &lt;em&gt;Courchevel 1850&lt;/em&gt;. There you&amp;rsquo;ll find high-end fashion boutiques, fine jewelry stores, gourmet restaurants, and luxury hotels.&lt;/p&gt;

&lt;p&gt;The villages are linked by buses, taxis, and gondolas. From &lt;em&gt;Le Praz&lt;/em&gt;, it’s just a seven-minute gondola ride to &lt;em&gt;Courchevel 1850&lt;/em&gt;.&lt;/p&gt;

&lt;table&gt;&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: center"&gt;&lt;img src="/assets/images/blogposts/courchevel-2025-p1-56e3297d.jpg" title="Les Peupliers, Courchevel Le Praz, France" alt="Les Peupliers" /&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;1.1 Hotel Room View, Le Praz, Courchevel, France&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

&lt;h2 id="snowboarding"&gt;Snowboarding&lt;/h2&gt;

&lt;p&gt;I’ve never had as much fun snowboarding as I did on this trip. As usual, I arrived in Courchevel overweight and out of shape. But to my surprise, my body responded remarkably well to five days of snowboarding.&lt;/p&gt;

&lt;p&gt;The snow conditions were great. The entire week was sunny, with very few exceptions. The mountain was never full of people, although moguls were forming early on Sunday.&lt;/p&gt;

&lt;p&gt;Wisely, I took a rest day after the first three days, which gave me the energy to fully enjoy the final two. I hadn&amp;rsquo;t expected to pull it off. On the last day, we snowboarded from Courchevel to Val Thorens and back - a seven-hour journey, with more than four hours spent on the slopes. Some runs were nothing short of spectacular.&lt;/p&gt;

&lt;p&gt;The mountains are rich in blue and red pistes. Small difference between them in difficulty. The black runs, though, are unmistakable. We steered clear of them, not wanting an early end to the day due to muscle strain.&lt;/p&gt;

&lt;p&gt;I hope to repeat the experience next year and possibly enjoy it even more!&lt;/p&gt;

&lt;table&gt;&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: center"&gt;&lt;img src="/assets/images/blogposts/courchevel-2025-p2-66bdcfa6.jpg" title="Courchevel" alt="Courchevel" /&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;2.1 Roc Mugnier top, Courchevel, France&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

&lt;h2 id="the-vacation"&gt;The Vacation&lt;/h2&gt;

&lt;p&gt;My vacations are usually short, just two to five days. This time, I took an entire week and it was worth it. My mind had time to rest, while my body handled gracefully a manageable strain load.&lt;/p&gt;

&lt;p&gt;There are plenty of outdoor activities during the day, but not much nightlife. It makes sense: after burning calories on the slopes all day, there’s little energy left for late-night revelry. For those who like partying, there’s no shortage of après-ski spots on the mountain and in the village. Some rather famous on-track après-ski spots are &amp;ldquo;La Folie Duce&amp;rdquo;, &amp;ldquo;Baïes&amp;rdquo; and &amp;ldquo;Bagatelle&amp;rdquo;. We visited only the last one and we had a great time.&lt;/p&gt;

&lt;h2 id="the-team"&gt;The Team&lt;/h2&gt;

&lt;p&gt;We formed a tight-knit group of four this year: three Greeks and one Canadian, all former coworkers. It was a great mix. We&amp;rsquo;re all at roughly the same skill level, which kept us moving steadily through the mountains. More importantly, everyone’s easygoing, making it easy to enjoy both the rides and the surroundings together. That’s what makes this group special.&lt;/p&gt;

&lt;table&gt;&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: center"&gt;&lt;img src="/assets/images/blogposts/courchevel-2025-p3-d5a5386e.jpg" title="the team" alt="The team" /&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: center"&gt;3.1 The Team, Courchevel, France&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
</content>
  </entry>
  <entry>
    <title>Serene Reverie playlist</title>
    <link rel="alternate" href="http://www.convalesco.org/notes/2024/12/11/playlist-serene-reverie.html"/>
    <id>http://www.convalesco.org/notes/2024/12/11/playlist-serene-reverie.html</id>
    <published>2024-12-11T16:26:00+02:00</published>
    <updated>2026-03-05T10:34:30+00:00</updated>
    <author>
      <name>atmosx</name>
    </author>
    <content type="html">&lt;p&gt;Not long ago, the fashion house Brunello Cucinelli presented a Spotify playlist intriguingly titled &lt;a href="https://shop.brunellocucinelli.com/en-gr/symphony-of-emotions.html"&gt;Symphony of Emotions&lt;/a&gt;. What struck me most was the remarkable variation of tracks. A harmonious blend of genres that seemed at first glance incoherent. Yet, for someone with a taste for musical variety, the playlist’s mosaic of styles resonated with me, evoking a sense of familiarity and delight. I was familiar with most tracks anyway.&lt;/p&gt;

&lt;p&gt;Since the playlist was not available on &lt;a href="https://tidal.com/"&gt;Tidal&lt;/a&gt;, a high-resolution music streaming service, I decided to generate a personalised version of the playlist and voilà!&lt;/p&gt;

&lt;iframe src="https://embed.tidal.com/playlists/a2c936ca-7161-4c20-9251-eab4be4752fd" width="700" height="600" allow="encrypted-media" sandbox="allow-same-origin allow-scripts allow-forms allow-popups" title="TIDAL Embed Player" /&gt;&lt;/iframe&gt;

&lt;p&gt;Happy listening!&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>MiniDLNA Server on Raspberry Pi Model B</title>
    <link rel="alternate" href="http://www.convalesco.org/notes/2024/11/03/minidlna-raspberry-pi-model-b-server.html"/>
    <id>http://www.convalesco.org/notes/2024/11/03/minidlna-raspberry-pi-model-b-server.html</id>
    <published>2024-11-03T22:46:00+02:00</published>
    <updated>2026-03-05T10:34:30+00:00</updated>
    <author>
      <name>atmosx</name>
    </author>
    <content type="html">&lt;h2 id="table-of-contents"&gt;Table of Contents&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="#introduction"&gt;Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#hardware"&gt;Hardware Specs and Cost&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#limitations"&gt;Hardware Limitations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#system-setup"&gt;System setup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#configure-vsftpd"&gt;Configure vsFTPd&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#configure-minidlna"&gt;Configure miniDLNA&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#conclusion"&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;

&lt;p&gt;The Raspberry Pi Model B can serve as dedicated video streaming device. It&amp;rsquo;s small, silent, and doesn&amp;rsquo;t consume much power.
Given the Raspberry Pi&amp;rsquo;s limited specifications, it is not suited tasks for heavy-duty tasks, but it&amp;rsquo;s perfect for services such as &lt;a href="http://sourceforge.net/projects/minidlna/"&gt;miniDLNA&lt;/a&gt;.
MiniDLNA is a lightweight DLNA universal plug and play (UPnP) media server that can stream media files to video clients.&lt;/p&gt;

&lt;h2 id="hardware"&gt;Hardware Specs and Cost&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://www.raspberrypi.com/products/raspberry-pi-2-model-b/"&gt;Raspberry Pi Model B (Rev 2)&lt;/a&gt; runs on BCM2835 SoC featuring a &lt;strong&gt;700 MHz&lt;/strong&gt;, ARM11 dual core CPU (ARMv6 architecture) and &lt;strong&gt;512 MB&lt;/strong&gt; of RAM.
The Pi has 2 x USB 2.0 ports and 100Mbps ethernet. However the &lt;em&gt;actual&lt;/em&gt; data transfer speed is closer to 160 Mbps (~22 MB/s).&lt;/p&gt;

&lt;p&gt;The project will require a raspberry Pi case, EU RPi power cable, ethernet 10/100 cable, 512GB USB v2 drive
to store data and an 8GB SD card for the operating system and the applications that are going to be installed.&lt;/p&gt;

&lt;p&gt;In Greece, putting the required hardware together costs around 65€. The most likely target group for this post however, are techies
with spare parts lying around. Otherwise you might want to look for a modern alternative.&lt;/p&gt;

&lt;h2 id="limitations"&gt;Hardware Limitations&lt;/h2&gt;

&lt;p&gt;Using &lt;a href="https://iperf.fr/iperf-download.php"&gt;iperf3&lt;/a&gt; to measure bandwidth shows a maximum data transfer speed of approximately 80 Mbps.
Sustained speeds typically range from 40 to 60 Mbps for &lt;strong&gt;unencrypted connections&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Encryption significantly reduces data transfer speeds, with the Raspberry Pi&amp;rsquo;s CPU acting as a bottleneck for encryption and decryption processes.
The optimal way to upload media to the Pi is via FTP. If you need to use SSL, it&amp;rsquo;s better to terminate the SSL connection elsewhere.
Transferring 100MB of data through SSH took 81 seconds, while the same data transferred through FTP took around 22 seconds reaching an average speed of 40Mbps.&lt;/p&gt;

&lt;p&gt;Streaming 1080p content typically requires between 7 and 14 Mbps of bandwidth, depending on factors such as the codec, bitrate, number of audio streams, etc.
I have tested 720p and 1080p content and it worked without problems. In theory we should be able to stream 4k content as well, as it requires 25 to 35 Mbps, but I haven&amp;rsquo;t tested it.
I have not tested media transcoding on this device but I would advice against it.&lt;/p&gt;

&lt;h2 id="system-setup"&gt;System setup&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://dietpi.com/"&gt;DietPi&lt;/a&gt; and &lt;a href="https://www.freebsd.org/"&gt;FreeBSD&lt;/a&gt; are, IMO, the operating system of choice for Pi projects. In this case, I went with DietPi.
Follow the &lt;a href="https://dietpi.com/docs/install/"&gt;installation instructions&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;lsblk&lt;/code&gt; command lists available storage devices, while &lt;code&gt;mkfs.ext4&lt;/code&gt; formats the selected partition to the &lt;code&gt;ext4&lt;/code&gt; filesystem. That can be done using the &lt;code&gt;cfdisk&lt;/code&gt; command.
To format and mount the USB disk:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;lsblk
NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
sda           8:0    1 461.3G  0 disk
└─sda1        8:1    1 461.2G  0 part /mnt/data
mmcblk0     179:0    0   7.4G  0 disk
├─mmcblk0p1 179:1    0   128M  0 part /boot
└─mmcblk0p2 179:2    0   7.3G  0 part /

&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;mkfs.ext4 /dev/sda1
&lt;span class="o"&gt;[&lt;/span&gt;...]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now you should be able to mount the disk to the &lt;code&gt;/mnt/data&lt;/code&gt; directory and create the media directories:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;mount /dev/sda1 /mnt/data
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo mkdir&lt;/span&gt; /mnt/data/&lt;span class="o"&gt;{&lt;/span&gt;sports,family&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo chown &lt;/span&gt;dietpi:dietpi /mnt/data/&lt;span class="o"&gt;{&lt;/span&gt;sports,family&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;dietpi-drive_manager&lt;/code&gt; command can be used to configure the system to mount the USB drive automatically during startup.&lt;/p&gt;

&lt;h2 id="configure-vsftpd"&gt;Configure vsFTPd&lt;/h2&gt;

&lt;p&gt;The vsFTPd server allows secure file transfers over FTP. The settings provided ensure that users can only access specific directories and disable unnecessary features for a lightweight, secure setup.
The FTP protocol supports SSL, but it&amp;rsquo;s disabled in this setup to maximize data transfer speeds.
Assuming &lt;code&gt;vsFTPd&lt;/code&gt; has been installed, the configuration is set in file &lt;code&gt;/etc/vsftpd.conf&lt;/code&gt;: &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="n"&gt;userlist_deny&lt;/span&gt;=&lt;span class="n"&gt;YES&lt;/span&gt;
&lt;span class="n"&gt;local_root&lt;/span&gt;=/&lt;span class="n"&gt;mnt&lt;/span&gt;/&lt;span class="n"&gt;data&lt;/span&gt;
&lt;span class="n"&gt;listen&lt;/span&gt;=&lt;span class="n"&gt;YES&lt;/span&gt;
&lt;span class="n"&gt;listen_ipv6&lt;/span&gt;=&lt;span class="n"&gt;NO&lt;/span&gt;
&lt;span class="n"&gt;anonymous_enable&lt;/span&gt;=&lt;span class="n"&gt;NO&lt;/span&gt;
&lt;span class="n"&gt;local_enable&lt;/span&gt;=&lt;span class="n"&gt;YES&lt;/span&gt;
&lt;span class="n"&gt;write_enable&lt;/span&gt;=&lt;span class="n"&gt;YES&lt;/span&gt;
&lt;span class="n"&gt;local_umask&lt;/span&gt;=&lt;span class="m"&gt;002&lt;/span&gt;
&lt;span class="n"&gt;anon_upload_enable&lt;/span&gt;=&lt;span class="n"&gt;NO&lt;/span&gt;
&lt;span class="n"&gt;anon_mkdir_write_enable&lt;/span&gt;=&lt;span class="n"&gt;NO&lt;/span&gt;
&lt;span class="n"&gt;dirmessage_enable&lt;/span&gt;=&lt;span class="n"&gt;YES&lt;/span&gt;
&lt;span class="n"&gt;use_localtime&lt;/span&gt;=&lt;span class="n"&gt;YES&lt;/span&gt;
&lt;span class="n"&gt;connect_from_port_20&lt;/span&gt;=&lt;span class="n"&gt;YES&lt;/span&gt;
&lt;span class="n"&gt;chown_uploads&lt;/span&gt;=&lt;span class="n"&gt;NO&lt;/span&gt;
&lt;span class="n"&gt;xferlog_enable&lt;/span&gt;=&lt;span class="n"&gt;NO&lt;/span&gt;
&lt;span class="n"&gt;xferlog_file&lt;/span&gt;=/&lt;span class="n"&gt;var&lt;/span&gt;/&lt;span class="n"&gt;log&lt;/span&gt;/&lt;span class="n"&gt;vsftpd&lt;/span&gt;.&lt;span class="n"&gt;log&lt;/span&gt;
&lt;span class="n"&gt;xferlog_std_format&lt;/span&gt;=&lt;span class="n"&gt;YES&lt;/span&gt;
&lt;span class="n"&gt;idle_session_timeout&lt;/span&gt;=&lt;span class="m"&gt;60&lt;/span&gt;
&lt;span class="n"&gt;data_connection_timeout&lt;/span&gt;=&lt;span class="m"&gt;30&lt;/span&gt;
&lt;span class="n"&gt;async_abor_enable&lt;/span&gt;=&lt;span class="n"&gt;NO&lt;/span&gt;
&lt;span class="n"&gt;ascii_upload_enable&lt;/span&gt;=&lt;span class="n"&gt;NO&lt;/span&gt;
&lt;span class="n"&gt;ascii_download_enable&lt;/span&gt;=&lt;span class="n"&gt;NO&lt;/span&gt;
&lt;span class="n"&gt;ftpd_banner&lt;/span&gt;=&lt;span class="n"&gt;DietPi&lt;/span&gt; &lt;span class="n"&gt;FTP&lt;/span&gt;
&lt;span class="n"&gt;chroot_local_user&lt;/span&gt;=&lt;span class="n"&gt;NO&lt;/span&gt;
&lt;span class="n"&gt;chroot_list_enable&lt;/span&gt;=&lt;span class="n"&gt;NO&lt;/span&gt;
&lt;span class="n"&gt;ls_recurse_enable&lt;/span&gt;=&lt;span class="n"&gt;YES&lt;/span&gt;
&lt;span class="n"&gt;secure_chroot_dir&lt;/span&gt;=/&lt;span class="n"&gt;run&lt;/span&gt;/&lt;span class="n"&gt;vsftpd&lt;/span&gt;/&lt;span class="n"&gt;empty&lt;/span&gt;
&lt;span class="n"&gt;pam_service_name&lt;/span&gt;=&lt;span class="n"&gt;vsftpd&lt;/span&gt;
&lt;span class="c"&gt;# rsa_cert_file=/etc/ssl/private/vsftpd.pem
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The important part is the &lt;code&gt;local_root&lt;/code&gt; configuration here. This setup will make sure the &lt;code&gt;dietpi&lt;/code&gt; user can upload files only under the &lt;code&gt;/mnd/data&lt;/code&gt; directory. SSL is disabled of course.&lt;/p&gt;

&lt;h2 id="configure-minidlna"&gt;Configure miniDLNA&lt;/h2&gt;

&lt;p&gt;The miniDLNA configuration is set on &lt;code&gt;/etc/minidlna.conf&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="n"&gt;media_dir&lt;/span&gt;=&lt;span class="n"&gt;V&lt;/span&gt;,/&lt;span class="n"&gt;mnt&lt;/span&gt;/&lt;span class="n"&gt;data&lt;/span&gt;/&lt;span class="n"&gt;family&lt;/span&gt;
&lt;span class="n"&gt;media_dir&lt;/span&gt;=&lt;span class="n"&gt;V&lt;/span&gt;,/&lt;span class="n"&gt;mnt&lt;/span&gt;/&lt;span class="n"&gt;data&lt;/span&gt;/&lt;span class="n"&gt;sports&lt;/span&gt;
&lt;span class="n"&gt;db_dir&lt;/span&gt;=/&lt;span class="n"&gt;mnt&lt;/span&gt;/&lt;span class="n"&gt;dietpi_userdata&lt;/span&gt;/.&lt;span class="n"&gt;MiniDLNA_Cache&lt;/span&gt;
&lt;span class="n"&gt;log_level&lt;/span&gt;=&lt;span class="n"&gt;warn&lt;/span&gt;
&lt;span class="n"&gt;network_interface&lt;/span&gt;=&lt;span class="n"&gt;eth0&lt;/span&gt;
&lt;span class="n"&gt;port&lt;/span&gt;=&lt;span class="m"&gt;8200&lt;/span&gt;
&lt;span class="n"&gt;friendly_name&lt;/span&gt;=&lt;span class="n"&gt;DietPi&lt;/span&gt; &lt;span class="n"&gt;MiniDLNA&lt;/span&gt;
&lt;span class="n"&gt;serial&lt;/span&gt;=&lt;span class="m"&gt;12345678&lt;/span&gt;
&lt;span class="n"&gt;model_number&lt;/span&gt;=&lt;span class="m"&gt;1&lt;/span&gt;
&lt;span class="n"&gt;inotify&lt;/span&gt;=&lt;span class="n"&gt;yes&lt;/span&gt;
&lt;span class="n"&gt;album_art_names&lt;/span&gt;=&lt;span class="n"&gt;Cover&lt;/span&gt;.&lt;span class="n"&gt;jpg&lt;/span&gt;/&lt;span class="n"&gt;cover&lt;/span&gt;.&lt;span class="n"&gt;jpg&lt;/span&gt;/&lt;span class="n"&gt;AlbumArtSmall&lt;/span&gt;.&lt;span class="n"&gt;jpg&lt;/span&gt;/&lt;span class="n"&gt;albumartsmall&lt;/span&gt;.&lt;span class="n"&gt;jpg&lt;/span&gt;/&lt;span class="n"&gt;AlbumArt&lt;/span&gt;.&lt;span class="n"&gt;jpg&lt;/span&gt;/&lt;span class="n"&gt;albumart&lt;/span&gt;.&lt;span class="n"&gt;jpg&lt;/span&gt;/&lt;span class="n"&gt;Album&lt;/span&gt;.&lt;span class="n"&gt;jpg&lt;/span&gt;/&lt;span class="n"&gt;album&lt;/span&gt;.&lt;span class="n"&gt;jpg&lt;/span&gt;/&lt;span class="n"&gt;Folder&lt;/span&gt;.&lt;span class="n"&gt;jpg&lt;/span&gt;/&lt;span class="n"&gt;folder&lt;/span&gt;.&lt;span class="n"&gt;jpg&lt;/span&gt;/&lt;span class="n"&gt;Thumb&lt;/span&gt;.&lt;span class="n"&gt;jpg&lt;/span&gt;/&lt;span class="n"&gt;thumb&lt;/span&gt;.&lt;span class="n"&gt;jpg&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Once the configuration is properly set and the service starts, the media files will be available to DLNA/UPnP clients.
MiniDLNA can stream music and images as well.&lt;/p&gt;

&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;The Raspberry Pi Model B breathes new life as a capable media server, offering a cost-effective way to share files and media with loved ones. With a few simple steps, it transforms from an outdated device to a valuable tool for your digital needs.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Setup photoprism in Gentoo GNU/Linux</title>
    <link rel="alternate" href="http://www.convalesco.org/notes/2024/09/29/setup-photoprism-in-gentoo-gnu-linux.html"/>
    <id>http://www.convalesco.org/notes/2024/09/29/setup-photoprism-in-gentoo-gnu-linux.html</id>
    <published>2024-09-29T08:51:00+03:00</published>
    <updated>2026-03-05T10:34:30+00:00</updated>
    <author>
      <name>atmosx</name>
    </author>
    <content type="html">&lt;ul&gt;
&lt;li&gt;&lt;a href="#introduction"&gt;Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#prerequisites"&gt;Prerequisites&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="#storage-filesystem"&gt;Storage Filesystem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#setup-mysql-and-nginx"&gt;Setup MySQL and Nginx&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#nginx-configuration"&gt;Nginx Configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#website-configuration"&gt;Website Configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#tensorflow"&gt;TensorFlow&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#setting-up-photoprism"&gt;Setting Up PhotoPrism&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="#setting-up-photoprism-init-script"&gt;Setting Up Photoprism Init Script&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#setting-up-photoprism-directories"&gt;Setting Up Photoprism Directories&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#configuration-files"&gt;Configuration Files&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#user-management"&gt;User Management&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#closing-notes"&gt;Closing Notes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id="introduction" &gt;Introduction&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.photoprism.app/"&gt;PhotoPrism&lt;/a&gt; is an AI-powered photos app for the decentralized web. It leverages modern technologies to automatically tag and search pictures without getting in your way. You can run it at home, on a private server, or in the cloud. While the proposed installation method is via Docker, this guide uses &lt;strong&gt;MariaDB&lt;/strong&gt; as the database and &lt;strong&gt;Nginx&lt;/strong&gt; as the web server.&lt;/p&gt;

&lt;p&gt;This guide is specifically tailored for the Gentoo GNU/Linux distribution, but the steps should be similar for other distributions.&lt;/p&gt;

&lt;h2 id="prerequisites"&gt;Prerequisites&lt;/h2&gt;

&lt;p&gt;Ensure you have installed &lt;code&gt;ImageMagick&lt;/code&gt;, &lt;code&gt;ffmpeg&lt;/code&gt;, &lt;a href="https://wiki.gentoo.org/wiki/MariaDB"&gt;MariaDB&lt;/a&gt;, and &lt;a href="https://wiki.gentoo.org/wiki/Nginx"&gt;Nginx&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;PhotoPrism requires several libraries and tools for a smooth experience, especially for handling photo and video formats. You need to install these libraries manually. Add the following USE flags to your &lt;code&gt;/etc/portage/make.conf&lt;/code&gt; file:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;jpeg tiff avif heic png webp ffmpeg imagemagick
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Next, install the required packages:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;emerge &lt;span class="nt"&gt;-av&lt;/span&gt; www-servers/nginx dev-db/mariadb media-libs/libheif media-libs/libavif media-video/ffmpeg media-gfx/imagemagick
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: PhotoPrism can integrate with tools like &lt;a href="https://www.darktable.org/"&gt;DarkTable&lt;/a&gt; for professional photographers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id="storage-filesystem"&gt;Storage Filesystem&lt;/h3&gt;

&lt;p&gt;The microserver features four 2TB disk drives in a storage array and a 250GB SSD drive for the operating system. The storage layer runs in ZFS mirror (&lt;a href="https://en.wikipedia.org/wiki/Standard_RAID_levels#RAID_1"&gt;RAID1&lt;/a&gt;) mode, providing 4TB of usable space on a system that can tolerate one HDD failure&lt;sup id="fnref1"&gt;&lt;a href="#fn1"&gt;1&lt;/a&gt;&lt;/sup&gt; without data loss.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: I recommend using RAID5 instead of RAID1. RAID5 offers more space, better performance, and nearly the same level of reliability.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Filesystem configuration is out of the scope of this document.&lt;/p&gt;

&lt;h3 id="setup-mysql-and-nginx"&gt;Setup MySQL and Nginx&lt;/h3&gt;

&lt;p&gt;Setting up &lt;code&gt;MySQL&lt;/code&gt; is also out of the scope of this guide. You can follow the &lt;a href="https://mariadb.com/kb/en/getting-installing-and-upgrading-mariadb/"&gt;official documentation&lt;/a&gt; for assistance. Once the database is set up, create a new database and user for PhotoPrism:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;DATABASE&lt;/span&gt; &lt;span class="n"&gt;photoprism&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;USER&lt;/span&gt; &lt;span class="s1"&gt;'photoprism'&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="s1"&gt;'localhost'&lt;/span&gt; &lt;span class="n"&gt;IDENTIFIED&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="s1"&gt;'password123'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;GRANT&lt;/span&gt; &lt;span class="k"&gt;ALL&lt;/span&gt; &lt;span class="k"&gt;PRIVILEGES&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;photoprism&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="s1"&gt;'photoprism'&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="s1"&gt;'localhost'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;FLUSH&lt;/span&gt; &lt;span class="k"&gt;PRIVILEGES&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For SSL certificates and DNS, I am using AWS Route53, but this is a personal preference, so I&amp;rsquo;ll skip the setup here. Connections over VPN are secure, so SSL setup isn&amp;rsquo;t mandatory.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: To set up Let&amp;rsquo;s Encrypt with AWS Route53 DNS verification, I recommend using the &lt;a href="https://github.com/acmesh-official/acme.sh"&gt;acme-sh&lt;/a&gt; package (&lt;code&gt;app-crypt/acme-sh&lt;/code&gt; in Gentoo) instead of &lt;code&gt;certbot&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here is my Nginx configuration for PhotoPrism. Adjust it according to your needs:&lt;/p&gt;

&lt;h3 id="nginx-configuration"&gt;Nginx Configuration&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="c1"&gt;# /etc/nginx/nginx.conf&lt;/span&gt;
&lt;span class="k"&gt;user&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;worker_processes&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;error_log&lt;/span&gt; &lt;span class="n"&gt;/var/log/nginx/error_log&lt;/span&gt; &lt;span class="s"&gt;info&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;events&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;worker_connections&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="s"&gt;epoll&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;http&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;include&lt;/span&gt; &lt;span class="n"&gt;/etc/nginx/mime.types&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;default_type&lt;/span&gt; &lt;span class="nc"&gt;application/octet-stream&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kn"&gt;dav_methods&lt;/span&gt; &lt;span class="s"&gt;PUT&lt;/span&gt; &lt;span class="s"&gt;DELETE&lt;/span&gt; &lt;span class="s"&gt;MKCOL&lt;/span&gt; &lt;span class="s"&gt;COPY&lt;/span&gt; &lt;span class="s"&gt;MOVE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;dav_ext_methods&lt;/span&gt; &lt;span class="s"&gt;PROPFIND&lt;/span&gt; &lt;span class="s"&gt;OPTIONS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;log_format&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;
        &lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="nv"&gt;$remote_addr&lt;/span&gt; &lt;span class="s"&gt;-&lt;/span&gt; &lt;span class="nv"&gt;$remote_user&lt;/span&gt; &lt;span class="s"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$time_local&lt;/span&gt;&lt;span class="s"&gt;]&lt;/span&gt; &lt;span class="s"&gt;'&lt;/span&gt;
        &lt;span class="s"&gt;'"&lt;/span&gt;&lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt; &lt;span class="nv"&gt;$status&lt;/span&gt; &lt;span class="nv"&gt;$bytes_sent&lt;/span&gt; &lt;span class="s"&gt;'&lt;/span&gt;
        &lt;span class="s"&gt;'"&lt;/span&gt;&lt;span class="nv"&gt;$http_referer&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$http_user_agent&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt; &lt;span class="s"&gt;'&lt;/span&gt;
        &lt;span class="s"&gt;'"&lt;/span&gt;&lt;span class="nv"&gt;$gzip_ratio&lt;/span&gt;&lt;span class="s"&gt;"'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kn"&gt;client_header_timeout&lt;/span&gt; &lt;span class="mi"&gt;10m&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;client_body_timeout&lt;/span&gt; &lt;span class="mi"&gt;30m&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;client_max_body_size&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;create_full_put_path&lt;/span&gt; &lt;span class="no"&gt;on&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;client_body_temp_path&lt;/span&gt; &lt;span class="n"&gt;/tmp/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;send_timeout&lt;/span&gt; &lt;span class="mi"&gt;10m&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kn"&gt;connection_pool_size&lt;/span&gt; &lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;client_header_buffer_size&lt;/span&gt; &lt;span class="mi"&gt;4k&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;large_client_header_buffers&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="mi"&gt;2k&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;request_pool_size&lt;/span&gt; &lt;span class="mi"&gt;4k&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kn"&gt;gzip&lt;/span&gt; &lt;span class="no"&gt;on&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kn"&gt;output_buffers&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;32k&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;postpone_output&lt;/span&gt; &lt;span class="mi"&gt;1460&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kn"&gt;sendfile&lt;/span&gt; &lt;span class="no"&gt;on&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;tcp_nopush&lt;/span&gt; &lt;span class="no"&gt;on&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;tcp_nodelay&lt;/span&gt; &lt;span class="no"&gt;on&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kn"&gt;keepalive_timeout&lt;/span&gt; &lt;span class="mi"&gt;75&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kn"&gt;ignore_invalid_headers&lt;/span&gt; &lt;span class="no"&gt;on&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kn"&gt;index&lt;/span&gt; &lt;span class="s"&gt;index.html&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kn"&gt;include&lt;/span&gt; &lt;span class="n"&gt;/etc/nginx/conf.d/*.conf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="website-configuration"&gt;Website Configuration&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt; &lt;span class="s"&gt;ssl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kn"&gt;server_name&lt;/span&gt; &lt;span class="s"&gt;photoprism.example.com&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kn"&gt;ssl_certificate&lt;/span&gt; &lt;span class="n"&gt;/etc/acme-sh/example.com_ecc/fullchain.cer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kn"&gt;ssl_certificate_key&lt;/span&gt; &lt;span class="n"&gt;/etc/acme-sh/example.com_ecc/example.com.key&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kn"&gt;ssl_ciphers&lt;/span&gt; &lt;span class="s"&gt;ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kn"&gt;ssl_dhparam&lt;/span&gt; &lt;span class="n"&gt;/etc/nginx/ssl/dhparams.pem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kn"&gt;ssl_prefer_server_ciphers&lt;/span&gt; &lt;span class="no"&gt;on&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kn"&gt;ssl_protocols&lt;/span&gt; &lt;span class="s"&gt;TLSv1&lt;/span&gt; &lt;span class="s"&gt;TLSv1.1&lt;/span&gt; &lt;span class="s"&gt;TLSv1.2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kn"&gt;ssl_session_cache&lt;/span&gt; &lt;span class="s"&gt;shared:SSL:10m&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kn"&gt;ssl_session_timeout&lt;/span&gt; &lt;span class="mi"&gt;30m&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kn"&gt;client_max_body_size&lt;/span&gt; &lt;span class="mi"&gt;15G&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Forwarded-For&lt;/span&gt; &lt;span class="nv"&gt;$proxy_add_x_forwarded_for&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Forwarded-Proto&lt;/span&gt; &lt;span class="nv"&gt;$scheme&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kn"&gt;proxy_pass&lt;/span&gt; &lt;span class="s"&gt;http://localhost:2342&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kn"&gt;proxy_buffering&lt;/span&gt; &lt;span class="no"&gt;off&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;proxy_http_version&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="s"&gt;.1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;Host&lt;/span&gt; &lt;span class="nv"&gt;$host&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;Upgrade&lt;/span&gt; &lt;span class="nv"&gt;$http_upgrade&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;Connection&lt;/span&gt; &lt;span class="s"&gt;"upgrade"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;While the PhotoPrism developers recommend Traefik as a reverse proxy, I am using Nginx because I am more familiar with it.&lt;/p&gt;

&lt;h3 id="tensorflow"&gt;TensorFlow&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.tensorflow.org/"&gt;TensorFlow&lt;/a&gt; is required for face recognition, a highly desired feature for family photo libraries. Photoprism comes with tensorflow libraries, installed under &lt;code&gt;/opt/photoprism/tensorflow&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id="setting-up-photoprism"&gt;Setting Up PhotoPrism&lt;/h2&gt;

&lt;p&gt;There is no Portage package for PhotoPrism. It is distributed as a Go binary, which you can download from the &lt;a href="https://github.com/photoprism/photoprism/releases"&gt;GitHub repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;First, create the &lt;code&gt;photoprism&lt;/code&gt; user and group:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;groupadd photoprism
useradd &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; photoprism &lt;span class="nt"&gt;-d&lt;/span&gt; /opt/photoprism &lt;span class="nt"&gt;-s&lt;/span&gt; /sbin/nologin photoprism
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /opt/photoprism
&lt;span class="nb"&gt;id &lt;/span&gt;photoprism &lt;span class="c"&gt;# Verify setup&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Download and extract the latest version to the &lt;code&gt;/opt/photoprism&lt;/code&gt; directory:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /tmp &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; curl &lt;span class="nt"&gt;-LO&lt;/span&gt; https://github.com/photoprism/photoprism/releases/download/240915-e1280b2fb/photoprism_240915-e1280b2fb-linux-amd64.tar.gz
&lt;span class="nb"&gt;tar &lt;/span&gt;zxf &lt;span class="nt"&gt;-C&lt;/span&gt; /opt/photoprism photoprism_240915-e1280b2fb-linux-amd64.tar.gz
&lt;span class="nb"&gt;chown &lt;/span&gt;photoprism:photoprism &lt;span class="nt"&gt;-R&lt;/span&gt; /opt/photoprism
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can run the binary directly, but I recommend creating an OpenRC service.&lt;/p&gt;

&lt;h3 id="setting-up-photoprism-init-script"&gt;Setting Up Photoprism Init Script&lt;/h3&gt;

&lt;p&gt;Create the init configuration in &lt;code&gt;/etc/conf.d/photoprism&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# /etc/conf.d/photoprism&lt;/span&gt;
&lt;span class="c"&gt;# Global photoprism options&lt;/span&gt;
&lt;span class="nv"&gt;group&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"photoprism"&lt;/span&gt;
&lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"photoprism"&lt;/span&gt;

&lt;span class="c"&gt;# Photoprism configuration&lt;/span&gt;
&lt;span class="nv"&gt;pidfile&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/var/run/photoprism.pid"&lt;/span&gt;
&lt;span class="nv"&gt;log&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/var/log/photoprism/photoprism.log"&lt;/span&gt;
&lt;span class="nv"&gt;photoprism_defaults&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/etc/photoprism/defaults.yml"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And the init script at &lt;code&gt;/etc/init.d/photoprism&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/sbin/openrc-run&lt;/span&gt;

&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"photoprism"&lt;/span&gt;
&lt;span class="nv"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Manage pictures automatically"&lt;/span&gt;
&lt;span class="nb"&gt;command&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/opt/photoprism/bin/photoprism"&lt;/span&gt;
&lt;span class="nv"&gt;pidfile&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;pidfile&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="s2"&gt;"/run/&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;RC_SVCNAME&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.pid"&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
&lt;span class="nv"&gt;output_log&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;log&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nv"&gt;error_log&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;log&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="nv"&gt;root&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
&lt;span class="nv"&gt;group&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;group&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="nv"&gt;root&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
&lt;span class="nv"&gt;command_user&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;group&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="nv"&gt;command_args&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"--defaults-yaml &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;photoprism_defaults&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; --pid-filename &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;pidfile&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; --log-filename &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;log&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; start"&lt;/span&gt;
&lt;span class="nv"&gt;command_background&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"true"&lt;/span&gt;

depend&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    need net
    use logger
&lt;span class="o"&gt;}&lt;/span&gt;

start_pre&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    checkpath &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt; 0755 &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;:&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;group&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; /var/log/photoprism
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="setting-up-photoprism-directories"&gt;Setting Up Photoprism Directories&lt;/h3&gt;

&lt;p&gt;Create the necessary directories:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /storage/photoprism/&lt;span class="o"&gt;{&lt;/span&gt;originals,import&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="nb"&gt;chown &lt;/span&gt;photoprism:photoprism &lt;span class="nt"&gt;-R&lt;/span&gt; /storage/photoprism
&lt;span class="nb"&gt;mkdir&lt;/span&gt; /etc/photoprism
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The library will live under &lt;code&gt;/storage/photoprism/originals&lt;/code&gt;, and files added to &lt;code&gt;/storage/photoprism/import&lt;/code&gt; will be automatically imported.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: Following best practices, the library is stored on the HDD, while thumbnails are stored on the SSD.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id="configuration-files"&gt;Configuration Files&lt;/h3&gt;

&lt;p&gt;Create the &lt;code&gt;defaults.yml&lt;/code&gt; configuration file in &lt;code&gt;/etc/photoprism&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;ConfigPath&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/etc/photoprism"&lt;/span&gt;
&lt;span class="na"&gt;StoragePath&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/opt/photoprism/storage"&lt;/span&gt;
&lt;span class="na"&gt;OriginalsPath&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/storage/photoprism/originals"&lt;/span&gt;
&lt;span class="na"&gt;AssetsPath&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/opt/photoprism/assets"&lt;/span&gt;
&lt;span class="na"&gt;ImportPath&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/storage/photoprism/import"&lt;/span&gt;
&lt;span class="na"&gt;HttpPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2342&lt;/span&gt;
&lt;span class="nn"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then set up the &lt;code&gt;options.yml&lt;/code&gt; file, which includes MySQL configuration:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;AdminPassword&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;password&amp;gt;&lt;/span&gt;
&lt;span class="na"&gt;AdminUser&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;admin&lt;/span&gt;
&lt;span class="na"&gt;AutoImport&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;60&lt;/span&gt;
&lt;span class="na"&gt;DatabaseDriver&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql&lt;/span&gt;
&lt;span class="nn"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ensure the correct permissions:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chown &lt;/span&gt;photoprism:photoprism &lt;span class="nt"&gt;-R&lt;/span&gt; /etc/storage
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="user-management"&gt;User Management&lt;/h3&gt;

&lt;p&gt;The self-hosted community edition doesn&amp;rsquo;t come with user management support in the web interface. User management can be done via command line. The photoprism
binary serves as the command line interface. Lets check the existing users:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;/opt/photoprism/bin/photoprism &lt;span class="nb"&gt;users ls

&lt;/span&gt;INFO[2025-09-30T10:59:59+03:00] Become a member today, support our mission and enjoy our member benefits! 💎
INFO[2025-09-30T10:59:59+03:00] Visit https://www.photoprism.app/membership to learn more.
INFO[2025-09-30T10:59:59+03:00] found 3 &lt;span class="nb"&gt;users&lt;/span&gt;

┌──────────────────┬──────────┬───────┬────────────────┬─────────────┬───────────┬─────────┬─────────────┐
│       UID        │ Username │ Role  │ Authentication │ Super Admin │ Web Login │ WebDAV  │ Upload Path │
├──────────────────┼──────────┼───────┼────────────────┼─────────────┼───────────┼─────────┼─────────────┤
│ id1              │ admin    │ Admin │ Local          │ Yes         │ Enabled   │ Enabled │             │
│ id2              │ john     │ Admin │ Local          │ No          │ Disabled  │ Enabled │ john        │
│ id3              │ rita     │ Admin │ Local          │ No          │ Enabled   │ Enabled │ rita        │
└──────────────────┴──────────┴───────┴────────────────┴─────────────┴───────────┴─────────┴─────────────┘

DEBU[2025-09-30T10:59:59+03:00] closed database connection
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Lets assume John Maynard Keynes is still alive, teaching at the University of Cambridge. To add JMK to Photoprism:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;/opt/photoprism/bin/photoprism &lt;span class="nb"&gt;users &lt;/span&gt;add &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"John Maynard Keynes"&lt;/span&gt; &lt;span class="nt"&gt;--email&lt;/span&gt; &lt;span class="s2"&gt;"jm.keynes@cam.ac.uk"&lt;/span&gt; &lt;span class="nt"&gt;--password&lt;/span&gt; superduperpassword &lt;span class="nt"&gt;--webdav&lt;/span&gt; &lt;span class="nt"&gt;--auth&lt;/span&gt; &lt;span class="nb"&gt;local &lt;/span&gt;keynes

INFO[2025-09-30T11:05:07+03:00] Become a member today, support our mission and enjoy our member benefits! 💎
INFO[2025-09-30T11:05:07+03:00] Visit https://www.photoprism.app/membership to learn more.
INFO[2025-09-30T11:05:07+03:00] successfully added user &lt;span class="s1"&gt;'keynes'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now lets make sure mr Keynes can upload pictures from his travels in Bretton Woods, US via iPhone using the webdav protocol:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;/opt/photoprism/bin/photoprism auth add &lt;span class="nt"&gt;--scope&lt;/span&gt; webdav &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"J.M. Keynes"&lt;/span&gt; keynes

INFO[2025-09-30T11:08:53+03:00] Become a member today, support our mission and enjoy our member benefits! 💎
INFO[2025-09-30T11:08:53+03:00] Visit https://www.photoprism.app/membership to learn more.

PLEASE COPY THE FOLLOWING RANDOMLY GENERATED APP PASSWORD AND KEEP IT IN A SAFE PLACE, AS YOU WILL NOT BE ABLE TO SEE IT AGAIN:

┌─────────────────────────────┬─────────────────────┐
│ App Password                │ Authorization Scope │
│ gXBudt-zh3NHI-Wzg2Uh-0DWUGF │ webdav              │
└─────────────────────────────┴─────────────────────┘

DEBU[2025-09-30T11:08:53+03:00] closed database connection
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now mr Keynes upload pictures and videos to Photoprism using the following webdav credentials:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;username: keynes
password: gXBudt-zh3NHI-Wzg2Uh-0DWUGF
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="closing-notes"&gt;Closing Notes&lt;/h2&gt;

&lt;p&gt;Explore PhotoPrism to understand its logic. With this setup, adding files to the &lt;code&gt;/import&lt;/code&gt; directory will trigger an import workflow after about 60 seconds.&lt;/p&gt;

&lt;p&gt;Use &lt;code&gt;/var/log/photoprism/photoprism.log&lt;/code&gt; for debugging startup issues. Photoprism can be finicky about permissions, so carefully review your setup.&lt;/p&gt;

&lt;div class="footnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;Under circumstances the system could support simultaneously two HDDs failures, assuming they don&amp;rsquo;t belong to the same source-mirror pair.&amp;nbsp;&lt;a href="#fnref1"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;
&lt;/div&gt;
</content>
  </entry>
  <entry>
    <title>Vancouver BC, Canada</title>
    <link rel="alternate" href="http://www.convalesco.org/notes/2024/09/06/travels-vancouver-canada.html"/>
    <id>http://www.convalesco.org/notes/2024/09/06/travels-vancouver-canada.html</id>
    <published>2024-09-06T17:02:00+03:00</published>
    <updated>2026-03-05T10:34:30+00:00</updated>
    <author>
      <name>atmosx</name>
    </author>
    <content type="html">&lt;p&gt;The weather is chilly during the summer and not only in terms of temperature.
There is an indiscernible fog over Vancouver’s inner harbour.
The harbour is part of the &lt;a href="https://en.wikipedia.org/wiki/Burrard_Inlet"&gt;Burrard inlet&lt;/a&gt;.
A shallow impressive fjord. The sky and mountains feel always wet from afar, even during sunny days.&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/blogposts/vancouver-bc-p2-b465e81a.jpg" title="Stanley Park, Vancouver BC, Canada" alt="Stanley Park, Vancouver, BC, Canada" /&gt;
&lt;div class="image-caption"&gt;
    Stanley Park, Vancouver BC, Canada. August 2024.
&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;The sidewalks are wide, in pristine conditions. Lots of green. The skyscrapers are similar the ones in the United States.
The bay area and the &lt;a href="https://en.wikipedia.org/wiki/Stanley_Park"&gt;Stanley park&lt;/a&gt; are great places for a stroll.
People seem welcoming. Lots of well integrated immigrants. I would love to learn more about the locals. Their daily problems, beliefs and culture.
British, French and American influence is everywhere. The hotel featured &lt;a href="https://en.wikipedia.org/wiki/Ionic_order"&gt;ionic style&lt;/a&gt; columns.
A strong Asian presence makes the place feel multi-racial and multi-cultural.&lt;/p&gt;

&lt;p&gt;We came across immigrants from India. Many work as uber drivers on the side. Distant yet polite.
Judging by the Turbans, they must be &lt;a href="https://en.wikipedia.org/wiki/Sikhs"&gt;Sikhs&lt;/a&gt;.
You have to appreciate their calm, kind and rule-abiding temperament. Something Mediterranean populations lack.
Maybe their religion and culture has something to do with it.&lt;/p&gt;

&lt;p&gt;&lt;img src="/assets/images/blogposts/vancouver-bc-p1-8841eeb9.jpg" title="The city of Vancouver BC, Canada" alt="The city of Vancouver, BC, Canada" /&gt;
&lt;div class="image-caption"&gt;
    The city of Vancouver BC, Canada. August 2024.
&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;There are numerous Asian restaurants in the city. We tried one. The food is good. 
My coworkers are well versed in Asian cuisine. I need to learn how to appreciate it. The steak house we tried was outstanding.&lt;/p&gt;

&lt;p&gt;I’m not sure if such a thing as &lt;em&gt;local food&lt;/em&gt; exists in British Columbia.
There were a few high-end restaurants advertising local and French fusion cuisine, so there must be &lt;em&gt;something&lt;/em&gt;?!
The ice-cream was good enough for me to make room for one ice-cream per day.&lt;/p&gt;

&lt;p&gt;I never thought that I would see so many Tesla cars in one city. I dare say that the most popular car-maker in Vancouver, British Columbia must be Tesla.
The city was full of charging stations and that with electric car adoption!&lt;/p&gt;

&lt;p&gt;I&amp;rsquo;ve heard that winters in Vancouver are infamous. I have no idea, obviously. How bad can it be?&lt;/p&gt;
</content>
  </entry>
</feed>
