<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Helmut Tammen</title>
    <link>https://text.tchncs.de/htammen/</link>
    <description>I have a great interest in FOSS and the Fediverse. In this blog I will occasionally publish my insights and opinions on these topics.</description>
    <pubDate>Sun, 05 Apr 2026 01:56:45 +0000</pubDate>
    <item>
      <title>Use Signal messenger to get informed about IP changes</title>
      <link>https://text.tchncs.de/htammen/use-signal-messenger-to-get-informed-about-ip-changes</link>
      <description>&lt;![CDATA[I&#39;m running my own Nextcloud server on a Raspberry PI. This is accessible from the internet. It works really fine.&#xA;&#xA;But sometimes my internet provider changes my IP address overnight. In the beginning, I used a dyndns service to update the IP address immediately from my browser. But I wanted to use my own domain name and not the one from the dns service and it shouldn&#39;t cost anything.&#xA;&#xA;So I created subdomains for my own domain and redirect those from my domain provider to my home router. From there I go to reverse proxy (nginx) and then to my Nextcloud server.&#xA;&#xA;Browser --  domain provider --  home router --  nginx --  Nextcloud server&#xA;&#xA;But every time my internet provider gives me a new IP address, my Nextcloud is not accessible anymore.&#xA;&#xA;In this blog post I describe how I (semi-automatically) solved the problem.&#xA;&#xA;!--more--&#xA;The problem&#xA;&#xA;Everytime I got a new IP address I had to &#xA;&#xA;open the web-ui of my router,&#xA;copy the new IP address,&#xA;open the web-ui of my domain provider,&#xA;open the settings dialog of my subdomain,&#xA;paste the new IP address into the A-Record of the subdomain and save it.&#xA;&#xA;This does not sound to be a time-consuming task and of course it&#39;s done in 5 minutes. But I didn&#39;t get informed about the change of the IP address and so I recognized the IP change when I tried to access my Nextcloud the next time.  &#xA;Because also my family, who live in their own houses, use the Nextcloud they also could not access it.   &#xA;You all know that if people use an internet service they want it to be available 24/7. If the service is not available a lot of times they don&#39;t use it. But I want my family to use my Nextcloud and not those data hungry services from the big Data octopuses.&#xA; &#xA;The solution&#xA;&#xA;So I thought about how I could minimize the downtime of my service.&#xA;&#xA;Unfortunately my domain provider does not offer an API to manage my subdomains. They only offer a web-ui. &#xA;&#xA;That&#39;s why I created this semi-automactic solution.&#xA;&#xA;On my Nextcloud server every early morning (the ip address change happens at night) I run a cron job which checks the public IP address of my router and the public IP address of my subdomain.&#xA;&#xA;If they are not the same I know that the public IP adress of my router has been changed. I then send a message to myself via the signal messenger. This message of course already contains the new IP address.  &#xA;When I awake in the morning I see the message at my smartphone and can quickly change the IP address for my subdomain at my domain provider.  &#xA;So there should only be a few hours of unavailability during the night, which is absolutely ok for my usecase. &#xA;&#xA;Technical details&#xA;&#xA;Getting the IP addresses&#xA;&#xA;I first had to retrieve the IP addresses of my router and of my subdomain. On Linux there is the dns lookup utility with the program dig. Sending &#xA;&#xA;dig +short url &#xA;&#xA;returns the IP address of the url.&#xA;&#xA;Sending a message from Linux via Signal&#xA;&#xA;Next I had to figure out how to send a signal message from a Linux pc. I quickly found this github repository. The docker container, that gets setup if you follow the description of the repo lets you send messages via http. So I only have to use curl from my Linux system. &#xA;I of course could have used the official Signal API but using this docker container was a no-brainer.&#xA;&#xA;Combining in a bash script&#xA;&#xA;I then wrote a small bash script that retrieves the IP addresses, compares them and sends a message if they differ.&#xA;&#xA;! /bin/bash&#xA;&#xA;publicip=$(dig +short xxx.myfritz.net)&#xA;nextcloudip=$(dig +short mynextcloudsubdomain.tammen-it-solutions.de)&#xA;if [[ $publicip != $nextcloudip ]]; then &#xA;  message=&#34;Die Fritzbox IP Adresse hat sich geändert\nBitte beim domain provider die A-records der Sub-Domains anpassen\nNeue IP: $publicip&#34;&#xA;  data=&#34;{\&#34;message\&#34;: \&#34;$message\&#34;, \&#34;number\&#34;: \&#34;+4911111111\&#34;, \&#34;recipients\&#34;: [\&#34;+4911111111\&#34;]}&#34;&#xA;  $(curl --silent -X POST -H &#34;Content-Type: application/json&#34; &#39;http://localhost:8090/v2/send&#39; -d &#34;$data&#34;)&#xA;fi&#xA;&#xA;Creating the cron job&#xA;&#xA;The last step was to create a crontab entry that invokes my script early in the morning every day.  &#xA;crontab -e  &#xA;opens the crontab editor. I added this line and that&#39;s it.   &#xA;5 5   * /home/helmutpi/signal/publicip_monitor&#xA;&#xA;Every morning at 05:05 the system checks if the IP address has changed and, if so, sends me a message.]]&gt;</description>
      <content:encoded><![CDATA[<p>I&#39;m running my own Nextcloud server on a Raspberry PI. This is accessible from the internet. It works really fine.</p>

<p>But sometimes my internet provider changes my IP address overnight. In the beginning, I used a dyndns service to update the IP address immediately from my browser. But I wanted to use my own domain name and not the one from the dns service and it shouldn&#39;t cost anything.</p>

<p>So I created subdomains for my own domain and redirect those from my domain provider to my home router. From there I go to reverse proxy (nginx) and then to my Nextcloud server.</p>

<p>Browser —&gt; domain provider —&gt; home router —&gt; nginx —&gt; Nextcloud server</p>

<p>But every time my internet provider gives me a new IP address, my Nextcloud is not accessible anymore.</p>

<p>In this blog post I describe how I (semi-automatically) solved the problem.</p>



<h2 id="the-problem">The problem</h2>

<p>Everytime I got a new IP address I had to</p>
<ul><li>open the web-ui of my router,</li>
<li>copy the new IP address,</li>
<li>open the web-ui of my domain provider,</li>
<li>open the settings dialog of my subdomain,</li>
<li>paste the new IP address into the A-Record of the subdomain and save it.</li></ul>

<p>This does not sound to be a time-consuming task and of course it&#39;s done in 5 minutes. But I didn&#39;t get informed about the change of the IP address and so I recognized the IP change when I tried to access my Nextcloud the next time.<br>
Because also my family, who live in their own houses, use the Nextcloud they also could not access it.<br>
You all know that if people use an internet service they want it to be available 24/7. If the service is not available a lot of times they don&#39;t use it. But I want my family to use my Nextcloud and not those data hungry services from the big Data octopuses.</p>

<h2 id="the-solution">The solution</h2>

<p>So I thought about how I could minimize the downtime of my service.</p>

<p>Unfortunately my domain provider does not offer an API to manage my subdomains. They only offer a web-ui.</p>

<p>That&#39;s why I created this semi-automactic solution.</p>

<p>On my Nextcloud server every early morning (the ip address change happens at night) I run a cron job which checks the public IP address of my router and the public IP address of my subdomain.</p>

<p>If they are not the same I know that the public IP adress of my router has been changed. I then send a message to myself via the <a href="https://signal.org/" rel="nofollow">signal</a> messenger. This message of course already contains the new IP address.<br>
When I awake in the morning I see the message at my smartphone and can quickly change the IP address for my subdomain at my domain provider.<br>
So there should only be a few hours of unavailability during the night, which is absolutely ok for my usecase.</p>

<h2 id="technical-details">Technical details</h2>

<h3 id="getting-the-ip-addresses">Getting the IP addresses</h3>

<p>I first had to retrieve the IP addresses of my router and of my subdomain. On Linux there is the dns lookup utility with the program <code>dig</code>. Sending</p>

<p><code>dig +short &lt;url&gt;</code></p>

<p>returns the IP address of the url.</p>

<h3 id="sending-a-message-from-linux-via-signal">Sending a message from Linux via Signal</h3>

<p>Next I had to figure out how to send a signal message from a Linux pc. I quickly found this <a href="https://github.com/bbernhard/signal-cli-rest-api" rel="nofollow">github repository</a>. The docker container, that gets setup if you follow the description of the repo lets you send messages via http. So I only have to use curl from my Linux system.
I of course could have used the official Signal API but using this docker container was a no-brainer.</p>

<h3 id="combining-in-a-bash-script">Combining in a bash script</h3>

<p>I then wrote a small bash script that retrieves the IP addresses, compares them and sends a message if they differ.</p>

<pre><code class="language-bash">#! /bin/bash

public_ip=$(dig +short xxx.myfritz.net)
nextcloud_ip=$(dig +short mynextcloudsubdomain.tammen-it-solutions.de)
if [[ $public_ip != $nextcloud_ip ]]; then 
  message=&#34;Die Fritzbox IP Adresse hat sich geändert\nBitte beim domain provider die A-records der Sub-Domains anpassen\nNeue IP: $public_ip&#34;
  data=&#34;{\&#34;message\&#34;: \&#34;$message\&#34;, \&#34;number\&#34;: \&#34;+4911111111\&#34;, \&#34;recipients\&#34;: [\&#34;+4911111111\&#34;]}&#34;
  $(curl --silent -X POST -H &#34;Content-Type: application/json&#34; &#39;http://localhost:8090/v2/send&#39; -d &#34;$data&#34;)
fi
</code></pre>

<h3 id="creating-the-cron-job">Creating the cron job</h3>

<p>The last step was to create a crontab entry that invokes my script early in the morning every day.<br>
<code>crontab -e</code><br>
opens the crontab editor. I added this line and that&#39;s it.<br>
<code>5 5 * * * /home/helmutpi/signal/public_ip_monitor</code></p>

<p>Every morning at 05:05 the system checks if the IP address has changed and, if so, sends me a message.</p>
]]></content:encoded>
      <guid>https://text.tchncs.de/htammen/use-signal-messenger-to-get-informed-about-ip-changes</guid>
      <pubDate>Wed, 24 Jul 2024 13:08:36 +0000</pubDate>
    </item>
    <item>
      <title>Frontend Business Rules Engine with UI5</title>
      <link>https://text.tchncs.de/htammen/for-the-source-have-a-look-at-my-github-account</link>
      <description>&lt;![CDATA[For the source have a look at my github account&#xA;!--more--&#xA;&lt;iframe style=&#34;            &#xA;            margin: 0px; &#xA;            padding: 0px; &#xA;            height: 100%; &#xA;            border: none; &#xA;            display: block; &#xA;            width: 100%; &#xA;            height: 600px;&#xA;            border: none; &#xA;            overflow-y: auto; &#xA;            overflow-x: hidden; &#34; &#xA;src=&#34;https://docsify-this.net/?basePath=https://raw.githubusercontent.com/htammen/ui5-json-rules-engine/master&amp;homepage=README.md&amp;sidebar=true&amp;link-color=1eab48#/?id=frontend-business-rules-engine-with-ui5&#34; frameborder=&#34;0&#34; &#xA;    marginheight=&#34;0&#34; &#xA;    marginwidth=&#34;0&#34; &#xA;    width=&#34;100%&#34; &#xA;    height=&#34;2000px&#34;  /iframe]]&gt;</description>
      <content:encoded><![CDATA[<p>For the source have a look at my <a href="https://github.com/htammen/ui5-json-rules-engine" rel="nofollow">github account</a>

<iframe style="            
            margin: 0px; 
            padding: 0px; 
            height: 100%; 
            border: none; 
            display: block; 
            width: 100%; 
            height: 600px;
            border: none; 
            overflow-y: auto; 
            overflow-x: hidden; " src="https://docsify-this.net/?basePath=https://raw.githubusercontent.com/htammen/ui5-json-rules-engine/master&amp;homepage=README.md&amp;sidebar=true&amp;link-color=1eab48#/?id=frontend-business-rules-engine-with-ui5" frameborder="0"></iframe></p>
]]></content:encoded>
      <guid>https://text.tchncs.de/htammen/for-the-source-have-a-look-at-my-github-account</guid>
      <pubDate>Sun, 30 Jun 2024 15:16:34 +0000</pubDate>
    </item>
    <item>
      <title>Leveraging DuckDB to convert csv into xlsx</title>
      <link>https://text.tchncs.de/htammen/leveraging-duckdb-to-convert-csv-into-xlsx</link>
      <description>&lt;![CDATA[When reading the headline you probably think &#34;what the hell does he do? Why does he not import the csv file into Excel and manage it there?&#34;&#xA;&#xA;Here are the reasons&#xA;&#xA;I don&#39;t like Excel.&#xA;My source csv file needs to be converted before generating the Excel file.&#xA;I wanted to explore DuckDB.&#xA;&#xA;TL;DR: Go to the source files at the very bottom of this blog post.&#xA;!--more--&#xA;&#xA;Business Use Case&#xA;&#xA;Before I describe the technical details I briefly describe my business use case.&#xA;&#xA;I record my working times with the really great tool prima:Time. But as with most tools there are things you miss. One thing I miss in prima:Time is that I can export my data in a format my customers expect.&#xA;&#xA;My current customers request an Excel file in a format (template) they have defined.&#xA;&#xA;Of course prima:Time can export to csv and even to xls, but those files or, to be exact, the columns of those files don&#39;t have the format my customers expect.&#xA;&#xA;Cause I stumbled across DuckDB recently and thought it would be worse to explore it I decided to create a solution for my business case with it.&#xA;&#xA;About DuckDB&#xA;&#xA;I first heard of DuckDB from Golo Roden in his Youtube VLOG. That made me curious.&#xA;&#xA;&#34;DuckDB is a fast in-process analytical database&#34; they say at their homepage. Sounds like it is a lightweight version of SAP HANA.  &#xA;&#xA;In-process means that it does not run in an independent database server but in the same process as your application. If you stop your application the DuckDB database also is no longer available. In this respect DuckDB behaves like SQLite.  &#xA;Nevertheless you can of cource save the data to a single database file.&#xA;&#xA;It integrates with a lot of external datasources like PostgreSQL, MySQL, AWS, Azure, ...  &#xA;It is highly portable which means that it runs on almost all OS. Furthermore it can handle up to terabytes of data and hundreds of CPUs.&#xA;&#xA;It is feature rich. Besides support for the complete SQL syntax it also has a large function library.&#xA;&#xA;It has also a lot of Client APIs. Just to name a few:&#xA;&#xA;R&#xA;Java&#xA;C++&#xA;Python&#xA;Node.js&#xA;CLI&#xA;...&#xA;&#xA;Yes, there is also a CLI and that&#39;s what I have used for my use case.&#xA;&#xA;As analytical database it&#39;s also supposed to be very fast.&#xA;&#xA;Last but not least DuckDB is available under MIT license which means it is free.&#xA;&#xA;DuckDB and CSV files&#xA;&#xA;One of the integrations that caught my attention was the one with csv files. You can easily import csv files into a database table.  &#xA;&#xA;Thanks to it&#39;s large function library you can even convert the csv data while importing it. After import you then have a database table with field types like DATE, TIME, INTEGER, DOUBLE, ... &#xA;&#xA;Having such a table you can run all sorts of database queries.&#xA;&#xA;I imported all my timesheet data into my DuckDB database and converted the data during the import. It&#39;s not big, but it has more than 5000 records. &#xA;&#xA;I&#39;m now able to run additional evaluations that I miss in prime:Time.&#xA;&#xA;My business use case in practice&#xA;&#xA;Let&#39;s come to my use case.&#xA;&#xA;Import my csv file into a database table&#xA;&#xA;From prima:time I exported a csv file like this&#xA;DATUM,VON,BIS,DAUER,DAUER (STUNDEN),BENUTZER,KUNDE,PROJEKTCODE,PROJEKT,AUFGABE,TÄTIGKEIT,BESCHREIBUNG,INTERNE BEMERKUNG,ABRECHENBARE ZEIT&#xA;03.06.2024,09:00,09:30,00:30,&#34;0,50&#34;,Tammen Helmut,Customer1,Projekt 1,Customer1 - Projekt 1,TPM (Techn. Projekt Management) ,Remote,&#34;Abstimmung mit Peter Urlaubsübergabe&#34;,,00:30&#xA;10.06.2024,09:30,11:30,02:00,&#34;2,00&#34;,Tammen Helmut,Customer1,Projekt 1,Customer1 - Projekt 1,TPM (Techn. Projekt Management) ,Remote,&#34;Planning Sprint 8&#34;,PRJ1-460,02:00&#xA;&#xA;You see that prima:Time exported a lot of columns. Let us have a deeper look at some of them&#xA;&#xA;VON (from). This is a time field, but it is delivered in the format hh:mm, e.g. 09:30&#xA;BIS (until). This is also a time field&#xA;&#34;DAUER (STUNDEN)&#34; (duration). This is a double field. It&#39;s delivered in the format xx,yy.&#xA;&#xA;The TIME fields are delivered with format hh:mm, but DuckDB needs the format hh:mm:ss to automatically recognize them as TIME fields. &#xA;&#xA;The duration field &#34;DAUER (STUNDEN)&#34; is a decimal field formatted with my local (german) format. In Germany we use a &#34;,&#34; as decimal separator. Databases and programming languages use a &#34;.&#34; for this.&#xA; &#xA;DuckDB offers the possibilty to convert those field on import of a csv file. Here is my SQL that imports a file, converts some fields and create a database table.&#xA;&#xA;CREATE TEMP TABLE tsmonth AS &#xA;  (SELECT DATUM, &#xA;          cast((von || &#39;:00&#39;) as TIME) as VON, &#xA;          cast((bis || &#39;:00&#39;) as TIME) as BIS, &#xA;          cast((DAUER || &#39;:00&#39;) as TIME) as DAUER, &#xA;          cast(replace(&#34;DAUER (STUNDEN)&#34;, &#39;,&#39;, &#39;.&#39;) as DOUBLE) as DAUERSTD,&#xA;          BENUTZER, KUNDE, PROJEKTCODE, AUFGABE, TÄTIGKEIT AS TAETIGKEIT, BESCHREIBUNG, &#34;INTERNE BEMERKUNG&#34; as BEMERKUNG, &#xA;          cast((&#34;ABRECHENBARE ZEIT&#34; || &#39;:00&#39;) as TIME) as ABRZEIT&#xA;          FROM readcsv(&#39;currentmonth.csv&#39;));&#xA;&#xA;Let me explain the details.&#xA;&#xA;CREATE TEMP TABLE creates a temporary database table. For my use case I don&#39;t need a permanent table. Temporary tables are deleted by DuckDB as soon as the operating process which runs DuckDB exits, even though you might save the DuckDB data to a permanent file.&#xA;&#xA;The following SELECT ... FROM readcsv(&#39;currentmonth.csv&#39;) statement imports my csv file into the created database table.&#xA;&#xA;The interesting things are the casts that I call in the SELECT statement for some of the columns. These casts convert the data from datatype string, which is the default when importing csv data, into a datatype that can be evaluated in SQL queries.&#xA;&#xA;The cast of the TIME field von e.g. is done by cast((von || &#39;:00&#39;) as TIME) as VON. Cause I get e.g. &#34;09:00&#34; from the csv file I need to add :00 to it first. Then I can cast the result to a real TIME field. Then I name the field VON. Without the latter as VON the field name would be cast((von || &#39;:00&#39;) as TIME) which is of course an ugly field name.&#xA;&#xA;To cast the &#34;DAUER (STUNDEN)&#34; field to a numeric (double) type I use the following expression cast(replace(&#34;DAUER (STUNDEN)&#34;, &#39;,&#39;, &#39;.&#39;) as DOUBLE) as DAUERSTD.  &#xA;Here I first replace the &#34;,&#34; by a &#34;.&#34; and then cast it to DOUBLE. The name of the field is DAUERSTD.&#xA;&#xA;Export the database table to excel&#xA;&#xA;Now as I have a database table with fields of type TIME and DOUBLE I can export this table to an excel file.&#xA;&#xA;There is a DuckDB extension that helps me with this. So at the top of my SQL script I first install and load this extension.  &#xA;&#xA;install spatial;&#xA;load spatial;&#xA;&#xA;The creation of the excel file is then done by calling this line.&#xA;&#xA;COPY (select projektcode, datum, von, bis, dauer, beschreibung, bemerkung from tsmonth order by projektcode, datum, von) TO &#39;month.xlsx&#39; WITH (FORMAT GDAL, DRIVER &#39;xlsx&#39;);&#xA;&#xA;I select only a few of my table field with the select inside the first parenthesis and then I export it to a file with the name month.xlsx&#xA;&#xA;Automatically create and open the xlsx file with a spreadsheet application&#xA;&#xA;Cause I&#39;m a lazy guy I don&#39;t want to want to open the created xlsx file manually in a spreadsheet application (libreoffice in my case) to do the copy-paste from it to the excel file of my customer.  &#xA;Note: the copy-paste is necessary cause my customers excel file has some other additional columns.&#xA;&#xA;To automate the complete process of creating the xlsx file from the csv file and open the month.xlsx with my spreadsheet application I created this little bash script.&#xA;&#xA;! /bin/bash&#xA;duckdb :memory: -s &#34;.read timesheetmonth.sql&#34;&#xA;libreoffice24.2 month.xlsx &amp;&#xA;wait&#xA;rm month.xlsx&#xA;&#xA;It runs my SQL script to create the database table and export it as xlsx file. Then it calls libreoffice with the created file in background.    &#xA;When I close libreoffice the script removes the created xlsx file cause I now longer need it.&#xA;&#xA;Conclusion of my business case&#xA;&#xA;Before I had this tiny script I, once a month, had to open my personal timesheet application, open the customer excel file in parallel and copy-paste every single timesheet entry from my timesheet app to the customer excel. This was an annoying and also error prone process.&#xA;&#xA;Now I simply have to run my script, open the customer excel in parallel and copy the entire columns that are contained in both files.&#xA;&#xA;The complete sources of my scripts&#xA;&#xA;timesheetmonth.sql SQL Script&#xA;&#xA;install spatial;&#xA;load spatial;&#xA;CREATE TEMP TABLE tsmonth AS &#xA;  (SELECT DATUM, &#xA;          cast((von || &#39;:00&#39;) as TIME) as VON, &#xA;          cast((bis || &#39;:00&#39;) as TIME) as BIS, &#xA;          cast((DAUER || &#39;:00&#39;) as TIME) as DAUER, &#xA;          cast(replace(&#34;DAUER (STUNDEN)&#34;, &#39;,&#39;, &#39;.&#39;) as DOUBLE) as DAUERSTD,&#xA;          BENUTZER, KUNDE, PROJEKTCODE, AUFGABE, TÄTIGKEIT AS TAETIGKEIT, BESCHREIBUNG, &#34;INTERNE BEMERKUNG&#34; as BEMERKUNG, &#xA;          cast((&#34;ABRECHENBARE ZEIT&#34; || &#39;:00&#39;) as TIME) as ABRZEIT&#xA;          FROM readcsv(&#39;currentmonth.csv&#39;));&#xA;COPY (select projektcode, datum, von, bis, dauer, beschreibung, bemerkung from tsmonth order by projektcode, datum, von) TO &#39;month.xlsx&#39; WITH (FORMAT GDAL, DRIVER &#39;xlsx&#39;);&#xA;&#xA;run-month bash script&#xA;  &#xA;! /bin/bash&#xA;duckdb :memory: -s &#34;.read timesheet_month.sql&#34;&#xA;libreoffice24.2 month.xlsx &amp;&#xA;wait&#xA;rm month.xlsx&#xA;&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<p>When reading the headline you probably think “what the hell does he do? Why does he not import the csv file into Excel and manage it there?”</p>

<p>Here are the reasons</p>
<ul><li>I don&#39;t like Excel.</li>
<li>My source csv file needs to be converted before generating the Excel file.</li>
<li>I wanted to explore <a href="https://duckdb.org/" rel="nofollow">DuckDB</a>.</li></ul>

<p>TL;DR: Go to the source files at the very bottom of this blog post.
</p>

<h2 id="business-use-case">Business Use Case</h2>

<p>Before I describe the technical details I briefly describe my business use case.</p>

<p>I record my working times with the really great tool <a href="https://primatime.com" rel="nofollow">prima:Time</a>. But as with most tools there are things you miss. One thing I miss in prima:Time is that I can export my data in a format my customers expect.</p>

<p>My current customers request an Excel file in a format (template) they have defined.</p>

<p>Of course prima:Time can export to csv and even to xls, but those files or, to be exact, the columns of those files don&#39;t have the format my customers expect.</p>

<p>Cause I stumbled across DuckDB recently and thought it would be worse to explore it I decided to create a solution for my business case with it.</p>

<h2 id="about-duckdb">About DuckDB</h2>

<p>I first heard of DuckDB from Golo Roden in his <a href="https://youtu.be/DFz23LzlBbc?si=cfZFbS8PrZB_bwaA" rel="nofollow">Youtube VLOG</a>. That made me curious.</p>

<p>“DuckDB is a fast in-process analytical database” they say at their homepage. Sounds like it is a lightweight version of SAP HANA.</p>

<p>In-process means that it does not run in an independent database server but in the same process as your application. If you stop your application the DuckDB database also is no longer available. In this respect DuckDB behaves like SQLite.<br>
Nevertheless you can of cource save the data to a single database file.</p>

<p>It integrates with a lot of external datasources like PostgreSQL, MySQL, AWS, Azure, ...<br>
It is highly portable which means that it runs on almost all OS. Furthermore it can handle up to terabytes of data and hundreds of CPUs.</p>

<p>It is feature rich. Besides support for the complete SQL syntax it also has a large function library.</p>

<p>It has also a lot of Client APIs. Just to name a few:</p>
<ul><li>R</li>
<li>Java</li>
<li>C++</li>
<li>Python</li>
<li>Node.js</li>
<li>CLI</li>
<li>...</li></ul>

<p>Yes, there is also a CLI and that&#39;s what I have used for my use case.</p>

<p>As analytical database it&#39;s also supposed to be very fast.</p>

<p>Last but not least DuckDB is available under MIT license which means it is free.</p>

<h2 id="duckdb-and-csv-files">DuckDB and CSV files</h2>

<p>One of the integrations that caught my attention was the one with csv files. You can easily import csv files into a database table.</p>

<p>Thanks to it&#39;s large function library you can even convert the csv data while importing it. After import you then have a database table with field types like DATE, TIME, INTEGER, DOUBLE, ...</p>

<p>Having such a table you can run all sorts of database queries.</p>

<p>I imported all my timesheet data into my DuckDB database and converted the data during the import. It&#39;s not big, but it has more than 5000 records.</p>

<p>I&#39;m now able to run additional evaluations that I miss in prime:Time.</p>

<h2 id="my-business-use-case-in-practice">My business use case in practice</h2>

<p>Let&#39;s come to my use case.</p>

<h3 id="import-my-csv-file-into-a-database-table">Import my csv file into a database table</h3>

<p>From prima:time I exported a csv file like this</p>

<pre><code>DATUM,VON,BIS,DAUER,DAUER (STUNDEN),BENUTZER,KUNDE,PROJEKTCODE,PROJEKT,AUFGABE,TÄTIGKEIT,BESCHREIBUNG,INTERNE BEMERKUNG,ABRECHENBARE ZEIT
03.06.2024,09:00,09:30,00:30,&#34;0,50&#34;,Tammen Helmut,Customer1,Projekt 1,Customer1 - Projekt 1,TPM (Techn. Projekt Management) ,Remote,&#34;Abstimmung mit Peter Urlaubsübergabe&#34;,,00:30
10.06.2024,09:30,11:30,02:00,&#34;2,00&#34;,Tammen Helmut,Customer1,Projekt 1,Customer1 - Projekt 1,TPM (Techn. Projekt Management) ,Remote,&#34;Planning Sprint 8&#34;,PRJ_1-460,02:00
</code></pre>

<p>You see that prima:Time exported a lot of columns. Let us have a deeper look at some of them</p>
<ul><li>VON (from). This is a time field, but it is delivered in the format hh:mm, e.g. 09:30</li>
<li>BIS (until). This is also a time field</li>
<li>“DAUER (STUNDEN)” (duration). This is a double field. It&#39;s delivered in the format xx,yy.</li></ul>

<p>The TIME fields are delivered with format hh:mm, but DuckDB needs the format hh:mm:ss to automatically recognize them as TIME fields.</p>

<p>The duration field “DAUER (STUNDEN)” is a decimal field formatted with my local (german) format. In Germany we use a “,” as decimal separator. Databases and programming languages use a “.” for this.</p>

<p>DuckDB offers the possibilty to convert those field on import of a csv file. Here is my SQL that imports a file, converts some fields and create a database table.</p>

<pre><code>CREATE TEMP TABLE ts_month AS 
  (SELECT DATUM, 
          cast((von || &#39;:00&#39;) as TIME) as VON, 
          cast((bis || &#39;:00&#39;) as TIME) as BIS, 
          cast((DAUER || &#39;:00&#39;) as TIME) as DAUER, 
          cast(replace(&#34;DAUER (STUNDEN)&#34;, &#39;,&#39;, &#39;.&#39;) as DOUBLE) as DAUER_STD,
          BENUTZER, KUNDE, PROJEKTCODE, AUFGABE, TÄTIGKEIT AS TAETIGKEIT, BESCHREIBUNG, &#34;INTERNE BEMERKUNG&#34; as BEMERKUNG, 
          cast((&#34;ABRECHENBARE ZEIT&#34; || &#39;:00&#39;) as TIME) as ABR_ZEIT
          FROM read_csv(&#39;current_month.csv&#39;));
</code></pre>

<p>Let me explain the details.</p>

<p><code>CREATE TEMP TABLE</code> creates a temporary database table. For my use case I don&#39;t need a permanent table. Temporary tables are deleted by DuckDB as soon as the operating process which runs DuckDB exits, even though you might save the DuckDB data to a permanent file.</p>

<p>The following <code>SELECT ... FROM read_csv(&#39;current_month.csv&#39;)</code> statement imports my csv file into the created database table.</p>

<p>The interesting things are the casts that I call in the SELECT statement for some of the columns. These casts convert the data from datatype <code>string</code>, which is the default when importing csv data, into a datatype that can be evaluated in SQL queries.</p>

<p>The cast of the TIME field <code>von</code> e.g. is done by <code>cast((von || &#39;:00&#39;) as TIME) as VON</code>. Cause I get e.g. “09:00” from the csv file I need to add <code>:00</code> to it first. Then I can cast the result to a real TIME field. Then I name the field VON. Without the latter <code>as VON</code> the field name would be <code>cast((von || &#39;:00&#39;) as TIME)</code> which is of course an ugly field name.</p>

<p>To cast the “DAUER (STUNDEN)” field to a numeric (double) type I use the following expression <code>cast(replace(&#34;DAUER (STUNDEN)&#34;, &#39;,&#39;, &#39;.&#39;) as DOUBLE) as DAUER_STD</code>.<br>
Here I first replace the “,” by a “.” and then cast it to DOUBLE. The name of the field is DAUER_STD.</p>

<h3 id="export-the-database-table-to-excel">Export the database table to excel</h3>

<p>Now as I have a database table with fields of type TIME and DOUBLE I can export this table to an excel file.</p>

<p>There is a DuckDB extension that helps me with this. So at the top of my SQL script I first install and load this extension.</p>

<pre><code>install spatial;
load spatial;
</code></pre>

<p>The creation of the excel file is then done by calling this line.</p>

<pre><code>COPY (select projektcode, datum, von, bis, dauer, beschreibung, bemerkung from ts_month order by projektcode, datum, von) TO &#39;month.xlsx&#39; WITH (FORMAT GDAL, DRIVER &#39;xlsx&#39;);
</code></pre>

<p>I select only a few of my table field with the <code>select</code> inside the first parenthesis and then I export it to a file with the name <code>month.xlsx</code></p>

<h3 id="automatically-create-and-open-the-xlsx-file-with-a-spreadsheet-application">Automatically create and open the xlsx file with a spreadsheet application</h3>

<p>Cause I&#39;m a lazy guy I don&#39;t want to want to open the created xlsx file manually in a spreadsheet application (libreoffice in my case) to do the copy-paste from it to the excel file of my customer.<br>
Note: the copy-paste is necessary cause my customers excel file has some other additional columns.</p>

<p>To automate the complete process of creating the xlsx file from the csv file and open the <code>month.xlsx</code> with my spreadsheet application I created this little bash script.</p>

<pre><code>#! /bin/bash
duckdb :memory: -s &#34;.read timesheet_month.sql&#34;
libreoffice24.2 month.xlsx &amp;
wait
rm month.xlsx
</code></pre>

<p>It runs my SQL script to create the database table and export it as xlsx file. Then it calls libreoffice with the created file in background.<br>
When I close libreoffice the script removes the created xlsx file cause I now longer need it.</p>

<h3 id="conclusion-of-my-business-case">Conclusion of my business case</h3>

<p>Before I had this tiny script I, once a month, had to open my personal timesheet application, open the customer excel file in parallel and copy-paste every single timesheet entry from my timesheet app to the customer excel. This was an annoying and also error prone process.</p>

<p>Now I simply have to run my script, open the customer excel in parallel and copy the entire columns that are contained in both files.</p>

<h2 id="the-complete-sources-of-my-scripts">The complete sources of my scripts</h2>

<p><code>timesheet_month.sql</code> SQL Script</p>

<pre><code>install spatial;
load spatial;
CREATE TEMP TABLE ts_month AS 
  (SELECT DATUM, 
          cast((von || &#39;:00&#39;) as TIME) as VON, 
          cast((bis || &#39;:00&#39;) as TIME) as BIS, 
          cast((DAUER || &#39;:00&#39;) as TIME) as DAUER, 
          cast(replace(&#34;DAUER (STUNDEN)&#34;, &#39;,&#39;, &#39;.&#39;) as DOUBLE) as DAUER_STD,
          BENUTZER, KUNDE, PROJEKTCODE, AUFGABE, TÄTIGKEIT AS TAETIGKEIT, BESCHREIBUNG, &#34;INTERNE BEMERKUNG&#34; as BEMERKUNG, 
          cast((&#34;ABRECHENBARE ZEIT&#34; || &#39;:00&#39;) as TIME) as ABR_ZEIT
          FROM read_csv(&#39;current_month.csv&#39;));
COPY (select projektcode, datum, von, bis, dauer, beschreibung, bemerkung from ts_month order by projektcode, datum, von) TO &#39;month.xlsx&#39; WITH (FORMAT GDAL, DRIVER &#39;xlsx&#39;);
</code></pre>

<p><code>run-month</code> bash script</p>

<pre><code>#! /bin/bash
duckdb :memory: -s &#34;.read timesheet_month.sql&#34;
libreoffice24.2 month.xlsx &amp;
wait
rm month.xlsx
</code></pre>
]]></content:encoded>
      <guid>https://text.tchncs.de/htammen/leveraging-duckdb-to-convert-csv-into-xlsx</guid>
      <pubDate>Sat, 22 Jun 2024 18:46:17 +0000</pubDate>
    </item>
    <item>
      <title>Trip to Costa Rica</title>
      <link>https://text.tchncs.de/htammen/trip-to-costa-rica</link>
      <description>&lt;![CDATA[Our trip to Costa Rica from Feb 18th, 2024 to March 13th, 2024&#xA;!--more--&#xA;&#xA;Day 1&#xA;Travel with Deutsche Bahn from Braunschweig to Frankfurt. Everything was fine. We arrived in time (very suspicious).&#xA;&#xA;Day 2&#xA;Flight from Frankfurt via Totonto to San Jose. After 18 hours (13 hours flight, 5 hours waiting time) we arrived San Jose at 9:30 pm.&#xA;Took a taxi to the hotel and fell into bed.&#xA;&#xA;Day 3&#xA;We got up very early and had a nice breakfast with excellent coffee.&#xA;Cause we had some time till we could pick up our car we walked around the area of Alajuela, which was supposed to be nice. It wasn&#39;t.&#xA;So we drove back to the airport where we got our car for the next three weeks at about 12am.&#xA;We planned to have our first activities in Corcovado national park which is a 3 to 4 hour trip by car. So we drove into that direction.&#xA;In Uvita, about 3 hours from San Jose we stopped and stayed the night in a hotel about 200 meters away from the pacific coast.&#xA;Before we went to bed we we swam in the pacific ocean and had dinner.&#xA;The water was warm and the waves were wonderful.&#xA;&#xA;Day 4&#xA;From Uvita we drove about one hour to Sierpe. In Sierpe we took a boat to Drake Bay which is located in Corcovado national park.&#xA;The boat trip already was a special experience. It was really fast and some of the waves of the open sea were really hard as steel. &#xA;We arrived in Drake Bay in the early afternoon and went to our accommodation. We had booked a nice holiday home at Kalaluna (the owners are Shirley and Claudio) directly opposite of the beach. It&#39;s a nice place with a perfect view to the &#34;harbour&#34;. The harbour is just the beach. The boats drive as near as they can to the beach and then let you out into the ocean. So you get at least wet feet, but only if you are lucky :-D. &#xA;In the afternoon we went to a beach Shirley has recommended us and had a bath in the ocean. &#xA;Then we had a walk to the center of Drake Bay. It&#39;s a lovely small village which lives from tourism. So you find there a lot of restaurants, two or three supermarkets and some shops that sell adventure tours. If you are from Europe maybe you are a bit shocked about the simplicity of all those places but I liked it very much. &#xA;I one of those restaurants we had a drink and met a guy from Chile. His name is Christian and he spoke nearly perfectly german, how funny. The next day we met Christian and his family two times more. &#xA;In the evening we gave Claudio (our host) a try. The food was good but because there were not much vegetarian options we decided to try other restaurants at the upcoming evenings. &#xA;&#xA;Day 5&#xA;Shirley had booked a snorkeling tour for us the day before.&#xA;We had to get up at 6 o&#39;clock, got breakfast at 6:30 and had to enter the catamaran at 7am.&#xA;The catamaran with its wonderful team around Melina brought us to Isla del Cuña, an island that people are not allowed to enter (national park). &#xA;On our way to the island a few dolphins have us a little show. &#xA;In front of the island we had our snorkeling tour. It was my first snorkeling adventure and it was amazing. We saw turtles, a few sharks at the bottom of the sea, a lot of fish and corals. The latter weren&#39;t that spectacular but the animals were in deed.&#xA;We had two 45 minutes snorkeling sessions with a break in which we were served some fruit.&#xA;At the way back to Drake Bay the team stopped the boat and served a delicious lunch with several salads.&#xA;I enjoyed the trip very much although I got a terrible sunburn. I&#39;m a guy from the north of Europe who hasn&#39;t seen the sun for several months.&#xA;After we came back to Drake Bay and refreshed ourselves we went into the center and had dinner. The vegetarian [casado] (https://www.puravidamoms.com/costa-rican-casado-recipe/) was very good.&#xA;Time to sleep after that.&#xA;&#xA;Day 6&#xA;This time we had to get up at 5am cause Shirley had booked a guided hiking tour to Corcovado national park.&#xA;We got there by boat of course. In the morning it rained (it&#39;s Costa Rica) but it stopped after a short time. Nevertheless everyone got wet. The ones who didn&#39;t have a rain jacket a bit more.&#xA;When we arrived we had to show our bags to the rangers cause you are not allowed to bring any food or plastic into the park.&#xA;Our guide Manfred (yes he has a German name) was very good and showed as well as told us a lot of details about the rain forrest, the health of Costa Ricas nature and the problems they face to preserve this unique place in the world.&#xA;It was an amazing tour into a world I haven&#39;t seen that way before.&#xA;After Manfred served us a lunch he had carried with him to the starting and end point of the tour, the boat brought us back to Drake Bay.&#xA;In the evening we had dinner in one of the nice restaurants of the village.&#xA;&#xA;Day 7&#xA;We left Drake Bay at 7am, by boat of course.&#xA;From Sierpe we drove through endless (a bit exaggerated) palm plantations to Jaco, a nice place at the coast with a really long and nice beach (https://costaricatravellife.com/jaco-costa-rica/). We had a walk there first and later we went swimming.&#xA;In the evening we drove to the center of Jaco which is quite big and busy. You find many restaurants and shops there. There is even a vegan restaurant where we had booked a table. Unfortunately it closed the kitchen unplanned shortly before we arrived there because of severe private reasons.&#xA;So we went to another restaurant which was also very good.&#xA;Because Jaco is the closest city to the coast and a surfer paradise you see a lot of people from US here who, I suppose, only come for relaxing, swimming and surfing, not to enjoy the fantastic nature of this beautiful country. So Jaco will probably not a place I will visit again.&#xA;&#xA;Day 8&#xA;This day started very relaxed. We could sleep quite long cause our day tour started at 12am.&#xA;&#xA;Our ride from Jacó to Manuel Antonio national park took a bit more than one hour. There we joined a 2 hour guided tour through the park. To be honest it was a mess compared to our tour through Corcovado national park a few days ago.&#xA;Yes we saw some sloths, iguanas and other animals as well as interesting plants, but the whole area was very touristic and the park was packed with people. In Corcovado our group consisted of ten people and we only saw others at the start/end point of the tour.&#xA;After the guided tour had been finished we were allowed to swim in the pacific. Cause it&#39;s always hot in Costa Rica we of course took the opportunity.&#xA;Then we drove back to our hotel, had a shower and again drove to the vegan restaurant in Jacó. This time we were lucky and had a really great vegan dinner.&#xA;&#xA;Day 9&#xA;Day 9 started at 8am. We had booked a zipline tour through the djungle. A tour with 9 sections from short and slow to long and fast. The longest section had 320 meters.&#xA;On our way to the top (start point) with a cabin train (gondola) we saw a Tucan sitting in a tree. What a wonderful bird. Our tour guide told us that we were really lucky to see one from such a short distance (when angels travel).&#xA;The zipline tour itself released some adrinalin. It was great fun and cause of the good support of the guides absolutely secure.&#xA;After this we went to the butterfly park which is located in the same area. A nice contrast to the zipline.&#xA;&#xA;After this adventure we drove about 1.5 hours to Puntarenas from where we took the ferry to Nicoya peninsula. The trip with the ferry was very relaxing. &#xA;At the peninsula we needed almost 2 hours for the 66 kilometers to Mal Pais, our next station. Our accommodation war very nice. We had a small house with one big room, a kitchen and a outdoor bathroom that was somehow part of the appartment, very nice.&#xA;&#xA;We unpacked and then went to the beach. This was only a few hundred meters walk away. As all other beaches, also this one was nearly empty. So we had hundreds of meters only for us. Here I took some nice fotos from the wonderful sunset.&#xA;In the evening we had dinner in a good israelic restaurant. They of course served vegan and vegetarian food.&#xA;&#xA;Day 10&#xA;Day 10 was very relaxing cause we didn&#39;t have planned any activities. We slept a bit longer and after we got up we sat down at the terrace of our appartement. When we sat there we were visited by quite a lot monkeys. The climbed the trees and had breakfast. It was amazing to see this. &#xA;Later we drove to the beach of Santa Teresa. Santa Teresa is one of the surfer hotspots in Costa Rica (they told us). We expected to have packed beaches. But when we got there it again was quite empty (wow!!!). We had a few hours at another wonderful beach, visited a beach cafe and went shopping a bit. A wonderful relaxing day.&#xA;This time we had dinner in another great restaurant directly at the beach. Again we got a delicous vegan and vegataring meal.&#xA;&#xA;What a nice day.&#xA;&#xA;Day 11&#xA;At Day 11 we spent a lot of time in our car cause we had to leave Mal Pais / Santa Teresa for Rincon. Cause we were tired after the long car trip we spent the evening in our appartment.&#xA;&#xA;By the way. Costa Rica is a small country, appr. as big as Lower Saxony in Germany. But it takes much longer to come from A to B. This is because the streets are not as good as in Europe / Germany but also because you are allowed to drive only max. 80 km/h and most times 60 km/h. If you make 50 km an hour in average you had a fast trip.&#xA;&#xA;Day 12&#xA;Early in the morning we drove to Parque National Rincón de la Vieja. We walked around there on our own. &#xA;The park is divided into two sections. The dry forrest and the humidity forrest. Both were interesting but I liked the humidity section more because it was greener and had more shadow. &#xA;&#xA;In the afternoon we drove to Monteverde / Santa Elena. This is an area in the mountains where you can walk in the cloud forrest and that&#39;s exactly what we did the next day. &#xA;At this day we had to adopt to the low temperatures. In the evenings it cooled down to 15 °C and it was very windy. That&#39;s why we were freezing, brrrr. &#xA;For dinner we again had good vegan or at least vegetarian (don&#39;t remember) food. &#xA;&#xA;Day 13&#xA;After breakfast (btw we can&#39;t see eggs and beans and rice any longer) we drove to Santa Elena cloud forrest where we had a fantastic 4 to 5 hours hike. &#xA;We fortunately didn&#39;t see the fog but the nature is so impressive. It blows away your mind. Additionally we had some great view to the Arenal volcan and across the amazing and huge forrest. &#xA;Most of the evening we spent in warm rooms cause we were still freezing. &#xA;&#xA;Btw, this was my first day with an online connection. Before I could only use wifi&#39;s of hotels and restaurants which all those Facilities offer. But this is another story that I might write down at the end or in a separate blog post. &#xA;&#xA;Day 14&#xA;Originally we wanted to spend 4 nights in Santa Elena but because of the &#34;bad&#34; weather we decided to leave a day ealier. &#xA;&#xA;Our last day in Santa Elena was a lazy one. We had breakfast in a little cafe where we got some vegatarian / vegan meal. We decided to go there cause we couldn&#39;t eat eggs in the morning any longer.&#xA;&#xA;After that we had a look at Santa Elena, did some shopping (tourist shopping and shopping of necessary things). Additionally we managed our (re)booking for Tortuguero National Park. After having another look at the details of this park we decided to book a new accomodation directly in the village of Tortuguero. Before we had a booking in a lodge a few kilometers away from it.&#xA;&#xA;In the evening we had a really nice mexican dinner (vegan and veggie) at the Taco Taco restaurant. We sat outside but because we wore all the warm clothes we brought to Costa Rica it was ok.&#xA;&#xA;When we went to bed we were happy that we would leave a tomorrow, a day earlier as planned.&#xA;&#xA;Day 15&#xA;We left Santa Elena very early cause we had a long trip of appr. 6 hours by car and 1 hour by boat to Tortuguero National Park. The nearer we came to Tortuguero the nicer the nature was. The last hour we passed a lot of banana, mango and other farms.&#xA;We arrived at La Pavona in the early afternoon appr. one hour before our booked boat brought us to Tortuguero.&#xA;Torguguero can only be arrived by either boat or plane (there is a little airport). The boat trip lasted one hour and besides an impressive nature we saw our first and only crocodile in Costa Rica.&#xA;&#xA;Tortuguero is a small village that is at the one side a tourist location but at the other side a place where most of the native inhabitants of Tortuguero live. So we got a little insight into the living of people there. Everything is very simple. The houses stand close together and there are no cars allowed at the peninsula.&#xA;&#xA;The decision to book a new accomodation directly inside the village of Tortuero was a good one. So we had short ways to our guided tours starting points the next days. Otherwise we would have been forced to take a water taxi to Tortuguero each time. &#xA;For us as vegetarians this decision also offered us a bigger variety of restaurants. &#xA;&#xA;When we arrived at Torguguero a guy brought us to our accomodation which was simple but had everything we needed. It had even a pool which we only used once at the arrival to relax from long day trip.&#xA;&#xA;The rest of the afternoon and evening we used to discover the small village. Even though this is small you can get lost easily. Every small pathway looks like the others and there are a lot of them.&#xA;&#xA;In the end we got to the center where we had a dinner and we got back to our holiday flat which was about 2 hundred meters away from the beach.&#xA;&#xA;Day 16&#xA;Cause we arrived a day earlier as planned we hadn&#39;t booked anything at this day. At the time writing this notes I don&#39;t exactlely remember how we spent the day but we of course went to the beach and discovered the village a bit more.&#xA;&#xA;In the afternoon we went to the office we had booked our next day tours to get instructed for the next day. It was funny that Jessica, the owner of tour orginisation, was a German and used to live in Neuwarmbüchen near Hannover. This is 3 km away from Burgwedel where I spent 15 years of my life.  &#xA;&#xA;Day 17&#xA;This day was packed with booked tours. We went to the starting point of our 3 hour morning boat tour through the jungle at 5:45 am. At the office we got a cup of coffee, some fruit and our binoculars.&#xA;&#xA;The boat tour was very interesting. We saw some birds, monkeys, iguanas and, of course, a lot of jungle. The nature always impressed me most in Costa Rica.&#xA;In Costa Rica you always should be prepared for a rain. That said we had rain on our tour for about half of the time.&#xA;&#xA;The boat tour ended at about 9 am. The next tour of the day started at 2 pm. So we had time enough to have a breakfast and cup of coffee in between. Our accomodation didn&#39;t gratefully offer breakfast. So we went somewhere where we had other options that eggs with beans and rice.&#xA;I had a big plate with fresh fruits, a little bit of yoghurt and crunch, how yummy.&#xA;&#xA;The afternoon tour was a hike through the national park of Tortuguero. The guide showed and told us a lot about the jungle. We saw frogs, spiders, monkeys and were told that the population of jaguars in Tortuguero is increasing. That&#39;s why they come to the village in the nights from time to time and hunt the dogs that are living there. That&#39;s a bit scary, isn&#39;t it?&#xA;&#xA;At 6 pm we finished the day tours with a night walk. The highlight of this hike was a sloth that slooowly climed in a tree. We made nice videos of this.&#xA;     &#xA;Day 18&#xA;This day started slowly. We slept a bit longer and had a self made breakfast with just bread, cheese, tomatoes and avocados and WITHOUT eggs.&#xA;&#xA;Later in the morning we attended a cacao tour. There were just we three and the lady that guided us. It was not a tour like a tour through the jungle but also very, vary interesting. We were shown the cacao plants, the fruits, could taste the fruits, got a cup of cacoa and prepared our own chocolate from the fruit we harvested before from one of the trees. Not spectacular but one of the highlights of our trip.&#xA;&#xA;In the afternoon we relaxed at the beach and just hang around.&#xA;&#xA;In the evening we enjoyed another highlight. We went to a restaurant we already wanted to visit the days before but either could get a table or it was closed. Now, at our last night in Tortuguero, we were lucky and had a wonderful dinner in a very lovely ambience. &#xA;It surprised us that such a restaurant exists in a place where space is rare and the people live under very simple conditions.&#xA;If you have dinner at such a place it creates ambivalent feelings cause you enjoy it but also feel bad if you think at the simple conditions there.&#xA;&#xA;Day 19&#xA;We had to get up early in the morning cause our boat to La Pavona where we parked our car left at 7 am. &#xA;&#xA;At this day we split. Felicia wanted to go to a music festival in Uvita (see day 2) the next days. Annette and I followed our preplanned tour.&#xA;So we brought Felicia to Guapiles where she took a bus to San Jose and from there to Uvita.&#xA;The bus transportation in Costa Rica is well organized and very cheap compared with DB in Germany.&#xA;&#xA;After we said good-bye to Felicia we drove about 4 hours by car to Manzanillo at the very south of Costa Ricas Atlantic coast.&#xA;The Atlantic coast is, like the Pacific coast, amazing. Long white (and black) beaches with palms. You feel like in heaven.&#xA;&#xA;In Manzanillo we, to be exact Felicia, had booked a Jungle house where we stayed three nights. Felicia wanted to go there. Now Annette and I were the ones who should spend their time there.&#xA;The Jungle house is a accomodation that is in the mid of the jungle, 10 minutes walk time away from the next house and another 5 minutes to the village Manzanillo.&#xA;As Annette and I are not the jungest (lets say we are around 60 years old) we were more than curious if we would like living in the jungle. To say it in advance, it was excellent. One, it not the, highlight of our tour.&#xA;&#xA;When we arrived we were brought to the Jungle house by Tereza. Tereza and Jan are the owners of the house and originally come from Czech republic. Seems that many people from Europe emigrate to Costa Rica.&#xA;&#xA;The way up to the Jungle house was very steep. Especially with a big backpack at the back and a smaller one at the front of you at 30+ °C it&#39;s a challengine hike. &#xA;The Jungle house itself is amazing. It has two floors. At the lower is the kitchen and living room, it&#39;s a terrace with a roof to be exact. Additionally there is the bathroom and a sleeping room which we didn&#39;t use. At the upper floor there is another sleeping room. Both floors give you an amazing view to the jungle. At the end of the jungle one can see the beach.&#xA;&#xA;After we unpacked our backpacks we decided to go down to Manzanillo &#34;downtown&#34; again to have dinner and buy something to eat for the next days. We thought that it would be ok if we go back into the house about 6 pm. It turned out that this was a bit late. The last part of the path we had to make with flashlights. Cause the path was steep this was a challenge again.&#xA;When we arrived at the house we had to take a shower. Of course the shower was outside of the house and we only got rain water from the water tanks at the roof.&#xA;After that we sat down in the living room (the terrace) and got biten by the mosquitos. So we decided to go to bed which had a mosquito net at about 8 pm. Living in the jungle is different from living elsewhere.&#xA;Cause we used our smartphones and ebook readers all the insects wanted to visit us. Thankfully we had the net around us. But nevertheless we decided to turn of the light emissioners quite early and sleep.&#xA;The nights in the jungle are also different from the nights elsewhere. You hear so many noises. Some of them seem to be very near. It&#39;s a bit scary for someone who normally lives in a bigger town with walls around himself. So we awoke several times in the night.&#xA;&#xA;Day 20&#xA;The next morning we got up very early at about 6 am. We went down to the living room and enjoyed the sounds of the jungle and the birds that flew around. Especially the tucans were great to see.&#xA;We had a breakfast (w/o eggs) and spend the whole morning listening and watching the nature.&#xA;At around lunchtime we walked down to our car and drove to Puerto Viajo where we had a vegetarian lunch (or second breakfast). Then we walked around this tourist town which gets visited by a lot of surfers and people who want to enjoy a beach vacation.&#xA;We drove to a smaller place where we spend a few hours at the beach.&#xA;&#xA;This time we went up to our jungle house a bit earlier. So we made it before sunset. There we cooked ourselves a simple dinner (pasta with vegetables). To not be biten by the mosquitos again we lit incense sticks which really helped a lot. Nevertheless we were tired early again and slept at about 9 pm.&#xA;&#xA;Day 21&#xA;Again we awoke early and enjoyed the nature till lunchtime. Then we walked down and drove to the beach of Manzanillo where we had a nice afternoon without too much sun. I did a little bit of snorkeling at the coast but this wasn&#39;t comparable to what we have experienced at Corcovado.&#xA;&#xA;We went up to the jungle house early again and ate the rests of our dinner we cooked the day before. Again we had a few hours at the terrace and went to bed early. Living in the jungle is different from living elsewhere.&#xA;&#xA;Day 22&#xA;We got up early again and enjoyed the nature. This might sound a bit boring but it&#39;s definetly not. It&#39;s so amazing to hear the sound of the jungle and to see the animals that live there. Even watching the spiders was interesting. Unlike as in Europe they don&#39;t come into houses cause they don&#39;t need to. They find everything outside.&#xA;&#xA;Around 11am we left the jungle house (thank you we had an amazing time) and drove to Limon where we booked a night in a hotel directly at the beach. The hotel was quite nice. The food wasn&#39;t but it was ok. &#xA;Before we checked in at the hotel we had a look at Limon. To be honest I don&#39;t have to go there a second time but it was ok to see how people in Costa Rica live in towns that are not packed with tourists. Limon is kown for it&#39;s harbour from where coffee and bananas are shipped into the whole world. Also a lot of cruize ships stop there to send their passengers from there to day trips in Costa Rica.&#xA;    &#xA;In the late afternoon we had a couple of hours at the beach of the hotel. Besides us there was noone at the very long beach. Maybe this was because of the bull sharks that are supposed to live there? We didn&#39;t go into deep water so we weren&#39;t frightened of that. &#xA;&#xA;Day 23&#xA;Our last day at the coast of Costa Rica. After breakfast (with eggs again) we went to the beach for another couple of hours. The sun was already hot and we enjoyed the last sun bath in Costa Rica.&#xA;&#xA;At lunchtime we that drove to San Jose where we had booked a hotel for two nights cause we had to return our car to the car rent and cause we thought it might be worth to have a look around the biggest city of Costa Rica. It wasn&#39;t I have to admit.&#xA;&#xA;After we arrived at the hotel we went into the center of the city. There is nothing to say. The city is simply not nice.&#xA;&#xA;Even worse, when we went back to the hotel someone stole the chain of Annette from her neck. Fortunately it was a cheap one cause she always only wears cheap jewellery in tourist cities.&#xA;&#xA;Day 24&#xA;Breakfast in the hotel was bad, with eggs again which I could eat. There is a time you can&#39;t eat any more eggs (maybe for the rest of your life).&#xA;&#xA;After breakfast I returned the car. This took a while cause the car rent was not in the center of the San Jose but at the airport.&#xA;At lunchtime we went into the center again to visit one or two museums. On our way to the museums we discovered a big market hall with a lot of little shops in it. They sell meat, vegetables, herbs, clothes and also tourist stuff there. To see that was quite interesting.&#xA;&#xA;Then we spent a couple of hours in the pre-columbian gold museum. That was quite interesting.&#xA;&#xA;After we left the museum we had to fetch Felicia from a bus station. So we went there and picked her up. She spent a few nice and interesting days with a bunch of young Costa Ricans at the music festival. They also did another snorkeling tour and visited a waterfall. Sounds that she also had a nice time.&#xA;&#xA;In the evening we had a dinner which wasn&#39;t really great and prepared ourselves for the long flight the next day.&#xA;&#xA;Day 25&#xA;We had to get up very early (4:15 am) to get to the airport. We took a Uber which brought us there very quickly.&#xA;&#xA;At 8:05 am our flight via Newark (New York) started. It took a bit more than 5 hours to Newark. There we had a pause for appr. 5:15 and from there we had to fly another 7:15 to Frankfurt. So the entire flight lasted about 18 hours. From Frankfurt where we landed at 9:15am we needed 6 or seven hours with Deutsche Bahn to reach our home in Braunschweig.  &#xA;&#xA;Two notes to the travel. &#xA;First: In the future I will not book a flight with a mid stop if there is also a direct filght available.&#xA;Second: It took us more than one hour in Newark to get from the first plane to the second. The reason for that was that we had to wait very long at the passport control. There was a long queue cause the US border officials take a foto and fingerprints from every one who enters the country, even if it&#39;s only to get a connection flight to another country. For me as a European that felt very weird. I haven&#39;t experienced something like that in any other country I&#39;ve been to yet.]]&gt;</description>
      <content:encoded><![CDATA[<p>Our trip to Costa Rica from Feb 18th, 2024 to March 13th, 2024
</p>

<h2 id="day-1">Day 1</h2>

<p>Travel with Deutsche Bahn from Braunschweig to Frankfurt. Everything was fine. We arrived in time (very suspicious).</p>

<h2 id="day-2">Day 2</h2>

<p>Flight from Frankfurt via Totonto to San Jose. After 18 hours (13 hours flight, 5 hours waiting time) we arrived San Jose at 9:30 pm.
Took a taxi to the hotel and fell into bed.</p>

<h2 id="day-3">Day 3</h2>

<p>We got up very early and had a nice breakfast with excellent coffee.
Cause we had some time till we could pick up our car we walked around the area of Alajuela, which was supposed to be nice. It wasn&#39;t.
So we drove back to the airport where we got our car for the next three weeks at about 12am.
We planned to have our first activities in Corcovado national park which is a 3 to 4 hour trip by car. So we drove into that direction.
In Uvita, about 3 hours from San Jose we stopped and stayed the night in a hotel about 200 meters away from the pacific coast.
Before we went to bed we we swam in the pacific ocean and had dinner.
The water was warm and the waves were wonderful.</p>

<h2 id="day-4">Day 4</h2>

<p>From Uvita we drove about one hour to Sierpe. In Sierpe we took a boat to Drake Bay which is located in Corcovado national park.
The boat trip already was a special experience. It was really fast and some of the waves of the open sea were really hard as steel.
We arrived in Drake Bay in the early afternoon and went to our accommodation. We had booked a nice holiday home at Kalaluna (the owners are Shirley and Claudio) directly opposite of the beach. It&#39;s a nice place with a perfect view to the “harbour”. The harbour is just the beach. The boats drive as near as they can to the beach and then let you out into the ocean. So you get at least wet feet, but only if you are lucky :-D.
In the afternoon we went to a beach Shirley has recommended us and had a bath in the ocean.
Then we had a walk to the center of Drake Bay. It&#39;s a lovely small village which lives from tourism. So you find there a lot of restaurants, two or three supermarkets and some shops that sell adventure tours. If you are from Europe maybe you are a bit shocked about the simplicity of all those places but I liked it very much.
I one of those restaurants we had a drink and met a guy from Chile. His name is Christian and he spoke nearly perfectly german, how funny. The next day we met Christian and his family two times more.
In the evening we gave Claudio (our host) a try. The food was good but because there were not much vegetarian options we decided to try other restaurants at the upcoming evenings.</p>

<h2 id="day-5">Day 5</h2>

<p>Shirley had booked a snorkeling tour for us the day before.
We had to get up at 6 o&#39;clock, got breakfast at 6:30 and had to enter the catamaran at 7am.
The catamaran with its wonderful team around Melina brought us to Isla del Cuña, an island that people are not allowed to enter (national park).
On our way to the island a few dolphins have us a little show.
In front of the island we had our snorkeling tour. It was my first snorkeling adventure and it was amazing. We saw turtles, a few sharks at the bottom of the sea, a lot of fish and corals. The latter weren&#39;t that spectacular but the animals were in deed.
We had two 45 minutes snorkeling sessions with a break in which we were served some fruit.
At the way back to Drake Bay the team stopped the boat and served a delicious lunch with several salads.
I enjoyed the trip very much although I got a terrible sunburn. I&#39;m a guy from the north of Europe who hasn&#39;t seen the sun for several months.
After we came back to Drake Bay and refreshed ourselves we went into the center and had dinner. The vegetarian [casado] (<a href="https://www.puravidamoms.com/costa-rican-casado-recipe/" rel="nofollow">https://www.puravidamoms.com/costa-rican-casado-recipe/</a>) was very good.
Time to sleep after that.</p>

<h2 id="day-6">Day 6</h2>

<p>This time we had to get up at 5am cause Shirley had booked a guided hiking tour to Corcovado national park.
We got there by boat of course. In the morning it rained (it&#39;s Costa Rica) but it stopped after a short time. Nevertheless everyone got wet. The ones who didn&#39;t have a rain jacket a bit more.
When we arrived we had to show our bags to the rangers cause you are not allowed to bring any food or plastic into the park.
Our guide Manfred (yes he has a German name) was very good and showed as well as told us a lot of details about the rain forrest, the health of Costa Ricas nature and the problems they face to preserve this unique place in the world.
It was an amazing tour into a world I haven&#39;t seen that way before.
After Manfred served us a lunch he had carried with him to the starting and end point of the tour, the boat brought us back to Drake Bay.
In the evening we had dinner in one of the nice restaurants of the village.</p>

<h2 id="day-7">Day 7</h2>

<p>We left Drake Bay at 7am, by boat of course.
From Sierpe we drove through endless (a bit exaggerated) palm plantations to Jaco, a nice place at the coast with a really long and nice beach (<a href="https://costaricatravellife.com/jaco-costa-rica/" rel="nofollow">https://costaricatravellife.com/jaco-costa-rica/</a>). We had a walk there first and later we went swimming.
In the evening we drove to the center of Jaco which is quite big and busy. You find many restaurants and shops there. There is even a vegan restaurant where we had booked a table. Unfortunately it closed the kitchen unplanned shortly before we arrived there because of severe private reasons.
So we went to another restaurant which was also very good.
Because Jaco is the closest city to the coast and a surfer paradise you see a lot of people from US here who, I suppose, only come for relaxing, swimming and surfing, not to enjoy the fantastic nature of this beautiful country. So Jaco will probably not a place I will visit again.</p>

<h2 id="day-8">Day 8</h2>

<p>This day started very relaxed. We could sleep quite long cause our day tour started at 12am.</p>

<p>Our ride from Jacó to Manuel Antonio national park took a bit more than one hour. There we joined a 2 hour guided tour through the park. To be honest it was a mess compared to our tour through Corcovado national park a few days ago.
Yes we saw some sloths, iguanas and other animals as well as interesting plants, but the whole area was very touristic and the park was packed with people. In Corcovado our group consisted of ten people and we only saw others at the start/end point of the tour.
After the guided tour had been finished we were allowed to swim in the pacific. Cause it&#39;s always hot in Costa Rica we of course took the opportunity.
Then we drove back to our hotel, had a shower and again drove to the vegan restaurant in Jacó. This time we were lucky and had a really great vegan dinner.</p>

<h2 id="day-9">Day 9</h2>

<p>Day 9 started at 8am. We had booked a zipline tour through the djungle. A tour with 9 sections from short and slow to long and fast. The longest section had 320 meters.
On our way to the top (start point) with a cabin train (gondola) we saw a Tucan sitting in a tree. What a wonderful bird. Our tour guide told us that we were really lucky to see one from such a short distance (when angels travel).
The zipline tour itself released some adrinalin. It was great fun and cause of the good support of the guides absolutely secure.
After this we went to the butterfly park which is located in the same area. A nice contrast to the zipline.</p>

<p>After this adventure we drove about 1.5 hours to Puntarenas from where we took the ferry to Nicoya peninsula. The trip with the ferry was very relaxing.
At the peninsula we needed almost 2 hours for the 66 kilometers to Mal Pais, our next station. Our accommodation war very nice. We had a small house with one big room, a kitchen and a outdoor bathroom that was somehow part of the appartment, very nice.</p>

<p>We unpacked and then went to the beach. This was only a few hundred meters walk away. As all other beaches, also this one was nearly empty. So we had hundreds of meters only for us. Here I took some nice fotos from the wonderful sunset.
In the evening we had dinner in a good israelic restaurant. They of course served vegan and vegetarian food.</p>

<h2 id="day-10">Day 10</h2>

<p>Day 10 was very relaxing cause we didn&#39;t have planned any activities. We slept a bit longer and after we got up we sat down at the terrace of our appartement. When we sat there we were visited by quite a lot monkeys. The climbed the trees and had breakfast. It was amazing to see this.
Later we drove to the beach of Santa Teresa. Santa Teresa is one of the surfer hotspots in Costa Rica (they told us). We expected to have packed beaches. But when we got there it again was quite empty (wow!!!). We had a few hours at another wonderful beach, visited a beach cafe and went shopping a bit. A wonderful relaxing day.
This time we had dinner in another great restaurant directly at the beach. Again we got a delicous vegan and vegataring meal.</p>

<p>What a nice day.</p>

<h2 id="day-11">Day 11</h2>

<p>At Day 11 we spent a lot of time in our car cause we had to leave Mal Pais / Santa Teresa for Rincon. Cause we were tired after the long car trip we spent the evening in our appartment.</p>

<p>By the way. Costa Rica is a small country, appr. as big as Lower Saxony in Germany. But it takes much longer to come from A to B. This is because the streets are not as good as in Europe / Germany but also because you are allowed to drive only max. 80 km/h and most times 60 km/h. If you make 50 km an hour in average you had a fast trip.</p>

<h2 id="day-12">Day 12</h2>

<p>Early in the morning we drove to Parque National Rincón de la Vieja. We walked around there on our own.
The park is divided into two sections. The dry forrest and the humidity forrest. Both were interesting but I liked the humidity section more because it was greener and had more shadow.</p>

<p>In the afternoon we drove to Monteverde / Santa Elena. This is an area in the mountains where you can walk in the cloud forrest and that&#39;s exactly what we did the next day.
At this day we had to adopt to the low temperatures. In the evenings it cooled down to 15 °C and it was very windy. That&#39;s why we were freezing, brrrr.
For dinner we again had good vegan or at least vegetarian (don&#39;t remember) food.</p>

<h2 id="day-13">Day 13</h2>

<p>After breakfast (btw we can&#39;t see eggs and beans and rice any longer) we drove to Santa Elena cloud forrest where we had a fantastic 4 to 5 hours hike.
We fortunately didn&#39;t see the fog but the nature is so impressive. It blows away your mind. Additionally we had some great view to the Arenal volcan and across the amazing and huge forrest.
Most of the evening we spent in warm rooms cause we were still freezing.</p>

<p>Btw, this was my first day with an online connection. Before I could only use wifi&#39;s of hotels and restaurants which all those Facilities offer. But this is another story that I might write down at the end or in a separate blog post.</p>

<h2 id="day-14">Day 14</h2>

<p>Originally we wanted to spend 4 nights in Santa Elena but because of the “bad” weather we decided to leave a day ealier.</p>

<p>Our last day in Santa Elena was a lazy one. We had breakfast in a little cafe where we got some vegatarian / vegan meal. We decided to go there cause we couldn&#39;t eat eggs in the morning any longer.</p>

<p>After that we had a look at Santa Elena, did some shopping (tourist shopping and shopping of necessary things). Additionally we managed our (re)booking for Tortuguero National Park. After having another look at the details of this park we decided to book a new accomodation directly in the village of Tortuguero. Before we had a booking in a lodge a few kilometers away from it.</p>

<p>In the evening we had a really nice mexican dinner (vegan and veggie) at the Taco Taco restaurant. We sat outside but because we wore all the warm clothes we brought to Costa Rica it was ok.</p>

<p>When we went to bed we were happy that we would leave a tomorrow, a day earlier as planned.</p>

<h2 id="day-15">Day 15</h2>

<p>We left Santa Elena very early cause we had a long trip of appr. 6 hours by car and 1 hour by boat to Tortuguero National Park. The nearer we came to Tortuguero the nicer the nature was. The last hour we passed a lot of banana, mango and other farms.
We arrived at La Pavona in the early afternoon appr. one hour before our booked boat brought us to Tortuguero.
Torguguero can only be arrived by either boat or plane (there is a little airport). The boat trip lasted one hour and besides an impressive nature we saw our first and only crocodile in Costa Rica.</p>

<p>Tortuguero is a small village that is at the one side a tourist location but at the other side a place where most of the native inhabitants of Tortuguero live. So we got a little insight into the living of people there. Everything is very simple. The houses stand close together and there are no cars allowed at the peninsula.</p>

<p>The decision to book a new accomodation directly inside the village of Tortuero was a good one. So we had short ways to our guided tours starting points the next days. Otherwise we would have been forced to take a water taxi to Tortuguero each time.
For us as vegetarians this decision also offered us a bigger variety of restaurants.</p>

<p>When we arrived at Torguguero a guy brought us to our accomodation which was simple but had everything we needed. It had even a pool which we only used once at the arrival to relax from long day trip.</p>

<p>The rest of the afternoon and evening we used to discover the small village. Even though this is small you can get lost easily. Every small pathway looks like the others and there are a lot of them.</p>

<p>In the end we got to the center where we had a dinner and we got back to our holiday flat which was about 2 hundred meters away from the beach.</p>

<h2 id="day-16">Day 16</h2>

<p>Cause we arrived a day earlier as planned we hadn&#39;t booked anything at this day. At the time writing this notes I don&#39;t exactlely remember how we spent the day but we of course went to the beach and discovered the village a bit more.</p>

<p>In the afternoon we went to the office we had booked our next day tours to get instructed for the next day. It was funny that Jessica, the owner of tour orginisation, was a German and used to live in Neuwarmbüchen near Hannover. This is 3 km away from Burgwedel where I spent 15 years of my life.</p>

<h2 id="day-17">Day 17</h2>

<p>This day was packed with booked tours. We went to the starting point of our 3 hour morning boat tour through the jungle at 5:45 am. At the office we got a cup of coffee, some fruit and our binoculars.</p>

<p>The boat tour was very interesting. We saw some birds, monkeys, iguanas and, of course, a lot of jungle. The nature always impressed me most in Costa Rica.
In Costa Rica you always should be prepared for a rain. That said we had rain on our tour for about half of the time.</p>

<p>The boat tour ended at about 9 am. The next tour of the day started at 2 pm. So we had time enough to have a breakfast and cup of coffee in between. Our accomodation didn&#39;t gratefully offer breakfast. So we went somewhere where we had other options that eggs with beans and rice.
I had a big plate with fresh fruits, a little bit of yoghurt and crunch, how yummy.</p>

<p>The afternoon tour was a hike through the national park of Tortuguero. The guide showed and told us a lot about the jungle. We saw frogs, spiders, monkeys and were told that the population of jaguars in Tortuguero is increasing. That&#39;s why they come to the village in the nights from time to time and hunt the dogs that are living there. That&#39;s a bit scary, isn&#39;t it?</p>

<p>At 6 pm we finished the day tours with a night walk. The highlight of this hike was a sloth that slooowly climed in a tree. We made nice videos of this.</p>

<h2 id="day-18">Day 18</h2>

<p>This day started slowly. We slept a bit longer and had a self made breakfast with just bread, cheese, tomatoes and avocados and WITHOUT eggs.</p>

<p>Later in the morning we attended a cacao tour. There were just we three and the lady that guided us. It was not a tour like a tour through the jungle but also very, vary interesting. We were shown the cacao plants, the fruits, could taste the fruits, got a cup of cacoa and prepared our own chocolate from the fruit we harvested before from one of the trees. Not spectacular but one of the highlights of our trip.</p>

<p>In the afternoon we relaxed at the beach and just hang around.</p>

<p>In the evening we enjoyed another highlight. We went to a restaurant we already wanted to visit the days before but either could get a table or it was closed. Now, at our last night in Tortuguero, we were lucky and had a wonderful dinner in a very lovely ambience.
It surprised us that such a restaurant exists in a place where space is rare and the people live under very simple conditions.
If you have dinner at such a place it creates ambivalent feelings cause you enjoy it but also feel bad if you think at the simple conditions there.</p>

<h2 id="day-19">Day 19</h2>

<p>We had to get up early in the morning cause our boat to La Pavona where we parked our car left at 7 am.</p>

<p>At this day we split. Felicia wanted to go to a music festival in Uvita (see day 2) the next days. Annette and I followed our preplanned tour.
So we brought Felicia to Guapiles where she took a bus to San Jose and from there to Uvita.
The bus transportation in Costa Rica is well organized and very cheap compared with DB in Germany.</p>

<p>After we said good-bye to Felicia we drove about 4 hours by car to Manzanillo at the very south of Costa Ricas Atlantic coast.
The Atlantic coast is, like the Pacific coast, amazing. Long white (and black) beaches with palms. You feel like in heaven.</p>

<p>In Manzanillo we, to be exact Felicia, had booked a Jungle house where we stayed three nights. Felicia wanted to go there. Now Annette and I were the ones who should spend their time there.
The Jungle house is a accomodation that is in the mid of the jungle, 10 minutes walk time away from the next house and another 5 minutes to the village Manzanillo.
As Annette and I are not the jungest (lets say we are around 60 years old) we were more than curious if we would like living in the jungle. To say it in advance, it was excellent. One, it not the, highlight of our tour.</p>

<p>When we arrived we were brought to the Jungle house by Tereza. Tereza and Jan are the owners of the house and originally come from Czech republic. Seems that many people from Europe emigrate to Costa Rica.</p>

<p>The way up to the Jungle house was very steep. Especially with a big backpack at the back and a smaller one at the front of you at 30+ °C it&#39;s a challengine hike.
The Jungle house itself is amazing. It has two floors. At the lower is the kitchen and living room, it&#39;s a terrace with a roof to be exact. Additionally there is the bathroom and a sleeping room which we didn&#39;t use. At the upper floor there is another sleeping room. Both floors give you an amazing view to the jungle. At the end of the jungle one can see the beach.</p>

<p>After we unpacked our backpacks we decided to go down to Manzanillo “downtown” again to have dinner and buy something to eat for the next days. We thought that it would be ok if we go back into the house about 6 pm. It turned out that this was a bit late. The last part of the path we had to make with flashlights. Cause the path was steep this was a challenge again.
When we arrived at the house we had to take a shower. Of course the shower was outside of the house and we only got rain water from the water tanks at the roof.
After that we sat down in the living room (the terrace) and got biten by the mosquitos. So we decided to go to bed which had a mosquito net at about 8 pm. Living in the jungle is different from living elsewhere.
Cause we used our smartphones and ebook readers all the insects wanted to visit us. Thankfully we had the net around us. But nevertheless we decided to turn of the light emissioners quite early and sleep.
The nights in the jungle are also different from the nights elsewhere. You hear so many noises. Some of them seem to be very near. It&#39;s a bit scary for someone who normally lives in a bigger town with walls around himself. So we awoke several times in the night.</p>

<h2 id="day-20">Day 20</h2>

<p>The next morning we got up very early at about 6 am. We went down to the living room and enjoyed the sounds of the jungle and the birds that flew around. Especially the tucans were great to see.
We had a breakfast (w/o eggs) and spend the whole morning listening and watching the nature.
At around lunchtime we walked down to our car and drove to Puerto Viajo where we had a vegetarian lunch (or second breakfast). Then we walked around this tourist town which gets visited by a lot of surfers and people who want to enjoy a beach vacation.
We drove to a smaller place where we spend a few hours at the beach.</p>

<p>This time we went up to our jungle house a bit earlier. So we made it before sunset. There we cooked ourselves a simple dinner (pasta with vegetables). To not be biten by the mosquitos again we lit incense sticks which really helped a lot. Nevertheless we were tired early again and slept at about 9 pm.</p>

<h2 id="day-21">Day 21</h2>

<p>Again we awoke early and enjoyed the nature till lunchtime. Then we walked down and drove to the beach of Manzanillo where we had a nice afternoon without too much sun. I did a little bit of snorkeling at the coast but this wasn&#39;t comparable to what we have experienced at Corcovado.</p>

<p>We went up to the jungle house early again and ate the rests of our dinner we cooked the day before. Again we had a few hours at the terrace and went to bed early. Living in the jungle is different from living elsewhere.</p>

<h2 id="day-22">Day 22</h2>

<p>We got up early again and enjoyed the nature. This might sound a bit boring but it&#39;s definetly not. It&#39;s so amazing to hear the sound of the jungle and to see the animals that live there. Even watching the spiders was interesting. Unlike as in Europe they don&#39;t come into houses cause they don&#39;t need to. They find everything outside.</p>

<p>Around 11am we left the jungle house (thank you we had an amazing time) and drove to Limon where we booked a night in a hotel directly at the beach. The hotel was quite nice. The food wasn&#39;t but it was ok.
Before we checked in at the hotel we had a look at Limon. To be honest I don&#39;t have to go there a second time but it was ok to see how people in Costa Rica live in towns that are not packed with tourists. Limon is kown for it&#39;s harbour from where coffee and bananas are shipped into the whole world. Also a lot of cruize ships stop there to send their passengers from there to day trips in Costa Rica.</p>

<p>In the late afternoon we had a couple of hours at the beach of the hotel. Besides us there was noone at the very long beach. Maybe this was because of the bull sharks that are supposed to live there? We didn&#39;t go into deep water so we weren&#39;t frightened of that.</p>

<h2 id="day-23">Day 23</h2>

<p>Our last day at the coast of Costa Rica. After breakfast (with eggs again) we went to the beach for another couple of hours. The sun was already hot and we enjoyed the last sun bath in Costa Rica.</p>

<p>At lunchtime we that drove to San Jose where we had booked a hotel for two nights cause we had to return our car to the car rent and cause we thought it might be worth to have a look around the biggest city of Costa Rica. It wasn&#39;t I have to admit.</p>

<p>After we arrived at the hotel we went into the center of the city. There is nothing to say. The city is simply not nice.</p>

<p>Even worse, when we went back to the hotel someone stole the chain of Annette from her neck. Fortunately it was a cheap one cause she always only wears cheap jewellery in tourist cities.</p>

<h2 id="day-24">Day 24</h2>

<p>Breakfast in the hotel was bad, with eggs again which I could eat. There is a time you can&#39;t eat any more eggs (maybe for the rest of your life).</p>

<p>After breakfast I returned the car. This took a while cause the car rent was not in the center of the San Jose but at the airport.
At lunchtime we went into the center again to visit one or two museums. On our way to the museums we discovered a big market hall with a lot of little shops in it. They sell meat, vegetables, herbs, clothes and also tourist stuff there. To see that was quite interesting.</p>

<p>Then we spent a couple of hours in the pre-columbian gold museum. That was quite interesting.</p>

<p>After we left the museum we had to fetch Felicia from a bus station. So we went there and picked her up. She spent a few nice and interesting days with a bunch of young Costa Ricans at the music festival. They also did another snorkeling tour and visited a waterfall. Sounds that she also had a nice time.</p>

<p>In the evening we had a dinner which wasn&#39;t really great and prepared ourselves for the long flight the next day.</p>

<h2 id="day-25">Day 25</h2>

<p>We had to get up very early (4:15 am) to get to the airport. We took a Uber which brought us there very quickly.</p>

<p>At 8:05 am our flight via Newark (New York) started. It took a bit more than 5 hours to Newark. There we had a pause for appr. 5:15 and from there we had to fly another 7:15 to Frankfurt. So the entire flight lasted about 18 hours. From Frankfurt where we landed at 9:15am we needed 6 or seven hours with Deutsche Bahn to reach our home in Braunschweig.</p>

<p>Two notes to the travel.
First: In the future I will not book a flight with a mid stop if there is also a direct filght available.
Second: It took us more than one hour in Newark to get from the first plane to the second. The reason for that was that we had to wait very long at the passport control. There was a long queue cause the US border officials take a foto and fingerprints from every one who enters the country, even if it&#39;s only to get a connection flight to another country. For me as a European that felt very weird. I haven&#39;t experienced something like that in any other country I&#39;ve been to yet.</p>
]]></content:encoded>
      <guid>https://text.tchncs.de/htammen/trip-to-costa-rica</guid>
      <pubDate>Sat, 24 Feb 2024 00:41:44 +0000</pubDate>
    </item>
    <item>
      <title>How I setup my personal Nextcloud server on the internet</title>
      <link>https://text.tchncs.de/htammen/how-i-setup-my-personal-nextcloud-server-on-the-internet</link>
      <description>&lt;![CDATA[#Nextcloud is a product that I have been looking at for some time. Since version Hub 6, it has been possible to develop your own applications not only in PHP, but with any programming language. Technically, it works with #Docker. This aroused my particular interest, which is why I finally decided to set up my own Nextcloud server.&#xA;In this blog post I describe the path I took and which documents / aids I used.&#xA;!--more--&#xA;## Nextcloud on #Raspberry PI 5&#xA;First I had to decide whether I wanted to use a hosted Nextcloud system or operate my own Nextcloud server. &#xA;After some research, I opted for my own server, which I wanted to install on a brand new Raspberry PI 5. The deciding factor was this excellent video on apfelcast.com.&#xA;As I have always been interested in the Raspberry PI, this was the perfect opportunity to gain some experience with it.&#xA;&#xA;So I bought a Raspberry PI 5 with 8 GB of RAM and a 2 TB external USB SSD hard disk. &#xA;The whole thing, including the fan, case and power supply for the PI, cost around Eur 210 (where else can you get a computer with these features for this price?).&#xA;The PI was ready for use within a few (approx. 30) minutes. I was then able to log on to it using SSH.&#xA;The setup of the PI is also described in the video above.&#xA;&#xA;Docker and Nextcloud&#xA;&#xA;Following the instructions in the video, I now installed Docker and Nextcloud. The latter runs in a Docker container. &#xA;I installed the Docker engine on the SD card from which the PI boots. However, I installed everything that belongs to Nextcloud (including the Nextcloud configuration, DB, ...) on the external SSD hard disk and not on the SD card. That way I&#39;m able to just connect the USB SSD to another server and run the Nextcloud with even more computing power.&#xA;The directory structure at my external SSD looks like this:&#xA;/mnt/ssdsda1/&#xA;├── docker-compose.yml&#xA;├── lost+found&#xA;├── ncdata&#xA;│   ├── appdataoc74sn132wxw&#xA;│   ├── filesexternal&#xA;│   ├── myuser&#xA;│   ├── ncadmin&#xA;│   ├── index.html&#xA;│   └── nextcloud.log&#xA;└── nextcloud&#xA;    ├── apps&#xA;    ├── config&#xA;    ├── mariadb&#xA;    └── nextcloud&#xA;ncdata contains all the data the users of my Nextcloud server save in their accounts.&#xA;nextcloud contains the configuration and runtime artifacts Nextcloud uses.&#xA;&#xA;As a reminder for me: The root directory of the ssd partition contains docker-compose.yml, which is used to start the containers.&#xA;&#xA;Now I was able to access the Nextcloud in my local network (http://ncpi.local:8080). &#xA;&#xA;Access from the internet&#xA;&#xA;Next, I made my Nextcloud instance accessible from the Internet. &#xA;I obtained a dyndns URL from ClouDNS and set up my Fritzbox router (the most common router in Germany) so that it forwards the requests to my dyndns URL to the Nextcloud instance. This is described very well in this video from approx. 7:25 to 10:23.&#xA;Nextcloud then had to be configured to accept requests from my new dyndns. This is also described in the video from approx. 10:23 to 11:07.&#xA;&#xA;Using Reverse proxy and SSL encryption&#xA;&#xA;Now my Nextcloud instance was accessible via http on the Internet. We all know that this is of course a no-go.&#xA;So I set to work encrypting the access with SSL.&#xA;Since I might want to provide other services on the Internet later, I thought it would be a good idea to install a reverse proxy that forwards the requests to my Nextcloud server and other ones later on. This reverse proxy would perform the SSL termination.&#xA;So I didn&#39;t have to deal with the SSL configuration of Nextcloud. This server is still contacted by the RP via http.&#xA;For some reason (I forgot which ones) I decided to use nginx as the RP. After initial unsuccessful attempts with the product itself, I came across the nginxproxymanager, which makes configuring a #nginx RP a breeze. &#xA;Even the generation and use of Letsencrypt SSL certificates works at the touch of a button.&#xA;Thus, the configuration of the RP with SSL encryption was completed within a short time. &#xA;Of course, the RP also runs in its own Docker container. Both the configuration of the Docker container and that of the nginx server are stored on my SD card.&#xA;As you can see I use a data directory to save the nginxproxymanager configuration. This is ok for me at the moment. Maybe I switch to a database as described in the documentation of the product lat.&#xA;└── nginx&#xA;    ├── data&#xA;    │   ├── access&#xA;    │   ├── customssl&#xA;    │   ├── database.sqlite&#xA;    │   ├── keys.json&#xA;    │   ├── letsencrypt-acme-challenge&#xA;    │   ├── logs&#xA;    │   └── nginx&#xA;    ├── docker-compose.yml&#xA;    └── letsencrypt&#xA;        ├── accounts&#xA;        ├── archive&#xA;        ├── live&#xA;        ├── renewal&#xA;        └── renewal-hooks&#xA;For the content of the docker-compose.yml have a look at the getting started guide.&#xA;&#xA;Now, of course, I had to change the port forwarding of my router to the RP. Once I had done this, I was able to access my Nextcloud server from the Internet via SSL :-)&#xA;&#xA;Access via Nextcloud Android app&#xA;&#xA;This worked perfectly from the browsers on my computer. However, when I used the Nextcloud Android App, I received the following error message &#34;Strict mode, no HTTP connection allowed!&#34;.&#xA;I metagered the internet and found this imformative forum discussion.&#xA;This instructed me to add the following lines to my config.php.&#xA;  &#39;overwrite.cli.url&#39; =  &#39;https://mydomainname.xxxx.xxx&#39;,&#xA;  &#39;overwriteprotocol&#39; =  &#39;https&#39;,&#xA;After I restarted the Nextcloud server I could also access it from my Android device.&#xA;&#xA;Here you can see my entire Nextcloud config.php file.&#xA;&lt;?php&#xA;$CONFIG = array (&#xA;  &#39;htaccess.RewriteBase&#39; =  &#39;/&#39;,&#xA;  &#39;memcache.local&#39; =  &#39;\\OC\\Memcache\\APCu&#39;,&#xA;  &#39;appspaths&#39; =  array (&#xA;    0 =  array (&#xA;      &#39;path&#39; =  &#39;/var/www/html/apps&#39;,&#xA;      &#39;url&#39; =  &#39;/apps&#39;,&#xA;      &#39;writable&#39; =  false,&#xA;    ),&#xA;    1 =  array (&#xA;      &#39;path&#39; =  &#39;/var/www/html/customapps&#39;,&#xA;      &#39;url&#39; =  &#39;/customapps&#39;,&#xA;      &#39;writable&#39; =  true,&#xA;    ),&#xA;  ),&#xA;  &#39;upgrade.disable-web&#39; =  true,&#xA;  &#39;instanceid&#39; =  &#39;xxxxxxxx&#39;,&#xA;  &#39;passwordsalt&#39; =  &#39;xxxxxxxx&#39;,&#xA;  &#39;secret&#39; =  &#39;xxxxxxxx&#39;,&#xA;  &#39;trusteddomains&#39; =  array (&#xA;    0 =  &#39;nextcloud.local:8080&#39;,&#xA;    1 =  &#39;mydomainname.xxxx.xxx&#39;,&#xA;  ),&#xA;  &#39;datadirectory&#39; =  &#39;/var/www/html/data&#39;,&#xA;  &#39;dbtype&#39; =  &#39;mysql&#39;,&#xA;  &#39;version&#39; =  &#39;28.0.1.1&#39;,&#xA;  &#39;overwrite.cli.url&#39; =  &#39;https://mydomainname.xxxx.xxx&#39;,&#xA;  &#39;overwriteprotocol&#39; =  &#39;https&#39;,&#xA;  &#39;dbname&#39; =  &#39;nextcloud&#39;,&#xA;  &#39;dbhost&#39; =  &#39;mariadb&#39;,&#xA;  &#39;dbport&#39; =  &#39;&#39;,&#xA;  &#39;dbtableprefix&#39; =  &#39;oc&#39;,&#xA;  &#39;mysql.utf8mb4&#39; =  true,&#xA;  &#39;dbuser&#39; =  &#39;mydbuser&#39;,&#xA;  &#39;dbpassword&#39; =  &#39;mydbpassword&#39;,&#xA;  &#39;installed&#39; =  true,&#xA;  &#39;loglevel&#39; =  0,&#xA;);&#xA;&#xA;Conclusion&#xA;As you can see, it is not difficult to operate a functional Nextcloud server securely on the Internet.&#xA;Now I&#39;m curious to see what&#39;s possible with Nextcloud and how I can integrate my own projects developed with node.js (#sapcap) into Nextcloud.&#xA;&#xA;Some more links&#xA;A good tutorial to install Nextcloud in a productive environment you&#39;ll find here&#xA;Here is the hargening and security guidance for Nextcloud.&#xA; &#xA;&#xA;  &#xA;&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<p><a href="/htammen/tag:Nextcloud" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">Nextcloud</span></a> is a product that I have been looking at for some time. Since version Hub 6, it has been possible to develop your own applications not only in PHP, but with any programming language. Technically, it works with <a href="/htammen/tag:Docker" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">Docker</span></a>. This aroused my particular interest, which is why I finally decided to set up my own Nextcloud server.
In this blog post I describe the path I took and which documents / aids I used.
</p>

<h2 id="nextcloud-on-raspberry-pi-5">Nextcloud on <a href="/htammen/tag:Raspberry" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">Raspberry</span></a> PI 5</h2>

<p>First I had to decide whether I wanted to use a hosted Nextcloud system or operate my own Nextcloud server.
After some research, I opted for my own server, which I wanted to install on a brand new Raspberry PI 5. The deciding factor was this excellent video on <a href="https://apfelcast.com/nextcloud-auf-raspberry-pi-5-installieren-einfach-mit-docker-container/" rel="nofollow">apfelcast.com</a>.
As I have always been interested in the Raspberry PI, this was the perfect opportunity to gain some experience with it.</p>

<p>So I bought a Raspberry PI 5 with 8 GB of RAM and a 2 TB external USB SSD hard disk.
The whole thing, including the fan, case and power supply for the PI, cost around Eur 210 (where else can you get a computer with these features for this price?).
The PI was ready for use within a few (approx. 30) minutes. I was then able to log on to it using SSH.
The setup of the PI is also described in the video above.</p>

<h2 id="docker-and-nextcloud">Docker and Nextcloud</h2>

<p>Following the instructions in the video, I now installed Docker and Nextcloud. The latter runs in a Docker container.
I installed the Docker engine on the SD card from which the PI boots. However, I installed everything that belongs to Nextcloud (including the Nextcloud configuration, DB, ...) on the external SSD hard disk and not on the SD card. That way I&#39;m able to just connect the USB SSD to another server and run the Nextcloud with even more computing power.
The directory structure at my external SSD looks like this:</p>

<pre><code>/mnt/ssd_sda1/
├── docker-compose.yml
├── lost+found
├── ncdata
│   ├── appdata_oc74sn132wxw
│   ├── files_external
│   ├── myuser
│   ├── ncadmin
│   ├── index.html
│   └── nextcloud.log
└── nextcloud
    ├── apps
    ├── config
    ├── mariadb
    └── nextcloud
</code></pre>

<p><code>ncdata</code> contains all the data the users of my Nextcloud server save in their accounts.
<code>nextcloud</code> contains the configuration and runtime artifacts Nextcloud uses.</p>

<p><em>As a reminder for me: The root directory of the ssd partition contains <code>docker-compose.yml</code>, which is used to start the containers.</em></p>

<p>Now I was able to access the Nextcloud in my local network (<a href="http://ncpi.local:8080" rel="nofollow">http://ncpi.local:8080</a>).</p>

<h2 id="access-from-the-internet">Access from the internet</h2>

<p>Next, I made my Nextcloud instance accessible from the Internet.
I obtained a dyndns URL from <a href="https://www.cloudns.net/" rel="nofollow">ClouDNS</a> and set up my Fritzbox router (the most common router in Germany) so that it forwards the requests to my dyndns URL to the Nextcloud instance. This is described very well in <a href="https://www.youtube.com/watch?v=g1mYxrxdJXM" rel="nofollow">this video</a> from approx. 7:25 to 10:23.
Nextcloud then had to be configured to accept requests from my new dyndns. This is also described in the video from approx. 10:23 to 11:07.</p>

<h2 id="using-reverse-proxy-and-ssl-encryption">Using Reverse proxy and SSL encryption</h2>

<p>Now my Nextcloud instance was accessible via http on the Internet. We all know that this is of course a no-go.
So I set to work encrypting the access with SSL.
Since I might want to provide other services on the Internet later, I thought it would be a good idea to install a reverse proxy that forwards the requests to my Nextcloud server and other ones later on. This reverse proxy would perform the SSL termination.
So I didn&#39;t have to deal with the SSL configuration of Nextcloud. This server is still contacted by the RP via http.
For some reason (I forgot which ones) I decided to use <a href="https://www.nginx.com/" rel="nofollow">nginx</a> as the RP. After initial unsuccessful attempts with the product itself, I came across the <a href="https://nginxproxymanager.com/" rel="nofollow">nginxproxymanager</a>, which makes configuring a <a href="/htammen/tag:nginx" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">nginx</span></a> RP a breeze.
Even the generation and use of Letsencrypt SSL certificates works at the touch of a button.
Thus, the configuration of the RP with SSL encryption was completed within a short time.
Of course, the RP also runs in its own Docker container. Both the configuration of the Docker container and that of the nginx server are stored on my SD card.
As you can see I use a <code>data</code> directory to save the nginxproxymanager configuration. This is ok for me at the moment. Maybe I switch to a database as described in the documentation of the product lat.</p>

<pre><code>└── nginx
    ├── data
    │   ├── access
    │   ├── custom_ssl
    │   ├── database.sqlite
    │   ├── keys.json
    │   ├── letsencrypt-acme-challenge
    │   ├── logs
    │   └── nginx
    ├── docker-compose.yml
    └── letsencrypt
        ├── accounts
        ├── archive
        ├── live
        ├── renewal
        └── renewal-hooks
</code></pre>

<p>For the content of the <code>docker-compose.yml</code> have a look at the <a href="https://nginxproxymanager.com/guide/#quick-setup" rel="nofollow">getting started guide</a>.</p>

<p>Now, of course, I had to change the port forwarding of my router to the RP. Once I had done this, I was able to access my Nextcloud server from the Internet via SSL :–)</p>

<h2 id="access-via-nextcloud-android-app">Access via Nextcloud Android app</h2>

<p>This worked perfectly from the browsers on my computer. However, when I used the <a href="https://f-droid.org/en/packages/com.nextcloud.client/" rel="nofollow">Nextcloud Android App</a>, I received the following error message “Strict mode, no HTTP connection allowed!”.
I <a href="https://metager.de/" rel="nofollow">metager</a>ed the internet and found this imformative <a href="https://help.nextcloud.com/t/android-app-error-strict-mode-no-http-connection-allowed/125063" rel="nofollow">forum discussion</a>.
This instructed me to add the following lines to my config.php.</p>

<pre><code>  &#39;overwrite.cli.url&#39; =&gt; &#39;https://mydomainname.xxxx.xxx&#39;,
  &#39;overwriteprotocol&#39; =&gt; &#39;https&#39;,
</code></pre>

<p>After I restarted the Nextcloud server I could also access it from my Android device.</p>

<p>Here you can see my entire Nextcloud config.php file.</p>

<pre><code>&lt;?php
$CONFIG = array (
  &#39;htaccess.RewriteBase&#39; =&gt; &#39;/&#39;,
  &#39;memcache.local&#39; =&gt; &#39;\\OC\\Memcache\\APCu&#39;,
  &#39;apps_paths&#39; =&gt;
  array (
    0 =&gt;
    array (
      &#39;path&#39; =&gt; &#39;/var/www/html/apps&#39;,
      &#39;url&#39; =&gt; &#39;/apps&#39;,
      &#39;writable&#39; =&gt; false,
    ),
    1 =&gt;
    array (
      &#39;path&#39; =&gt; &#39;/var/www/html/custom_apps&#39;,
      &#39;url&#39; =&gt; &#39;/custom_apps&#39;,
      &#39;writable&#39; =&gt; true,
    ),
  ),
  &#39;upgrade.disable-web&#39; =&gt; true,
  &#39;instanceid&#39; =&gt; &#39;xxxxxxxx&#39;,
  &#39;passwordsalt&#39; =&gt; &#39;xxxxxxxx&#39;,
  &#39;secret&#39; =&gt; &#39;xxxxxxxx&#39;,
  &#39;trusted_domains&#39; =&gt;
  array (
    0 =&gt; &#39;nextcloud.local:8080&#39;,
    1 =&gt; &#39;mydomainname.xxxx.xxx&#39;,
  ),
  &#39;datadirectory&#39; =&gt; &#39;/var/www/html/data&#39;,
  &#39;dbtype&#39; =&gt; &#39;mysql&#39;,
  &#39;version&#39; =&gt; &#39;28.0.1.1&#39;,
  &#39;overwrite.cli.url&#39; =&gt; &#39;https://mydomainname.xxxx.xxx&#39;,
  &#39;overwriteprotocol&#39; =&gt; &#39;https&#39;,
  &#39;dbname&#39; =&gt; &#39;nextcloud&#39;,
  &#39;dbhost&#39; =&gt; &#39;mariadb&#39;,
  &#39;dbport&#39; =&gt; &#39;&#39;,
  &#39;dbtableprefix&#39; =&gt; &#39;oc_&#39;,
  &#39;mysql.utf8mb4&#39; =&gt; true,
  &#39;dbuser&#39; =&gt; &#39;mydbuser&#39;,
  &#39;dbpassword&#39; =&gt; &#39;mydbpassword&#39;,
  &#39;installed&#39; =&gt; true,
  &#39;loglevel&#39; =&gt; 0,
);
</code></pre>

<h2 id="conclusion">Conclusion</h2>

<p>As you can see, it is not difficult to operate a functional Nextcloud server securely on the Internet.
Now I&#39;m curious to see what&#39;s possible with Nextcloud and how I can integrate my own projects developed with node.js (<a href="/htammen/tag:sapcap" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">sapcap</span></a>) into Nextcloud.</p>

<h2 id="some-more-links">Some more links</h2>
<ul><li>A good tutorial to install Nextcloud in a productive environment you&#39;ll find <a href="https://www.c-rieger.de/nextcloud-installationsanleitung/" rel="nofollow">here</a></li>
<li>Here is the <a href="https://docs.nextcloud.com/server/28/admin_manual/installation/harden_server.html#use-https" rel="nofollow">hargening and security guidance</a> for Nextcloud.



<br></li></ul>
]]></content:encoded>
      <guid>https://text.tchncs.de/htammen/how-i-setup-my-personal-nextcloud-server-on-the-internet</guid>
      <pubDate>Sun, 07 Jan 2024 09:43:20 +0000</pubDate>
    </item>
    <item>
      <title>Run your own Mastodon server on localhost</title>
      <link>https://text.tchncs.de/htammen/run-your-own-mastodon-server-on-localhost</link>
      <description>&lt;![CDATA[I want to play around with #Mastodon API. So I thought about an environment I could use for it.&#xA;!--more--&#xA;I had these options:&#xA;&#xA;Create an account at an arbitrary server and pollute this server with my test messages. Uhhh, don&#39;t do that!!! The owner of the server will hate you and that for good reasons.&#xA;Find a server in the world that was setup especially for this purpose. I have not found one and didn&#39;t want to look for it very long.&#xA;Create a &#34;fake&#34; account at my server (saptodon.org) and use this. No good idea. I would spam the local timeline with my test posts. This would disturb the other users of saptodon.&#xA;Setup a server on my own PC and use it. Sounds good but also like a lot of work.&#xA;&#xA;I decided to setup a server on my PC to access it via localhost. &#xA;Cause I didn&#39;t want to install the software and set several environment variables at my PC I went to Dockerhub and searched for an image. I found an image from VMWARE that was easy to install (no config at all). There is also another promising image from linuxserver.io but this needs some additional services (e.g. postgresql database) that needs to be setup and linked to your mastodon container by yourself.&#xA;&#xA;The installation was very easy. I just downloaded a docker-compose.yaml file and ran it.&#xA;curl -sSL https://raw.githubusercontent.com/bitnami/containers/main/bitnami/mastodon/docker-compose.yml   docker-compose.yml&#xA;&#xA;docker-compose up -d&#xA;&#xA;Note: If you, unlike me, want to save some time read the docker-hub documentation of the bitnami image completely till the end. Otherwise you will wonder and search the internet for the default usernames and passwords :-).&#xA;&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<p>I want to play around with <a href="/htammen/tag:Mastodon" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">Mastodon</span></a> API. So I thought about an environment I could use for it.

I had these options:</p>
<ul><li>Create an account at an arbitrary server and pollute this server with my test messages. <strong>Uhhh, don&#39;t do that!!!</strong> The owner of the server will hate you and that for good reasons.</li>
<li>Find a server in the world that was setup especially for this purpose. I have not found one and didn&#39;t want to look for it very long.</li>
<li>Create a “fake” account at my server (saptodon.org) and use this. No good idea. I would spam the local timeline with my test posts. This would disturb the other users of saptodon.</li>
<li>Setup a server on my own PC and use it. Sounds good but also like a lot of work.</li></ul>

<p>I decided to setup a server on my PC to access it via localhost.
Cause I didn&#39;t want to install the software and set several environment variables at my PC I went to <a href="https://hub.docker.com/" rel="nofollow">Dockerhub</a> and searched for an image. I found an image from <a href="https://hub.docker.com/r/bitnami/mastodon" rel="nofollow">VMWARE</a> that was easy to install (no config at all). There is also another promising image from <a href="https://hub.docker.com/r/linuxserver/mastodon" rel="nofollow">linuxserver.io</a> but this needs some additional services (e.g. postgresql database) that needs to be setup and linked to your mastodon container by yourself.</p>

<p>The installation was very easy. I just downloaded a docker-compose.yaml file and ran it.</p>

<pre><code class="language-bash">curl -sSL https://raw.githubusercontent.com/bitnami/containers/main/bitnami/mastodon/docker-compose.yml &gt; docker-compose.yml

docker-compose up -d
</code></pre>

<p>Note: If you, unlike me, want to save some time read the docker-hub documentation of the bitnami image completely till the end. Otherwise you will wonder and search the internet for the default usernames and passwords :–).</p>
]]></content:encoded>
      <guid>https://text.tchncs.de/htammen/run-your-own-mastodon-server-on-localhost</guid>
      <pubDate>Tue, 02 Jan 2024 18:01:13 +0000</pubDate>
    </item>
    <item>
      <title>Why should you register with a small Mastodon server?</title>
      <link>https://text.tchncs.de/htammen/why-should-you-register-with-a-small-mastodon-server</link>
      <description>&lt;![CDATA[If you want to set up a Mastodon account, you should not necessarily choose the one with the most users.&#xA;In this article, I will give you a few reasons why a large provider is not always the best choice.&#xA;!--more--&#xA;&#xA;Unlike centralized services such as Instagram, X, ..., Mastodon, as well as the entire Fediverse, is decentralized. This means that there is not just one provider with whom you can set up an account, but many. The Fediverse servers are connected with each other, so that you can follow accounts on any other server from &#34;your&#34; server. This means that you have access to the same information regardless of which provider you choose.&#xA;&#xA;When choosing the best server for you, you should consider the following points.&#xA;&#xA;Many servers have a specific focus. Users who log on to a server usually exchange messages about this main topic. &#xA;For example, there are servers that focus on science, software development, computer games, religion or certain regions of the world/country.&#xA;Choose a server that best suits your interests.&#xA;Mastodon has a global timeline, a local timeline and a follower timeline. &#xA;  The global timeline shows you all posts from accounts that your server recognizes.&#xA;  The local timeline shows the posts that have been published on &#34;your&#34; server.&#xA;  Your personal timeline shows you all posts from the accounts you follow.&#xA;  The global and local timeline can quickly become confusing on large servers or contain posts that are of less interest to you.&#xA;By selecting a &#34;small&#34; server, you can restrict these timelines to the topics that interest you.&#xA;Each server operator defines its own participation rules, which you agree to when you register your account. Be sure to take a look at these. You may find that you like the rules of one provider or another better.&#xA;The Fediverse thrives on decentralization. This ensures that not one or a few providers set the rules for the entire fediverse like this is the case for commercial platforms. &#xA;If a provider develops in a direction that is not in line with your world view or interests, you can simply move your account to another server,&#xA;By creating your account with a small provider, you ensure that there are a variety of servers and that the spirit of the Fediverse is maintained. &#xA;It&#39;s similar to democracy. A democracy only works if there are different parties. In a state with one party, this does not exist.&#xA;&#xA;This list of arguments in favor of small Mastodon servers is not exhaustive. There are also good reasons for creating an account with a large provider.&#xA;&#xA;#fediverse #mastodon #federation &#xA;]]&gt;</description>
      <content:encoded><![CDATA[<p>If you want to set up a Mastodon account, you should not necessarily choose the one with the most users.
In this article, I will give you a few reasons why a large provider is not always the best choice.
</p>

<p>Unlike centralized services such as Instagram, X, ..., Mastodon, as well as the entire Fediverse, is decentralized. This means that there is not just one provider with whom you can set up an account, but many. The Fediverse servers are connected with each other, so that you can follow accounts on any other server from “your” server. This means that you have access to the same information regardless of which provider you choose.</p>

<p>When choosing the best server for you, you should consider the following points.</p>
<ul><li>Many servers have a specific focus. Users who log on to a server usually exchange messages about this main topic.
For example, there are servers that focus on science, software development, computer games, religion or certain regions of the world/country.
Choose a server that best suits your interests.</li>
<li>Mastodon has a global timeline, a local timeline and a follower timeline.
<ul><li>The global timeline shows you all posts from accounts that your server recognizes.</li>
<li>The local timeline shows the posts that have been published on “your” server.</li>
<li>Your personal timeline shows you all posts from the accounts you follow.</li>
<li>The global and local timeline can quickly become confusing on large servers or contain posts that are of less interest to you.
By selecting a “small” server, you can restrict these timelines to the topics that interest you.</li></ul></li>
<li>Each server operator defines its own participation rules, which you agree to when you register your account. Be sure to take a look at these. You may find that you like the rules of one provider or another better.</li>
<li>The Fediverse thrives on decentralization. This ensures that not one or a few providers set the rules for the entire fediverse like this is the case for commercial platforms.
If a provider develops in a direction that is not in line with your world view or interests, you can simply move your account to another server,</li>
<li>By creating your account with a small provider, you ensure that there are a variety of servers and that the spirit of the Fediverse is maintained.
It&#39;s similar to democracy. A democracy only works if there are different parties. In a state with one party, this does not exist.</li></ul>

<p>This list of arguments in favor of small Mastodon servers is not exhaustive. There are also good reasons for creating an account with a large provider.</p>

<p><a href="/htammen/tag:fediverse" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">fediverse</span></a> <a href="/htammen/tag:mastodon" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">mastodon</span></a> <a href="/htammen/tag:federation" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">federation</span></a></p>
]]></content:encoded>
      <guid>https://text.tchncs.de/htammen/why-should-you-register-with-a-small-mastodon-server</guid>
      <pubDate>Tue, 26 Dec 2023 21:05:02 +0000</pubDate>
    </item>
  </channel>
</rss>