<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Emanuel Pina</title><link>https://emanuelpina.pt/</link><description>Recent content on Emanuel Pina</description><generator>Hugo -- gohugo.io</generator><language>en-gb</language><lastBuildDate>Sat, 14 Aug 2021 16:41:27 +0100</lastBuildDate><atom:link href="https://emanuelpina.pt/index.xml" rel="self" type="application/rss+xml"/><item><title>Debian 11 Released</title><link>https://emanuelpina.pt/debian-11-released/</link><pubDate>Sat, 14 Aug 2021 16:41:27 +0100</pubDate><guid>https://emanuelpina.pt/debian-11-released/</guid><description>&lt;p>The most recent version of Debian, with the code name &amp;ldquo;Bullseye&amp;rdquo;, &lt;a href="https://www.debian.org/News/2021/20210814">was released today&lt;/a>!&lt;/p>
&lt;p>Debian is one of oldest Linux distributions, notorious for been stable and reliable. Used as base for &lt;a href="https://distrowatch.com/search.php?basedon=Debian#simple">many other distributions&lt;/a>. And a popular choice to run on servers.&lt;/p>
&lt;p>Debian sees a new release each two years (more or less) and in conjunction with their &lt;a href="https://wiki.debian.org/LTS">Long Term Support&lt;/a> team, they promise at least 5 years of extended support for the each stable release.&lt;/p>
&lt;p>I was waiting with special anticipation for this release, after recently &lt;a href="https://emanuelpina.pt/my-first-year-with-linux-on-desktop/">decided to stop relying on enterprise developed distributions&lt;/a>.&lt;/p>
&lt;p>I&amp;rsquo;ll now migrate my server from Ubuntu 20.04 to Debian 11 and, therefore, it was only logic that my first step should be update the tutorials on this blog. From the &lt;a href="https://emanuelpina.pt/debian-server-initial-setup/">initial server setup&lt;/a>, to install &lt;a href="https://emanuelpina.pt/nginx-installation-on-debian/">Nginx&lt;/a>, &lt;a href="https://emanuelpina.pt/postgresql-installation-on-debian/">PostgreSQL&lt;/a> and &lt;a href="https://emanuelpina.pt/php-installation-on-debian/">PHP&lt;/a>, and finally installing &lt;a href="https://emanuelpina.pt/nextcloud-22-installation-on-debian/">Nextcloud&lt;/a>, all were updated to reflect the use of Debian 11.&lt;/p></description></item><item><title>My First Year With Linux on Desktop</title><link>https://emanuelpina.pt/my-first-year-with-linux-on-desktop/</link><pubDate>Fri, 11 Jun 2021 15:49:08 +0100</pubDate><guid>https://emanuelpina.pt/my-first-year-with-linux-on-desktop/</guid><description>&lt;p>&lt;a href="https://emanuelpina.pt/getting-started-with-linux-on-desktop/">A year ago&lt;/a>, after a couple months of head scratching and intense distro hopping, I settled with Manjaro with Gnome. But it didn&amp;rsquo;t take long for another Arch based project get my attention!&lt;/p>
&lt;p>With their motto “a terminal-centric distro with a vibrant and friendly community at its core”, &lt;a href="https://endeavouros.com/">EndeavourOS&lt;/a> sounded perfect.&lt;/p>
&lt;p>First, as I began my journey with Linux on the server side, terminal is my natural choice to manage things. And more, EndeavourOS promised: a lean installation, close to a &lt;em>vanilla&lt;/em> Arch experience; a user-friendly installer, with a dozen options between desktop environments and windows managers; and a great community.&lt;/p>
&lt;p>I took my time with Manjaro, but a couple of months later I moved to EndeavourOS, and it didn&amp;rsquo;t disappoint! It was my home for months. First with Gnome, but mostly with &lt;a href="https://kde.org/plasma-desktop/">KDE Plasma&lt;/a>.&lt;/p>
&lt;p>After my initial choice of Gnome, I got bored and decided to give Plasma another shot. At first it felt bloated with its large array of settings and customisation options. I had to fight that initial overwhelm feeling and increase my understanding of those settings to get my way with it.&lt;/p>
&lt;p>KDE Plasma is powerful, pleasant and fulfilled my needs. But with the changes and hype around the release of &lt;a href="https://help.gnome.org/misc/release-notes/40.0/">Gnome 40&lt;/a>, I couldn&amp;rsquo;t resist getting back to it.&lt;/p>
&lt;p>At the end, I think the look and feel of Gnome is more at my taste. Although, to be honest I cannot point a distinct favourite. They&amp;rsquo;re both capable desktop environments that I can adapt to my workflow.&lt;/p>
&lt;p>By the time I made plans to get back to Gnome, with the knowledge I acquired over the year, I felt that moving to &lt;a href="https://archlinux.org/">Arch Linux&lt;/a> would be a natural step. And so I did!&lt;/p>
&lt;p>Meanwhile, I looked for a distro that I could install on my parents laptop. Something with a fixed release model, that I could forget for a few months. I tested Fedora, Elementary and Zorin, but my favourite keeps being &lt;a href="https://linuxmint.com/">Linux Mint&lt;/a>. One can agree or not with &lt;a href="https://blog.linuxmint.com/?p=3766">their view about Snaps and its implementation on Ubuntu&lt;/a> (I do!). But is indisputable the great work they keep doing, putting together a stable, predictable and user-friendly distro.&lt;/p>
&lt;p>From the events of last year, there was one that made me think the most. The &lt;a href="https://lists.centos.org/pipermail/centos-announce/2020-December/048208.html">refocus of CentOS&lt;/a>. I didn&amp;rsquo;t use CentOS or any distro from Red Hat, but was alarming seeing how much people/business relied on a project that an enterprise could change/end with the snap-of-a-finger.&lt;/p>
&lt;p>I recognise the importance of those enterprises on the development and adoption of Linux, and I&amp;rsquo;m not against the use of their products. But keep in mind that enterprises will always behave according to its interests. So, if you rely on an enterprise developed product, have a backup plan.&lt;/p>
&lt;p>Personally, I plan to migrate my server to &lt;a href="https://www.debian.org/releases/testing/releasenotes">Debian 11&lt;/a> once it&amp;rsquo;s released.&lt;/p>
&lt;p>Furthermore, I hope Linux Mint keeps developing a version based on Debian instead of Ubuntu. And would like to see other projects, such as Zorin and Elementary, replicate that same strategy.&lt;/p></description></item><item><title>Using Hetzner to Self Host Nextcloud</title><link>https://emanuelpina.pt/using-hetzner-to-self-host-nextcloud/</link><pubDate>Tue, 22 Sep 2020 20:10:39 +0100</pubDate><guid>https://emanuelpina.pt/using-hetzner-to-self-host-nextcloud/</guid><description>&lt;p>This is a brief, but long owed post.&lt;/p>
&lt;p>Last year, I decided that the best path to claim ownership of my data was self-hosting Nextcloud.&lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup> I faced some issues using Hetzner&amp;rsquo;s 1 vCPU plan and I convinced myself that the culprit was their vCPU not being powerful enough.&lt;sup id="fnref:2">&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref">2&lt;/a>&lt;/sup>&lt;/p>
&lt;p>If it&amp;rsquo;s true that their vCPU wasn&amp;rsquo;t as powerful as Vultr&amp;rsquo;s one. It&amp;rsquo;s also true that with the right know-how I would be able to debug the issue and make things work. &lt;strong>The culprit was in fact my lack of knowledge.&lt;/strong>&lt;/p>
&lt;p>So, what changed? I just learned how to tune PHP&lt;sup id="fnref:3">&lt;a href="#fn:3" class="footnote-ref" role="doc-noteref">3&lt;/a>&lt;/sup> and PostgreSQL&lt;sup id="fnref:4">&lt;a href="#fn:4" class="footnote-ref" role="doc-noteref">4&lt;/a>&lt;/sup> according to the server resources. That&amp;rsquo;s it!&lt;/p>
&lt;p>That settled, I end up moving to Hetzner at the beginning of this year. Currently, on a 1 vCPU VPS (that costs €2.49/month), I&amp;rsquo;m hosting Nextcloud, Drone CI, Miniflux, MailyGo and this blog without issues. In the future, if I see myself in need of more CPU power, I can easy rescale the VPS to an optimized for CPU plan (based on AMD EPYC 2nd Gen processors) with 2 vCPU for €3.49/month. Which is still cheaper than the Vultr&amp;rsquo;s 1 vCPU plan.&lt;/p>
&lt;p>If you&amp;rsquo;re looking for a VPS in Europe, give Hetzner a try. They have datacenters in Germany (Nuremberg and Falkenstein) and Finland (Helsinki). You can use my &lt;a href="https://hetzner.cloud/?ref=c3vVEBlaZbLD">referral link&lt;/a> to get €20 in credits.
&lt;span class="marker red">For full disclosure, if you choose to stick with them and after you spend €10, I receive €10 in credits.&lt;/span>&lt;sup id="fnref:5">&lt;a href="#fn:5" class="footnote-ref" role="doc-noteref">5&lt;/a>&lt;/sup>&lt;/p>
&lt;div class="footnotes" role="doc-endnotes">
&lt;hr>
&lt;ol>
&lt;li id="fn:1">
&lt;p>&lt;a href="https://emanuelpina.pt/be-the-owner-of-your-data-with-nextcloud/">Be the Owner of Your Data With Nextcloud&lt;/a>&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;li id="fn:2">
&lt;p>&lt;a href="https://emanuelpina.pt/how-i-ended-up-with-vultr-to-self-host-nextcloud/">How I Ended Up With Vultr to Self Host Nextcloud&lt;/a>&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;li id="fn:3">
&lt;p>&lt;a href="https://emanuelpina.pt/php-installation-on-ubuntu/#tune-php">PHP Installation on Ubuntu - Tune PHP&lt;/a>&amp;#160;&lt;a href="#fnref:3" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;li id="fn:4">
&lt;p>&lt;a href="https://emanuelpina.pt/postgresql-installation-on-ubuntu/#tune-postgresql">PostgreSQL Installation on Ubuntu - Tune PostgreSQL&lt;/a>&amp;#160;&lt;a href="#fnref:4" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;li id="fn:5">
&lt;p>&lt;a href="https://console.hetzner.cloud/assets/legal/Referral-Programm_en.pdf">Conditions of participation of the referral program&lt;/a>&amp;#160;&lt;a href="#fnref:5" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;/ol>
&lt;/div></description></item><item><title>Handle HTML Forms Through Email With MailyGo</title><link>https://emanuelpina.pt/handle-html-forms-through-email-with-mailygo/</link><pubDate>Thu, 30 Jul 2020 22:28:28 +0100</pubDate><guid>https://emanuelpina.pt/handle-html-forms-through-email-with-mailygo/</guid><description>&lt;p>You may have already notice the &lt;a href="https://emanuelpina.pt/contact">contact form&lt;/a> on this blog. Until recently, it was handled by Netlify and used a &lt;a href="https://github.com/emanuelpina/blog/commit/34024920a96c140d5d10186c8bda26f9f8b1510e">serverless function&lt;/a> to send an email both to me and the submitter. This worked fine, but was far from ideal because I had to trust the data to a third party (Netlify).&lt;/p>
&lt;p>As I was already running a server (with Nextcloud and Mastodon), I looked for a self-hosted solution and found &lt;a href="https://codeberg.org/jlelse/MailyGo">MailyGo&lt;/a> from Jan-Lukas Else. A small tool written in Go that allows send HTML forms through email. Exactly what I was looking for!&lt;/p>
&lt;p>I just needed to tailor it a little bit to my use case. A good challenge as this was my first time working with Go. Keep that in mind and be kind when you review my code, please!&lt;/p>
&lt;p>So, there&amp;rsquo;s the list of changes I made:&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://codeberg.org/emanuelpina/mailygo/commit/cc8d366d96bae3208292b9459cf4e5a65905f11c">Created the ability to add text to the beginning and end of the email message&lt;/a>;&lt;/li>
&lt;li>&lt;a href="https://codeberg.org/emanuelpina/mailygo/commit/3fb966fe2773e2b586aee7e13fd6056498aa7fbe">Created the ability to send an email to the submitter too&lt;/a>;&lt;/li>
&lt;li>&lt;a href="https://codeberg.org/emanuelpina/mailygo/commit/90986863c8655174e31badf8b8f4db2f496a56bc">Created the ability to add text to the beginning and end of the email message sent to the submitter&lt;/a>;&lt;/li>
&lt;li>&lt;a href="https://codeberg.org/emanuelpina/mailygo/commit/896d055b53f03b0cd1cc733642e423dbb5684747">Created the ability to use specifics fields for Name, Subject and Message&lt;/a>.&lt;/li>
&lt;/ul>
&lt;h3 id="fighting-spam">Fighting Spam&lt;/h3>
&lt;p>When a form is placed online it&amp;rsquo;s a matter of time until it get some bots&amp;rsquo; attention and being targeted with spam. To fight it, the original version of MailyGo already used an honeypot field, a spamlist and integrated Google Safe Browsing to check URLs. And that seemed enough.&lt;/p>
&lt;p>But I didn&amp;rsquo;t want to use any third party, even less Google! And unfortunately the honeypot field and spamlist alone shown insufficient.&lt;/p>
&lt;p>I got some bots sending a particular field (submit) that wasn&amp;rsquo;t part of the form. And so, I &lt;a href="https://codeberg.org/emanuelpina/mailygo/commit/43bf54c8e2f85d8f49244bd185d64c38834d5697">created a denylist&lt;/a>, a list of fields names that MailyGo will look for and, if present, mark the submission as spam.&lt;/p>
&lt;p>I too got bots that &lt;em>grabbed&lt;/em> the URL of MailyGo and posted a submission directly to it, bypassing the form. To prevent this, I &lt;a href="https://codeberg.org/emanuelpina/mailygo/commit/749c137bfd39b0e2a5a79ed634fe8d64673f93f0">created the ability to use a token&lt;/a> to assure only the submissions that come from the form are handle by MailyGo. This token can be any combination of letters and numbers. If a &lt;code>TOKEN&lt;/code> is defined on configuration, MailyGo will look for a field named &lt;code>_token&lt;/code>. If this field doesn’t exist or its value doesn’t match the one defined on configuration the submission will be marked as spam.&lt;/p>
&lt;p>I&amp;rsquo;m using this set of solutions for more than a week now with zero spam. Seems enough. At least for now!&lt;/p>
&lt;p>An that&amp;rsquo;s it, &lt;a href="https://codeberg.org/emanuelpina/mailygo">my fork of MailyGo&lt;/a>!&lt;/p>
&lt;p>A big thanks to Jan-Lukas Else. Follow his &lt;a href="https://jlelse.blog/">blog&lt;/a> and know &lt;a href="https://jlelse.dev/projects/">more of his projects&lt;/a>.&lt;/p></description></item><item><title>Getting Started With Linux on Desktop</title><link>https://emanuelpina.pt/getting-started-with-linux-on-desktop/</link><pubDate>Wed, 24 Jun 2020 19:46:29 +0100</pubDate><guid>https://emanuelpina.pt/getting-started-with-linux-on-desktop/</guid><description>&lt;p>At the beginning of March, I bought a laptop and decided to finally embrace Linux as my daily drive desktop. Till that day I had only used Linux, more precisely Ubuntu, on servers. So, obviously it was my first choice, but I faced a lot of issues, just to find out that the 3rd generation AMD Ryzen CPU on my laptop wasn&amp;rsquo;t yet supported by the kernel version (5.3) used on Ubuntu 19.10. I wasn&amp;rsquo;t able to use any Ubuntu based distro. At first it sucked, but now I&amp;rsquo;m glad that happen!&lt;/p>
&lt;p>I then saw myself digging the Linux world to find a solution for me. I met and tried different distros and desktop environments. I saw dozens of videos, heard hours of podcasts, read a bunch of wikis, learned a lot and found a supportive community. There were moments of frustration, where I get paralyzed by indecision in the middle of so many choices. But that&amp;rsquo;s one of the beauties of Linux, right! You always have multiple choices and paths you can follow to tailor made your experience.&lt;/p>
&lt;p>After almost two months of distro hopping, I finally settled with &lt;a href="https://manjaro.org/">Manjaro&lt;/a>. A rolling release, based on &lt;a href="https://www.archlinux.org/">Arch Linux&lt;/a> and so more up-to-date and compatible with the &lt;a href="https://aur.archlinux.org/">AUR (Arch Linux User Repository)&lt;/a>. From the ones I tried, I kept others distros in a shortlist of favorites, like Solus and Fedora, but at the end of the day I always started missing AUR!&lt;/p>
&lt;p>Talking about desktop environments, I&amp;rsquo;m using &lt;a href="https://www.gnome.org/">Gnome&lt;/a>. It&amp;rsquo;s not perfect and I spent some time exploring XFCE and KDE too, but I still prefer the look and feel of Gnome. Well, to be honest, so far my favorite DE is Budgie, but feels like its development is somehow on idle, limited to bugfixes. Which is understanding because the Solus&amp;rsquo; team (who too develop Budgie) is small and have already a lot on their plate maintaining Solus.&lt;/p>
&lt;p>I have yet to explore window managers like i3 and so many other things that I don&amp;rsquo;t know exists yet!&lt;/p>
&lt;p>Any suggestion?&lt;/p></description></item><item><title>GoatCounter</title><link>https://emanuelpina.pt/goatcounter/</link><pubDate>Wed, 08 Apr 2020 10:35:32 +0100</pubDate><guid>https://emanuelpina.pt/goatcounter/</guid><description>&lt;p>Although page views aren&amp;rsquo;t my immediate concern when I write on this blog, is good to know if someone is reading what I share! But when doing it I wanted to assure that I wasn&amp;rsquo;t tracking you. In others words, that the data gathered couldn&amp;rsquo;t identify or being associated to you. To do so I started by using the self-hosted version of &lt;a href="https://github.com/usefathom/fathom/">Fathom&lt;/a>.&lt;/p>
&lt;p>Unfortunately, some time ago the developers of Fathom decided change their business model. They developed a new version of Fathom, closed source, only for paid customers, named &lt;a href="https://usefathom.com/">Fathom PRO&lt;/a> and renamed the original Fathom as Fathom Lite. Since then the development of this first version seems to had come to an end, as its latest release is from November 2018.&lt;/p>
&lt;p>I then started looking for alternatives and that&amp;rsquo;s when I found &lt;a href="https://lobste.rs/s/gzkue1/what_is_your_preferred_web_traffic/">this discussion on Lobsters&lt;/a> and met GoatCounter. A recent project of an &lt;a href="https://github.com/zgoat/goatcounter/">open source&lt;/a> and privacy-aware web statistics platform.&lt;/p>
&lt;p>As its developer states:&lt;/p>
&lt;blockquote>
&lt;p>No personal information (such as IP address) is collected; a hash of the IP address, User-Agent, and a daily changing random number (“salt”) is stored for 24 hours at the most to identify unique visitors.&lt;/p>
&lt;p>There is no information stored in the browser with e.g. cookies. &lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup>&lt;/p>
&lt;/blockquote>
&lt;p>So what data does GoatCounter collect?&lt;/p>
&lt;ul>
&lt;li>URL of the visited page;&lt;/li>
&lt;li>Referer header;&lt;/li>
&lt;li>User-Agent header;&lt;/li>
&lt;li>Screen size;&lt;/li>
&lt;li>Country name based on IP address;&lt;/li>
&lt;li>A hash of the IP address, User-Agent, and random number.&lt;/li>
&lt;/ul>
&lt;p>The script that by default you need to add to your site so GoatCounter can do its job is lightweight (~1.5kB), and there&amp;rsquo;s a no-JavaScript image-based tracker option, or you can use it from your application&amp;rsquo;s middleware.&lt;/p>
&lt;p>There&amp;rsquo;s an &lt;a href="https://goatcounter.com/">hosted version&lt;/a> of GoatCounter that includes a free plan for non-commercial use or you can host it yourself. In either case, if you&amp;rsquo;re going to use it for free, don&amp;rsquo;t forget to, as you can, donate to the developer so he can pay his bills and continue support this project.&lt;/p>
&lt;p>The &lt;a href="https://github.com/zgoat/goatcounter/issues/">issues tracking&lt;/a> is done on GitHub and you can join the project&amp;rsquo;s &lt;a href="https://t.me/goatcounter">Telegram group&lt;/a>.&lt;/p>
&lt;div class="footnotes" role="doc-endnotes">
&lt;hr>
&lt;ol>
&lt;li id="fn:1">
&lt;p>&lt;a href="https://www.goatcounter.com/privacy/">GoatCounter privacy policy&lt;/a>&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;/ol>
&lt;/div></description></item><item><title>Nextcloud 27 Installation on Debian</title><link>https://emanuelpina.pt/nextcloud-27-installation-on-debian/</link><pubDate>Sun, 23 Jul 2023 17:34:51 +0100</pubDate><guid>https://emanuelpina.pt/nextcloud-27-installation-on-debian/</guid><description>&lt;p>Finally, I&amp;rsquo;ll now cover the installation of Nextcloud on Debian!&lt;/p>
&lt;p>At this point, is expected that you already had:&lt;/p>
&lt;ul>
&lt;li>Choose a VPS provider and &lt;a href="https://emanuelpina.pt/debian-server-initial-setup/">concluded the initial setup of your Debian server&lt;/a>;&lt;/li>
&lt;li>Installed &lt;a href="https://emanuelpina.pt/nginx-installation-on-debian/">Nginx&lt;/a>;&lt;/li>
&lt;li>Installed &lt;a href="https://emanuelpina.pt/postgresql-installation-on-debian/">PostgreSQL&lt;/a>;&lt;/li>
&lt;li>Installed &lt;a href="https://emanuelpina.pt/php-installation-on-debian/">PHP 8.2&lt;/a>.&lt;/li>
&lt;/ul>
&lt;p>I’m currently using Debian 12, but these instructions may be equally valid for other versions of Debian and Ubuntu.&lt;/p>
&lt;h2 id="download-nextcloud-27">Download Nextcloud 27&lt;/h2>
&lt;p>To download Nextcloud 27, change into the &lt;code>/tmp&lt;/code> folder, to keep things clean, and use &lt;code>wget&lt;/code> to download the archive:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># cd /tmp
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"># wget https://download.nextcloud.com/server/releases/latest.zip
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>With the archive downloaded, now unzip it. We’ll also attempt to install &lt;code>unzip&lt;/code>, in case we don’t have it installed already. The &lt;code>-d&lt;/code> switch specifies the target directory, so the archive will be extracted to &lt;code>/var/www/nextcloud&lt;/code>:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo apt install unzip
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"># sudo unzip latest.zip -d /var/www
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Now we’ll have to change the owner of &lt;code>/var/www/nextcloud&lt;/code> so Nginx can write to it:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo chown www-data:www-data /var/www/nextcloud -R
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="install-php-required-modules">Install PHP Required Modules&lt;/h2>
&lt;p>Beyond the ones we &lt;a href="https://emanuelpina.pt/php-installation-on-debian/#install-php">installed previously&lt;/a>, Nextcloud requires some additional PHP modules. To install them, run the following command:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo apt install php8.2-curl php8.2-gd php8.2-mbstring php8.2-xml php8.2-zip php8.2-bz2 php8.2-intl php8.2-ldap php8.2-imap php8.2-bcmath php8.2-gmp php8.2-imagick
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="configure-php">Configure PHP&lt;/h3>
&lt;p>To meet the requirements of Nextcloud we need to make some changes in PHP configuration. The first one is changing the &lt;code>memory_limit&lt;/code>. This setting is in &lt;strong>php.ini&lt;/strong>, we can edit it running:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo nano /etc/php/8.2/fpm/php.ini
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Search for &lt;code>memory_limit&lt;/code> and change it to &lt;code>512M&lt;/code>.&lt;/p>
&lt;p>&lt;span class="marker yellow">Once we&amp;rsquo;re editing &lt;strong>php.ini&lt;/strong> you can take the opportunity to set &lt;a href="https://www.php.net/manual/en/ini.core.php#ini.upload-max-filesize">upload_max_filesize&lt;/a> and &lt;a href="https://www.php.net/manual/en/ini.core.php#ini.post-max-size">post_max_size&lt;/a> according to your preferences.&lt;/span>&lt;/p>
&lt;p>Another thing is that as we&amp;rsquo;re using &lt;code>php-fpm&lt;/code>, system environment variables like PATH, TMP or others are not automatically populated. A PHP call like &lt;code>getenv('PATH');&lt;/code> can therefore return an empty result. So we need to manually configure the environment variables in &lt;strong>www.conf&lt;/strong>. To edit this file run:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo nano /etc/php/8.2/fpm/pool.d/www.conf
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Usually, near the bottom of the file, we will find some or all of the environment variables already, but commented out like this:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-php" data-lang="php">&lt;span class="line">&lt;span class="cl">&lt;span class="p">;&lt;/span>&lt;span class="nx">env&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">HOSTNAME&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nv">$HOSTNAME&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">;&lt;/span>&lt;span class="nx">env&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">PATH&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="o">/&lt;/span>&lt;span class="nx">usr&lt;/span>&lt;span class="o">/&lt;/span>&lt;span class="nx">local&lt;/span>&lt;span class="o">/&lt;/span>&lt;span class="nx">bin&lt;/span>&lt;span class="o">:/&lt;/span>&lt;span class="nx">usr&lt;/span>&lt;span class="o">/&lt;/span>&lt;span class="nx">bin&lt;/span>&lt;span class="o">:/&lt;/span>&lt;span class="nx">bin&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">;&lt;/span>&lt;span class="nx">env&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">TMP&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="o">/&lt;/span>&lt;span class="nx">tmp&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">;&lt;/span>&lt;span class="nx">env&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">TMPDIR&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="o">/&lt;/span>&lt;span class="nx">tmp&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">;&lt;/span>&lt;span class="nx">env&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">TEMP&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="o">/&lt;/span>&lt;span class="nx">tmp&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Just uncomment the ones that refer to PATH and TMP, like this:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-php" data-lang="php">&lt;span class="line">&lt;span class="cl">&lt;span class="o">...&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">env&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">PATH&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="o">/&lt;/span>&lt;span class="nx">usr&lt;/span>&lt;span class="o">/&lt;/span>&lt;span class="nx">local&lt;/span>&lt;span class="o">/&lt;/span>&lt;span class="nx">bin&lt;/span>&lt;span class="o">:/&lt;/span>&lt;span class="nx">usr&lt;/span>&lt;span class="o">/&lt;/span>&lt;span class="nx">bin&lt;/span>&lt;span class="o">:/&lt;/span>&lt;span class="nx">bin&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">env&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">TMP&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="o">/&lt;/span>&lt;span class="nx">tmp&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">...&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>With this changes done, restart the PHP service:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo systemctl restart php8.2-fpm
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="create-postgresql-user-and-database">Create PostgreSQL User and Database&lt;/h2>
&lt;p>To create a user and database for Nextcloud we first need to login to PostgreSQL prompt:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo -i -u postgres psql
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Then create a username (choose a &lt;strong>username&lt;/strong> and &lt;strong>password&lt;/strong> according to your preferences):&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-postgres" data-lang="postgres">&lt;span class="line">&lt;span class="cl">&lt;span class="k">CREATE&lt;/span> &lt;span class="k">USER&lt;/span> &lt;span class="n">username&lt;/span> &lt;span class="k">WITH&lt;/span> &lt;span class="k">PASSWORD&lt;/span> &lt;span class="s1">&amp;#39;password&amp;#39;&lt;/span> &lt;span class="n">CREATEDB&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Create a database:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-postgres" data-lang="postgres">&lt;span class="line">&lt;span class="cl">&lt;span class="k">CREATE&lt;/span> &lt;span class="k">DATABASE&lt;/span> &lt;span class="n">nextcloud&lt;/span> &lt;span class="k">TEMPLATE&lt;/span> &lt;span class="n">template0&lt;/span> &lt;span class="k">ENCODING&lt;/span> &lt;span class="s1">&amp;#39;UTF8&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Set the user you created as the owner of the database:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-postgres" data-lang="postgres">&lt;span class="line">&lt;span class="cl">&lt;span class="k">ALTER&lt;/span> &lt;span class="k">DATABASE&lt;/span> &lt;span class="n">nextcloud&lt;/span> &lt;span class="k">OWNER&lt;/span> &lt;span class="k">TO&lt;/span> &lt;span class="n">username&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Grant the user all the privileges over the database:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-postgres" data-lang="postgres">&lt;span class="line">&lt;span class="cl">&lt;span class="k">GRANT&lt;/span> &lt;span class="k">ALL&lt;/span> &lt;span class="k">PRIVILEGES&lt;/span> &lt;span class="k">ON&lt;/span> &lt;span class="k">DATABASE&lt;/span> &lt;span class="n">nextcloud&lt;/span> &lt;span class="k">TO&lt;/span> &lt;span class="n">username&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">GRANT&lt;/span> &lt;span class="k">ALL&lt;/span> &lt;span class="k">PRIVILEGES&lt;/span> &lt;span class="k">ON&lt;/span> &lt;span class="k">SCHEMA&lt;/span> &lt;span class="n">public&lt;/span> &lt;span class="k">TO&lt;/span> &lt;span class="n">username&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>To quit the PostgreSQL prompt, run:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl">\q
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="configure-nginx">Configure Nginx&lt;/h2>
&lt;p>We&amp;rsquo;ll now create a Nginx &lt;em>server block&lt;/em> to nextcloud. I&amp;rsquo;m naming it &lt;strong>nextcloud&lt;/strong> but you can name it whatever you like:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo nano /etc/nginx/sites-available/nextcloud
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Copy the following content to the file and change the &lt;code>server_name&lt;/code> from &lt;strong>box.emanuelpina.pt&lt;/strong> to the domain address you want use:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-nginx" data-lang="nginx">&lt;span class="line">&lt;span class="cl">&lt;span class="k">server&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">listen&lt;/span> &lt;span class="mi">80&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">listen&lt;/span> &lt;span class="s">[::]:80&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">server_name&lt;/span> &lt;span class="s">box.emanuelpina.pt&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Save and close the file when you’re done.&lt;/p>
&lt;p>Once created, to enable the &lt;em>server block&lt;/em> we need to create a symbolic link of it into &lt;code>/etc/nginx/sites-enabled/&lt;/code> using the following command:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo ln -s /etc/nginx/sites-available/nextcloud /etc/nginx/sites-enabled/
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Make sure that there are no syntax errors in the Nginx files:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo nginx -t
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>If there aren’t any issues, restart Nginx to enable the changes:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo systemctl reload nginx
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="enable-ssl">Enable SSL&lt;/h3>
&lt;p>We can use &lt;code>certbot&lt;/code> to obtain a Let&amp;rsquo;s Encrypt SSL certificate to our Nextcloud. If you didn&amp;rsquo;t already, install it as its Nginx package running the following command:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo apt install certbot python3-certbot-nginx
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Then to use Certbot, run:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo certbot --nginx
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>At our first time running Certbot, we&amp;rsquo;ll be prompted to enter an email address, agree to the terms of service and authorise or not EEF (the entity that mantains Certbot) to send emails to us.&lt;/p>
&lt;p>We&amp;rsquo;ll then be presented with a list of all domains enabled on our server:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl">Which names would you like to activate HTTPS for?
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------------------------------------------------------------------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">1: box.emanuelpina.pt
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------------------------------------------------------------------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Select the appropriate numbers separated by commas and/or spaces, or leave input
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">blank to select all options shown (Enter &amp;#39;c&amp;#39; to cancel):
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Select the appropriate number for the domain you want to obtain a certificate (for our example type &lt;code>1&lt;/code>) and press &lt;code>ENTER&lt;/code>. After doing so, Certbot will communicate with the Let’s Encrypt server, then run a challenge to verify that we control the domain we’re requesting a certificate for.&lt;/p>
&lt;p>If that’s successful, Certbot will finish with a message like below.
&lt;span class="marker yellow">Look at &lt;strong>IMPORTANT NOTES&lt;/strong> and save the locations of both the certificate and key&lt;/span>.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl">- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Congratulations! You have successfully enabled https://box.emanuelpina.pt
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">IMPORTANT NOTES:
&lt;/span>&lt;/span>&lt;span class="line hl">&lt;span class="cl"> - Congratulations! Your certificate and chain have been saved at:
&lt;/span>&lt;/span>&lt;span class="line hl">&lt;span class="cl"> /etc/letsencrypt/live/box.emanuelpina.pt/fullchain.pem
&lt;/span>&lt;/span>&lt;span class="line hl">&lt;span class="cl"> Your key file has been saved at:
&lt;/span>&lt;/span>&lt;span class="line hl">&lt;span class="cl"> /etc/letsencrypt/live/box.emanuelpina.pt/privkey.pem
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">...
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Now, edit the Nextcloud&amp;rsquo;s &lt;em>server block&lt;/em>:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo nano /etc/nginx/sites-available/nextcloud
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>And replace its content with the following code.
&lt;span class="marker yellow">Don&amp;rsquo;t forget to change the &lt;em>server_name&lt;/em> from &lt;strong>box.emanuelpina.ml&lt;/strong> to the domain address you want and &lt;strong>update the locations to the SSL certificate and key&lt;/strong>&lt;/span>:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-nginx" data-lang="nginx">&lt;span class="line">&lt;span class="cl">&lt;span class="k">upstream&lt;/span> &lt;span class="s">php-handler&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">#server 127.0.0.1:9000;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kn">server&lt;/span> &lt;span class="s">unix:/var/run/php/php8.2-fpm.sock&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Set the `immutable` cache control options only for assets with a cache busting `v` argument
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="k">map&lt;/span> &lt;span class="nv">$arg_v&lt;/span> &lt;span class="nv">$asset_immutable&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">&amp;#34;&amp;#34;&lt;/span> &lt;span class="s">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">default&lt;/span> &lt;span class="s">&amp;#34;immutable&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">server&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">listen&lt;/span> &lt;span class="mi">80&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">listen&lt;/span> &lt;span class="s">[::]:80&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line hl">&lt;span class="cl"> &lt;span class="kn">server_name&lt;/span> &lt;span class="s">box.emanuelpina.ml&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Prevent nginx HTTP Server Detection
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kn">server_tokens&lt;/span> &lt;span class="no">off&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Enforce HTTPS
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kn">return&lt;/span> &lt;span class="mi">301&lt;/span> &lt;span class="s">https://&lt;/span>&lt;span class="nv">$server_name$request_uri&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">server&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">listen&lt;/span> &lt;span class="mi">443&lt;/span> &lt;span class="s">ssl&lt;/span> &lt;span class="s">http2&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">listen&lt;/span> &lt;span class="s">[::]:443&lt;/span> &lt;span class="s">ssl&lt;/span> &lt;span class="s">http2&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line hl">&lt;span class="cl"> &lt;span class="kn">server_name&lt;/span> &lt;span class="s">box.emanuelpina.ml&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Path to the root of your installation
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kn">root&lt;/span> &lt;span class="s">/var/www/nextcloud&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line hl">&lt;span class="cl"> &lt;span class="kn">ssl_certificate&lt;/span> &lt;span class="s">/etc/letsencrypt/live/box.emanuelpina.ml/fullchain.pem&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line hl">&lt;span class="cl"> &lt;span class="kn">ssl_certificate_key&lt;/span> &lt;span class="s">/etc/letsencrypt/live/box.emanuelpina.ml/privkey.pem&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Prevent nginx HTTP Server Detection
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kn">server_tokens&lt;/span> &lt;span class="no">off&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># HSTS settings
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1"># WARNING: Only add the preload option once you read about
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1"># the consequences in https://hstspreload.org/. This option
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1"># will add the domain to a hardcoded list that is shipped
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1"># in all major browsers and getting removed from this list
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1"># could take several months.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kn">add_header&lt;/span> &lt;span class="s">Strict-Transport-Security&lt;/span> &lt;span class="s">&amp;#34;max-age=15768000&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="kn">includeSubDomains&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="kn">preload&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="kn">&amp;#34;&lt;/span> &lt;span class="s">always&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># set max upload size and increase upload timeout:
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kn">client_max_body_size&lt;/span> &lt;span class="s">512M&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">client_body_timeout&lt;/span> &lt;span class="s">300s&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">fastcgi_buffers&lt;/span> &lt;span class="mi">64&lt;/span> &lt;span class="s">4K&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Enable gzip but do not remove ETag headers
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kn">gzip&lt;/span> &lt;span class="no">on&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">gzip_vary&lt;/span> &lt;span class="no">on&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">gzip_comp_level&lt;/span> &lt;span class="mi">4&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">gzip_min_length&lt;/span> &lt;span class="mi">256&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">gzip_proxied&lt;/span> &lt;span class="s">expired&lt;/span> &lt;span class="s">no-cache&lt;/span> &lt;span class="s">no-store&lt;/span> &lt;span class="s">private&lt;/span> &lt;span class="s">no_last_modified&lt;/span> &lt;span class="s">no_etag&lt;/span> &lt;span class="s">auth&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">gzip_types&lt;/span> &lt;span class="s">application/atom+xml&lt;/span> &lt;span class="s">text/javascript&lt;/span> &lt;span class="s">application/javascript&lt;/span> &lt;span class="s">application/json&lt;/span> &lt;span class="s">application/ld+json&lt;/span> &lt;span class="s">application/manifest+json&lt;/span> &lt;span class="s">application/rss+xml&lt;/span> &lt;span class="s">application/vnd.geo+json&lt;/span> &lt;span class="s">application/vnd.ms-fontobject&lt;/span> &lt;span class="s">application/wasm&lt;/span> &lt;span class="s">application/x-font-ttf&lt;/span> &lt;span class="s">application/x-web-app-manifest+json&lt;/span> &lt;span class="s">application/xhtml+xml&lt;/span> &lt;span class="s">application/xml&lt;/span> &lt;span class="s">font/opentype&lt;/span> &lt;span class="s">image/bmp&lt;/span> &lt;span class="s">image/svg+xml&lt;/span> &lt;span class="s">image/x-icon&lt;/span> &lt;span class="s">text/cache-manifest&lt;/span> &lt;span class="s">text/css&lt;/span> &lt;span class="s">text/plain&lt;/span> &lt;span class="s">text/vcard&lt;/span> &lt;span class="s">text/vnd.rim.location.xloc&lt;/span> &lt;span class="s">text/vtt&lt;/span> &lt;span class="s">text/x-component&lt;/span> &lt;span class="s">text/x-cross-domain-policy&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Pagespeed is not supported by Nextcloud, so if your server is built
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1"># with the `ngx_pagespeed` module, uncomment this line to disable it.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">#pagespeed off;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># The settings allows you to optimize the HTTP2 bandwitdth.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1"># See https://blog.cloudflare.com/delivering-http-2-upload-speed-improvements/
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1"># for tunning hints
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kn">client_body_buffer_size&lt;/span> &lt;span class="mi">512k&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># HTTP response headers borrowed from Nextcloud `.htaccess`
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kn">add_header&lt;/span> &lt;span class="s">Referrer-Policy&lt;/span> &lt;span class="s">&amp;#34;no-referrer&amp;#34;&lt;/span> &lt;span class="s">always&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">add_header&lt;/span> &lt;span class="s">X-Content-Type-Options&lt;/span> &lt;span class="s">&amp;#34;nosniff&amp;#34;&lt;/span> &lt;span class="s">always&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">add_header&lt;/span> &lt;span class="s">X-Download-Options&lt;/span> &lt;span class="s">&amp;#34;noopen&amp;#34;&lt;/span> &lt;span class="s">always&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">add_header&lt;/span> &lt;span class="s">X-Frame-Options&lt;/span> &lt;span class="s">&amp;#34;SAMEORIGIN&amp;#34;&lt;/span> &lt;span class="s">always&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">add_header&lt;/span> &lt;span class="s">X-Permitted-Cross-Domain-Policies&lt;/span> &lt;span class="s">&amp;#34;none&amp;#34;&lt;/span> &lt;span class="s">always&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">add_header&lt;/span> &lt;span class="s">X-Robots-Tag&lt;/span> &lt;span class="s">&amp;#34;noindex,&lt;/span> &lt;span class="s">nofollow&amp;#34;&lt;/span> &lt;span class="s">always&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">add_header&lt;/span> &lt;span class="s">X-XSS-Protection&lt;/span> &lt;span class="s">&amp;#34;1&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="kn">mode=block&amp;#34;&lt;/span> &lt;span class="s">always&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Opt out of Google Chrome tracking everything you do.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1"># Note: if you’re reading this, stop using Google Chrome.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1"># It is ridiculous for web servers to essentially have to ask
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1"># “please do not violate the privacy of the people who are viewing
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1"># this site” with every request.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1"># For more info, see: https://plausible.io/blog/google-floc
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kn">add_header&lt;/span> &lt;span class="s">Permissions-Policy&lt;/span> &lt;span class="s">&amp;#34;interest-cohort=()&amp;#34;&lt;/span> &lt;span class="s">always&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Remove X-Powered-By, which is an information leak
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kn">fastcgi_hide_header&lt;/span> &lt;span class="s">X-Powered-By&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Add .mjs as a file extension for javascript
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1"># Either include it in the default mime.types list
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1"># or include you can include that list explicitly and add the file extension
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1"># only for Nextcloud like below:
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kn">include&lt;/span> &lt;span class="s">mime.types&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">types&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">text/javascript&lt;/span> &lt;span class="s">js&lt;/span> &lt;span class="s">mjs&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Specify how to handle directories -- specifying `/index.php$request_uri`
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1"># here as the fallback means that Nginx always exhibits the desired behaviour
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1"># when a client requests a path that corresponds to a directory that exists
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1"># on the server. In particular, if that directory contains an index.php file,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1"># that file is correctly served; if it doesn&amp;#39;t, then the request is passed to
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1"># the front-end controller. This consistent behaviour means that we don&amp;#39;t need
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1"># to specify custom rules for certain paths (e.g. images and other assets,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1"># `/updater`, `/ocm-provider`, `/ocs-provider`), and thus
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1"># `try_files $uri $uri/ /index.php$request_uri`
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1"># always provides the desired behaviour.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kn">index&lt;/span> &lt;span class="s">index.php&lt;/span> &lt;span class="s">index.html&lt;/span> &lt;span class="s">/index.php&lt;/span>&lt;span class="nv">$request_uri&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Rule borrowed from `.htaccess` to handle Microsoft DAV clients
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kn">location&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s">/&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">if&lt;/span> &lt;span class="s">(&lt;/span> &lt;span class="nv">$http_user_agent&lt;/span> &lt;span class="p">~&lt;/span> &lt;span class="sr">^DavClnt&lt;/span> &lt;span class="s">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">return&lt;/span> &lt;span class="mi">302&lt;/span> &lt;span class="s">/remote.php/webdav/&lt;/span>&lt;span class="nv">$is_args$args&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">location&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s">/robots.txt&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">allow&lt;/span> &lt;span class="s">all&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">log_not_found&lt;/span> &lt;span class="no">off&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">access_log&lt;/span> &lt;span class="no">off&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Make a regex exception for `/.well-known` so that clients can still
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1"># access it despite the existence of the regex rule
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1"># `location ~ /(\.|autotest|...)` which would otherwise handle requests
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1"># for `/.well-known`.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kn">location&lt;/span> &lt;span class="s">^~&lt;/span> &lt;span class="s">/.well-known&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># The rules in this block are an adaptation of the rules
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1"># in `.htaccess` that concern `/.well-known`.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">location&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s">/.well-known/carddav&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="kn">return&lt;/span> &lt;span class="mi">301&lt;/span> &lt;span class="s">/remote.php/dav/&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">location&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s">/.well-known/caldav&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="kn">return&lt;/span> &lt;span class="mi">301&lt;/span> &lt;span class="s">/remote.php/dav/&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">location&lt;/span> &lt;span class="s">/.well-known/acme-challenge&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="kn">try_files&lt;/span> &lt;span class="nv">$uri&lt;/span> &lt;span class="nv">$uri/&lt;/span> &lt;span class="p">=&lt;/span>&lt;span class="mi">404&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">location&lt;/span> &lt;span class="s">/.well-known/pki-validation&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="kn">try_files&lt;/span> &lt;span class="nv">$uri&lt;/span> &lt;span class="nv">$uri/&lt;/span> &lt;span class="p">=&lt;/span>&lt;span class="mi">404&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Let Nextcloud&amp;#39;s API for `/.well-known` URIs handle all other
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1"># requests by passing them to the front-end controller.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kn">return&lt;/span> &lt;span class="mi">301&lt;/span> &lt;span class="s">/index.php&lt;/span>&lt;span class="nv">$request_uri&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Rules borrowed from `.htaccess` to hide certain paths from clients
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kn">location&lt;/span> &lt;span class="p">~&lt;/span> &lt;span class="sr">^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/)&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="kn">return&lt;/span> &lt;span class="mi">404&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">location&lt;/span> &lt;span class="p">~&lt;/span> &lt;span class="sr">^/(?:\.|autotest|occ|issue|indie|db_|console)&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="kn">return&lt;/span> &lt;span class="mi">404&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Ensure this block, which passes PHP files to the PHP process, is above the blocks
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1"># which handle static assets (as seen below). If this block is not declared first,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1"># then Nginx will encounter an infinite rewriting loop when it prepends `/index.php`
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1"># to the URI, resulting in a HTTP 500 error response.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kn">location&lt;/span> &lt;span class="p">~&lt;/span> &lt;span class="sr">\.php(?:$|/)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Required for legacy support
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kn">rewrite&lt;/span> &lt;span class="s">^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+|.+\/richdocumentscode\/proxy)&lt;/span> &lt;span class="s">/index.php&lt;/span>&lt;span class="nv">$request_uri&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">fastcgi_split_path_info&lt;/span> &lt;span class="s">^(.+?\.php)(/.*)&lt;/span>$&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">set&lt;/span> &lt;span class="nv">$path_info&lt;/span> &lt;span class="nv">$fastcgi_path_info&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">try_files&lt;/span> &lt;span class="nv">$fastcgi_script_name&lt;/span> &lt;span class="p">=&lt;/span>&lt;span class="mi">404&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">include&lt;/span> &lt;span class="s">fastcgi_params&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">fastcgi_param&lt;/span> &lt;span class="s">SCRIPT_FILENAME&lt;/span> &lt;span class="nv">$document_root$fastcgi_script_name&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">fastcgi_param&lt;/span> &lt;span class="s">PATH_INFO&lt;/span> &lt;span class="nv">$path_info&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">fastcgi_param&lt;/span> &lt;span class="s">HTTPS&lt;/span> &lt;span class="no">on&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">fastcgi_param&lt;/span> &lt;span class="s">modHeadersAvailable&lt;/span> &lt;span class="s">true&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1"># Avoid sending the security headers twice
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kn">fastcgi_param&lt;/span> &lt;span class="s">front_controller_active&lt;/span> &lt;span class="s">true&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1"># Enable pretty urls
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kn">fastcgi_pass&lt;/span> &lt;span class="s">php-handler&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">fastcgi_intercept_errors&lt;/span> &lt;span class="no">on&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">fastcgi_request_buffering&lt;/span> &lt;span class="no">off&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">fastcgi_max_temp_file_size&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">location&lt;/span> &lt;span class="p">~&lt;/span> &lt;span class="sr">\.(?:css|js|svg|gif|png|jpg|ico|wasm|tflite|map)$&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">try_files&lt;/span> &lt;span class="nv">$uri&lt;/span> &lt;span class="s">/index.php&lt;/span>&lt;span class="nv">$request_uri&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">add_header&lt;/span> &lt;span class="s">Cache-Control&lt;/span> &lt;span class="s">&amp;#34;public,&lt;/span> &lt;span class="s">max-age=15778463,&lt;/span> &lt;span class="nv">$asset_immutable&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">access_log&lt;/span> &lt;span class="no">off&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1"># Optional: Don&amp;#39;t log access to assets
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">location&lt;/span> &lt;span class="p">~&lt;/span> &lt;span class="sr">\.wasm$&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">default_type&lt;/span> &lt;span class="s">application/wasm&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">location&lt;/span> &lt;span class="p">~&lt;/span> &lt;span class="sr">\.woff2?$&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">try_files&lt;/span> &lt;span class="nv">$uri&lt;/span> &lt;span class="s">/index.php&lt;/span>&lt;span class="nv">$request_uri&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">expires&lt;/span> &lt;span class="s">7d&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1"># Cache-Control policy borrowed from `.htaccess`
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kn">access_log&lt;/span> &lt;span class="no">off&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1"># Optional: Don&amp;#39;t log access to assets
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Rule borrowed from `.htaccess`
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kn">location&lt;/span> &lt;span class="s">/remote&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">return&lt;/span> &lt;span class="mi">301&lt;/span> &lt;span class="s">/remote.php&lt;/span>&lt;span class="nv">$request_uri&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">location&lt;/span> &lt;span class="s">/&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">try_files&lt;/span> &lt;span class="nv">$uri&lt;/span> &lt;span class="nv">$uri/&lt;/span> &lt;span class="s">/index.php&lt;/span>&lt;span class="nv">$request_uri&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Make sure that there are no syntax errors in the Nginx files:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo nginx -t
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>If there aren’t any issues, restart Nginx to enable the changes:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo systemctl reload nginx
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="complete-installation">Complete Installation&lt;/h2>
&lt;p>Now, to complete Nextcloud installation, in a browser visit the domain address you chosed and you will be presented with a form to fill.&lt;/p>
&lt;p>On this form on &lt;strong>&amp;ldquo;Create an admin account&amp;rdquo;&lt;/strong> we should chose a &lt;strong>username&lt;/strong> and &lt;strong>password&lt;/strong> for our admin account. And on &lt;strong>&amp;ldquo;Configure Database&amp;rdquo;&lt;/strong> we should fill it with the &lt;strong>username&lt;/strong>, &lt;strong>password&lt;/strong> and &lt;strong>database name&lt;/strong> defined &lt;a href="#create-postgresql-user-and-database">above&lt;/a>.&lt;/p>
&lt;p>After filling the form just click on &lt;code>Finish setup&lt;/code> and wait for the installation to complete. At the end we&amp;rsquo;ll be redirected to our dashboard.&lt;/p>
&lt;p>And that&amp;rsquo;s it! Our Nextcloud installation is ready for use.&lt;/p>
&lt;h2 id="additional-configurations">Additional configurations&lt;/h2>
&lt;p>Following we&amp;rsquo;ll look at some additional configurations that despite being optional, are advisable.&lt;/p>
&lt;h3 id="memory-caching">Memory Caching&lt;/h3>
&lt;p>Enabling memory caching can significantly improve the perfomance of your Nextcloud. The recommend solutions to implement should be based on the size and propose of our Nextcloud. For a small instance with a single server the recommended configuration is APCu for local memcache and Redis for everything else:&lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup>&lt;/p>
&lt;ul>
&lt;li>&lt;strong>APCu&lt;/strong>: an in-memory key-value store for PHP;&lt;/li>
&lt;li>&lt;strong>Redis&lt;/strong>: an excellent modern memcache to use for distributed caching, and as a key-value store for Transactional File Locking.&lt;/li>
&lt;/ul>
&lt;p>To install &lt;strong>APCu&lt;/strong>, go back to your terminal and run the following commands:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo apt install php8.2-apcu
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="box red">
APCu is disabled by default on CLI which could cause issues with Nextcloud’s cron jobs. Make sure to set &lt;code>apc.enable_cli&lt;/code> to &lt;code>1&lt;/code> on &lt;code>/etc/php/8.2/cli/php.ini&lt;/code> or append &lt;code>--define apc.enable_cli=1&lt;/code> to the cron job command.
&lt;/div>
&lt;p>And to install &lt;strong>Redis&lt;/strong>, run:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo apt install redis-server php8.2-redis
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Then restart Nginx:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo systemctl reload nginx
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Now we need to configure Nextcloud to use both APCu and Redis. To do so let&amp;rsquo;s edit the Nextcloud configuration file:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo nano /var/www/nextcloud/config/config.php
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>And add the following lines just bellow &lt;code>'installed' =&amp;gt; true,&lt;/code>:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-php" data-lang="php">&lt;span class="line">&lt;span class="cl">&lt;span class="s1">&amp;#39;memcache.local&amp;#39;&lt;/span> &lt;span class="o">=&amp;gt;&lt;/span> &lt;span class="s1">&amp;#39;\OC\Memcache\APCu&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1">&amp;#39;memcache.locking&amp;#39;&lt;/span> &lt;span class="o">=&amp;gt;&lt;/span> &lt;span class="s1">&amp;#39;\OC\Memcache\Redis&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1">&amp;#39;memcache.distributed&amp;#39;&lt;/span> &lt;span class="o">=&amp;gt;&lt;/span> &lt;span class="s1">&amp;#39;\OC\Memcache\Redis&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1">&amp;#39;redis&amp;#39;&lt;/span> &lt;span class="o">=&amp;gt;&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;host&amp;#39;&lt;/span> &lt;span class="o">=&amp;gt;&lt;/span> &lt;span class="s1">&amp;#39;localhost&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;port&amp;#39;&lt;/span> &lt;span class="o">=&amp;gt;&lt;/span> &lt;span class="mi">6379&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="background-jobs">Background jobs&lt;/h3>
&lt;p>A system like Nextcloud sometimes requires tasks to be done on a regular basis without the need for user interaction or hindering Nextcloud performance. For that purpose, we can define background jobs. These jobs are typically referred to as &lt;em>cron jobs&lt;/em>.&lt;/p>
&lt;p>Cron jobs are commands or shell-based scripts that are scheduled to run periodically at fixed times, dates, or intervals. &lt;code>cron.php&lt;/code> is a Nextcloud internal process that runs such background jobs on demand.&lt;/p>
&lt;p>We can schedule cron jobs in three ways – using AJAX, Webcron, or cron. The default method is to use AJAX. However, &lt;strong>the recommended method is to use the operating system cron feature&lt;/strong>.&lt;sup id="fnref:2">&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref">2&lt;/a>&lt;/sup>&lt;/p>
&lt;p>To run a cron job on our system, every 5 minutes, under the default Web server user, we must set up the following cron job to call the &lt;code>cron.php&lt;/code> script.&lt;/p>
&lt;p>Edit the crontab of the default Web server user (&lt;code>www-data&lt;/code>):&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo crontab -u www-data -e
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>And append the following line, replacing the path &lt;code>/var/www/nextcloud/cron.php&lt;/code> with the path to your current Nextcloud installation:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl">*/5 * * * * php -f /var/www/nextcloud/cron.php
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>We can verify if the cron job has been added and scheduled running:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo crontab -u www-data -l
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Finally, choose &lt;code>Cron&lt;/code> in the &lt;em>Background jobs&lt;/em> section of the &lt;em>Admin settings&lt;/em> page at &lt;code>Setting &amp;gt; Administration &amp;gt; Basic settings &amp;gt; Background jobs&lt;/code>.&lt;/p>
&lt;h3 id="previews-generation">Previews generation&lt;/h3>
&lt;p>By default, Nextcloud thumbnail system generates previews of files for the following filetypes:&lt;/p>
&lt;ul>
&lt;li>Images files;&lt;/li>
&lt;li>Cover of MP3 files;&lt;/li>
&lt;li>Text documents.&lt;/li>
&lt;/ul>
&lt;p>Additional, we can add support for SVG and video files, installing those packages:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo apt install libmagickcore-6.q16-6-extra ffmpeg
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>To add support for PDF files, we must install &lt;code>ghostscript&lt;/code>:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo apt install ghostscript
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>And tweak ImageMagick&amp;rsquo;s security policy:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo nano /etc/ImageMagick-6/policy.xml
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Look for &lt;code>&amp;lt;policy domain=&amp;quot;coder&amp;quot; rights=&amp;quot;none&amp;quot; pattern=&amp;quot;PDF&amp;quot; /&amp;gt;&lt;/code> at the end of the file. And comment the line, so it look like:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl">...
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&amp;lt;!-- &amp;lt;policy domain=&amp;#34;coder&amp;#34; rights=&amp;#34;none&amp;#34; pattern=&amp;#34;PDF&amp;#34; /&amp;gt; --&amp;gt;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">...
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The generation of previews can use a fair amount of hardware resources and can degrade our experience when using Nextcloud. We can prevent that, using an app called &lt;strong>Preview Generator&lt;/strong> and setting a cron job that runs periodically on the background and generates previews for new or recently changed files.&lt;/p>
&lt;p>To do so, first run the following commands to install and enable the app, where &lt;code>/var/www/nextcloud/&lt;/code> is the path to our Nextcloud installation:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo -u www-data php /var/www/nextcloud/occ app:install previewgenerator
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"># sudo -u www-data php /var/www/nextcloud/occ app:enable previewgenerator
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>To set for which filetypes Nextcloud should generate previews, edit the Nextcloud configuration file:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo nano /var/www/nextcloud/config/config.php
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>And add the following lines just bellow &lt;code>'installed' =&amp;gt; true,&lt;/code>:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-php" data-lang="php">&lt;span class="line">&lt;span class="cl">&lt;span class="s1">&amp;#39;enable_previews&amp;#39;&lt;/span> &lt;span class="o">=&amp;gt;&lt;/span> &lt;span class="k">true&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1">&amp;#39;enabledPreviewProviders&amp;#39;&lt;/span> &lt;span class="o">=&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">array&lt;/span> &lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="mi">0&lt;/span> &lt;span class="o">=&amp;gt;&lt;/span> &lt;span class="s1">&amp;#39;OC\\Preview\\PNG&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="mi">1&lt;/span> &lt;span class="o">=&amp;gt;&lt;/span> &lt;span class="s1">&amp;#39;OC\\Preview\\JPEG&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="mi">2&lt;/span> &lt;span class="o">=&amp;gt;&lt;/span> &lt;span class="s1">&amp;#39;OC\\Preview\\GIF&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="mi">3&lt;/span> &lt;span class="o">=&amp;gt;&lt;/span> &lt;span class="s1">&amp;#39;OC\\Preview\\HEIC&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="mi">4&lt;/span> &lt;span class="o">=&amp;gt;&lt;/span> &lt;span class="s1">&amp;#39;OC\\Preview\\BMP&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="mi">5&lt;/span> &lt;span class="o">=&amp;gt;&lt;/span> &lt;span class="s1">&amp;#39;OC\\Preview\\XBitmap&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="mi">6&lt;/span> &lt;span class="o">=&amp;gt;&lt;/span> &lt;span class="s1">&amp;#39;OC\\Preview\\MP3&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="mi">7&lt;/span> &lt;span class="o">=&amp;gt;&lt;/span> &lt;span class="s1">&amp;#39;OC\\Preview\\TXT&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="mi">8&lt;/span> &lt;span class="o">=&amp;gt;&lt;/span> &lt;span class="s1">&amp;#39;OC\\Preview\\MarkDown&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="mi">9&lt;/span> &lt;span class="o">=&amp;gt;&lt;/span> &lt;span class="s1">&amp;#39;OC\\Preview\\Movie&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="mi">10&lt;/span> &lt;span class="o">=&amp;gt;&lt;/span> &lt;span class="s1">&amp;#39;OC\\Preview\\MKV&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="mi">11&lt;/span> &lt;span class="o">=&amp;gt;&lt;/span> &lt;span class="s1">&amp;#39;OC\\Preview\\MP4&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="mi">12&lt;/span> &lt;span class="o">=&amp;gt;&lt;/span> &lt;span class="s1">&amp;#39;OC\\Preview\\AVI&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="mi">13&lt;/span> &lt;span class="o">=&amp;gt;&lt;/span> &lt;span class="s1">&amp;#39;OC\\Preview\\PDF&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">),&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Then, before setting a cron job, we should generate all previews running:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo -u www-data php /var/www/nextcloud/occ preview:generate-all -vvv
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>We can now edit the crontab of the default Web server user (&lt;code>www-data&lt;/code>):&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo crontab -u www-data -e
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>And add a cron job that will run the application each 10 minutes:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl">*/10 * * * * php /var/www/nextcloud/occ preview:pre-generate
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="email">Email&lt;/h3>
&lt;p>Nextcloud is capable of sending password reset emails, notifying users of new file shares, changes in files, and activity notifications.&lt;/p>
&lt;p>Nextcloud does not contain a full email server, but rather connects to your existing mail server, and supports three types of connections: SMTP, qmail, and Sendmail.&lt;/p>
&lt;p>I recommend using a SMTP server, more precisely a SMTP relay, like &lt;a href="https://www.mailgun.com/">Mailgun&lt;/a>.&lt;/p>
&lt;p>To connect Nextcloud to a remote SMTP server, we need the following information:&lt;/p>
&lt;ul>
&lt;li>Encryption type: None, SSL/TLS, or STARTTLS;&lt;/li>
&lt;li>The From address we want our outgoing Nextcloud mails to use;&lt;/li>
&lt;li>Whether authentication is required;&lt;/li>
&lt;li>Authentication method: None, Login, Plain, or NT LAN Manager;&lt;/li>
&lt;li>The server’s IP address or fully-qualified domain name and the SMTP port;&lt;/li>
&lt;li>Login credentials (if required).&lt;/li>
&lt;/ul>
&lt;p>Having this information we can then fill the configuration wizzard in the &lt;em>Email Server&lt;/em> section of the &lt;em>Admin settings&lt;/em> page at &lt;code>Setting &amp;gt; Administration &amp;gt; Basic settings &amp;gt; Email server&lt;/code>.&lt;/p>
&lt;h3 id="default-phone-region">Default phone region&lt;/h3>
&lt;p>Since Nextcloud 21, is recommend setting a default region for phone numbers, using &lt;a href="https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements">ISO 3166-1 country codes&lt;/a> such as &lt;code>DE&lt;/code> for Germany, &lt;code>FR&lt;/code> for France, &lt;code>PT&lt;/code> for Portugal&amp;hellip; It is required to allow inserting phone numbers in the user profiles starting without the country code (e.g. +351 for Portugal).&lt;/p>
&lt;p>We can do that by editing the Nextcloud configuration file:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo nano /var/www/nextcloud/config/config.php
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>And adding the following line, just bellow &lt;code>'installed' =&amp;gt; true,&lt;/code>, changing the value to correspond to your country:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-php" data-lang="php">&lt;span class="line">&lt;span class="cl">&lt;span class="s1">&amp;#39;default_phone_region&amp;#39;&lt;/span> &lt;span class="o">=&amp;gt;&lt;/span> &lt;span class="s1">&amp;#39;PT&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="congratulations-">Congratulations 🎉&lt;/h4>
&lt;p>You now have your self-hosted cloud storage solution and are one step closer to &lt;a href="https://emanuelpina.pt/be-the-owner-of-your-data-with-nextcloud/">be the owner of your data&lt;/a>!&lt;/p>
&lt;div class="box grey cfc">
&lt;p>Do you want contribute and add something to this tutorial? Have you found a typo, grammar or formatting error? Please, feel free to
&lt;a href="https://emanuelpina.pt/contact/">contact me&lt;/a> or
&lt;a href="https://github.com/emanuelpina/emanuelpina.pt/blob/main/content/posts/nextcloud-18-installation-on-ubuntu.md">edit&lt;/a>
this post and open a pull resquest.&lt;/p>
&lt;/div>
&lt;div class="footnotes" role="doc-endnotes">
&lt;hr>
&lt;ol>
&lt;li id="fn:1">
&lt;p>&lt;a href="https://docs.nextcloud.com/server/stable/admin_manual/configuration_server/caching_configuration.html#recommendations-based-on-type-of-deployment">Nextcloud documentation - Memory caching: Recommendations based on type of deployment&lt;/a>&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;li id="fn:2">
&lt;p>&lt;a href="https://docs.nextcloud.com/server/stable/admin_manual/configuration_server/background_jobs_configuration.html#cron-jobs">Nextcloud documentation - Background jobs: Cron jobs&lt;/a>&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;/ol>
&lt;/div></description></item><item><title>PHP Installation on Debian</title><link>https://emanuelpina.pt/php-installation-on-debian/</link><pubDate>Thu, 23 Jan 2020 18:52:25 +0000</pubDate><guid>https://emanuelpina.pt/php-installation-on-debian/</guid><description>&lt;p>On the way to install Nextcloud we&amp;rsquo;ve already completed the &lt;a href="https://emanuelpina.pt/debian-server-initial-setup/">initial setup of our VPS&lt;/a>, the &lt;a href="https://emanuelpina.pt/nginx-installation-on-debian/">installation of Nginx&lt;/a> and &lt;a href="https://emanuelpina.pt/postgresql-installation-on-debian/">the installation of PostgreSQL&lt;/a>.&lt;/p>
&lt;p>I will now cover the installation of PHP 8.2, the recommended version to run Nextcloud 27.&lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup>&lt;/p>
&lt;p>I’m currently using Debian 12, but these instructions may be equally valid for other versions of Debian and Ubuntu.&lt;/p>
&lt;h2 id="install-php">Install PHP&lt;/h2>
&lt;p>PHP (recursive acronym for &lt;em>PHP: Hypertext Preprocessor&lt;/em>) is an open source server side scripting language, widely used to create dynamic interactive web pages.&lt;/p>
&lt;p>To install PHP 8.2 along with some of it most common extensions use the following commands:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo apt update
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"># sudo apt install php8.2 php8.2-common php8.2-fpm php8.2-pgsql
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>And that&amp;rsquo;s it. At any moment you can check the PHP 8.2 service status running:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># systemctl status php8.2-fpm
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="test-php-processing">Test PHP Processing&lt;/h2>
&lt;p>To test PHP Processing we first need to configure Nginx to use it for dynamic content.&lt;/p>
&lt;p>This is done at the &lt;em>server block&lt;/em> level. For this example edit the &lt;em>server block&lt;/em> we&amp;rsquo;ve created &lt;a href="https://emanuelpina.pt/nginx-installation-on-ubuntu/#set-up-a-server-block">earlier&lt;/a>. To do so, run:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo nano /etc/nginx/sites-available/emanuelpina.pt
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>And edit the &lt;em>server block&lt;/em> to add the following code, just bellow the &lt;strong>server_name&lt;/strong>. Like this:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-nginx" data-lang="nginx">&lt;span class="line">&lt;span class="cl">&lt;span class="k">server&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">###
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">server_name&lt;/span> &lt;span class="s">emanuelpina.pt&lt;/span> &lt;span class="s">www.emanuelpina.pt&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line hl">&lt;span class="cl"> &lt;span class="kn">location&lt;/span> &lt;span class="p">~&lt;/span> &lt;span class="sr">\.php$&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line hl">&lt;span class="cl"> &lt;span class="kn">include&lt;/span> &lt;span class="s">snippets/fastcgi-php.conf&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line hl">&lt;span class="cl"> &lt;span class="kn">fastcgi_pass&lt;/span> &lt;span class="s">unix:/var/run/php/php8.2-fpm.sock&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line hl">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">###
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Test to make sure that there are no syntax errors in our Nginx files:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo nginx -t
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>If there aren’t any issues, restart Nginx to enable the changes:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo systemctl reload nginx
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Now let&amp;rsquo;s create a test PHP file in the website root folder:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo nano /var/www/html/info.php
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Add the following content to the file, which is a valid PHP code that generates a page containing information about the server:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-php" data-lang="php">&lt;span class="line">&lt;span class="cl">&lt;span class="o">&amp;lt;?&lt;/span>&lt;span class="nx">php&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">phpinfo&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Now visiting the page &lt;code>https://emanuelpina.pt/info.php&lt;/code> on a browser we should see a page generated by PHP containing structured information about our server.&lt;/p>
&lt;p>If you see this page then Nginx is successfully communicating with PHP!&lt;/p>
&lt;p>At the end of this test, don&amp;rsquo;t forget to remove the PHP file we created:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo rm /var/www/html/info.php
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>This is imporant because it exposes important information about our server and can make it vulnerable.&lt;/p>
&lt;h2 id="tune-php">Tune PHP&lt;/h2>
&lt;p>Similar to what we did with PostgreSQL, we can tune some PHP settings depending on the hardware at our disposale.&lt;sup id="fnref:2">&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref">2&lt;/a>&lt;/sup>&lt;/p>
&lt;p>To proceed with this we need to know three things: how many CPU cores our server have; how much memory (RAM) we can dedicate to PHP; and how much memory the average PHP process consume.&lt;/p>
&lt;p>To find out how many CPU cores your server has, run the following command:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># echo Cores = $(( $(lscpu | awk &amp;#39;/^Socket/{ print $2 }&amp;#39;) * $(lscpu | awk &amp;#39;/^Core/{ print $4 }&amp;#39;) ))
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>When determining how much memory you can dedicate to PHP, keep in mind that the server is also running Nginx and PostgreSQL. How much memory are these other processes consuming? For example, if you have 4GB of RAM and the other processes are consuming 1GB, that leaves you with 3GB – or 2GB if you want to play safe.&lt;/p>
&lt;p>Finally, to get a general idea on how much memory each PHP process is consuming, run:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># ps --no-headers -o &amp;#34;rss,cmd&amp;#34; -C php-fpm8.2 | awk &amp;#39;{ sum+=$1 } END { printf (&amp;#34;%d%s\n&amp;#34;, sum/NR/1024,&amp;#34;M&amp;#34;) }&amp;#39;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The settigns you need to change are all in the &lt;code>www.conf&lt;/code> file. To edit it, run:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo nano /etc/php/8.2/fpm/pool.d/www.conf
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Search for each one of the following settings and change it accordingly.&lt;/p>
&lt;p>To get a good value for &lt;strong>pm.max_children&lt;/strong>, take the memory that you want to allocate to PHP and divide it by the average memory that is consumed by each PHP process. For example, if you want to allocate 2GB (2000MB) and each process consumes about 50MB. Dividing 2000 by 50 we get around 40.&lt;br>
So, set pm.max_children to 40.&lt;/p>
&lt;p>For &lt;strong>pm.start_servers&lt;/strong>, multiply the number of cores that you have by 4.&lt;br>
If you have 2 cores: 2 x 4 = 8&lt;br>
So, set pm.start_servers to 8.&lt;/p>
&lt;p>For &lt;strong>pm.min_spare_servers&lt;/strong>, multiply the number of cores that you have by 2.&lt;br>
If you have 2 cores: 2 x 2 = 4&lt;br>
So, set pm.min_spare_servers to 4.&lt;/p>
&lt;p>For &lt;strong>pm.max_spare_servers&lt;/strong>, multiply the number of cores on your server by 4.&lt;br>
If you have 2 cores: 2 x 4 = 8&lt;br>
So, set pm.max_spare_servers to 8. The same used before for pm.start_servers.&lt;/p>
&lt;p>To finish, just restart the PHP-FPM service:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo systemctl restart php8.2-fpm
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>And that&amp;rsquo;s all 😀&lt;/p>
&lt;h2 id="whats-next">What&amp;rsquo;s next?&lt;/h2>
&lt;p>With Nginx, PostgreSQL and PHP up and running we&amp;rsquo;re now ready to &lt;a href="https://emanuelpina.pt/nextcloud-27-installation-on-debian/">install Nextcloud&lt;/a>!&lt;/p>
&lt;div class="box grey cfc">
&lt;p>Do you want contribute and add something to this tutorial? Have you found a typo, grammar or formatting error? Please, feel free to
&lt;a href="https://emanuelpina.pt/contact/">contact me&lt;/a> or
&lt;a href="https://github.com/emanuelpina/emanuelpina.pt/blob/main/content/posts/php-installation-on-ubuntu.md">edit&lt;/a>
this post and open a pull resquest.&lt;/p>
&lt;/div>
&lt;div class="footnotes" role="doc-endnotes">
&lt;hr>
&lt;ol>
&lt;li id="fn:1">
&lt;p>&lt;a href="https://docs.nextcloud.com/server/27/admin_manual/installation/system_requirements.html">Nextcloud 27 System requirements&lt;/a>&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;li id="fn:2">
&lt;p>&lt;a href="https://thisinterestsme.com/php-fpm-settings/">PHP-FPM settings tutorial. max_servers, min_servers, etc.&lt;/a>&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;/ol>
&lt;/div></description></item><item><title>PostgreSQL Installation on Debian</title><link>https://emanuelpina.pt/postgresql-installation-on-debian/</link><pubDate>Sat, 21 Dec 2019 11:12:04 +0000</pubDate><guid>https://emanuelpina.pt/postgresql-installation-on-debian/</guid><description>&lt;p>On the way to install Nextcloud we&amp;rsquo;ve already completed the &lt;a href="https://emanuelpina.pt/debian-server-initial-setup/">initial setup of our VPS&lt;/a> and the &lt;a href="https://emanuelpina.pt/nginx-installation-on-debian/">installation of a webserver (Nginx)&lt;/a>.&lt;/p>
&lt;p>We&amp;rsquo;ll now proceed with the installation of PostgreSQL, a relational database management system.&lt;/p>
&lt;p>I’m currently using Debian 12, but these instructions may be equally valid for other versions of Debian and Ubuntu.&lt;/p>
&lt;h2 id="why-postgresql">Why PostgreSQL&lt;/h2>
&lt;p>PostgreSQL isn&amp;rsquo;t the obvious choice to use with Nextcloud. In fact, the officially recommended database management system by Nextcloud is MySQL or MariaDB.&lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup>&lt;/p>
&lt;p>I choosed PostgreSQL mainly because I planned to run other applications, in the same server, that are only compatible with it. My goal was to have a simple as possible setup, avoiding run multiple database systems simultaneously.&lt;/p>
&lt;p>Either way, PostgreSQL has its advantages like an extensive SQL compliance, data integrity and being open source and community driven.&lt;/p>
&lt;p>But maybe it isn&amp;rsquo;t the right choice for you and for a more informed decision you can, for example, read this &lt;a href="https://www.digitalocean.com/community/tutorials/sqlite-vs-mysql-vs-postgresql-a-comparison-of-relational-database-management-systems/">comparison between SQLite vs MySQL vs PostgreSQL&lt;/a>. I found it really usefull.&lt;/p>
&lt;h2 id="install-postgresql">Install PostgreSQL&lt;/h2>
&lt;p>Debian’s default repositories contain PostgreSQL packages, so we can install these using the &lt;code>apt&lt;/code> packaging system.&lt;/p>
&lt;p>First, refresh the local package index:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo apt update
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Then, install the PostgreSQL package along with a &lt;code>-contrib&lt;/code> package that adds some additional utilities and functionality:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo apt install postgresql postgresql-contrib
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>To learn the basics about using PostgreSQL you can start by reading &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-install-and-use-postgresql-on-ubuntu-22-04/">this tutorial on Digital Ocean&lt;/a>.&lt;/p>
&lt;h2 id="tune-postgresql">Tune PostgreSQL&lt;/h2>
&lt;p>One of the downsides of PostgreSQL is its memory performance, so besides optional is highly recommended tune its settings depending on the hardware at your disposale.&lt;/p>
&lt;p>To do so, we can visit &lt;a href="https://pgtune.leopard.in.ua/">PGTune&lt;/a>, fill the form with our system informations and get a list of settings to add/modify in &lt;code>postgresql.conf&lt;/code>. This file can be found in &lt;code>/etc/postgresql/&amp;lt;version_number&amp;gt;/main&lt;/code> folder. In my case, as I&amp;rsquo;m using the version 13 of PostgreSQL, I use the following command to edit it:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo nano /etc/postgresql/15/main/postgresql.conf
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Then is a matter of search for each one of the parameters in the list and modify or add it to match the values generated by PGTune.&lt;/p>
&lt;p>Save the changes and just restart the PostgreSQL service:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo systemctl restart postgresql
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="whats-next">What&amp;rsquo;s next?&lt;/h2>
&lt;p>Now that we&amp;rsquo;ve installed a webserver and a database management system, all that&amp;rsquo;s missing so we can install Nextcloud is &lt;a href="https://emanuelpina.pt/php-installation-on-debian/">PHP&lt;/a>.&lt;/p>
&lt;div class="box grey cfc">
&lt;p>Do you want contribute and add something to this tutorial? Have you found a typo, grammar or formatting error? Please, feel free to
&lt;a href="https://emanuelpina.pt/contact/">contact me&lt;/a> or
&lt;a href="https://github.com/emanuelpina/emanuelpina.pt/blob/main/content/posts/postgresql-installation-on-ubuntu.md">edit&lt;/a>
this post and open a pull resquest.&lt;/p>
&lt;/div>
&lt;div class="footnotes" role="doc-endnotes">
&lt;hr>
&lt;ol>
&lt;li id="fn:1">
&lt;p>&lt;a href="https://docs.nextcloud.com/server/latest/admin_manual/installation/system_requirements.html#system-requirements">Nextcloud system requirements&lt;/a>&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;/ol>
&lt;/div></description></item><item><title>Nginx Installation on Debian</title><link>https://emanuelpina.pt/nginx-installation-on-debian/</link><pubDate>Sat, 05 Oct 2019 03:45:57 +0100</pubDate><guid>https://emanuelpina.pt/nginx-installation-on-debian/</guid><description>&lt;p>This is the second post on the road to self-host Nextcloud. At this point we have already &lt;a href="https://emanuelpina.pt/using-hetzner-to-self-host-nextcloud/">choosed a provider and deployed a VPS&lt;/a> and &lt;a href="https://emanuelpina.pt/debian-server-initial-setup/">completed its initial setup&lt;/a>.&lt;/p>
&lt;p>Now, we&amp;rsquo;re going to cover the installation of Nginx, the use of Let&amp;rsquo;s Encrypt SSL certificates and the configuration of the web server to use HTTP Strict Transport Security (HSTS).&lt;/p>
&lt;p>I’m currently using Debian 12, but these instructions may be equally valid for other versions of Debian and Ubuntu.&lt;/p>
&lt;h2 id="install-nginx">Install Nginx&lt;/h2>
&lt;p>First, let&amp;rsquo;s update the package lists from the repositories:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo apt update
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Then, install Nginx:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo apt install nginx
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>We can check if it’s working by running:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo systemctl status nginx
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>If all went well, we should get something like this:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl">● nginx.service - A high performance web server and a reverse proxy server
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> Loaded: loaded (/lib/systemd/system/nginx.service; enabled; preset: enabled)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> Active: active (running) since Sun 2023-07-23 16:43:52 UTC; 1min 17s ago
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> Docs: man:nginx(8)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> Process: 2471 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> Process: 2472 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> Main PID: 2495 (nginx)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> Tasks: 2 (limit: 2251)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> Memory: 1.8M
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> CPU: 25ms
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> CGroup: /system.slice/nginx.service
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ├─2495 &amp;#34;nginx: master process /usr/sbin/nginx -g daemon on; master_process on;&amp;#34;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> └─2496 &amp;#34;nginx: worker process&amp;#34;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="adjust-the-firewall">Adjust the Firewall&lt;/h2>
&lt;p>Before using Nginx, the firewall needs to be adjusted to allow access to the service. Nginx registers itself as a service with &lt;strong>UFW&lt;/strong> upon installation, making it straightforward to allow Nginx access.&lt;/p>
&lt;p>List the application configurations that &lt;strong>UFW&lt;/strong> knows how to work with by typing:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo ufw app list
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>We get a listing of the application profiles, like this:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl">Available applications:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ...
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> Nginx Full
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> Nginx HTTP
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> Nginx HTTPS
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ...
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>There are three profiles available for Nginx:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Nginx Full:&lt;/strong> This profile opens both port 80 (normal, unencrypted web traffic) and port 443 (TLS/SSL encrypted traffic);&lt;/li>
&lt;li>&lt;strong>Nginx HTTP:&lt;/strong> This profile opens only port 80 (normal, unencrypted web traffic);&lt;/li>
&lt;li>&lt;strong>Nginx HTTPS:&lt;/strong> This profile opens only port 443 (TLS/SSL encrypted traffic).&lt;/li>
&lt;/ul>
&lt;p>We plan to use TLS/SSL so choose the profile &lt;strong>Nginx Full&lt;/strong> to open both ports:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo ufw allow &amp;#39;Nginx Full&amp;#39;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Visiting our IP address on a browser will now show the Nginx&amp;rsquo;s default page, like bellow.&lt;/p>
&lt;p>&lt;img src="https://img.emanuelpina.pt/c_fit,f_auto,q_auto,w_700/v1570212267/2019/nginx-installation-one.jpg" alt="Nginx Default Page">&lt;/p>
&lt;h2 id="set-up-a-server-block">Set Up a Server Block&lt;/h2>
&lt;p>When using the Nginx web server, &lt;em>server blocks&lt;/em> can be used to encapsulate configuration details and host more than one domain from a single server. We will set up a domain called &lt;strong>emanuelpina.ml&lt;/strong>, but you should &lt;strong>replace this with your own domain name&lt;/strong>.&lt;/p>
&lt;p>On this example the content of our site will be stored in the folder &lt;code>/var/www/html&lt;/code>, change this to match your preferences.&lt;/p>
&lt;p>Let&amp;rsquo;s create a &lt;code>index.html&lt;/code> file for our site using &lt;a href="https://help.ubuntu.com/community/Nano/">Nano&lt;/a> or use your favorite editor:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo nano /var/www/html/index.html
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Add the following HTML to the file:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-html" data-lang="html">&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">html&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">head&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">title&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>Welcome to EmanuelPina.pt!&lt;span class="p">&amp;lt;/&lt;/span>&lt;span class="nt">title&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">&amp;lt;/&lt;/span>&lt;span class="nt">head&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">body&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">h1&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>Hello World!&lt;span class="p">&amp;lt;/&lt;/span>&lt;span class="nt">h1&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">p&lt;/span>&lt;span class="p">&amp;gt;&amp;lt;&lt;/span>&lt;span class="nt">b&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>The emanuelpina.pt server block is working!&lt;span class="p">&amp;lt;/&lt;/span>&lt;span class="nt">b&lt;/span>&lt;span class="p">&amp;gt;&amp;lt;/&lt;/span>&lt;span class="nt">p&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">&amp;lt;/&lt;/span>&lt;span class="nt">body&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;/&lt;/span>&lt;span class="nt">html&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Save and close the file when you&amp;rsquo;re finished.&lt;/p>
&lt;p>In order for Nginx to serve this content, we need to create a &lt;em>server block&lt;/em> with the correct directives. Instead of modifying the default configuration file directly, let’s make a new one. We&amp;rsquo;ll name it &lt;strong>emanuelpina.pt&lt;/strong> but you can name it whatever you like:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo nano /etc/nginx/sites-available/emanuelpina.pt
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Paste in the following configuration block, which is similar to the default, but updated for our new directory and domain name:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-nginx" data-lang="nginx">&lt;span class="line">&lt;span class="cl">&lt;span class="k">server&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">listen&lt;/span> &lt;span class="mi">80&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">listen&lt;/span> &lt;span class="s">[::]:80&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">root&lt;/span> &lt;span class="s">/var/www/html&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">index&lt;/span> &lt;span class="s">index.html&lt;/span> &lt;span class="s">index.htm&lt;/span> &lt;span class="s">index.nginx-debian.html&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">server_name&lt;/span> &lt;span class="s">emanuelpina.pt&lt;/span> &lt;span class="s">www.emanuelpina.pt&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">location&lt;/span> &lt;span class="s">/&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">try_files&lt;/span> &lt;span class="nv">$uri&lt;/span> &lt;span class="nv">$uri/&lt;/span> &lt;span class="p">=&lt;/span>&lt;span class="mi">404&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;p>&lt;span class="marker yellow">Notice that we’ve updated the &lt;strong>root&lt;/strong> configuration to our site directory, and the &lt;strong>server_name&lt;/strong> to our domain name.&lt;/span>&lt;/p>
&lt;p>Next, let’s enable the site by creating a link from this file to the &lt;code>sites-enabled&lt;/code> directory, which Nginx reads from during startup:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo ln -s /etc/nginx/sites-available/emanuelpina.pt /etc/nginx/sites-enabled/
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Then, test to make sure that there are no syntax errors in the Nginx files:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo nginx -t
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>If there aren’t any problems, restart Nginx to enable the changes:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo systemctl reload nginx
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Visiting our domain address on a browser will now show the content of the &lt;code>index.html&lt;/code> file we&amp;rsquo;ve created.&lt;/p>
&lt;p>&lt;img src="https://img.emanuelpina.pt/c_fit,f_auto,q_auto,w_700/v1570214982/2019/nginx-installation-two.jpg" alt="Your index.html Page">&lt;/p>
&lt;h2 id="enable-ssl">Enable SSL&lt;/h2>
&lt;p>At this point we have set Nginx to serve our site, but notice that the browser is connecting to the server through a unencrypted/non-secure connection.&lt;/p>
&lt;p>&lt;img src="https://img.emanuelpina.pt/c_fit,f_auto,q_auto,w_700/v1570216401/2019/nginx-installation-three.jpg" alt="Non-secure Connection">&lt;/p>
&lt;p>To enable the browser to use a encrypted/secure connection we&amp;rsquo;ve to install an SSL certificate. We can obtain a free SSL certificate using Let’s Encrypt. To easily do this we can use a open source software called &lt;a href="https://certbot.eff.org/about/">Certbot&lt;/a>. To install Certbot and its Nginx package run the following command:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo apt install certbot python3-certbot-nginx
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>We can now use Certbot to obtaining an SSL certificate typing:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo certbot --nginx
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>At first time we run Certbot, we&amp;rsquo;ll be prompted to enter an email address, agree to the terms of service and authorise or not EEF (the entity that mantains Certbot) to send emails to us.&lt;/p>
&lt;p>We&amp;rsquo;ll then be presented with a list of all domains enabled on our server:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl">Which names would you like to activate HTTPS for?
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------------------------------------------------------------------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">1: emanuelpina.pt
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">2: www.emanuelpina.pt
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------------------------------------------------------------------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Select the appropriate numbers separated by commas and/or spaces, or leave input
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">blank to select all options shown (Enter &amp;#39;c&amp;#39; to cancel):
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Select the appropriate numbers for the domains you want to obtain a certificate separated with a &lt;code>,&lt;/code> (for our example type &lt;code>1,2&lt;/code>) and press &lt;code>ENTER&lt;/code>. After doing so, Certbot will communicate with the Let’s Encrypt server, then run a challenge to verify that we control the domain we’re requesting a certificate for.&lt;/p>
&lt;p>If that’s successful, Certbot will update the &lt;em>server block&lt;/em> and Nginx will reload to pick up the new settings.&lt;/p>
&lt;p>Now, visiting our domain address on a browser we can notice that a encrypted/secure connection is being used.&lt;/p>
&lt;p>&lt;img src="https://img.emanuelpina.pt/c_fit,f_auto,q_auto,w_700/v1570216401/2019/nginx-installation-four.jpg" alt="Secure Connection">&lt;/p>
&lt;h2 id="enable-hsts">Enable HSTS&lt;/h2>
&lt;p>Let&amp;rsquo;s run our domain on &lt;a href="https://www.ssllabs.com/ssltest/">this SSL Server Test&lt;/a> from SSL Labs. The test takes a couple of minutes&amp;hellip;&lt;/p>
&lt;p>&lt;img src="https://img.emanuelpina.pt/c_fit,f_auto,q_auto,w_700/v1570216401/2021/nginx-installation-five.png" alt="SSL Labs First Test Result">&lt;/p>
&lt;p>We got an &lt;strong>A&lt;/strong>. Not bad, but we can do better! To do so we&amp;rsquo;ll enable HSTS.&lt;/p>
&lt;p>HSTS stands for &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security/">HTTP Strict Transport Security&lt;/a> and is a response header that informs the browser that it should never load a site using HTTP and should automatically convert all attempts to access it to HTTPS requests instead.&lt;/p>
&lt;p>Enabling HSTS is as easy as editting our &lt;em>server block&lt;/em>:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo nano /etc/nginx/sites-available/emanuelpina.pt
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>And adding &lt;code>add_header Strict-Transport-Security &amp;quot;max-age=31536000; includeSubDomains&amp;quot; always;&lt;/code> just bellow the &lt;strong>server_name&lt;/strong>, like this:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-nginx" data-lang="nginx">&lt;span class="line">&lt;span class="cl">&lt;span class="k">server&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">###
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">server_name&lt;/span> &lt;span class="s">emanuelpina.pt&lt;/span> &lt;span class="s">www.emanuelpina.pt&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line hl">&lt;span class="cl"> &lt;span class="kn">add_header&lt;/span> &lt;span class="s">Strict-Transport-Security&lt;/span> &lt;span class="s">&amp;#34;max-age=31536000&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="kn">includeSubDomains&amp;#34;&lt;/span> &lt;span class="s">always&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">###
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Test to make sure that there are no syntax errors in our Nginx files:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo nginx -t
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>And if there aren’t any problems, restart Nginx to enable the changes:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo systemctl reload nginx
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Now let&amp;rsquo;s run again the &lt;a href="https://www.ssllabs.com/ssltest/">SSL Server Test&lt;/a> from SSL Labs.&lt;/p>
&lt;p>&lt;img src="https://img.emanuelpina.pt/c_fit,f_auto,q_auto,w_700/v1570219492/2021/nginx-installation-six.png" alt="SSL Labs Final Test Result">&lt;/p>
&lt;p>And that&amp;rsquo;s it. HSTS is enabled and we got an &lt;strong>A+&lt;/strong>!&lt;/p>
&lt;h2 id="whats-next">What&amp;rsquo;s next?&lt;/h2>
&lt;p>Now that we&amp;rsquo;ve connected our server to the Internet, to run Nextcloud we still need PHP and PostgreSQL. That&amp;rsquo;s what I&amp;rsquo;ll cover in a &lt;a href="https://emanuelpina.pt/postgresql-installation-on-debian/">following post&lt;/a>.&lt;/p>
&lt;div class="box grey cfc">
&lt;p>Do you want contribute and add something to this tutorial? Have you found a typo, grammar or formatting error? Please, feel free to
&lt;a href="https://emanuelpina.pt/contact/">contact me&lt;/a> or
&lt;a href="https://github.com/emanuelpina/emanuelpina.pt/blob/main/content/posts/nginx-installation-on-ubuntu.md">edit&lt;/a>
this post and open a pull resquest.&lt;/p>
&lt;/div></description></item><item><title>Global Climate Strike</title><link>https://emanuelpina.pt/global-climate-strike/</link><pubDate>Thu, 19 Sep 2019 22:47:51 +0100</pubDate><guid>https://emanuelpina.pt/global-climate-strike/</guid><description>&lt;p>Climate crisis is a fact. It&amp;rsquo;s not something you choose to believe in or to deny. It&amp;rsquo;s an emergency.&lt;/p>
&lt;p>Because of human activity the world is changing at great pace and this time it&amp;rsquo;s not for the better. We are no longer in time to avoid many of the drastic consequences of our aggressions to the planet, but we are still in time and have the responsibility to restrain them as much as we can.&lt;/p>
&lt;p>The &lt;a href="https://globalclimatestrike.net/">Global Climate Strike&lt;/a> initiative is another attempt to raise awareness to the consequences of our actions, the policies of our governments and the imperative and urgent need for change.&lt;/p>
&lt;p>For this initiative, the proposal is for millions of people around the world leave their homes and workplaces, on September 20th, to join the young climate strikers on the streets and demand an end to the era of fossil fuels.&lt;/p>
&lt;p>You can use this &lt;a href="https://globalclimatestrike.net/#map">map&lt;/a> to find a climate strike near you, and if you&amp;rsquo;re unable to strike on September 20th, &lt;a href="https://globalclimatestrike.net/organise/">here&lt;/a> are some other ways you can join the movement.&lt;/p>
&lt;p>Fight for our home 🌍 There&amp;rsquo;s no Planet B&amp;hellip;&lt;/p></description></item><item><title>Debian Server Initial Setup</title><link>https://emanuelpina.pt/debian-server-initial-setup/</link><pubDate>Wed, 18 Sep 2019 12:03:48 +0100</pubDate><guid>https://emanuelpina.pt/debian-server-initial-setup/</guid><description>&lt;p>This is the first of a series of posts that will cover from the deployment of a VPS up to the installation of Nextcloud. These are the kind of posts I will write mostly for future memory, but if they will be useful to you, even better. I&amp;rsquo;m not reinventing the wheel here, these are just the result of the sum of tutorials and lessons I keep learning.&lt;/p>
&lt;p>On this post I will cover the use of SSH to connect to a server, the creation of a new user with administrative privileges and the setup of a firewall.&lt;/p>
&lt;p>I’m currently using Debian 12, but these instructions may be equally valid for other versions of Debian and Ubuntu.&lt;/p>
&lt;h2 id="update-the-system">Update the system&lt;/h2>
&lt;p>Keeping our system updated is important not only, but mostly for security reasons. To do so, let&amp;rsquo;s first update the package lists from the repositories:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># apt update
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>If an update is available a list is presented. To apply the update(s), run:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># apt upgrade -y
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Don&amp;rsquo;t forget to periodically run those commands and keep the system up-to-date!&lt;/p>
&lt;h2 id="use-ssh">Use SSH&lt;/h2>
&lt;p>While managing our server, we&amp;rsquo;ll spend a lot of time working on a terminal session and the safest way to connect to it is through SSH, or secure shell.&lt;/p>
&lt;p>To do that we&amp;rsquo;ve to make use of an SSH key, which is a pair of encryption keys mathematically linked to each other: a private key and a public key. The public key is used to encrypt a message whereas the private key is used to decrypt it. There are several ways to generate an SSH key. Usually the SSH client we&amp;rsquo;ll use is capable of doing it and that&amp;rsquo;s probably the easiest way. For Windows, the most popular SSH client is &lt;a href="https://putty.org/">Putty&lt;/a>, but I use &lt;a href="https://www.termius.com/">Termius&lt;/a>. To know more on how to connect to a server using SSH, see &lt;a href="https://www.digitalocean.com/docs/droplets/how-to/connect-with-ssh/">this tutorial from DigitalOcean&lt;/a>.&lt;/p>
&lt;p>So, we&amp;rsquo;ll keep our private key to ourself, to use with the SSH client, and install/copy the public key to our server. Almost any VPS provider nowadays have an option on their console that let&amp;rsquo;s add our public SSH keys so we can chose to automatically add them upon server deployment. That&amp;rsquo;s how I do it. But if you prefer to install/copy your SSH key only after the server deployment, see &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-set-up-ssh-keys-on-debian-11">this tutorial&lt;/a>.&lt;/p>
&lt;p>Moving on, after creating a new Debian server there are a few configuration steps that we should take to increase security and usability.&lt;/p>
&lt;h2 id="create-a-new-user">Create a new user&lt;/h2>
&lt;p>To first access our server we need to login as &lt;strong>root&lt;/strong>.&lt;/p>
&lt;blockquote>
&lt;p>The &lt;strong>root&lt;/strong> user is the administrative user in a Linux environment that has very broad privileges. Because of the heightened privileges of the root account, you are discouraged from using it on a regular basis. This is because part of the power inherent with the root account is the ability to make very destructive changes, even by accident. &lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup>&lt;/p>
&lt;/blockquote>
&lt;p>So, our first step is to set up an alternative user account with a reduced scope of influence for day-to-day work.&lt;/p>
&lt;p>On this example we will create a new user called &lt;strong>johndoe&lt;/strong>, but you should replace it with a username of your choice:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># adduser johndoe
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>We&amp;rsquo;ll be asked to set up a password and some information. Enter a strong one and, optionally, fill in any of the additional information if you would like. This is not required and you can just hit &lt;code>ENTER&lt;/code> in any field you wish to skip.&lt;/p>
&lt;h3 id="grant-administrative-privileges">Grant administrative privileges&lt;/h3>
&lt;p>To grant administrative privileges to the new user we need to add it to &lt;strong>sudo&lt;/strong> group:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># usermod -aG sudo johndoe
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="copy-ssh-key-to-a-new-user">Copy SSH key to a new user&lt;/h3>
&lt;p>Next you&amp;rsquo;ve to copy the public SSH key from &lt;strong>root&lt;/strong> user to the new user. This way you can login as both using the same SSH key. The simplest way to copy the files with the correct ownership and permissions is with the &lt;code>rsync&lt;/code> command. This will copy the &lt;strong>root&lt;/strong> user’s &lt;code>.ssh&lt;/code> directory, preserve the permissions, and modify the file owners, all in a single command:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># rsync --archive --chown=johndoe:johndoe ~/.ssh /home/johndoe
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Now we can login with our new user account typping:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo -i -u johndoe
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>We should be logged in to the new user account without using a password. Remember, if you need to run a command with administrative privileges, type &lt;code>sudo&lt;/code> before it like this:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo command_to_run
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>You will be prompted for your regular user password when using &lt;code>sudo&lt;/code> for the first time each session.&lt;/p>
&lt;h2 id="setup-a-firewall">Setup a firewall&lt;/h2>
&lt;p>You can use UFW (Uncomplicated Firewall) to manage which connections are allowed to/from the server.&lt;/p>
&lt;p>So, let&amp;rsquo;s update the package lists from the repositories and install UFW:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo apt update
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"># sudo apt install ufw
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Different applications can register their profiles with UFW upon installation. These profiles allow UFW to manage these applications by name. OpenSSH, the service allowing us to connect to our server now, has a profile registered with UFW.&lt;/p>
&lt;p>You can see this by typing:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo ufw app list
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl">Available applications:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> OpenSSH
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>We need to make sure that the firewall allows SSH connections so that we can log back in next time. We can allow these connections by typing:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo ufw allow OpenSSH
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Afterwards, we can enable the firewall by typing:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo ufw enable
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Type &lt;code>y&lt;/code> and press ENTER to proceed. We can see that SSH connections are still allowed by typing:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl"># sudo ufw status
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-plain" data-lang="plain">&lt;span class="line">&lt;span class="cl">Status: active
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">To Action From
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-- ------ ----
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">OpenSSH ALLOW Anywhere
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">OpenSSH (v6) ALLOW Anywhere (v6)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="whats-next">What&amp;rsquo;s next?&lt;/h2>
&lt;p>Now that we&amp;rsquo;ve completed the initial configuration of our server, we can proceed with the installation of a webserver to present it to the vast and incredible world wide web!&lt;/p>
&lt;p>In a following post I will cover the &lt;a href="https://emanuelpina.pt/nginx-installation-on-debian/">installation of Nginx&lt;/a>.&lt;/p>
&lt;div class="box grey cfc">
&lt;p>Do you want contribute and add something to this tutorial? Have you found a typo, grammar or formatting error? Please, feel free to
&lt;a href="https://emanuelpina.pt/contact/">contact me&lt;/a> or
&lt;a href="https://github.com/emanuelpina/emanuelpina.pt/blob/main/content/posts/ubuntu-server-initial-setup.md">edit&lt;/a>
this post and open a pull resquest.&lt;/p>
&lt;/div>
&lt;div class="footnotes" role="doc-endnotes">
&lt;hr>
&lt;ol>
&lt;li id="fn:1">
&lt;p>&lt;a href="https://www.digitalocean.com/community/tutorials/initial-server-setup-with-debian-11">Initial Server Setup with Debian 11&lt;/a>&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;/ol>
&lt;/div></description></item><item><title>This Blog's Source Code Is Now Public</title><link>https://emanuelpina.pt/this-blogs-source-code-is-now-public/</link><pubDate>Sun, 15 Sep 2019 12:03:09 +0100</pubDate><guid>https://emanuelpina.pt/this-blogs-source-code-is-now-public/</guid><description>&lt;p>This blog was built following the &lt;a href="https://jamstack.org/">JAMStack&lt;/a> philosophy using &lt;a href="https://gohugo.io/">Hugo&lt;/a>, with its development being done at GitHub and now &lt;a href="https://github.com/emanuelpina/blog">publicly available&lt;/a> under the &lt;a href="https://github.com/emanuelpina/blog/blob/master/LICENSE/">MIT license&lt;/a>. It&amp;rsquo;s deployed and hosted on &lt;a href="https://www.netlify.com/">Netlify&lt;/a>.&lt;/p>
&lt;p>Keep in mind that the theme used was tailor-made, and if you decide to use it, you will probably have a lot of work to do to adjust it to your needs.&lt;/p>
&lt;p>I am making the source code public so it can be useful to you, but also so it can be audited. So please, &lt;strong>if you find any typos, grammar or formatting errors, or any other issue that needs to be addressed, feel free to open a Pull Resquest&lt;/strong>. On posts you can use the link &lt;code>Edit&lt;/code> (below the title) to fix them directly on GitHub.&lt;/p>
&lt;p>Enjoy and contribute 😄&lt;/p></description></item><item><title>How I Ended Up With Vultr to Self Host Nextcloud</title><link>https://emanuelpina.pt/how-i-ended-up-with-vultr-to-self-host-nextcloud/</link><pubDate>Wed, 11 Sep 2019 19:50:36 +0100</pubDate><guid>https://emanuelpina.pt/how-i-ended-up-with-vultr-to-self-host-nextcloud/</guid><description>&lt;p>In the process of self-hosting Nextcloud the first step was to choose a VPS provider. It wasn&amp;rsquo;t a straightforward choice and in the process I ended up experiencing, by this order, Hetzner, DigitalOcean and Vultr.&lt;/p>
&lt;p>&lt;span class="marker blue">But, first of all, let me advise you that this isn&amp;rsquo;t intended to be a factual analysis, supported by quantifiable and specific data. It is rather a subjective assessment based on my use case. Therefore, I believe that your experience with these providers could be completely different. If you are into more technical and detailed analyses you can go &lt;a href="https://www.vpsbenchmarks.com/">here&lt;/a> and &lt;a href="https://community.centminmod.com/threads/13-way-vps-server-benchmark-comparison-tests-upcloud-vs-digitalocean-vs-linode-vs-vultr-vs-hetzner.17742/">here&lt;/a>, for example.&lt;/span>&lt;/p>
&lt;p>So my first choice was &lt;a href="https://www.hetzner.com/cloud/">Hetzner&lt;/a>. A company with a high reputation and a very inviting features/price ratio. A VPS with 1vCPU, 2GB RAM, 20GB Disk and 20TB Traffic for €2.49 ($2.75) looks great. It seemed a logical choice. So I proceeded with the installation and configuration of Nextcloud and uploaded my files to the server. Everything was going well, until I started to browse through Nextcloud and tried to open some of my videos. The server crashed. I thought it was a one-time event, but I repeated the process always with the same outcome. According to Hetzner&amp;rsquo;s console the culprit seemed to be the CPU. On idle it remained arround 30% and very often reached 100%. So I upgraded the VPS to 2vCPU, 4GB RAM and 40GB Disk for €4.90 ($5.41) and it all started to work like a charm.&lt;/p>
&lt;p>But then I kept wondering, does it take 2vCPU to run a personal Nextcloud? So I decided to give a try with the only provider I had ever worked with, &lt;a href="https://www.digitalocean.com/pricing/">DigitalOcean&lt;/a> (DO). Of course I chose a droplet with 1vCPU, 1GB RAM and 25GB Disk ($5, €4.54). The user experience was very similar to Hetzner&amp;rsquo;s 2vCPU plan. Of course, CPU utilization was higher in DO (1vCPU vs 2vCPU), but with rare peaks and generally never exceeding 60%. One noticeable difference was the higher download/load speed in DO. Something I expected, because by the reviews I read they have a better network performance with higher download and upload speeds.&lt;/p>
&lt;p>The same reviews pointed out that &lt;a href="https://www.vultr.com/products/cloud-compute/">Vultr&lt;/a> has a network performance on par with DO and a better overall performance. Besides that they have a datacenter in Paris (500km closer to me than Amsterdam) and free snapshots. So I decided to give it a spin. As in DO I deployed a server with 1vCPU, 1GB RAM and 25GB Disk ($5, €4.54). The user experience was slightly better than with DO. The response time was shorter. As a result the pages opened more quickly and the download/load of files was also faster. A better overall experience. This, combined with the ability to create and store snapshots for free, made it easier for me to choose Vultr.&lt;/p>
&lt;p>For now I see no advantage in using DO over Vultr. Hetzner can be back in play if I find myself in need of a little more disk space, or of the extra performance the 2vCPUs and 4GB RAM can offer.&lt;/p>
&lt;h3 id="wrapping-up">Wrapping up&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Hetzner 1vCPU, 2GB RAM, 20GB Disk at €2.49 ($2.75)&lt;/strong>: High CPU utilization and server crashed when loading videos, aparently because of CPU limitations.&lt;/li>
&lt;li>&lt;strong>Hetzner 2vCPU, 4GB RAM, 40GB Disk at €4.90 ($5.41)&lt;/strong>: Worked like a charm.&lt;/li>
&lt;li>&lt;strong>DigitalOcean 1vCPU, 1GB RAM, 25GB Disk at $5 (€4.54)&lt;/strong>: Similar experience as with Hetzner 2vCPU plan. Download/load of files was faster than Hetzner.&lt;/li>
&lt;li>&lt;strong>Vultr 1vCPU, 1GB RAM, 25GB Disk at $5 (€4.54)&lt;/strong>: Slightly better exeprience than DO. Faster response time and download/load of files. Free snapshots.&lt;/li>
&lt;/ul></description></item><item><title>Be the Owner of Your Data With Nextcloud</title><link>https://emanuelpina.pt/be-the-owner-of-your-data-with-nextcloud/</link><pubDate>Sun, 08 Sep 2019 19:36:09 +0100</pubDate><guid>https://emanuelpina.pt/be-the-owner-of-your-data-with-nextcloud/</guid><description>&lt;p>Since a few years now I started to get concern with how much of my data was being gathered and how it was being used.&lt;/p>
&lt;p>Nowadays we spend a big part of our lives online and over the years companies have grown basing their business on tracking our actions. The searches we made, the sites and pages we visit, the time you spent on them&amp;hellip; and so on.&lt;/p>
&lt;p>Let&amp;rsquo;s face it, Google Search was a revolution, and Gmail, OneDrive, iCloud, Facebook or Youtube are excellent products in terms of usability and features. And best of all they&amp;rsquo;re free, you would say. Are they?&lt;/p>
&lt;p>So, how can this companies create and mantain such great products, give them free and be profitable? More than been profitable, all those are now in the &lt;a href="https://fxssi.com/top-10-most-valuable-companies-in-the-world/">top 10 list of the most values companies&lt;/a>. How?&lt;/p>
&lt;p>Because data is nowadays the most profitable resource. The metadata those companies gather of us can be used, for instance, to place ads or shape what we see when we do a search on Google or view our timeline on Facebook or Youtube. In the end, they can condition us to buy a product or to vote in a certain politic. Do you think I&amp;rsquo;m being dramatic? Take a look at Netflix documentary &lt;a href="https://www.netflix.com/Title/80117542/">&lt;em>The Great Hack&lt;/em>&lt;/a> about Facebook and Cambridge Analytica actions during Trump and Brexit campaigns.&lt;/p>
&lt;p>One question that came up in that documentary and made me think was &lt;em>&amp;ldquo;how much of Facebook&amp;rsquo;s profits come from the use of its users&amp;rsquo; data?&amp;rdquo;&lt;/em> The answer is all. All of the more than $400 billion dollars that Facebook worth are result of how much of our data they gather and own. That&amp;rsquo;s disturbing.&lt;/p>
&lt;p>What can we do? Well, look for alternative products with privacy in mind. But the first step you need to take is acknowledge the importance of protect your data. Why? Because some of the alternatives to those big companies produtcs don&amp;rsquo;t offer the same features or don&amp;rsquo;t come free, or both. Yes, the truth is that presently privacy can be seen in some way as a &amp;ldquo;luxury&amp;rdquo; product.&lt;/p>
&lt;p>So far, in pursuit for privacy, what changes did I make? A couple years ago I ditched Chrome for &lt;a href="https://www.mozilla.org/firefox/new/">Firefox&lt;/a>. Gradually stopped using Facebook or Messenger, and recently adopted &lt;a href="https://www.signal.org/">Signal&lt;/a> for messaging and &lt;a href="https://joinmastodon.org/">Mastodon&lt;/a> as social network. My email, contacts and calendars are now handled by &lt;a href="https://tutanota.com/">Tutanota&lt;/a>.&lt;/p>
&lt;p>For now there was still one big piece missing, cloud storage. I was using OneDrive because of his deep integration with Windows and Office. Looking for alternatives I found good, open source, but expensive ones like &lt;a href="https://leastauthority.com/">Least Authority S4&lt;/a> ($25/month), and more affordable, but closed source ones like &lt;a href="https://www.sync.com/">Sync&lt;/a> and &lt;a href="https://tresorit.com/">Tresorit&lt;/a>. Then I decided to take what I already knew on SysAdmin, learn a couple of new things, and give a try on self-hosting &lt;a href="https://nextcloud.com/">Nextcloud&lt;/a>. And two weeks later there&amp;rsquo;s no looking back!&lt;/p>
&lt;p>Nextcloud is a community-driven, free and open source software with all is code published on &lt;a href="https://github.com/nextcloud/">GitHub&lt;/a>. It offers &lt;a href="https://nextcloud.com/encryption/">server-side encryption&lt;/a> and end-to-end encryption is &lt;a href="https://help.nextcloud.com/t/status-end2end-encryption-in-nextcloud/50490">under development&lt;/a>. It&amp;rsquo;s mainly a cloud storage, but &lt;a href="https://nextcloud.com/groupware/">groupware capabilities&lt;/a> could be easily added. It meets all my most urgent requirements and have room for grow and improvement.&lt;/p>
&lt;p>So far, my roadmap on self-hosting Nextcloud:&lt;/p>
&lt;ul>
&lt;li>Deploy a Ubuntu server with Nginx, PHP and PostgreSQL installed;&lt;/li>
&lt;li>Install and tune Nextcloud;&lt;/li>
&lt;li>Use Restic to automate backups of Nextcloud files and database to Backblaze B2;&lt;/li>
&lt;li>Use Vultr&amp;rsquo;s API to automate snapshots management.&lt;/li>
&lt;/ul>
&lt;p>I&amp;rsquo;m no expert, but I will try detail each one of these steps on upcoming posts.&lt;/p>
&lt;p>For now I&amp;rsquo;m using Nextcloud only to store files and notes. As next step I will probably work on the integration with &lt;a href="https://www.onlyoffice.com/">OnlyOffice&lt;/a>.&lt;/p></description></item><item><title>Hello World</title><link>https://emanuelpina.pt/hello-world/</link><pubDate>Thu, 29 Aug 2019 12:43:44 +0100</pubDate><guid>https://emanuelpina.pt/hello-world/</guid><description>&lt;p>Maybe the best way to begin is with a introduction&amp;hellip;&lt;/p>
&lt;p>I&amp;rsquo;m a pediatric nurse by ☀️ and 🌙, ☕ lover and a 🐶 owner for life!&lt;/p>
&lt;p>In between I taught myself a couple of things on web development, currently focused on JAMstack and with more than 15 years of experience on trying to learn JavaScript!&lt;/p>
&lt;p>I&amp;rsquo;m a motorsport fan (F1, WEC, IMSA&amp;hellip;) and I do some sim racing on iRacing.&lt;/p>
&lt;p>There&amp;rsquo;re days (less than it should) when I take some time to cycling.&lt;/p>
&lt;p>What to expect from this blog? Well, the way I see it I will use it more like a journal. A place to log some thoughts, ideas, events and keep track of things, like tutorials, for future memory.&lt;/p>
&lt;p>I hope, if you share my interests, you will find here something enjoyable or useful.&lt;/p>
&lt;p>For sure, I have the expectation to ear things from you too. So fell free to reach me out commenting on posts or through &lt;a href="https://emanuelpina.pt/contact">this form&lt;/a>.&lt;/p>
&lt;p>I have accounts on &lt;a href="https://twitter.com/emanuelpina">Twitter&lt;/a> and &lt;a href="https://instagram.com/emanuelpina">Instagram&lt;/a>, but I don&amp;rsquo;t post much by there. I&amp;rsquo;m more active on &lt;a href="https://mstdn.io/@emanuel">Mastodon&lt;/a>, so feel free to follow me there 😀&lt;/p></description></item></channel></rss>