<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Andres&#39; Blog</title>
    <link>https://andresrcs.rbind.io/</link>
    <description>Recent content on Andres&#39; Blog</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <copyright>Copyright © 2020, Andrés Castro Socolich; all rights reserved.</copyright>
    <lastBuildDate>Sat, 11 Feb 2023 00:00:00 +0000</lastBuildDate>
    
	<atom:link href="https://andresrcs.rbind.io/index.xml" rel="self" type="application/rss+xml" />
    
    
    <item>
      <title>Options to install R on a Raspberry Pi and other ARM systems</title>
      <link>https://andresrcs.rbind.io/2023/02/11/r_on_arm/</link>
      <pubDate>Sat, 11 Feb 2023 00:00:00 +0000</pubDate>
      
      <guid>https://andresrcs.rbind.io/2023/02/11/r_on_arm/</guid>
      <description>
&lt;style type=&#34;text/css&#34;&gt;
pre &gt; code.sourceCode { white-space: pre; position: relative; }
pre &gt; code.sourceCode &gt; span { line-height: 1.25; }
pre &gt; code.sourceCode &gt; span:empty { height: 1.2em; }
.sourceCode { overflow: visible; }
code.sourceCode &gt; span { color: inherit; text-decoration: inherit; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
pre &gt; code.sourceCode { white-space: pre-wrap; }
pre &gt; code.sourceCode &gt; span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
  { counter-reset: source-line 0; }
pre.numberSource code &gt; span
  { position: relative; left: -4em; counter-increment: source-line; }
pre.numberSource code &gt; span &gt; a:first-child::before
  { content: counter(source-line);
    position: relative; left: -1em; text-align: right; vertical-align: baseline;
    border: none; display: inline-block;
    -webkit-touch-callout: none; -webkit-user-select: none;
    -khtml-user-select: none; -moz-user-select: none;
    -ms-user-select: none; user-select: none;
    padding: 0 4px; width: 4em;
  }
pre.numberSource { margin-left: 3em;  padding-left: 4px; }
div.sourceCode
  { color: #cccccc; background-color: #303030; }
@media screen {
pre &gt; code.sourceCode &gt; span &gt; a:first-child::before { text-decoration: underline; }
}
code span.al { color: #ffcfaf; } /* Alert */
code span.an { color: #7f9f7f; font-weight: bold; } /* Annotation */
code span.at { } /* Attribute */
code span.bn { color: #dca3a3; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #f0dfaf; } /* ControlFlow */
code span.ch { color: #dca3a3; } /* Char */
code span.cn { color: #dca3a3; font-weight: bold; } /* Constant */
code span.co { color: #7f9f7f; } /* Comment */
code span.cv { color: #7f9f7f; font-weight: bold; } /* CommentVar */
code span.do { color: #7f9f7f; } /* Documentation */
code span.dt { color: #dfdfbf; } /* DataType */
code span.dv { color: #dcdccc; } /* DecVal */
code span.er { color: #c3bf9f; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #c0bed1; } /* Float */
code span.fu { color: #efef8f; } /* Function */
code span.im { } /* Import */
code span.in { color: #7f9f7f; font-weight: bold; } /* Information */
code span.kw { color: #f0dfaf; } /* Keyword */
code span.op { color: #f0efd0; } /* Operator */
code span.ot { color: #efef8f; } /* Other */
code span.pp { color: #ffcfaf; font-weight: bold; } /* Preprocessor */
code span.sc { color: #dca3a3; } /* SpecialChar */
code span.ss { color: #cc9393; } /* SpecialString */
code span.st { color: #cc9393; } /* String */
code span.va { } /* Variable */
code span.vs { color: #cc9393; } /* VerbatimString */
code span.wa { color: #7f9f7f; font-weight: bold; } /* Warning */
&lt;/style&gt;

&lt;div id=&#34;TOC&#34;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#install-from-the-operating-systems-repositories&#34; id=&#34;toc-install-from-the-operating-systems-repositories&#34;&gt;Install from the Operating System’s repositories&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#compile-r-from-source&#34; id=&#34;toc-compile-r-from-source&#34;&gt;Compile R from source&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#install-r-using-rig&#34; id=&#34;toc-install-r-using-rig&#34;&gt;Install R using rig&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#install-r-from-the-r4pi-project&#34; id=&#34;toc-install-r-from-the-r4pi-project&#34;&gt;Install R from the R4Pi Project&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;

&lt;p&gt;This started out as a section in some of my other posts but as installation options started to pile up it began to take too much space to be just a section in an article so I’ve decided to turn it into an article of its own.&lt;/p&gt;
&lt;p&gt;The options described here are mostly applicable to the Raspberry Pi family of Single Board Computers but since most options also work on Ubuntu distributions they can also be applicable to other Linux ARM systems like other SBCs or even “full-size” ARM computers like Ampere Altra or AWS Graviton.&lt;/p&gt;
&lt;div id=&#34;install-from-the-operating-systems-repositories&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Install from the Operating System’s repositories&lt;/h2&gt;
&lt;p&gt;This is the easiest option, you can install R from the standard repositories for your OS, but those R versions are usually quite old, for example, the latest Raspberry Pi OS comes with R 4.2.2 and Ubuntu 22.04 comes with R 4.1.2.&lt;/p&gt;
&lt;p&gt;To install R with this option you just need to run this command in your system terminal:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb1&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb1-1&#34;&gt;&lt;a href=&#34;#cb1-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; apt install r-base&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is fine if you just want to try R or do simple stuff with it but if you are going to work on a serious project, chances are you want to start with an up-to-date version of R instead.&lt;/p&gt;
&lt;/div&gt;
&lt;div id=&#34;compile-r-from-source&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Compile R from source&lt;/h2&gt;
&lt;p&gt;Another option is to compile the latest R version yourself (4.3.1 at the moment of writing) from the source code files, this is a time-consuming task and it might feel a little intimidating for newcomers but it gives you the most flexibility when it comes to set compilation options, for example, you can choose options like compiling with BLAS and LAPACK to speed up matrix calculations.&lt;/p&gt;
&lt;p&gt;You can compile R from source by running this script on a system terminal, it works for both Raspberry Pi OS and Ubuntu distributions:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb2&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb2-1&#34;&gt;&lt;a href=&#34;#cb2-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; su&lt;/span&gt;
&lt;span id=&#34;cb2-2&#34;&gt;&lt;a href=&#34;#cb2-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;/span&gt;
&lt;span id=&#34;cb2-3&#34;&gt;&lt;a href=&#34;#cb2-3&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Set the R version to install&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-4&#34;&gt;&lt;a href=&#34;#cb2-4&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;va&#34;&gt;R_VERSION&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;=&lt;/span&gt;4.3.1&lt;/span&gt;
&lt;span id=&#34;cb2-5&#34;&gt;&lt;a href=&#34;#cb2-5&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-6&#34;&gt;&lt;a href=&#34;#cb2-6&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;apt&lt;/span&gt; install &lt;span class=&#34;at&#34;&gt;-y&lt;/span&gt; g++ gcc gfortran libreadline-dev libx11-dev libxt-dev &lt;span class=&#34;dt&#34;&gt;\&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-7&#34;&gt;&lt;a href=&#34;#cb2-7&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;            libpng-dev libjpeg-dev libcairo2-dev xvfb &lt;span class=&#34;dt&#34;&gt;\&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-8&#34;&gt;&lt;a href=&#34;#cb2-8&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;            libbz2-dev libzstd-dev liblzma-dev libtiff5 &lt;span class=&#34;dt&#34;&gt;\&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-9&#34;&gt;&lt;a href=&#34;#cb2-9&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;            libssh-dev libgit2-dev libcurl4-openssl-dev &lt;span class=&#34;dt&#34;&gt;\&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-10&#34;&gt;&lt;a href=&#34;#cb2-10&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;            libblas-dev liblapack-dev libopenblas-base &lt;span class=&#34;dt&#34;&gt;\&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-11&#34;&gt;&lt;a href=&#34;#cb2-11&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;            zlib1g-dev openjdk-11-jdk &lt;span class=&#34;dt&#34;&gt;\&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-12&#34;&gt;&lt;a href=&#34;#cb2-12&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;            texinfo texlive texlive-fonts-extra &lt;span class=&#34;dt&#34;&gt;\&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-13&#34;&gt;&lt;a href=&#34;#cb2-13&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;            screen wget libpcre2-dev make cmake&lt;/span&gt;
&lt;span id=&#34;cb2-14&#34;&gt;&lt;a href=&#34;#cb2-14&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;bu&#34;&gt;cd&lt;/span&gt; /usr/local/src&lt;/span&gt;
&lt;span id=&#34;cb2-15&#34;&gt;&lt;a href=&#34;#cb2-15&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;wget&lt;/span&gt; https://cran.rstudio.com/src/base/R-&lt;span class=&#34;va&#34;&gt;${R_VERSION&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;dv&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;va&#34;&gt;}&lt;/span&gt;/R-&lt;span class=&#34;va&#34;&gt;$R_VERSION&lt;/span&gt;.tar.gz&lt;/span&gt;
&lt;span id=&#34;cb2-16&#34;&gt;&lt;a href=&#34;#cb2-16&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;tar&lt;/span&gt; zxvf R-&lt;span class=&#34;va&#34;&gt;$R_VERSION&lt;/span&gt;.tar.gz&lt;/span&gt;
&lt;span id=&#34;cb2-17&#34;&gt;&lt;a href=&#34;#cb2-17&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;bu&#34;&gt;cd&lt;/span&gt; R-&lt;span class=&#34;va&#34;&gt;$R_VERSION&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-18&#34;&gt;&lt;a href=&#34;#cb2-18&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;./configure&lt;/span&gt; &lt;span class=&#34;at&#34;&gt;--enable-R-shlib&lt;/span&gt; &lt;span class=&#34;at&#34;&gt;--enable-memory-profiling&lt;/span&gt; &lt;span class=&#34;at&#34;&gt;--with-blas&lt;/span&gt; &lt;span class=&#34;at&#34;&gt;--with-lapack&lt;/span&gt; &lt;span class=&#34;co&#34;&gt;#BLAS and LAPACK are optional&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-19&#34;&gt;&lt;a href=&#34;#cb2-19&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;make&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-20&#34;&gt;&lt;a href=&#34;#cb2-20&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;make&lt;/span&gt; install&lt;/span&gt;
&lt;span id=&#34;cb2-21&#34;&gt;&lt;a href=&#34;#cb2-21&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;bu&#34;&gt;cd&lt;/span&gt; ..&lt;/span&gt;
&lt;span id=&#34;cb2-22&#34;&gt;&lt;a href=&#34;#cb2-22&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;rm&lt;/span&gt; &lt;span class=&#34;at&#34;&gt;-rf&lt;/span&gt; R-&lt;span class=&#34;va&#34;&gt;$R_VERSION&lt;/span&gt;&lt;span class=&#34;pp&#34;&gt;*&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-23&#34;&gt;&lt;a href=&#34;#cb2-23&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;bu&#34;&gt;exit&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&#34;install-r-using-rig&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Install R using rig&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/r-lib/rig&#34;&gt;&lt;code&gt;rig&lt;/code&gt;&lt;/a&gt; is an R installation manager that allows you to install multiple R versions side by side, it has recently added support for Linux ARM64 systems through the &lt;code&gt;rstudio/r-builds&lt;/code&gt; GitHub repository, although, these builds are stated to be a community resource, they are not professionally supported by Posit. It currently supports only Ubuntu and Debian distributions (The latest Raspberry Pi OS version is based on Debian 12 so it is compatible too).&lt;/p&gt;
&lt;p&gt;You can install &lt;code&gt;rig&lt;/code&gt; in your system by running this command on a system terminal:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb3&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb3-1&#34;&gt;&lt;a href=&#34;#cb3-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;curl&lt;/span&gt; &lt;span class=&#34;at&#34;&gt;-Ls&lt;/span&gt; https://github.com/r-lib/rig/releases/download/latest/rig-linux-arm64-latest.tar.gz &lt;span class=&#34;kw&#34;&gt;|&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-2&#34;&gt;&lt;a href=&#34;#cb3-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; tar xz &lt;span class=&#34;at&#34;&gt;-C&lt;/span&gt; /usr/local&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then you can install the latest stable R version with these commands:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb4&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb4-1&#34;&gt;&lt;a href=&#34;#cb4-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; rig add release &lt;span class=&#34;co&#34;&gt;# Or an specific version like 4.3.1&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-2&#34;&gt;&lt;a href=&#34;#cb4-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; rig default release&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Optionally, you can manually download and install R from &lt;a href=&#34;https://github.com/r-hub/R/releases&#34;&gt;R-hub&lt;/a&gt; as explained on the &lt;a href=&#34;https://github.com/rstudio/r-builds&#34;&gt;&lt;code&gt;rstudio/r-builds&lt;/code&gt;&lt;/a&gt; GitHub repository, but this is a more involved procedure only worthy if you are going to integrate this into your own infrastructure management workflow and you want to avoid the overhead of installing &lt;code&gt;rig&lt;/code&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div id=&#34;install-r-from-the-r4pi-project&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Install R from the R4Pi Project&lt;/h2&gt;
&lt;p&gt;And last but not least, my new favorite, you can install R from the &lt;a href=&#34;https://r4pi.org/&#34; title=&#34;R for the Raspberry Pi&#34;&gt;R4Pi project&lt;/a&gt; through its deb repository, which means you will always get R version updates just by running &lt;code&gt;sudo apt update &amp;amp;&amp;amp; sudo apt upgrade&lt;/code&gt;. Currently supports the latest (Debian 12 based) Raspberry Pi OS version but support is 64-bits only. Also, there are plans to support Ubuntu 24.04 LTS arm64 in the near future.&lt;/p&gt;
&lt;p&gt;To add the R4Pi deb repository to your deb source list and install R run these commands on a system terminal:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb5&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb5-1&#34;&gt;&lt;a href=&#34;#cb5-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;bu&#34;&gt;source&lt;/span&gt; /etc/os-release&lt;/span&gt;
&lt;span id=&#34;cb5-2&#34;&gt;&lt;a href=&#34;#cb5-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;curl&lt;/span&gt; &lt;span class=&#34;at&#34;&gt;-O&lt;/span&gt;  https://pkgs.r4pi.org/dl/&lt;span class=&#34;va&#34;&gt;${VERSION_CODENAME}&lt;/span&gt;/r4pi-repo-conf_0.0.1-1_all.deb&lt;/span&gt;
&lt;span id=&#34;cb5-3&#34;&gt;&lt;a href=&#34;#cb5-3&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; dpkg &lt;span class=&#34;at&#34;&gt;-i&lt;/span&gt;  r4pi-repo-conf_0.0.1-1_all.deb&lt;/span&gt;
&lt;span id=&#34;cb5-4&#34;&gt;&lt;a href=&#34;#cb5-4&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; apt update&lt;/span&gt;
&lt;span id=&#34;cb5-5&#34;&gt;&lt;a href=&#34;#cb5-5&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; apt upgrade&lt;/span&gt;
&lt;span id=&#34;cb5-6&#34;&gt;&lt;a href=&#34;#cb5-6&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; apt install r4pi&lt;/span&gt;
&lt;span id=&#34;cb5-7&#34;&gt;&lt;a href=&#34;#cb5-7&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;rm&lt;/span&gt; r4pi-repo-conf_0.0.1-1_all.deb&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The main benefit of the R4Pi project is that it also provides R package repositories with precompiled binaries for a big selection of R packages which greatly reduces the time and effort required to install R packages on the Raspberry Pi, and by the way, you can also use the R4Pi package repository with all the previous installation options just by setting the “repos” option in a &lt;code&gt;.Rprofile&lt;/code&gt; file.&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb6&#34;&gt;&lt;pre class=&#34;sourceCode r&#34;&gt;&lt;code class=&#34;sourceCode r&#34;&gt;&lt;span id=&#34;cb6-1&#34;&gt;&lt;a href=&#34;#cb6-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;local&lt;/span&gt;({r &lt;span class=&#34;ot&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;getOption&lt;/span&gt;(&lt;span class=&#34;st&#34;&gt;&amp;quot;repos&amp;quot;&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb6-2&#34;&gt;&lt;a href=&#34;#cb6-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;       r[&lt;span class=&#34;st&#34;&gt;&amp;quot;R4Pi&amp;quot;&lt;/span&gt;] &lt;span class=&#34;ot&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;https://pkgs.r4pi.org/bookworm&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-3&#34;&gt;&lt;a href=&#34;#cb6-3&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;       r[&lt;span class=&#34;st&#34;&gt;&amp;quot;CRAN&amp;quot;&lt;/span&gt;] &lt;span class=&#34;ot&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;https://cran.rstudio.com/&amp;quot;&lt;/span&gt; &lt;span class=&#34;co&#34;&gt;# Secondary repository for when no binary is available&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-4&#34;&gt;&lt;a href=&#34;#cb6-4&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;       &lt;span class=&#34;fu&#34;&gt;options&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;repos=&lt;/span&gt;r)})&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Installing Quarto-CLI on Linux-arm64 systems</title>
      <link>https://andresrcs.rbind.io/2022/12/09/quarto_arm64/</link>
      <pubDate>Fri, 09 Dec 2022 00:00:00 +0000</pubDate>
      
      <guid>https://andresrcs.rbind.io/2022/12/09/quarto_arm64/</guid>
      <description>
&lt;style type=&#34;text/css&#34;&gt;
pre &gt; code.sourceCode { white-space: pre; position: relative; }
pre &gt; code.sourceCode &gt; span { display: inline-block; line-height: 1.25; }
pre &gt; code.sourceCode &gt; span:empty { height: 1.2em; }
.sourceCode { overflow: visible; }
code.sourceCode &gt; span { color: inherit; text-decoration: inherit; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
pre &gt; code.sourceCode { white-space: pre-wrap; }
pre &gt; code.sourceCode &gt; span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
  { counter-reset: source-line 0; }
pre.numberSource code &gt; span
  { position: relative; left: -4em; counter-increment: source-line; }
pre.numberSource code &gt; span &gt; a:first-child::before
  { content: counter(source-line);
    position: relative; left: -1em; text-align: right; vertical-align: baseline;
    border: none; display: inline-block;
    -webkit-touch-callout: none; -webkit-user-select: none;
    -khtml-user-select: none; -moz-user-select: none;
    -ms-user-select: none; user-select: none;
    padding: 0 4px; width: 4em;
  }
pre.numberSource { margin-left: 3em;  padding-left: 4px; }
div.sourceCode
  { color: #cccccc; background-color: #303030; }
@media screen {
pre &gt; code.sourceCode &gt; span &gt; a:first-child::before { text-decoration: underline; }
}
code span.al { color: #ffcfaf; } /* Alert */
code span.an { color: #7f9f7f; font-weight: bold; } /* Annotation */
code span.at { } /* Attribute */
code span.bn { color: #dca3a3; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #f0dfaf; } /* ControlFlow */
code span.ch { color: #dca3a3; } /* Char */
code span.cn { color: #dca3a3; font-weight: bold; } /* Constant */
code span.co { color: #7f9f7f; } /* Comment */
code span.cv { color: #7f9f7f; font-weight: bold; } /* CommentVar */
code span.do { color: #7f9f7f; } /* Documentation */
code span.dt { color: #dfdfbf; } /* DataType */
code span.dv { color: #dcdccc; } /* DecVal */
code span.er { color: #c3bf9f; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #c0bed1; } /* Float */
code span.fu { color: #efef8f; } /* Function */
code span.im { } /* Import */
code span.in { color: #7f9f7f; font-weight: bold; } /* Information */
code span.kw { color: #f0dfaf; } /* Keyword */
code span.op { color: #f0efd0; } /* Operator */
code span.ot { color: #efef8f; } /* Other */
code span.pp { color: #ffcfaf; font-weight: bold; } /* Preprocessor */
code span.sc { color: #dca3a3; } /* SpecialChar */
code span.ss { color: #cc9393; } /* SpecialString */
code span.st { color: #cc9393; } /* String */
code span.va { } /* Variable */
code span.vs { color: #cc9393; } /* VerbatimString */
code span.wa { color: #7f9f7f; font-weight: bold; } /* Warning */
&lt;/style&gt;

&lt;div id=&#34;TOC&#34;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#testing-platform&#34; id=&#34;toc-testing-platform&#34;&gt;Testing Platform&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#installing-dependencies&#34; id=&#34;toc-installing-dependencies&#34;&gt;Installing Dependencies&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#installing-quarto&#34; id=&#34;toc-installing-quarto&#34;&gt;Installing Quarto&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;UPDATE:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This article is no longer relevant since the availability of official Quarto arm64 builds. Installation is pretty simple now:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb1&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb1-1&#34;&gt;&lt;a href=&#34;#cb1-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Download deb installer&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-2&#34;&gt;&lt;a href=&#34;#cb1-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;wget&lt;/span&gt; https://github.com/quarto-dev/quarto-cli/releases/download/v1.3.433/quarto-1.3.433-linux-arm64.deb&lt;/span&gt;
&lt;span id=&#34;cb1-3&#34;&gt;&lt;a href=&#34;#cb1-3&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Install Quarto&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-4&#34;&gt;&lt;a href=&#34;#cb1-4&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; dpkg &lt;span class=&#34;at&#34;&gt;-i&lt;/span&gt; quarto-1.3.433-linux-arm64.deb&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I’ll leave the old article down below for reference.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Quarto is Posit’s new open-source scientific and technical publishing system built on Pandoc that allows you to weave together narrative text and code to produce high-quality outputs including reports, presentations, websites, and more. It’s the successor of the highly successful, but R specific, R Markdown ecosystem, bringing all the benefits of R Markdown to other programming langues like Python, Julia and Observable.&lt;/p&gt;
&lt;p&gt;Unfortunately, because of the lack of official arm64 binary sources for some of its dependencies (e.g. Deno, SASS, Pandoc), and as explained to me, their limited bandwidth to support not sufficiently popular architectures like Linux arm64. Quarto does not officially support the arm64 architecture, but that doesn’t mean we can’t make it work on it ourselves.&lt;/p&gt;
&lt;p&gt;With the kind help of Carlos Scheidegger (&lt;a href=&#34;https://mastodon.social/@scheidegger&#34;&gt;&lt;span class=&#34;citation&#34;&gt;@scheidegger&lt;/span&gt;&lt;span class=&#34;citation&#34;&gt;@mastodon.social&lt;/span&gt;&lt;/a&gt;), a software engineer at Posit working on Quarto, I have managed to hack my way into installing Quarto on arm64 systems, and I’ll like to share how I did it with the R community.&lt;/p&gt;
&lt;div id=&#34;testing-platform&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Testing Platform&lt;/h2&gt;
&lt;p&gt;I have tried this on Raspberry Pi 3B+ and 4B running Raspberry Pi OS and Ubuntu 22.04 LT, and on an Oracle Ampere Altra VM running Ubuntu 22.04 LTS, so I’m pretty sure this should work on any arm64 system, provided that you can get suitable arm64 versions of Quarto’s dependencies on your specific Linux distribution. In all cases, I started with a clean and up-to-date install of the operating system so make sure you update yours as well before you start.&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb2&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb2-1&#34;&gt;&lt;a href=&#34;#cb2-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; apt update&lt;/span&gt;
&lt;span id=&#34;cb2-2&#34;&gt;&lt;a href=&#34;#cb2-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; apt dist-upgrade&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&#34;installing-dependencies&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Installing Dependencies&lt;/h2&gt;
&lt;p&gt;First, we need a sufficiently modern arm64 version of Pandoc, and since the version that comes with the standard deb repositories for your OS is most likely too old, it is better if we download a modern version ourselves (this is very important since Quarto will fail with older Pandoc versions).&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb3&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb3-1&#34;&gt;&lt;a href=&#34;#cb3-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;wget&lt;/span&gt; https://github.com/jgm/pandoc/releases/download/2.19.2/pandoc-2.19.2-1-arm64.deb&lt;/span&gt;
&lt;span id=&#34;cb3-2&#34;&gt;&lt;a href=&#34;#cb3-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; dpkg &lt;span class=&#34;at&#34;&gt;-i&lt;/span&gt; pandoc-2.19.2-1-arm64.deb&lt;/span&gt;
&lt;span id=&#34;cb3-3&#34;&gt;&lt;a href=&#34;#cb3-3&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;rm&lt;/span&gt; pandoc-2.19.2-1-arm64.deb&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Also, we need R and the &lt;code&gt;rmarkdown&lt;/code&gt; R package, but since you are reading this article on an R related blog, I will assume you already have R installed in your system and you know how to install R packages, if you don’t, you can check this &lt;a href=&#34;https://andresrcs.rbind.io/2023/02/11/r_on_arm/&#34;&gt;other post&lt;/a&gt; where I detail options to install R on a Pi. To clarify, I’m considering R as a dependency because I’m writing on an R related blog, but if you are going to use Quarto with some other programming language, R is not mandatory.&lt;/p&gt;
&lt;/div&gt;
&lt;div id=&#34;installing-quarto&#34; class=&#34;section level1&#34;&gt;
&lt;h1&gt;Installing Quarto&lt;/h1&gt;
&lt;p&gt;Since there are no arm64 binaries for Quarto, we are going to install it from source. Follow these steps from top to bottom without skipping any since they all depend on the previous one:&lt;/p&gt;
&lt;p&gt;First, we need to clone the GitHub repository in a suitable location. Note that you can optionally clone a specific release version if you prefer by using the &lt;code&gt;--branch&lt;/code&gt; option (e.g. &lt;code&gt;--branch v1.3.47&lt;/code&gt;)&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb4&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb4-1&#34;&gt;&lt;a href=&#34;#cb4-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; su &lt;span class=&#34;at&#34;&gt;-&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-2&#34;&gt;&lt;a href=&#34;#cb4-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-3&#34;&gt;&lt;a href=&#34;#cb4-3&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;bu&#34;&gt;cd&lt;/span&gt; /usr/local/src&lt;/span&gt;
&lt;span id=&#34;cb4-4&#34;&gt;&lt;a href=&#34;#cb4-4&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-5&#34;&gt;&lt;a href=&#34;#cb4-5&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;git&lt;/span&gt; clone &lt;span class=&#34;at&#34;&gt;--depth&lt;/span&gt; 1 https://github.com/quarto-dev/quarto-cli&lt;/span&gt;
&lt;span id=&#34;cb4-6&#34;&gt;&lt;a href=&#34;#cb4-6&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-7&#34;&gt;&lt;a href=&#34;#cb4-7&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;bu&#34;&gt;cd&lt;/span&gt; quarto-cli&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Next, we are going to trick Quarto into installing an arm64 version of Deno from an &lt;a href=&#34;https://github.com/LukeChannings/deno-arm64&#34;&gt;alternative source&lt;/a&gt; by modifying its &lt;code&gt;configure.sh&lt;/code&gt; file before executing it.&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb5&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb5-1&#34;&gt;&lt;a href=&#34;#cb5-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sed&lt;/span&gt; &lt;span class=&#34;at&#34;&gt;-i&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;s/https:\/\/github.com\/denoland\/deno\/releases\/download/https:\/\/github.com\/LukeChannings\/deno-arm64\/releases\/download/&amp;#39;&lt;/span&gt; configure.sh&lt;/span&gt;
&lt;span id=&#34;cb5-2&#34;&gt;&lt;a href=&#34;#cb5-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sed&lt;/span&gt; &lt;span class=&#34;at&#34;&gt;-i&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;s/DENOFILES=deno-x86_64-unknown-linux-gnu.zip/DENOFILES=deno-linux-arm64.zip/&amp;#39;&lt;/span&gt; package/scripts/common/utils.sh&lt;/span&gt;
&lt;span id=&#34;cb5-3&#34;&gt;&lt;a href=&#34;#cb5-3&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sed&lt;/span&gt; &lt;span class=&#34;at&#34;&gt;-i&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;s/DENO_DIR=deno-x86_64-unknown-linux-gnu/DENO_DIR=deno-linux-arm64/&amp;#39;&lt;/span&gt; package/scripts/common/utils.sh&lt;/span&gt;
&lt;span id=&#34;cb5-4&#34;&gt;&lt;a href=&#34;#cb5-4&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-5&#34;&gt;&lt;a href=&#34;#cb5-5&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;./configure.sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Finally, we are going to replace the external amd64 binaries Quarto downloads during installation with arm64 ones.&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb6&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb6-1&#34;&gt;&lt;a href=&#34;#cb6-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;mkdir&lt;/span&gt; package/dist/bin/tools/deno-x86_64-unknown-linux-gnu/&lt;/span&gt;
&lt;span id=&#34;cb6-2&#34;&gt;&lt;a href=&#34;#cb6-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;ln&lt;/span&gt; &lt;span class=&#34;at&#34;&gt;-s&lt;/span&gt; /usr/local/src/quarto-cli/package/dist/bin/tools/deno-linux-arm64/deno package/dist/bin/tools/deno-x86_64-unknown-linux-gnu/deno&lt;/span&gt;
&lt;span id=&#34;cb6-3&#34;&gt;&lt;a href=&#34;#cb6-3&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-4&#34;&gt;&lt;a href=&#34;#cb6-4&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;rm&lt;/span&gt; package/dist/bin/tools/pandoc&lt;/span&gt;
&lt;span id=&#34;cb6-5&#34;&gt;&lt;a href=&#34;#cb6-5&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;ln&lt;/span&gt; &lt;span class=&#34;at&#34;&gt;-s&lt;/span&gt; /usr/bin/pandoc package/dist/bin/tools/pandoc&lt;/span&gt;
&lt;span id=&#34;cb6-6&#34;&gt;&lt;a href=&#34;#cb6-6&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-7&#34;&gt;&lt;a href=&#34;#cb6-7&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;rm&lt;/span&gt; &lt;span class=&#34;at&#34;&gt;-rf&lt;/span&gt; package/dist/bin/tools/dart-sass/&lt;/span&gt;
&lt;span id=&#34;cb6-8&#34;&gt;&lt;a href=&#34;#cb6-8&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;wget&lt;/span&gt; https://github.com/sass/dart-sass/releases/download/1.57.1/dart-sass-1.57.1-linux-arm64.tar.gz&lt;/span&gt;
&lt;span id=&#34;cb6-9&#34;&gt;&lt;a href=&#34;#cb6-9&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;tar&lt;/span&gt; zxvf dart-sass-1.57.1-linux-arm64.tar.gz&lt;/span&gt;
&lt;span id=&#34;cb6-10&#34;&gt;&lt;a href=&#34;#cb6-10&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;rm&lt;/span&gt; dart-sass-1.57.1-linux-arm64.tar.gz&lt;/span&gt;
&lt;span id=&#34;cb6-11&#34;&gt;&lt;a href=&#34;#cb6-11&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;mv&lt;/span&gt; &lt;span class=&#34;at&#34;&gt;-f&lt;/span&gt; dart-sass/ package/dist/bin/tools/&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If all went well, you now have a working installation of the Quarto Command Line Interface in your system, and you can start rendering &lt;code&gt;qmd&lt;/code&gt; files from the terminal. To test if it actually works, let’s render a test document; create a &lt;code&gt;test.qmd&lt;/code&gt; file with the following content:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb7&#34;&gt;&lt;pre class=&#34;sourceCode markdown&#34;&gt;&lt;code class=&#34;sourceCode markdown&#34;&gt;&lt;span id=&#34;cb7-1&#34;&gt;&lt;a href=&#34;#cb7-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;---&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb7-2&#34;&gt;&lt;a href=&#34;#cb7-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;an&#34;&gt;title:&lt;/span&gt;&lt;span class=&#34;co&#34;&gt; &amp;quot;Test Document&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb7-3&#34;&gt;&lt;a href=&#34;#cb7-3&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;an&#34;&gt;format:&lt;/span&gt;&lt;span class=&#34;co&#34;&gt; html&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb7-4&#34;&gt;&lt;a href=&#34;#cb7-4&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;---&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb7-5&#34;&gt;&lt;a href=&#34;#cb7-5&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb7-6&#34;&gt;&lt;a href=&#34;#cb7-6&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;## Hello&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb7-7&#34;&gt;&lt;a href=&#34;#cb7-7&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb7-8&#34;&gt;&lt;a href=&#34;#cb7-8&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;in&#34;&gt;```{r}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb7-9&#34;&gt;&lt;a href=&#34;#cb7-9&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;in&#34;&gt;print(&amp;quot;world&amp;quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb7-10&#34;&gt;&lt;a href=&#34;#cb7-10&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;in&#34;&gt;```&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And render the document from a system terminal with the following command:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb8&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb8-1&#34;&gt;&lt;a href=&#34;#cb8-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;quarto&lt;/span&gt; render test.qmd&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If all goes well, you will get a &lt;code&gt;test.html&lt;/code&gt; file in the current location.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://andresrcs.rbind.io/post/2022-12-09-quarto_arm64.en_files/test_html.jpg&#34; width=&#34;700&#34; height=&#34;350&#34; /&gt;&lt;/p&gt;
&lt;p&gt;I haven’t figured out how to enable the RStudio IDE integration with Quarto (RStudio’s experimental builds for arm64 come with Quarto integration features disabled). I have raised the question on the GitHub repository, and I’ll update this post if a solution or workaround arises.&lt;/p&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Setting up your own Shiny and RStudio Server on a Raspberry Pi</title>
      <link>https://andresrcs.rbind.io/2022/09/05/shiny_rstudio_server/</link>
      <pubDate>Mon, 05 Sep 2022 00:00:00 +0000</pubDate>
      
      <guid>https://andresrcs.rbind.io/2022/09/05/shiny_rstudio_server/</guid>
      <description>
&lt;style type=&#34;text/css&#34;&gt;
html { -webkit-text-size-adjust: 100%; }
pre &gt; code.sourceCode { white-space: pre; position: relative; }
pre &gt; code.sourceCode &gt; span { display: inline-block; line-height: 1.25; }
pre &gt; code.sourceCode &gt; span:empty { height: 1.2em; }
.sourceCode { overflow: visible; }
code.sourceCode &gt; span { color: inherit; text-decoration: inherit; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
pre &gt; code.sourceCode { white-space: pre-wrap; }
pre &gt; code.sourceCode &gt; span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
  { counter-reset: source-line 0; }
pre.numberSource code &gt; span
  { position: relative; left: -4em; counter-increment: source-line; }
pre.numberSource code &gt; span &gt; a:first-child::before
  { content: counter(source-line);
    position: relative; left: -1em; text-align: right; vertical-align: baseline;
    border: none; display: inline-block;
    -webkit-touch-callout: none; -webkit-user-select: none;
    -khtml-user-select: none; -moz-user-select: none;
    -ms-user-select: none; user-select: none;
    padding: 0 4px; width: 4em;
  }
pre.numberSource { margin-left: 3em;  padding-left: 4px; }
div.sourceCode
  { color: #cccccc; background-color: #303030; }
@media screen {
pre &gt; code.sourceCode &gt; span &gt; a:first-child::before { text-decoration: underline; }
}
code span.al { color: #ffcfaf; } /* Alert */
code span.an { color: #7f9f7f; font-weight: bold; } /* Annotation */
code span.at { } /* Attribute */
code span.bn { color: #dca3a3; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #f0dfaf; } /* ControlFlow */
code span.ch { color: #dca3a3; } /* Char */
code span.cn { color: #dca3a3; font-weight: bold; } /* Constant */
code span.co { color: #7f9f7f; } /* Comment */
code span.cv { color: #7f9f7f; font-weight: bold; } /* CommentVar */
code span.do { color: #7f9f7f; } /* Documentation */
code span.dt { color: #dfdfbf; } /* DataType */
code span.dv { color: #dcdccc; } /* DecVal */
code span.er { color: #c3bf9f; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #c0bed1; } /* Float */
code span.fu { color: #efef8f; } /* Function */
code span.im { } /* Import */
code span.in { color: #7f9f7f; font-weight: bold; } /* Information */
code span.kw { color: #f0dfaf; } /* Keyword */
code span.op { color: #f0efd0; } /* Operator */
code span.ot { color: #efef8f; } /* Other */
code span.pp { color: #ffcfaf; font-weight: bold; } /* Preprocessor */
code span.sc { color: #dca3a3; } /* SpecialChar */
code span.ss { color: #cc9393; } /* SpecialString */
code span.st { color: #cc9393; } /* String */
code span.va { } /* Variable */
code span.vs { color: #cc9393; } /* VerbatimString */
code span.wa { color: #7f9f7f; font-weight: bold; } /* Warning */
&lt;/style&gt;

&lt;div id=&#34;TOC&#34;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#prepare-the-raspberry-pi&#34; id=&#34;toc-prepare-the-raspberry-pi&#34;&gt;Prepare The Raspberry Pi&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#install-r&#34; id=&#34;toc-install-r&#34;&gt;Install R&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#install-shiny-server&#34; id=&#34;toc-install-shiny-server&#34;&gt;Install Shiny Server&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#install-rstudio-server&#34; id=&#34;toc-install-rstudio-server&#34;&gt;Install Rstudio Server&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#install-additional-support-services-optional&#34; id=&#34;toc-install-additional-support-services-optional&#34;&gt;Install Additional Support Services (optional)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#extra-steps-optional&#34; id=&#34;toc-extra-steps-optional&#34;&gt;Extra Steps (optional)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#final-comments&#34; id=&#34;toc-final-comments&#34;&gt;Final Comments&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;

&lt;p&gt;This article was originally published back in 2018 and a lot has changed since then, so I have completely re-write it to take into account the most recent advancements in support for the arm64 architecture within the R ecosystem.&lt;/p&gt;
&lt;p&gt;Back in 2018, I participated in a forum topic at &lt;a href=&#34;https://forum.posit.co/t/raspberry-pi-as-a-viable-shiny-server/18672?u=andresrcs&#34;&gt;Posit Community&lt;/a&gt; where &lt;a href=&#34;https://twitter.com/jladata&#34;&gt;@jladata&lt;/a&gt; was asking if a Raspberry Pi 3B+ could make it as a viable Shiny server. I actually use a Raspberry Pi for that very purpose so I decided to share with the R community, my experience setting up Shiny and Rstudio Server natively on a Raspberry Pi.&lt;/p&gt;
&lt;p&gt;In those days there was almost &lt;strong&gt;zero support for ARM&lt;/strong&gt; architectures (either x32 or x64) so most of the software had to be compiled from source on the Pi itself, which makes the installation process a titanic effort with lots and lots of waiting hours.&lt;/p&gt;
&lt;p&gt;Nowadays, things have changed and we have better support for the arm64 architecture due to community efforts and even official RStudio support in the works. In this renewed article I’m going to guide you through the installation options we have currently available.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;✏️ I also have a &lt;a href=&#34;https://andresrcs.rbind.io/2021/01/13/raspberry_pi_server/&#34;&gt;related article&lt;/a&gt; showing how to automate the installation process using Ansible.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div id=&#34;prepare-the-raspberry-pi&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Prepare The Raspberry Pi&lt;/h2&gt;
&lt;p&gt;First, you need a 64-bit operating system for your Pi (make sure it’s 64-bit since RStudio only has support for the arm64 architecture), these installation instructions work for both Raspberry Pi OS and Ubuntu, you can download either of those using the Raspberry Pi Imager software from &lt;a href=&#34;https://www.raspberrypi.com/software/&#34;&gt;their official site&lt;/a&gt;. Also, make sure to update your system libraries with &lt;code&gt;sudo apt update &amp;amp;&amp;amp; sudo apt dist-upgrade&lt;/code&gt; before you start.&lt;/p&gt;
&lt;p&gt;Although not mandatory, I recommend performing the following actions using the &lt;code&gt;sudo raspi-config&lt;/code&gt; application (In Ubuntu you need to install it first with &lt;code&gt;sudo apt install raspi-config&lt;/code&gt;):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Expand the filesystem (Advanced Options / Expand Filesystem).&lt;/li&gt;
&lt;li&gt;Configure your locale, and make sure to choose an UTF.8 option to avoid compilation issues (Localisation Options / Locale).&lt;/li&gt;
&lt;li&gt;Disable “Predictable network interfaces” (Advanced Options / Network Interface Names).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Next, you need to set a static IP for the Pi so you can easily find it on your network.&lt;/p&gt;
&lt;p&gt;For setting a static IP on Raspberry Pi OS, run these commands. This is a sample IP configuration for a wired connection, modify accordingly with your own needs:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb1&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb1-1&#34;&gt;&lt;a href=&#34;#cb1-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Sample static IP configuration:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-2&#34;&gt;&lt;a href=&#34;#cb1-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; nmcli c mod &lt;span class=&#34;st&#34;&gt;&amp;#39;Wired connection 1&amp;#39;&lt;/span&gt; ipv4.addresses 192.168.1.101/24 ipv4.method manual&lt;/span&gt;
&lt;span id=&#34;cb1-3&#34;&gt;&lt;a href=&#34;#cb1-3&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; nmcli con mod &lt;span class=&#34;st&#34;&gt;&amp;#39;Wired connection 1&amp;#39;&lt;/span&gt; ipv4.gateway 192.168.1.1&lt;/span&gt;
&lt;span id=&#34;cb1-4&#34;&gt;&lt;a href=&#34;#cb1-4&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; nmcli con mod &lt;span class=&#34;st&#34;&gt;&amp;#39;Wired connection 1&amp;#39;&lt;/span&gt; ipv4.dns &lt;span class=&#34;st&#34;&gt;&amp;quot;192.168.1.1&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-5&#34;&gt;&lt;a href=&#34;#cb1-5&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; nmcli c down &lt;span class=&#34;st&#34;&gt;&amp;#39;Wired connection 1&amp;#39;&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; nmcli c up &lt;span class=&#34;st&#34;&gt;&amp;#39;Wired connection 1&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And for setting the IP on Ubuntu you have to create this file, &lt;code&gt;sudo nano /etc/netplan/01-netcfg.yaml&lt;/code&gt;,add this content (edit as needed) and apply the configuration with this command, &lt;code&gt;sudo netplan apply&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb2&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb2-1&#34;&gt;&lt;a href=&#34;#cb2-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;network:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-2&#34;&gt;&lt;a href=&#34;#cb2-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;ex&#34;&gt;version:&lt;/span&gt; 2&lt;/span&gt;
&lt;span id=&#34;cb2-3&#34;&gt;&lt;a href=&#34;#cb2-3&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;ex&#34;&gt;renderer:&lt;/span&gt; networkd&lt;/span&gt;
&lt;span id=&#34;cb2-4&#34;&gt;&lt;a href=&#34;#cb2-4&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;ex&#34;&gt;ethernets:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-5&#34;&gt;&lt;a href=&#34;#cb2-5&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;eth0:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-6&#34;&gt;&lt;a href=&#34;#cb2-6&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;ex&#34;&gt;dhcp4:&lt;/span&gt; false&lt;/span&gt;
&lt;span id=&#34;cb2-7&#34;&gt;&lt;a href=&#34;#cb2-7&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;ex&#34;&gt;addresses:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-8&#34;&gt;&lt;a href=&#34;#cb2-8&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                &lt;span class=&#34;ex&#34;&gt;-&lt;/span&gt; 192.168.1.101/24&lt;/span&gt;
&lt;span id=&#34;cb2-9&#34;&gt;&lt;a href=&#34;#cb2-9&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;ex&#34;&gt;nameservers:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-10&#34;&gt;&lt;a href=&#34;#cb2-10&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                &lt;span class=&#34;ex&#34;&gt;addresses:&lt;/span&gt; [8.8.8.8, 8.8.4.4, 192.168.1.1]&lt;/span&gt;
&lt;span id=&#34;cb2-11&#34;&gt;&lt;a href=&#34;#cb2-11&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;ex&#34;&gt;routes:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-12&#34;&gt;&lt;a href=&#34;#cb2-12&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                &lt;span class=&#34;ex&#34;&gt;-&lt;/span&gt; to: default&lt;/span&gt;
&lt;span id=&#34;cb2-13&#34;&gt;&lt;a href=&#34;#cb2-13&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                  &lt;span class=&#34;ex&#34;&gt;via:&lt;/span&gt; 192.168.1.1&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In case you have a low-RAM Raspberry Pi model, you have to add some swap memory for the installation process. For 1GB Pi models, 3GB of swap would be enough, you can do it with these commands:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb3&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb3-1&#34;&gt;&lt;a href=&#34;#cb3-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; /bin/dd if=/dev/zero of=/var/swap.1 bs=1M count=3072&lt;/span&gt;
&lt;span id=&#34;cb3-2&#34;&gt;&lt;a href=&#34;#cb3-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; chmod 600 /var/swap.1&lt;/span&gt;
&lt;span id=&#34;cb3-3&#34;&gt;&lt;a href=&#34;#cb3-3&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; /sbin/mkswap /var/swap.1&lt;/span&gt;
&lt;span id=&#34;cb3-4&#34;&gt;&lt;a href=&#34;#cb3-4&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; /sbin/swapon /var/swap.1&lt;/span&gt;
&lt;span id=&#34;cb3-5&#34;&gt;&lt;a href=&#34;#cb3-5&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; sh &lt;span class=&#34;at&#34;&gt;-c&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;echo &amp;quot;/var/swap.1 swap swap defaults 0 0 &amp;quot; &amp;gt;&amp;gt; /etc/fstab&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For preventing unnecessary use of swap memory and protect your SD card, open this file, &lt;code&gt;sudo nano /etc/sysctl.conf&lt;/code&gt;, and add this line at the end:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb4&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb4-1&#34;&gt;&lt;a href=&#34;#cb4-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;vm.swappiness=10&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&#34;install-r&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Install R&lt;/h2&gt;
&lt;p&gt;You have several options for installing R on your Pi:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Install from the Operating System’s repositories (Not recommended)&lt;/li&gt;
&lt;li&gt;Compile R from source&lt;/li&gt;
&lt;li&gt;Install R using rig&lt;/li&gt;
&lt;li&gt;Install R from the R4Pi Project&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Since there are several options now I have moved this section to a separate article that you can consult &lt;a href=&#34;https://andresrcs.rbind.io/2023/02/11/r_on_arm/&#34;&gt;here&lt;/a&gt; for more details.&lt;/p&gt;
&lt;p&gt;Whenever possible (whit a compatible OS), I strongly recommend using the &lt;a href=&#34;https://r4pi.org/&#34;&gt;R4Pi&lt;/a&gt; package repository as your R packages source since it provides precompiled binaries that make installation easier and faster.&lt;/p&gt;
&lt;/div&gt;
&lt;div id=&#34;install-shiny-server&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Install Shiny Server&lt;/h2&gt;
&lt;p&gt;Currently, &lt;code&gt;shiny-server&lt;/code&gt; offers no ARM support so the only option for installing it on the Pi is to compile from source. There is hope this will change in the future as per the response on this &lt;a href=&#34;https://github.com/rstudio/shiny-server/issues/532#issuecomment-1223282001&#34;&gt;GitHub Issue&lt;/a&gt;, but for the time being we are stuck with this.&lt;/p&gt;
&lt;p&gt;First, you need to install the R package dependencies, if you are using a CRAN repository, this is going to take a while, but it is much quicker if you are using the R4Pi repository (available with R installed from R4Pi):&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb5&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb5-1&#34;&gt;&lt;a href=&#34;#cb5-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Define your R package repository (You have to choose one of these)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-2&#34;&gt;&lt;a href=&#34;#cb5-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# REPO=&amp;quot;&amp;#39;http://cran.rstudio.com/&amp;#39;&amp;quot; # For OSes that are not compatible with R binaries build for RPi OS (Debian 12 based)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-3&#34;&gt;&lt;a href=&#34;#cb5-3&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# REPO=&amp;quot;c(&amp;#39;https://pkgs.r4pi.org/noble&amp;#39;, &amp;#39;http://cran.rstudio.com/&amp;#39;)&amp;quot; # For Ubuntu 24.04&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-4&#34;&gt;&lt;a href=&#34;#cb5-4&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;va&#34;&gt;REPO&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;&amp;quot;c(&amp;#39;https://pkgs.r4pi.org/bookworm&amp;#39;, &amp;#39;http://cran.rstudio.com/&amp;#39;)&amp;quot;&lt;/span&gt; &lt;span class=&#34;co&#34;&gt;# For the latest RPi OS (Debian 12 based)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-5&#34;&gt;&lt;a href=&#34;#cb5-5&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-6&#34;&gt;&lt;a href=&#34;#cb5-6&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Make sure the system dependencies are installed&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-7&#34;&gt;&lt;a href=&#34;#cb5-7&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; apt install libcairo2-dev libxt-dev git cmake pandoc&lt;/span&gt;
&lt;span id=&#34;cb5-8&#34;&gt;&lt;a href=&#34;#cb5-8&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-9&#34;&gt;&lt;a href=&#34;#cb5-9&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Install required R packages as sudo&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-10&#34;&gt;&lt;a href=&#34;#cb5-10&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; su &lt;span class=&#34;at&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;at&#34;&gt;-c&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;R -e &lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;install.packages(&amp;#39;Rcpp&amp;#39;, repos=&lt;/span&gt;&lt;span class=&#34;va&#34;&gt;$REPO&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-11&#34;&gt;&lt;a href=&#34;#cb5-11&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; su &lt;span class=&#34;at&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;at&#34;&gt;-c&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;R -e &lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;install.packages(&amp;#39;later&amp;#39;, repos=&lt;/span&gt;&lt;span class=&#34;va&#34;&gt;$REPO&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-12&#34;&gt;&lt;a href=&#34;#cb5-12&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; su &lt;span class=&#34;at&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;at&#34;&gt;-c&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;R -e &lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;install.packages(&amp;#39;fs&amp;#39;, repos=&lt;/span&gt;&lt;span class=&#34;va&#34;&gt;$REPO&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-13&#34;&gt;&lt;a href=&#34;#cb5-13&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; su &lt;span class=&#34;at&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;at&#34;&gt;-c&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;R -e &lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;install.packages(&amp;#39;R6&amp;#39;, repos=&lt;/span&gt;&lt;span class=&#34;va&#34;&gt;$REPO&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-14&#34;&gt;&lt;a href=&#34;#cb5-14&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; su &lt;span class=&#34;at&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;at&#34;&gt;-c&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;R -e &lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;install.packages(&amp;#39;Cairo&amp;#39;, repos=&lt;/span&gt;&lt;span class=&#34;va&#34;&gt;$REPO&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-15&#34;&gt;&lt;a href=&#34;#cb5-15&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; su &lt;span class=&#34;at&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;at&#34;&gt;-c&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;R -e &lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;install.packages(&amp;#39;httpuv&amp;#39;, repos=&lt;/span&gt;&lt;span class=&#34;va&#34;&gt;$REPO&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-16&#34;&gt;&lt;a href=&#34;#cb5-16&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; su &lt;span class=&#34;at&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;at&#34;&gt;-c&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;R -e &lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;install.packages(&amp;#39;mime&amp;#39;, repos=&lt;/span&gt;&lt;span class=&#34;va&#34;&gt;$REPO&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-17&#34;&gt;&lt;a href=&#34;#cb5-17&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; su &lt;span class=&#34;at&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;at&#34;&gt;-c&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;R -e &lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;install.packages(&amp;#39;jsonlite&amp;#39;, repos=&lt;/span&gt;&lt;span class=&#34;va&#34;&gt;$REPO&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-18&#34;&gt;&lt;a href=&#34;#cb5-18&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; su &lt;span class=&#34;at&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;at&#34;&gt;-c&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;R -e &lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;install.packages(&amp;#39;digest&amp;#39;, repos=&lt;/span&gt;&lt;span class=&#34;va&#34;&gt;$REPO&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-19&#34;&gt;&lt;a href=&#34;#cb5-19&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; su &lt;span class=&#34;at&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;at&#34;&gt;-c&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;R -e &lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;install.packages(&amp;#39;htmltools&amp;#39;, repos=&lt;/span&gt;&lt;span class=&#34;va&#34;&gt;$REPO&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-20&#34;&gt;&lt;a href=&#34;#cb5-20&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; su &lt;span class=&#34;at&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;at&#34;&gt;-c&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;R -e &lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;install.packages(&amp;#39;xtable&amp;#39;, repos=&lt;/span&gt;&lt;span class=&#34;va&#34;&gt;$REPO&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-21&#34;&gt;&lt;a href=&#34;#cb5-21&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; su &lt;span class=&#34;at&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;at&#34;&gt;-c&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;R -e &lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;install.packages(&amp;#39;sourcetools&amp;#39;, repos=&lt;/span&gt;&lt;span class=&#34;va&#34;&gt;$REPO&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-22&#34;&gt;&lt;a href=&#34;#cb5-22&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; su &lt;span class=&#34;at&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;at&#34;&gt;-c&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;R -e &lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;install.packages(&amp;#39;shiny&amp;#39;, repos=&lt;/span&gt;&lt;span class=&#34;va&#34;&gt;$REPO&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-23&#34;&gt;&lt;a href=&#34;#cb5-23&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; su &lt;span class=&#34;at&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;at&#34;&gt;-c&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;R -e &lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;install.packages(&amp;#39;rmarkdown&amp;#39;, repos=&lt;/span&gt;&lt;span class=&#34;va&#34;&gt;$REPO&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;✏️ It’s necessary to install R packages as sudo for shiny-server to be able to use them, do not install these packages from the R console using your regular user.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now, you can install shiny-server with these commands:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb6&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb6-1&#34;&gt;&lt;a href=&#34;#cb6-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Download the source code for the latest shiny-server release from GitHub&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-2&#34;&gt;&lt;a href=&#34;#cb6-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;git&lt;/span&gt; clone &lt;span class=&#34;at&#34;&gt;--depth&lt;/span&gt; 1 &lt;span class=&#34;at&#34;&gt;--branch&lt;/span&gt; v1.5.23.1030 https://github.com/rstudio/shiny-server.git&lt;/span&gt;
&lt;span id=&#34;cb6-3&#34;&gt;&lt;a href=&#34;#cb6-3&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-4&#34;&gt;&lt;a href=&#34;#cb6-4&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Compile the source code&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-5&#34;&gt;&lt;a href=&#34;#cb6-5&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;bu&#34;&gt;cd&lt;/span&gt; shiny-server&lt;/span&gt;
&lt;span id=&#34;cb6-6&#34;&gt;&lt;a href=&#34;#cb6-6&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;va&#34;&gt;DIR&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;`&lt;/span&gt;&lt;span class=&#34;bu&#34;&gt;pwd&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;`&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-7&#34;&gt;&lt;a href=&#34;#cb6-7&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;va&#34;&gt;PATH&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;va&#34;&gt;$DIR&lt;/span&gt;/bin:&lt;span class=&#34;va&#34;&gt;$PATH&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-8&#34;&gt;&lt;a href=&#34;#cb6-8&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;mkdir&lt;/span&gt; tmp&lt;/span&gt;
&lt;span id=&#34;cb6-9&#34;&gt;&lt;a href=&#34;#cb6-9&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;bu&#34;&gt;cd&lt;/span&gt; tmp&lt;/span&gt;
&lt;span id=&#34;cb6-10&#34;&gt;&lt;a href=&#34;#cb6-10&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;va&#34;&gt;PYTHON&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;`&lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;which&lt;/span&gt; python&lt;span class=&#34;kw&#34;&gt;`&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-11&#34;&gt;&lt;a href=&#34;#cb6-11&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; cmake &lt;span class=&#34;at&#34;&gt;-DCMAKE_INSTALL_PREFIX&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;=&lt;/span&gt;/usr/local &lt;span class=&#34;at&#34;&gt;-DPYTHON&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;va&#34;&gt;$PYTHON&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;&amp;quot;&lt;/span&gt; ../&lt;/span&gt;
&lt;span id=&#34;cb6-12&#34;&gt;&lt;a href=&#34;#cb6-12&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; make&lt;/span&gt;
&lt;span id=&#34;cb6-13&#34;&gt;&lt;a href=&#34;#cb6-13&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;mkdir&lt;/span&gt; ../build&lt;/span&gt;
&lt;span id=&#34;cb6-14&#34;&gt;&lt;a href=&#34;#cb6-14&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-15&#34;&gt;&lt;a href=&#34;#cb6-15&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Install node&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-16&#34;&gt;&lt;a href=&#34;#cb6-16&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bu&#34;&gt;cd&lt;/span&gt; .. &lt;span class=&#34;kw&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; ./external/node/install-node.sh&lt;span class=&#34;kw&#34;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-17&#34;&gt;&lt;a href=&#34;#cb6-17&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;kw&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bu&#34;&gt;cd&lt;/span&gt; .. &lt;span class=&#34;kw&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&#34;ex&#34;&gt;./bin/npm&lt;/span&gt; ci &lt;span class=&#34;at&#34;&gt;--omit-dev&lt;/span&gt; &lt;span class=&#34;at&#34;&gt;--python&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;va&#34;&gt;${PYTHON}&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;)&lt;/span&gt; &lt;/span&gt;
&lt;span id=&#34;cb6-18&#34;&gt;&lt;a href=&#34;#cb6-18&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-19&#34;&gt;&lt;a href=&#34;#cb6-19&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Install shiny-server&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-20&#34;&gt;&lt;a href=&#34;#cb6-20&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; make install&lt;/span&gt;
&lt;span id=&#34;cb6-21&#34;&gt;&lt;a href=&#34;#cb6-21&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-22&#34;&gt;&lt;a href=&#34;#cb6-22&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Configure shiny-server&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-23&#34;&gt;&lt;a href=&#34;#cb6-23&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; mkdir &lt;span class=&#34;at&#34;&gt;-p&lt;/span&gt; /etc/shiny-server&lt;/span&gt;
&lt;span id=&#34;cb6-24&#34;&gt;&lt;a href=&#34;#cb6-24&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; cp ../config/default.config /etc/shiny-server/shiny-server.conf&lt;/span&gt;
&lt;span id=&#34;cb6-25&#34;&gt;&lt;a href=&#34;#cb6-25&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;bu&#34;&gt;cd&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-26&#34;&gt;&lt;a href=&#34;#cb6-26&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; rm &lt;span class=&#34;at&#34;&gt;-rf&lt;/span&gt; shiny-server&lt;/span&gt;
&lt;span id=&#34;cb6-27&#34;&gt;&lt;a href=&#34;#cb6-27&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; ln &lt;span class=&#34;at&#34;&gt;-s&lt;/span&gt; /usr/local/shiny-server/bin/shiny-server /usr/bin/shiny-server&lt;/span&gt;
&lt;span id=&#34;cb6-28&#34;&gt;&lt;a href=&#34;#cb6-28&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; useradd &lt;span class=&#34;at&#34;&gt;-r&lt;/span&gt; &lt;span class=&#34;at&#34;&gt;-m&lt;/span&gt; shiny&lt;/span&gt;
&lt;span id=&#34;cb6-29&#34;&gt;&lt;a href=&#34;#cb6-29&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; mkdir &lt;span class=&#34;at&#34;&gt;-p&lt;/span&gt; /var/log/shiny-server&lt;/span&gt;
&lt;span id=&#34;cb6-30&#34;&gt;&lt;a href=&#34;#cb6-30&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; mkdir &lt;span class=&#34;at&#34;&gt;-p&lt;/span&gt; /srv/shiny-server&lt;/span&gt;
&lt;span id=&#34;cb6-31&#34;&gt;&lt;a href=&#34;#cb6-31&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; mkdir &lt;span class=&#34;at&#34;&gt;-p&lt;/span&gt; /var/lib/shiny-server&lt;/span&gt;
&lt;span id=&#34;cb6-32&#34;&gt;&lt;a href=&#34;#cb6-32&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; chown shiny /var/log/shiny-server&lt;/span&gt;
&lt;span id=&#34;cb6-33&#34;&gt;&lt;a href=&#34;#cb6-33&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-34&#34;&gt;&lt;a href=&#34;#cb6-34&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Edit the shiny-server.service file&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-35&#34;&gt;&lt;a href=&#34;#cb6-35&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; nano /etc/systemd/system/shiny-server.service &lt;/span&gt;
&lt;span id=&#34;cb6-36&#34;&gt;&lt;a href=&#34;#cb6-36&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;co&#34;&gt;# Paste the following content&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-37&#34;&gt;&lt;a href=&#34;#cb6-37&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;/span&gt;
&lt;span id=&#34;cb6-38&#34;&gt;&lt;a href=&#34;#cb6-38&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;ex&#34;&gt;[Unit]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-39&#34;&gt;&lt;a href=&#34;#cb6-39&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;va&#34;&gt;Description&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;=&lt;/span&gt;ShinyServer&lt;/span&gt;
&lt;span id=&#34;cb6-40&#34;&gt;&lt;a href=&#34;#cb6-40&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-41&#34;&gt;&lt;a href=&#34;#cb6-41&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;ex&#34;&gt;[Service]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-42&#34;&gt;&lt;a href=&#34;#cb6-42&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;va&#34;&gt;Type&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;=&lt;/span&gt;simple&lt;/span&gt;
&lt;span id=&#34;cb6-43&#34;&gt;&lt;a href=&#34;#cb6-43&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;va&#34;&gt;ExecStart&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;=&lt;/span&gt;/usr/bin/env &lt;span class=&#34;fu&#34;&gt;bash&lt;/span&gt; &lt;span class=&#34;at&#34;&gt;-c&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;exec /usr/local/shiny-server/bin/shiny-server &amp;gt;&amp;gt;     /var/log/shiny-server.log 2&amp;gt;&amp;amp;1&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-44&#34;&gt;&lt;a href=&#34;#cb6-44&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;va&#34;&gt;KillMode&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;=&lt;/span&gt;process&lt;/span&gt;
&lt;span id=&#34;cb6-45&#34;&gt;&lt;a href=&#34;#cb6-45&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;va&#34;&gt;ExecReload&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;=&lt;/span&gt;/usr/bin/env &lt;span class=&#34;bu&#34;&gt;kill&lt;/span&gt; &lt;span class=&#34;at&#34;&gt;-HUP&lt;/span&gt; &lt;span class=&#34;va&#34;&gt;$MAINPID&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-46&#34;&gt;&lt;a href=&#34;#cb6-46&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;va&#34;&gt;ExecStopPost&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;=&lt;/span&gt;/usr/bin/env &lt;span class=&#34;fu&#34;&gt;sleep&lt;/span&gt; 5&lt;/span&gt;
&lt;span id=&#34;cb6-47&#34;&gt;&lt;a href=&#34;#cb6-47&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;va&#34;&gt;Restart&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;=&lt;/span&gt;on-failure&lt;/span&gt;
&lt;span id=&#34;cb6-48&#34;&gt;&lt;a href=&#34;#cb6-48&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;va&#34;&gt;RestartSec&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;=&lt;/span&gt;1&lt;/span&gt;
&lt;span id=&#34;cb6-49&#34;&gt;&lt;a href=&#34;#cb6-49&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;va&#34;&gt;StartLimitInterval&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;=&lt;/span&gt;45&lt;/span&gt;
&lt;span id=&#34;cb6-50&#34;&gt;&lt;a href=&#34;#cb6-50&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;va&#34;&gt;StartLimitBurst&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;=&lt;/span&gt;3&lt;/span&gt;
&lt;span id=&#34;cb6-51&#34;&gt;&lt;a href=&#34;#cb6-51&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-52&#34;&gt;&lt;a href=&#34;#cb6-52&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;ex&#34;&gt;[Install]&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-53&#34;&gt;&lt;a href=&#34;#cb6-53&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;va&#34;&gt;WantedBy&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;=&lt;/span&gt;multi-user.target&lt;/span&gt;
&lt;span id=&#34;cb6-54&#34;&gt;&lt;a href=&#34;#cb6-54&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-55&#34;&gt;&lt;a href=&#34;#cb6-55&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Edit the shiny-server logrotate file&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-56&#34;&gt;&lt;a href=&#34;#cb6-56&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; nano /etc/logrotate.d/shiny-server &lt;/span&gt;
&lt;span id=&#34;cb6-57&#34;&gt;&lt;a href=&#34;#cb6-57&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;co&#34;&gt;# Paste the following content&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-58&#34;&gt;&lt;a href=&#34;#cb6-58&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;/span&gt;
&lt;span id=&#34;cb6-59&#34;&gt;&lt;a href=&#34;#cb6-59&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;ex&#34;&gt;/var/log/shiny-server.log&lt;/span&gt; {&lt;/span&gt;
&lt;span id=&#34;cb6-60&#34;&gt;&lt;a href=&#34;#cb6-60&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;       &lt;span class=&#34;ex&#34;&gt;rotate&lt;/span&gt; 12&lt;/span&gt;
&lt;span id=&#34;cb6-61&#34;&gt;&lt;a href=&#34;#cb6-61&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;       &lt;span class=&#34;ex&#34;&gt;copytruncate&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-62&#34;&gt;&lt;a href=&#34;#cb6-62&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;       &lt;span class=&#34;ex&#34;&gt;compress&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-63&#34;&gt;&lt;a href=&#34;#cb6-63&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;       &lt;span class=&#34;ex&#34;&gt;missingok&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-64&#34;&gt;&lt;a href=&#34;#cb6-64&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;       &lt;span class=&#34;fu&#34;&gt;size&lt;/span&gt; 1M&lt;/span&gt;
&lt;span id=&#34;cb6-65&#34;&gt;&lt;a href=&#34;#cb6-65&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;er&#34;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-66&#34;&gt;&lt;a href=&#34;#cb6-66&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-67&#34;&gt;&lt;a href=&#34;#cb6-67&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Set permissions for the files&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-68&#34;&gt;&lt;a href=&#34;#cb6-68&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; chown root:root /etc/systemd/system/shiny-server.service&lt;/span&gt;
&lt;span id=&#34;cb6-69&#34;&gt;&lt;a href=&#34;#cb6-69&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; chmod 644 /etc/systemd/system/shiny-server.service&lt;/span&gt;
&lt;span id=&#34;cb6-70&#34;&gt;&lt;a href=&#34;#cb6-70&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; chown root:root /etc/logrotate.d/shiny-server&lt;/span&gt;
&lt;span id=&#34;cb6-71&#34;&gt;&lt;a href=&#34;#cb6-71&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; chmod 644 /etc/logrotate.d/shiny-server&lt;/span&gt;
&lt;span id=&#34;cb6-72&#34;&gt;&lt;a href=&#34;#cb6-72&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-73&#34;&gt;&lt;a href=&#34;#cb6-73&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Start the service&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-74&#34;&gt;&lt;a href=&#34;#cb6-74&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; systemctl daemon-reload&lt;/span&gt;
&lt;span id=&#34;cb6-75&#34;&gt;&lt;a href=&#34;#cb6-75&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; systemctl enable shiny-server&lt;/span&gt;
&lt;span id=&#34;cb6-76&#34;&gt;&lt;a href=&#34;#cb6-76&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; systemctl start shiny-server&lt;/span&gt;
&lt;span id=&#34;cb6-77&#34;&gt;&lt;a href=&#34;#cb6-77&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-78&#34;&gt;&lt;a href=&#34;#cb6-78&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Create symlinks for pandoc and the sample apps&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-79&#34;&gt;&lt;a href=&#34;#cb6-79&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; ln &lt;span class=&#34;at&#34;&gt;-s&lt;/span&gt; &lt;span class=&#34;at&#34;&gt;-f&lt;/span&gt; /usr/bin/pandoc /usr/local/shiny-server/ext/pandoc/pandoc&lt;/span&gt;
&lt;span id=&#34;cb6-80&#34;&gt;&lt;a href=&#34;#cb6-80&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; ln &lt;span class=&#34;at&#34;&gt;-s&lt;/span&gt; &lt;span class=&#34;at&#34;&gt;-f&lt;/span&gt; /usr/bin/pandoc-citeproc-preamble /usr/local/shiny-server/ext/pandoc/pandoc-citeproc&lt;/span&gt;
&lt;span id=&#34;cb6-81&#34;&gt;&lt;a href=&#34;#cb6-81&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; ln &lt;span class=&#34;at&#34;&gt;-s&lt;/span&gt; /usr/local/shiny-server/samples/sample-apps /srv/shiny-server/sample-apps&lt;/span&gt;
&lt;span id=&#34;cb6-82&#34;&gt;&lt;a href=&#34;#cb6-82&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; ln &lt;span class=&#34;at&#34;&gt;-s&lt;/span&gt; /usr/local/shiny-server/samples/welcome.html /srv/shiny-server/index.html&lt;/span&gt;
&lt;span id=&#34;cb6-83&#34;&gt;&lt;a href=&#34;#cb6-83&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-84&#34;&gt;&lt;a href=&#34;#cb6-84&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Set proper user permissions, I&amp;#39;m assuming your user is &amp;quot;pi&amp;quot;, change it if it isn&amp;#39;t&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-85&#34;&gt;&lt;a href=&#34;#cb6-85&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; groupadd shiny-apps&lt;/span&gt;
&lt;span id=&#34;cb6-86&#34;&gt;&lt;a href=&#34;#cb6-86&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; usermod &lt;span class=&#34;at&#34;&gt;-aG&lt;/span&gt; shiny-apps pi&lt;/span&gt;
&lt;span id=&#34;cb6-87&#34;&gt;&lt;a href=&#34;#cb6-87&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; usermod &lt;span class=&#34;at&#34;&gt;-aG&lt;/span&gt; shiny-apps shiny&lt;/span&gt;
&lt;span id=&#34;cb6-88&#34;&gt;&lt;a href=&#34;#cb6-88&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;bu&#34;&gt;cd&lt;/span&gt; /srv/shiny-server&lt;/span&gt;
&lt;span id=&#34;cb6-89&#34;&gt;&lt;a href=&#34;#cb6-89&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; chown &lt;span class=&#34;at&#34;&gt;-R&lt;/span&gt; pi:shiny-apps .&lt;/span&gt;
&lt;span id=&#34;cb6-90&#34;&gt;&lt;a href=&#34;#cb6-90&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; chmod g+w .&lt;/span&gt;
&lt;span id=&#34;cb6-91&#34;&gt;&lt;a href=&#34;#cb6-91&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; chmod g+s .&lt;/span&gt;
&lt;span id=&#34;cb6-92&#34;&gt;&lt;a href=&#34;#cb6-92&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;bu&#34;&gt;cd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&#34;install-rstudio-server&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Install Rstudio Server&lt;/h2&gt;
&lt;p&gt;In the past, the only way to install RStudio Server on a Pi was to compile from source and this was extremely time-consuming (took me 3 days the last time I tried on a Pi 3B+) and very prone to failure because the RStudio IDE was under active development.&lt;/p&gt;
&lt;p&gt;Luckily, since then, RStudio has made available “experimental” builds of the IDE for arm64 (I wrote an &lt;a href=&#34;https://andresrcs.rbind.io/2022/08/22/rstudio_ide_arm/&#34;&gt;article about it&lt;/a&gt;), they are compiled for Ubuntu 22, 24 LTS, RedHat 9 and 10. The Ubuntu 22 and 24 binaries are compatible with Raspberry Pi OS as well. You can check the available daily builds &lt;a href=&#34;https://dailies.rstudio.com/rstudio/&#34;&gt;here&lt;/a&gt;. Choose a link accordingly to the operating system you are using, also, have in mind that these builds are meant for testing so they are likely to have bugs or be unstable, if you have problems installing the latest one available, try with an older version.&lt;/p&gt;
&lt;p&gt;The following instructions use a link for Ubuntu 24 (Raspberry Pi OS compatible), remember to change the link if you want to use another OS or a more recent IDE version:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb7&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb7-1&#34;&gt;&lt;a href=&#34;#cb7-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; apt install gdebi&lt;/span&gt;
&lt;span id=&#34;cb7-2&#34;&gt;&lt;a href=&#34;#cb7-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;wget&lt;/span&gt; https://s3.amazonaws.com/rstudio-ide-build/server/jammy/arm64/rstudio-server-2026.01.0-392-arm64.deb&lt;/span&gt;
&lt;span id=&#34;cb7-3&#34;&gt;&lt;a href=&#34;#cb7-3&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; gdebi rstudio-server-2026.01.0-392-arm64.deb&lt;/span&gt;
&lt;span id=&#34;cb7-4&#34;&gt;&lt;a href=&#34;#cb7-4&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; rm rstudio-server-2026.01.0-392-arm64.deb&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;✏️ I’ll update this section once the arm64 support becomes a stable feature for the RStudio IDE.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div id=&#34;install-additional-support-services-optional&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Install Additional Support Services (optional)&lt;/h2&gt;
&lt;p&gt;Nginx is a low-requirements web server, which comes in handy to self-host HTML files but also to use as a reverse proxy (more about this in the next section). You can install it with this command:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb8&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb8-1&#34;&gt;&lt;a href=&#34;#cb8-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; apt install nginx&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Also, for working with “bigger than memory” data sets (have in mind that the Pi doesn’t have much RAM), having an RDBMS comes in handy. I personally prefer PostgreSQL since it’s open-source and has impressive capabilities, you can install PostgreSQL with this command:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb9&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb9-1&#34;&gt;&lt;a href=&#34;#cb9-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; apt install postgresql libpq-dev postgresql-client postgresql-client-common&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&#34;extra-steps-optional&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Extra Steps (optional)&lt;/h2&gt;
&lt;p&gt;Make pretty URLs for Shiny and Rstudio Server (e.g. &lt;code&gt;http://your-ip/shiny/your-app&lt;/code&gt; instead of &lt;code&gt;http://your-ip:3838/your-app&lt;/code&gt;) by using Nginx as a reverse proxy, you only need to replace the content of this file &lt;code&gt;sudo nano /etc/nginx/sites-enabled/default&lt;/code&gt;, with this:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb10&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb10-1&#34;&gt;&lt;a href=&#34;#cb10-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;map&lt;/span&gt; &lt;span class=&#34;va&#34;&gt;$http_upgrade&lt;/span&gt; &lt;span class=&#34;va&#34;&gt;$connection_upgrade&lt;/span&gt; {&lt;/span&gt;
&lt;span id=&#34;cb10-2&#34;&gt;&lt;a href=&#34;#cb10-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;ex&#34;&gt;default&lt;/span&gt; upgrade&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb10-3&#34;&gt;&lt;a href=&#34;#cb10-3&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;st&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;      close&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb10-4&#34;&gt;&lt;a href=&#34;#cb10-4&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;er&#34;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb10-5&#34;&gt;&lt;a href=&#34;#cb10-5&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb10-6&#34;&gt;&lt;a href=&#34;#cb10-6&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;server&lt;/span&gt; {&lt;/span&gt;
&lt;span id=&#34;cb10-7&#34;&gt;&lt;a href=&#34;#cb10-7&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;ex&#34;&gt;listen&lt;/span&gt; 80 default_server&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb10-8&#34;&gt;&lt;a href=&#34;#cb10-8&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;ex&#34;&gt;listen&lt;/span&gt; &lt;span class=&#34;pp&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;pp&#34;&gt;]&lt;/span&gt;:80 default_server&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb10-9&#34;&gt;&lt;a href=&#34;#cb10-9&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;/span&gt;
&lt;span id=&#34;cb10-10&#34;&gt;&lt;a href=&#34;#cb10-10&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;ex&#34;&gt;root&lt;/span&gt; /var/www/html&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb10-11&#34;&gt;&lt;a href=&#34;#cb10-11&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;/span&gt;
&lt;span id=&#34;cb10-12&#34;&gt;&lt;a href=&#34;#cb10-12&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;ex&#34;&gt;index&lt;/span&gt; index.html index.htm&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb10-13&#34;&gt;&lt;a href=&#34;#cb10-13&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;/span&gt;
&lt;span id=&#34;cb10-14&#34;&gt;&lt;a href=&#34;#cb10-14&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;ex&#34;&gt;server_name&lt;/span&gt; _&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb10-15&#34;&gt;&lt;a href=&#34;#cb10-15&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;/span&gt;
&lt;span id=&#34;cb10-16&#34;&gt;&lt;a href=&#34;#cb10-16&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;ex&#34;&gt;location&lt;/span&gt; / {&lt;/span&gt;
&lt;span id=&#34;cb10-17&#34;&gt;&lt;a href=&#34;#cb10-17&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;try_files&lt;/span&gt; &lt;span class=&#34;va&#34;&gt;$uri&lt;/span&gt; &lt;span class=&#34;va&#34;&gt;$uri&lt;/span&gt;/ =404&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb10-18&#34;&gt;&lt;a href=&#34;#cb10-18&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;er&#34;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb10-19&#34;&gt;&lt;a href=&#34;#cb10-19&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;/span&gt;
&lt;span id=&#34;cb10-20&#34;&gt;&lt;a href=&#34;#cb10-20&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;ex&#34;&gt;rewrite&lt;/span&gt; ^/shiny$ &lt;span class=&#34;va&#34;&gt;$scheme&lt;/span&gt;://&lt;span class=&#34;va&#34;&gt;$http_host&lt;/span&gt;/shiny/ permanent&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb10-21&#34;&gt;&lt;a href=&#34;#cb10-21&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;/span&gt;
&lt;span id=&#34;cb10-22&#34;&gt;&lt;a href=&#34;#cb10-22&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;ex&#34;&gt;location&lt;/span&gt; /shiny/ {&lt;/span&gt;
&lt;span id=&#34;cb10-23&#34;&gt;&lt;a href=&#34;#cb10-23&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;rewrite&lt;/span&gt; ^/shiny/&lt;span class=&#34;er&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bu&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;pp&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;ex&#34;&gt;$&lt;/span&gt; /&lt;span class=&#34;va&#34;&gt;$1&lt;/span&gt; break&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb10-24&#34;&gt;&lt;a href=&#34;#cb10-24&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;proxy_set_header&lt;/span&gt;    Host &lt;span class=&#34;va&#34;&gt;$host&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb10-25&#34;&gt;&lt;a href=&#34;#cb10-25&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;proxy_set_header&lt;/span&gt;    X-Real-IP &lt;span class=&#34;va&#34;&gt;$remote_addr&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb10-26&#34;&gt;&lt;a href=&#34;#cb10-26&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;proxy_set_header&lt;/span&gt;    X-Forwarded-For &lt;span class=&#34;va&#34;&gt;$proxy_add_x_forwarded_for&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb10-27&#34;&gt;&lt;a href=&#34;#cb10-27&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;proxy_set_header&lt;/span&gt;    X-Forwarded-Proto &lt;span class=&#34;va&#34;&gt;$scheme&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb10-28&#34;&gt;&lt;a href=&#34;#cb10-28&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;proxy_pass&lt;/span&gt;          http://localhost:3838&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb10-29&#34;&gt;&lt;a href=&#34;#cb10-29&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;proxy_read_timeout&lt;/span&gt;  20d&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb10-30&#34;&gt;&lt;a href=&#34;#cb10-30&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;proxy_buffering&lt;/span&gt; off&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb10-31&#34;&gt;&lt;a href=&#34;#cb10-31&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;/span&gt;
&lt;span id=&#34;cb10-32&#34;&gt;&lt;a href=&#34;#cb10-32&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;proxy_set_header&lt;/span&gt; Upgrade &lt;span class=&#34;va&#34;&gt;$http_upgrade&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb10-33&#34;&gt;&lt;a href=&#34;#cb10-33&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;proxy_set_header&lt;/span&gt; Connection &lt;span class=&#34;va&#34;&gt;$connection_upgrade&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb10-34&#34;&gt;&lt;a href=&#34;#cb10-34&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;proxy_http_version&lt;/span&gt; 1.1&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb10-35&#34;&gt;&lt;a href=&#34;#cb10-35&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;/span&gt;
&lt;span id=&#34;cb10-36&#34;&gt;&lt;a href=&#34;#cb10-36&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;proxy_redirect&lt;/span&gt;      / &lt;span class=&#34;va&#34;&gt;$scheme&lt;/span&gt;://&lt;span class=&#34;va&#34;&gt;$host&lt;/span&gt;/shiny/&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb10-37&#34;&gt;&lt;a href=&#34;#cb10-37&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;er&#34;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb10-38&#34;&gt;&lt;a href=&#34;#cb10-38&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;/span&gt;
&lt;span id=&#34;cb10-39&#34;&gt;&lt;a href=&#34;#cb10-39&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;ex&#34;&gt;location&lt;/span&gt; /rstudio/ {&lt;/span&gt;
&lt;span id=&#34;cb10-40&#34;&gt;&lt;a href=&#34;#cb10-40&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;rewrite&lt;/span&gt; ^/rstudio/&lt;span class=&#34;er&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bu&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;pp&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;ex&#34;&gt;$&lt;/span&gt; /&lt;span class=&#34;va&#34;&gt;$1&lt;/span&gt; break&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb10-41&#34;&gt;&lt;a href=&#34;#cb10-41&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;/span&gt;
&lt;span id=&#34;cb10-42&#34;&gt;&lt;a href=&#34;#cb10-42&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;proxy_pass&lt;/span&gt; http://localhost:8787&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb10-43&#34;&gt;&lt;a href=&#34;#cb10-43&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;/span&gt;
&lt;span id=&#34;cb10-44&#34;&gt;&lt;a href=&#34;#cb10-44&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;proxy_http_version&lt;/span&gt; 1.1&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb10-45&#34;&gt;&lt;a href=&#34;#cb10-45&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;proxy_set_header&lt;/span&gt; Upgrade &lt;span class=&#34;va&#34;&gt;$http_upgrade&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb10-46&#34;&gt;&lt;a href=&#34;#cb10-46&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;proxy_set_header&lt;/span&gt; Connection &lt;span class=&#34;va&#34;&gt;$connection_upgrade&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb10-47&#34;&gt;&lt;a href=&#34;#cb10-47&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;proxy_read_timeout&lt;/span&gt; 20d&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb10-48&#34;&gt;&lt;a href=&#34;#cb10-48&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;proxy_buffering&lt;/span&gt; off&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb10-49&#34;&gt;&lt;a href=&#34;#cb10-49&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;/span&gt;
&lt;span id=&#34;cb10-50&#34;&gt;&lt;a href=&#34;#cb10-50&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;proxy_set_header&lt;/span&gt; X-RStudio-Root-Path /rstudio&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb10-51&#34;&gt;&lt;a href=&#34;#cb10-51&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;/span&gt;
&lt;span id=&#34;cb10-52&#34;&gt;&lt;a href=&#34;#cb10-52&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;proxy_set_header&lt;/span&gt; Host &lt;span class=&#34;va&#34;&gt;$host&lt;/span&gt;:&lt;span class=&#34;va&#34;&gt;$server_port&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb10-53&#34;&gt;&lt;a href=&#34;#cb10-53&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;er&#34;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb10-54&#34;&gt;&lt;a href=&#34;#cb10-54&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;er&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;On Raspberry Pi OS there is a weird issue where Nginx starts before RStudio Server is able to start, and the reverse proxy fails. A walk-around for this is to edit this file, &lt;code&gt;sudo nano /etc/systemd/system/multi-user.target.wants/nginx.service&lt;/code&gt;, and replace the part that says &lt;code&gt;After=network.target&lt;/code&gt; with &lt;code&gt;After=network-online.target&lt;/code&gt; and reload the daemon with &lt;code&gt;sudo systemctl daemon-reload&lt;/code&gt;. You can omit this if you are using Ubuntu.&lt;/p&gt;
&lt;p&gt;Now you have to restart Nginx to apply the changes:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb11&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb11-1&#34;&gt;&lt;a href=&#34;#cb11-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; systemctl restart nginx&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you want to have access to your server from remote origins (over the internet) you must follow these extra steps:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If you don’t have a static public IP:
&lt;ul&gt;
&lt;li&gt;Open an account in a Dynamic DNS Service (e.g. &lt;a href=&#34;https://www.noip.com&#34; class=&#34;uri&#34;&gt;https://www.noip.com&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Configure Dynamic DNS in your router/modem, if you don’t have that option, you can install a DDNS client on your server.&lt;/li&gt;
&lt;li&gt;Optionally configure your personal domain name to point to your DDNS service&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;If you have a public IPv4, configure port forwarding in your router/modem:
&lt;ul&gt;
&lt;li&gt;For SSH, SCP and SFPT open port TCP/UDP 22&lt;/li&gt;
&lt;li&gt;If you haven’t configured Nginx, open port 8787 for RStudio.&lt;/li&gt;
&lt;li&gt;If you haven’t configured Nginx, open port 3838 for Shiny server.&lt;/li&gt;
&lt;li&gt;For HTTP open port TCP 80 (also for using Nginx as a reverse proxy).&lt;/li&gt;
&lt;li&gt;For PostgreSQL open port TCP/UDP 5432&lt;/li&gt;
&lt;li&gt;Make sure you have “Block WAN traffic” disabled on your router/modem.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you are interested, I have an &lt;a href=&#34;https://andresrcs.rbind.io/2021/08/16/port_forwarding/&#34;&gt;article&lt;/a&gt; that provides an example on how to configure port forwarding at home.&lt;/p&gt;
&lt;/div&gt;
&lt;div id=&#34;final-comments&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Final Comments&lt;/h2&gt;
&lt;p&gt;Arm64 support in general is increasing rapidly, so very likely things are going to change in the near future. I’m going to try my best to keep this article up to date with the latest developments so you can leverage the benefits.&lt;/p&gt;
&lt;p&gt;Performance is relatively poor, especially for plotting, but usable. Keep in mind that even though the Raspberry Pi has 4 cores they are not fast ones and most of the R packages don’t use parallel computing.&lt;/p&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Take the RStudio IDE experimental support for arm64 architectures out for a spin</title>
      <link>https://andresrcs.rbind.io/2022/08/22/rstudio_ide_arm/</link>
      <pubDate>Mon, 22 Aug 2022 00:00:00 +0000</pubDate>
      
      <guid>https://andresrcs.rbind.io/2022/08/22/rstudio_ide_arm/</guid>
      <description>
&lt;style type=&#34;text/css&#34;&gt;
pre &gt; code.sourceCode { white-space: pre; position: relative; }
pre &gt; code.sourceCode &gt; span { line-height: 1.25; }
pre &gt; code.sourceCode &gt; span:empty { height: 1.2em; }
.sourceCode { overflow: visible; }
code.sourceCode &gt; span { color: inherit; text-decoration: inherit; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
pre &gt; code.sourceCode { white-space: pre-wrap; }
pre &gt; code.sourceCode &gt; span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
  { counter-reset: source-line 0; }
pre.numberSource code &gt; span
  { position: relative; left: -4em; counter-increment: source-line; }
pre.numberSource code &gt; span &gt; a:first-child::before
  { content: counter(source-line);
    position: relative; left: -1em; text-align: right; vertical-align: baseline;
    border: none; display: inline-block;
    -webkit-touch-callout: none; -webkit-user-select: none;
    -khtml-user-select: none; -moz-user-select: none;
    -ms-user-select: none; user-select: none;
    padding: 0 4px; width: 4em;
  }
pre.numberSource { margin-left: 3em;  padding-left: 4px; }
div.sourceCode
  { color: #cccccc; background-color: #303030; }
@media screen {
pre &gt; code.sourceCode &gt; span &gt; a:first-child::before { text-decoration: underline; }
}
code span.al { color: #ffcfaf; } /* Alert */
code span.an { color: #7f9f7f; font-weight: bold; } /* Annotation */
code span.at { } /* Attribute */
code span.bn { color: #dca3a3; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #f0dfaf; } /* ControlFlow */
code span.ch { color: #dca3a3; } /* Char */
code span.cn { color: #dca3a3; font-weight: bold; } /* Constant */
code span.co { color: #7f9f7f; } /* Comment */
code span.cv { color: #7f9f7f; font-weight: bold; } /* CommentVar */
code span.do { color: #7f9f7f; } /* Documentation */
code span.dt { color: #dfdfbf; } /* DataType */
code span.dv { color: #dcdccc; } /* DecVal */
code span.er { color: #c3bf9f; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #c0bed1; } /* Float */
code span.fu { color: #efef8f; } /* Function */
code span.im { } /* Import */
code span.in { color: #7f9f7f; font-weight: bold; } /* Information */
code span.kw { color: #f0dfaf; } /* Keyword */
code span.op { color: #f0efd0; } /* Operator */
code span.ot { color: #efef8f; } /* Other */
code span.pp { color: #ffcfaf; font-weight: bold; } /* Preprocessor */
code span.sc { color: #dca3a3; } /* SpecialChar */
code span.ss { color: #cc9393; } /* SpecialString */
code span.st { color: #cc9393; } /* String */
code span.va { } /* Variable */
code span.vs { color: #cc9393; } /* VerbatimString */
code span.wa { color: #7f9f7f; font-weight: bold; } /* Warning */
&lt;/style&gt;

&lt;div id=&#34;TOC&#34;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#basic-set-up-and-dependencies&#34; id=&#34;toc-basic-set-up-and-dependencies&#34;&gt;Basic Set Up and Dependencies&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#installing-the-rstudio-ide&#34; id=&#34;toc-installing-the-rstudio-ide&#34;&gt;Installing the RStudio IDE&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#final-comments&#34; id=&#34;toc-final-comments&#34;&gt;Final Comments&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;

&lt;p&gt;Apple’s bet on the arm architecture with their M1 and M2 processors has had an interesting side effect, developers of mainstream software are now forced to support the arm64 architecture and, since they are already supporting macOS for Apple Silicon processors anyways, supporting Linux arm64 distributions is no longer that much of a burden for them. The RStudio IDE development team is not strange to this circumstance and they have been working on general arm64 support, currently, they have made available experimental builds for the arm64 architecture (also known as aarch64) compiled for Ubuntu 20/22 LTS (the Ubuntu 22 build being compatible with the latest Raspberry Pi OS x64 based on Bookworm) and RedHat 9. I have decided to give them a try on my Raspberry Pi SBC, if you are interested, join me in the installation process.&lt;/p&gt;
&lt;div id=&#34;basic-set-up-and-dependencies&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Basic Set Up and Dependencies&lt;/h2&gt;
&lt;p&gt;The first thing you need is a Raspberry Pi (3/4/5) with the lastest Raspberry Pi x64 OS (Debian 12 based) or Ubuntu 20/22 LTS x64 installed and updated (or any other Linux arm64 system running a supported OS), make sure to update your system libraries before you start:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb1&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb1-1&#34;&gt;&lt;a href=&#34;#cb1-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; apt update&lt;/span&gt;
&lt;span id=&#34;cb1-2&#34;&gt;&lt;a href=&#34;#cb1-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; apt dist-upgrade&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then, the most important dependency for RStudio is, unsurprisingly, the R language. You have some options for installing R on arm systems, each one with its own pros and cons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Install from the Operating System’s repositories&lt;/li&gt;
&lt;li&gt;Compile R from source&lt;/li&gt;
&lt;li&gt;Install R using rig&lt;/li&gt;
&lt;li&gt;Install R from the R4Pi Project&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Since there are several options now I have moved this section to a separate article that you can consult &lt;a href=&#34;https://andresrcs.rbind.io/2023/02/11/r_on_arm/&#34;&gt;here&lt;/a&gt; for more details.&lt;/p&gt;
&lt;p&gt;In all cases, I strongly recommend using the &lt;a href=&#34;https://r4pi.org/&#34;&gt;R4Pi&lt;/a&gt; package repository as your R packages source since it provides precompiled binaries that make installation easier and faster.&lt;/p&gt;
&lt;p&gt;The latest experimental RStudio IDE builds (&amp;gt;= 2023.08.0 builds) for arm64 now come with Quarto and Pandoc bundled so there is no longer the need to install them separately and Quarto integration features are now fully supported on arm64 systems, although, if you want a newer version of any of these software you can download the corresponding &lt;code&gt;.deb&lt;/code&gt; file and install it using the &lt;code&gt;dpkg&lt;/code&gt; command.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You can download the latest Pandoc installer from here: &lt;a href=&#34;https://github.com/jgm/pandoc/releases/&#34; class=&#34;uri&#34;&gt;https://github.com/jgm/pandoc/releases/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;And the latest Quarto installer from here: &lt;a href=&#34;https://github.com/quarto-dev/quarto-cli/releases&#34; class=&#34;uri&#34;&gt;https://github.com/quarto-dev/quarto-cli/releases&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And the installation command would be something like this:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb2&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb2-1&#34;&gt;&lt;a href=&#34;#cb2-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; dpkg &lt;span class=&#34;at&#34;&gt;-i&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;&amp;lt;&amp;lt;file_name.deb&amp;gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Lastly, for installing the RStudio IDE deb file, as you would do on an x86_64 system, you might want to install &lt;code&gt;gdebi&lt;/code&gt; to handle package dependencies for you:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb3&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb3-1&#34;&gt;&lt;a href=&#34;#cb3-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; apt install gdebi&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&#34;installing-the-rstudio-ide&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Installing the RStudio IDE&lt;/h2&gt;
&lt;p&gt;Now we get to the point. There is no stable release of the RStudio IDE for arm64 but there are experimental daily builds available &lt;a href=&#34;https://dailies.rstudio.com/rstudio/&#34;&gt;here&lt;/a&gt;, both for the server and desktop versions and compiled for Ubuntu 20/22 LTS and RedHat9. I’m going to try out the server version for Ubuntu 22 because it is compatible with Raspberry Pi OS x64 and I prefer to work with the IDE on my regular computer instead of directly on the Raspberry Pi, but you can install the desktop version the same way if you prefer, just change the link accordingly.&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb4&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb4-1&#34;&gt;&lt;a href=&#34;#cb4-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;wget&lt;/span&gt; https://s3.amazonaws.com/rstudio-ide-build/server/jammy/arm64/rstudio-server-2023.12.0-daily-232-arm64.deb&lt;/span&gt;
&lt;span id=&#34;cb4-2&#34;&gt;&lt;a href=&#34;#cb4-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; gdebi rstudio-server-2023.12.0-daily-232-arm64.deb&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Once the installation process is completed, you get a working RStudio IDE installation running on your Raspberry Pi, if you have chosen to install the server version as I did, you can open an RStudio session by opening a browser on any device in your network and typing the proper address i.e. &lt;code&gt;http:\\your_pi_ip_addres:8787&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://andresrcs.rbind.io/post/2022-08-20-rstudio_ide_arm.en_files/rstudio_ide.jpg&#34; width=&#34;800&#34; height=&#34;400&#34; /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div id=&#34;final-comments&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Final Comments&lt;/h2&gt;
&lt;p&gt;Have in mind that these are experimental builds of the development version of the RStudio IDE and they are likely to be unstable and buggy so do not trust this for any sort of critical job. You can follow along with the progress on this &lt;a href=&#34;https://github.com/rstudio/rstudio/issues/8809&#34;&gt;GitHub issue&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Performance on the Raspberry Pi is acceptable, within reason for under-powered systems like these SBCs, but it is pretty far from the performance you would get on more powerful systems like Apple Silicon or full-size arm64 computers if you have access to one of those (tested on an Ampere VM and works great). If you want to get the most performance out of your Pi, use Raspberry Pi OS Lite since it’s the lightest option.&lt;/p&gt;
&lt;p&gt;I hope you found this article useful, I will be updating the content as things develop.&lt;/p&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>How to make your home Shiny or Rstudio Server accessible from the public internet</title>
      <link>https://andresrcs.rbind.io/2021/08/16/port_forwarding/</link>
      <pubDate>Mon, 16 Aug 2021 00:00:00 +0000</pubDate>
      
      <guid>https://andresrcs.rbind.io/2021/08/16/port_forwarding/</guid>
      <description>
&lt;style type=&#34;text/css&#34;&gt;
pre &gt; code.sourceCode { white-space: pre; position: relative; }
pre &gt; code.sourceCode &gt; span { display: inline-block; line-height: 1.25; }
pre &gt; code.sourceCode &gt; span:empty { height: 1.2em; }
.sourceCode { overflow: visible; }
code.sourceCode &gt; span { color: inherit; text-decoration: inherit; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
pre &gt; code.sourceCode { white-space: pre-wrap; }
pre &gt; code.sourceCode &gt; span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
  { counter-reset: source-line 0; }
pre.numberSource code &gt; span
  { position: relative; left: -4em; counter-increment: source-line; }
pre.numberSource code &gt; span &gt; a:first-child::before
  { content: counter(source-line);
    position: relative; left: -1em; text-align: right; vertical-align: baseline;
    border: none; display: inline-block;
    -webkit-touch-callout: none; -webkit-user-select: none;
    -khtml-user-select: none; -moz-user-select: none;
    -ms-user-select: none; user-select: none;
    padding: 0 4px; width: 4em;
  }
pre.numberSource { margin-left: 3em;  padding-left: 4px; }
div.sourceCode
  { color: #cccccc; background-color: #303030; }
@media screen {
pre &gt; code.sourceCode &gt; span &gt; a:first-child::before { text-decoration: underline; }
}
code span.al { color: #ffcfaf; } /* Alert */
code span.an { color: #7f9f7f; font-weight: bold; } /* Annotation */
code span.at { } /* Attribute */
code span.bn { color: #dca3a3; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #f0dfaf; } /* ControlFlow */
code span.ch { color: #dca3a3; } /* Char */
code span.cn { color: #dca3a3; font-weight: bold; } /* Constant */
code span.co { color: #7f9f7f; } /* Comment */
code span.cv { color: #7f9f7f; font-weight: bold; } /* CommentVar */
code span.do { color: #7f9f7f; } /* Documentation */
code span.dt { color: #dfdfbf; } /* DataType */
code span.dv { color: #dcdccc; } /* DecVal */
code span.er { color: #c3bf9f; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #c0bed1; } /* Float */
code span.fu { color: #efef8f; } /* Function */
code span.im { } /* Import */
code span.in { color: #7f9f7f; font-weight: bold; } /* Information */
code span.kw { color: #f0dfaf; } /* Keyword */
code span.op { color: #f0efd0; } /* Operator */
code span.ot { color: #efef8f; } /* Other */
code span.pp { color: #ffcfaf; font-weight: bold; } /* Preprocessor */
code span.sc { color: #dca3a3; } /* SpecialChar */
code span.ss { color: #cc9393; } /* SpecialString */
code span.st { color: #cc9393; } /* String */
code span.va { } /* Variable */
code span.vs { color: #cc9393; } /* VerbatimString */
code span.wa { color: #7f9f7f; font-weight: bold; } /* Warning */
&lt;/style&gt;

&lt;div id=&#34;TOC&#34;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#prerequisites&#34; id=&#34;toc-prerequisites&#34;&gt;Prerequisites&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#open-the-required-ports-in-the-server&#34; id=&#34;toc-open-the-required-ports-in-the-server&#34;&gt;Open the Required Ports in the Server&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#configure-port-forwarding-in-your-router&#34; id=&#34;toc-configure-port-forwarding-in-your-router&#34;&gt;Configure Port Forwarding in your Router&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#optional-extra-steps&#34; id=&#34;toc-optional-extra-steps&#34;&gt;Optional Extra Steps&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#setup-a-dynamic-dns-service-ddns&#34; id=&#34;toc-setup-a-dynamic-dns-service-ddns&#34;&gt;Setup a Dynamic DNS Service (DDNS)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#configure-a-reverse-proxy&#34; id=&#34;toc-configure-a-reverse-proxy&#34;&gt;Configure a Reverse Proxy&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ Some assembly required! This project is going to require you to investigate the specifics of your network equipment on your own.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You have installed Shiny and/or RStudio server in your home computer and it works great as long as you are connected to your local network, however, you can’t access it from other locations, What can you do?&lt;/p&gt;
&lt;p&gt;The solution is to expose your server to the public internet by forwarding incoming traffic to the corresponding port in your server. Now, I’m not going to lie to you telling you that this article is going to give you detailed instructions on how to do it with your specific router because it would be virtually impossible, each router brand (an even model) has a different management interface, I can only give you the required steps along with an example using the router I have at home, although, generally speaking, the procedure involves the same steps regardless of the specific router model you have, so with a little effort on your part you should be able to figure out how to make it work with your own router.&lt;/p&gt;
&lt;div id=&#34;prerequisites&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Prerequisites&lt;/h2&gt;
&lt;ol style=&#34;list-style-type: decimal&#34;&gt;
&lt;li&gt;&lt;p&gt;I’m writing this article under the assumption that you already have Shiny and/or RStudio server properly installed on a computer at home (if you haven’t, you can check out the other articles in my blog for inspiration).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You need to have a public IP assigned to your router (it doesn’t matter if it changes dynamically), not everybody has one since some Internet Service Providers (ISPs) use a NAT3 configuration, which basically means that you share a public IP with a group of their clients and there will be no means to map an HTTP request to your home server, however, it is possible that you can get your NAT configuration changed if you call your ISP and request for a public IP so you might want to give it a try.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You need to know the user and password to access your router’s configuration interface, some ISPs let it as default and you only need to google the default password for your router’s model, but in most cases, they change it so you would need to give them a call and ask for your credentials.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div id=&#34;open-the-required-ports-in-the-server&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Open the Required Ports in the Server&lt;/h2&gt;
&lt;p&gt;Specific ports for Shiny and/or RStudio server need to be accessible in your server to be able to connect to those services. Most Linux distributions come with all ports accessible by default but it is a common (and good) practice to install a firewall to restrict access to your server, if this is your case, you need to make sure that you have the required ports open.&lt;/p&gt;
&lt;p&gt;For Shiny server the default port is 3838 and for RStudio server it is 8787 (this can be customized). If you have configured a reverse proxy with &lt;code&gt;Nginx&lt;/code&gt; or &lt;code&gt;Apache&lt;/code&gt; you can obviate those ports and only open port &lt;code&gt;80&lt;/code&gt; for HTTP or port &lt;code&gt;443&lt;/code&gt; for HTTPS. For example, the command to allow incoming traffic on port 80 using the &lt;code&gt;ufw&lt;/code&gt; firewall in Ubuntu-based systems would be like this:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb1&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb1-1&#34;&gt;&lt;a href=&#34;#cb1-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; ufw allow 80/tcp&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And using &lt;code&gt;firewalld&lt;/code&gt; in RHEL-based systems would be:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb2&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb2-1&#34;&gt;&lt;a href=&#34;#cb2-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; firewall-cmd &lt;span class=&#34;at&#34;&gt;--permanent&lt;/span&gt; &lt;span class=&#34;at&#34;&gt;--zone&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;=&lt;/span&gt;public &lt;span class=&#34;at&#34;&gt;--add-port&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;=&lt;/span&gt;80/tcp&lt;/span&gt;
&lt;span id=&#34;cb2-2&#34;&gt;&lt;a href=&#34;#cb2-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; firewall-cmd &lt;span class=&#34;at&#34;&gt;--reload&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You could have other rules that could prevent traffic from going into your server from remote locations so you might want to inspect your firewall rules and look for anything restricting incoming traffic.&lt;/p&gt;
&lt;/div&gt;
&lt;div id=&#34;configure-port-forwarding-in-your-router&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Configure Port Forwarding in your Router&lt;/h2&gt;
&lt;p&gt;Open a web browser on a device that is connected to your local network and type your router’s local IP, usually, it is something like &lt;code&gt;192.168.0.1&lt;/code&gt; or &lt;code&gt;192.168.1.1&lt;/code&gt;. All routers have a web server running on port 80 by default so by typing their IP it would open a web page with the configuration interface.&lt;/p&gt;
&lt;p&gt;In my particular case, I’m steel using a cheap Sagemcom HFC modem my ISP gave me (because I’m always going to set up my custom &lt;code&gt;pfSense&lt;/code&gt; router very soon), so if I open a Chrome browser and type &lt;code&gt;192.168.0.1&lt;/code&gt; this is what I get.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://andresrcs.rbind.io/post/2021-08-16-port-forwarding.en_files/login.jpg&#34; width=&#34;800&#34; height=&#34;400&#34; /&gt;
In your case, the user interface would look different and options might have slightly different names but they are basically the same.&lt;/p&gt;
&lt;p&gt;Enter your credentials to get access to the configuration interface, which in my case looks like this.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://andresrcs.rbind.io/post/2021-08-16-port-forwarding.en_files/console.jpg&#34; width=&#34;800&#34; height=&#34;400&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Then, search among all the available tabs to find the “port forwarding” section, it is not going to be in the same place for you but most modern routers have this section.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://andresrcs.rbind.io/post/2021-08-16-port-forwarding.en_files/forwarding.jpg&#34; width=&#34;800&#34; height=&#34;400&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Once in there add forwarding rules for Shiny and/or Rstudio server (You have to replace “your_sever_ip” with your actual server’s local IP) and apply changes.&lt;/p&gt;
&lt;table&gt;
&lt;colgroup&gt;
&lt;col width=&#34;19%&#34; /&gt;
&lt;col width=&#34;14%&#34; /&gt;
&lt;col width=&#34;11%&#34; /&gt;
&lt;col width=&#34;23%&#34; /&gt;
&lt;col width=&#34;11%&#34; /&gt;
&lt;col width=&#34;19%&#34; /&gt;
&lt;/colgroup&gt;
&lt;thead&gt;
&lt;tr class=&#34;header&#34;&gt;
&lt;th align=&#34;left&#34;&gt;Local Address&lt;/th&gt;
&lt;th align=&#34;left&#34;&gt;Start Port&lt;/th&gt;
&lt;th align=&#34;left&#34;&gt;End Port&lt;/th&gt;
&lt;th align=&#34;left&#34;&gt;External Address&lt;/th&gt;
&lt;th align=&#34;left&#34;&gt;Protocol&lt;/th&gt;
&lt;th align=&#34;left&#34;&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class=&#34;odd&#34;&gt;
&lt;td align=&#34;left&#34;&gt;your_sever_ip&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;3838&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;3838&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;0.0.0.0&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;TCP&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;Shiny-Server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&#34;even&#34;&gt;
&lt;td align=&#34;left&#34;&gt;your_sever_ip&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;8787&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;8787&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;0.0.0.0&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;TCP&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;RStudio-Server&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;If you are using a reverse proxy, you only need to make sure you have one of these.&lt;/p&gt;
&lt;table&gt;
&lt;colgroup&gt;
&lt;col width=&#34;19%&#34; /&gt;
&lt;col width=&#34;14%&#34; /&gt;
&lt;col width=&#34;11%&#34; /&gt;
&lt;col width=&#34;23%&#34; /&gt;
&lt;col width=&#34;11%&#34; /&gt;
&lt;col width=&#34;19%&#34; /&gt;
&lt;/colgroup&gt;
&lt;thead&gt;
&lt;tr class=&#34;header&#34;&gt;
&lt;th align=&#34;left&#34;&gt;Local Address&lt;/th&gt;
&lt;th align=&#34;left&#34;&gt;Start Port&lt;/th&gt;
&lt;th align=&#34;left&#34;&gt;End Port&lt;/th&gt;
&lt;th align=&#34;left&#34;&gt;External Address&lt;/th&gt;
&lt;th align=&#34;left&#34;&gt;Protocol&lt;/th&gt;
&lt;th align=&#34;left&#34;&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class=&#34;odd&#34;&gt;
&lt;td align=&#34;left&#34;&gt;your_sever_ip&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;80&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;80&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;0.0.0.0&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;TCP&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;HTTP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&#34;even&#34;&gt;
&lt;td align=&#34;left&#34;&gt;your_sever_ip&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;443&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;443&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;0.0.0.0&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;TCP&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;HTTPS&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Also, make sure you don’t have a “Block WAN traffic” option enabled in your router, this will block all incoming traffic whatsoever.&lt;/p&gt;
&lt;p&gt;After doing all these you should be able to access your shiny apps by typing &lt;code&gt;your.public.ip:3838/your_app_name&lt;/code&gt; and/or your Rstudio Server by typing &lt;code&gt;your.public.ip:8787&lt;/code&gt; in any browser.&lt;/p&gt;
&lt;/div&gt;
&lt;div id=&#34;optional-extra-steps&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Optional Extra Steps&lt;/h2&gt;
&lt;div id=&#34;setup-a-dynamic-dns-service-ddns&#34; class=&#34;section level3&#34;&gt;
&lt;h3&gt;Setup a Dynamic DNS Service (DDNS)&lt;/h3&gt;
&lt;p&gt;Most residential internet services do not include a “static” public IP, which means that even if you have a public IP assigned at any given moment, it will not always be the same. A public IP is needed to access your server from the internet directly or to point your custom domain (web address) to it, so you can imagine how inconvenient would be having to figure out what the value is at any given moment.&lt;/p&gt;
&lt;p&gt;To address this issue, you can use a Dynamic DNS Service (I like to use &lt;a href=&#34;https://www.noip.com/&#34;&gt;No-IP&lt;/a&gt;). What this service does, is to automatically update your domain (they can even give you a free subdomain if you want) to point towards your current public IP every time it changes, it does it by using a built-in DDNS agent in your router if available or if not, by using a service installed in your server that automatically reports the current IP to the DDNS service.&lt;/p&gt;
&lt;p&gt;If your router has a compatible built-in DDNS agent, you just have to enter your credentials and you are ready to go.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://andresrcs.rbind.io/post/2021-08-16-port-forwarding.en_files/ddns.jpg&#34; width=&#34;700&#34; height=&#34;400&#34; /&gt;&lt;/p&gt;
&lt;p&gt;If your router does not have a DDNS agent, you are going to have to install one in your server (provided by the DDNS provider). How to install it depends on what DDNS provider you are using and what operating system your server is running but surely you can find detailed instructions on the DDNS provider’s documentation page.&lt;/p&gt;
&lt;p&gt;With this extra step, you will access your shiny apps with &lt;code&gt;your_domain:3838/your_app_name&lt;/code&gt; and your RStudio server with &lt;code&gt;your_domain:8787&lt;/code&gt; which doesn’t require you to know your current public IP in advance.&lt;/p&gt;
&lt;/div&gt;
&lt;div id=&#34;configure-a-reverse-proxy&#34; class=&#34;section level3&#34;&gt;
&lt;h3&gt;Configure a Reverse Proxy&lt;/h3&gt;
&lt;p&gt;Up until the previous step we had solved the problem with the changing IP address but we still have awkward port numbers in the web addresses for our server, by configuring a reverse proxy we can get to use nicer addresses like &lt;code&gt;your_domain/shiny/your_app_name&lt;/code&gt; and &lt;code&gt;your_domain/rstudio&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To configure a reverse proxy, install Nginx&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb3&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb3-1&#34;&gt;&lt;a href=&#34;#cb3-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; apt install nginx&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Edit Nginx config file: &lt;code&gt;sudo nano /etc/nginx/sites-enabled/default&lt;/code&gt;, add the following lines before the line that reads &lt;code&gt;server {&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb4&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb4-1&#34;&gt;&lt;a href=&#34;#cb4-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;map&lt;/span&gt; &lt;span class=&#34;va&#34;&gt;$http_upgrade&lt;/span&gt; &lt;span class=&#34;va&#34;&gt;$connection_upgrade&lt;/span&gt; {&lt;/span&gt;
&lt;span id=&#34;cb4-2&#34;&gt;&lt;a href=&#34;#cb4-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;      &lt;span class=&#34;ex&#34;&gt;default&lt;/span&gt; upgrade&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-3&#34;&gt;&lt;a href=&#34;#cb4-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;      &lt;span class=&#34;st&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;      close&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-4&#34;&gt;&lt;a href=&#34;#cb4-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;er&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and the following lines right after the line that reads &lt;code&gt;server_name _;&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb5&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb5-1&#34;&gt;&lt;a href=&#34;#cb5-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;ex&#34;&gt;rewrite&lt;/span&gt; ^/shiny$ &lt;span class=&#34;va&#34;&gt;$scheme&lt;/span&gt;://&lt;span class=&#34;va&#34;&gt;$http_host&lt;/span&gt;/shiny/ permanent&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-2&#34;&gt;&lt;a href=&#34;#cb5-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;co&#34;&gt;# This part is for Shiny server&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-3&#34;&gt;&lt;a href=&#34;#cb5-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;ex&#34;&gt;location&lt;/span&gt; /shiny/ {&lt;/span&gt;
&lt;span id=&#34;cb5-4&#34;&gt;&lt;a href=&#34;#cb5-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;rewrite&lt;/span&gt; ^/shiny/&lt;span class=&#34;er&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bu&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;pp&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;ex&#34;&gt;$&lt;/span&gt; /&lt;span class=&#34;va&#34;&gt;$1&lt;/span&gt; break&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-5&#34;&gt;&lt;a href=&#34;#cb5-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;proxy_pass&lt;/span&gt; http://localhost:3838&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-6&#34;&gt;&lt;a href=&#34;#cb5-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;proxy_redirect&lt;/span&gt; / &lt;span class=&#34;va&#34;&gt;$scheme&lt;/span&gt;://&lt;span class=&#34;va&#34;&gt;$http_host&lt;/span&gt;/shiny/&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-7&#34;&gt;&lt;a href=&#34;#cb5-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;proxy_http_version&lt;/span&gt; 1.1&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-8&#34;&gt;&lt;a href=&#34;#cb5-8&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;proxy_set_header&lt;/span&gt; Upgrade &lt;span class=&#34;va&#34;&gt;$http_upgrade&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-9&#34;&gt;&lt;a href=&#34;#cb5-9&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;proxy_set_header&lt;/span&gt; Connection &lt;span class=&#34;va&#34;&gt;$connection_upgrade&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-10&#34;&gt;&lt;a href=&#34;#cb5-10&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;proxy_read_timeout&lt;/span&gt; 20d&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-11&#34;&gt;&lt;a href=&#34;#cb5-11&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;proxy_buffering&lt;/span&gt; off&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-12&#34;&gt;&lt;a href=&#34;#cb5-12&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;er&#34;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-13&#34;&gt;&lt;a href=&#34;#cb5-13&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;co&#34;&gt;# This part is for RStudio server&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-14&#34;&gt;&lt;a href=&#34;#cb5-14&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;ex&#34;&gt;location&lt;/span&gt; /rstudio {&lt;/span&gt;
&lt;span id=&#34;cb5-15&#34;&gt;&lt;a href=&#34;#cb5-15&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;       &lt;span class=&#34;co&#34;&gt;# Needed only for prefix of /rstudio&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-16&#34;&gt;&lt;a href=&#34;#cb5-16&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;       &lt;span class=&#34;ex&#34;&gt;rewrite&lt;/span&gt; ^/rstudio/&lt;span class=&#34;er&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bu&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;pp&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;ex&#34;&gt;$&lt;/span&gt; /&lt;span class=&#34;va&#34;&gt;$1&lt;/span&gt; break&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-17&#34;&gt;&lt;a href=&#34;#cb5-17&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-18&#34;&gt;&lt;a href=&#34;#cb5-18&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;       &lt;span class=&#34;co&#34;&gt;# Use http here when ssl-enabled=0 is set in rserver.conf&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-19&#34;&gt;&lt;a href=&#34;#cb5-19&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;       &lt;span class=&#34;ex&#34;&gt;proxy_pass&lt;/span&gt; http://localhost:8787&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-20&#34;&gt;&lt;a href=&#34;#cb5-20&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;       &lt;span class=&#34;ex&#34;&gt;proxy_http_version&lt;/span&gt; 1.1&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-21&#34;&gt;&lt;a href=&#34;#cb5-21&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-22&#34;&gt;&lt;a href=&#34;#cb5-22&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;       &lt;span class=&#34;ex&#34;&gt;proxy_set_header&lt;/span&gt; Upgrade &lt;span class=&#34;va&#34;&gt;$http_upgrade&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-23&#34;&gt;&lt;a href=&#34;#cb5-23&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;       &lt;span class=&#34;ex&#34;&gt;proxy_set_header&lt;/span&gt; Connection &lt;span class=&#34;va&#34;&gt;$connection_upgrade&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-24&#34;&gt;&lt;a href=&#34;#cb5-24&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-25&#34;&gt;&lt;a href=&#34;#cb5-25&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;       &lt;span class=&#34;co&#34;&gt;# Optionally, use an explicit hostname and omit the port if using 80/443&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-26&#34;&gt;&lt;a href=&#34;#cb5-26&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;       &lt;span class=&#34;ex&#34;&gt;proxy_set_header&lt;/span&gt; Host &lt;span class=&#34;va&#34;&gt;$host&lt;/span&gt;:&lt;span class=&#34;va&#34;&gt;$server_port&lt;/span&gt;&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-27&#34;&gt;&lt;a href=&#34;#cb5-27&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-28&#34;&gt;&lt;a href=&#34;#cb5-28&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;       &lt;span class=&#34;co&#34;&gt;# Not needed if there&amp;#39;s no prefix or www-root-path is set in rserver.conf&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-29&#34;&gt;&lt;a href=&#34;#cb5-29&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;       &lt;span class=&#34;ex&#34;&gt;proxy_set_header&lt;/span&gt; X-RStudio-Root-Path /rstudio&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-30&#34;&gt;&lt;a href=&#34;#cb5-30&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-31&#34;&gt;&lt;a href=&#34;#cb5-31&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;       &lt;span class=&#34;ex&#34;&gt;proxy_read_timeout&lt;/span&gt; 20d&lt;span class=&#34;kw&#34;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-32&#34;&gt;&lt;a href=&#34;#cb5-32&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;er&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now you just have to restart Nginx to apply the changes and you are done.&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb6&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb6-1&#34;&gt;&lt;a href=&#34;#cb6-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; service nginx restart&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Automatically installing Shiny and RStudio server on Amazon Web Services with Ansible</title>
      <link>https://andresrcs.rbind.io/2021/03/28/aws_r_server/</link>
      <pubDate>Sun, 28 Mar 2021 00:00:00 +0000</pubDate>
      
      <guid>https://andresrcs.rbind.io/2021/03/28/aws_r_server/</guid>
      <description>
&lt;style type=&#34;text/css&#34;&gt;
pre &gt; code.sourceCode { white-space: pre; position: relative; }
pre &gt; code.sourceCode &gt; span { line-height: 1.25; }
pre &gt; code.sourceCode &gt; span:empty { height: 1.2em; }
.sourceCode { overflow: visible; }
code.sourceCode &gt; span { color: inherit; text-decoration: inherit; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
pre &gt; code.sourceCode { white-space: pre-wrap; }
pre &gt; code.sourceCode &gt; span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
  { counter-reset: source-line 0; }
pre.numberSource code &gt; span
  { position: relative; left: -4em; counter-increment: source-line; }
pre.numberSource code &gt; span &gt; a:first-child::before
  { content: counter(source-line);
    position: relative; left: -1em; text-align: right; vertical-align: baseline;
    border: none; display: inline-block;
    -webkit-touch-callout: none; -webkit-user-select: none;
    -khtml-user-select: none; -moz-user-select: none;
    -ms-user-select: none; user-select: none;
    padding: 0 4px; width: 4em;
  }
pre.numberSource { margin-left: 3em;  padding-left: 4px; }
div.sourceCode
  { color: #cccccc; background-color: #303030; }
@media screen {
pre &gt; code.sourceCode &gt; span &gt; a:first-child::before { text-decoration: underline; }
}
code span.al { color: #ffcfaf; } /* Alert */
code span.an { color: #7f9f7f; font-weight: bold; } /* Annotation */
code span.at { } /* Attribute */
code span.bn { color: #dca3a3; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #f0dfaf; } /* ControlFlow */
code span.ch { color: #dca3a3; } /* Char */
code span.cn { color: #dca3a3; font-weight: bold; } /* Constant */
code span.co { color: #7f9f7f; } /* Comment */
code span.cv { color: #7f9f7f; font-weight: bold; } /* CommentVar */
code span.do { color: #7f9f7f; } /* Documentation */
code span.dt { color: #dfdfbf; } /* DataType */
code span.dv { color: #dcdccc; } /* DecVal */
code span.er { color: #c3bf9f; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #c0bed1; } /* Float */
code span.fu { color: #efef8f; } /* Function */
code span.im { } /* Import */
code span.in { color: #7f9f7f; font-weight: bold; } /* Information */
code span.kw { color: #f0dfaf; } /* Keyword */
code span.op { color: #f0efd0; } /* Operator */
code span.ot { color: #efef8f; } /* Other */
code span.pp { color: #ffcfaf; font-weight: bold; } /* Preprocessor */
code span.sc { color: #dca3a3; } /* SpecialChar */
code span.ss { color: #cc9393; } /* SpecialString */
code span.st { color: #cc9393; } /* String */
code span.va { } /* Variable */
code span.vs { color: #cc9393; } /* VerbatimString */
code span.wa { color: #7f9f7f; font-weight: bold; } /* Warning */
&lt;/style&gt;

&lt;div id=&#34;TOC&#34;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#create-an-aws-account-and-security-credentials&#34; id=&#34;toc-create-an-aws-account-and-security-credentials&#34;&gt;Create an AWS Account and Security Credentials&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#install-ansible&#34; id=&#34;toc-install-ansible&#34;&gt;Install Ansible&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#download-and-configure-the-playbooks&#34; id=&#34;toc-download-and-configure-the-playbooks&#34;&gt;Download and Configure the Playbooks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#run-the-playbooks&#34; id=&#34;toc-run-the-playbooks&#34;&gt;Run the Playbooks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#final-notes&#34; id=&#34;toc-final-notes&#34;&gt;Final Notes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;

&lt;p&gt;After writing a very &lt;a href=&#34;https://andresrcs.rbind.io/2021/01/13/raspberry_pi_server/&#34;&gt;similar post&lt;/a&gt; about installing Shiny and RStudio server on a Raspberry Pi using automation with Ansible, I realized that the same approach can be easily ported to work with cloud computing services as well, so, basically, this is going to be the Amazon Web Services (AWS from now on) version of that post.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;✏️ Have in mind that this is a beginner-oriented project, it is not meant as a production tool, so if you are already familiar with Ansible you might want to simply download some roles from Ansible Galaxy and integrate them into your workflow instead of following this article.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In case you haven’t read the aforementioned post, I’m going to tell you what this is about. The installation and configuration process of an R-based data science server on AWS can be automated using a tool called &lt;a href=&#34;https://en.wikipedia.org/wiki/Ansible_(software)&#34;&gt;Ansible&lt;/a&gt;, those in DevOps must be familiar with the power of Ansible but even if you’ve never heard of it, don’t worry, you don’t need to know Ansible in order to take advantage of its automation capabilities, I’m not an Ansible expert myself and I’ve been capable of accomplishing this project with just basic knowledge of the tool, so if I can do it, so can you. I’m going to guide you through the process assuming you have no prior experience with this tool and just some basic Linux terminal skills.&lt;/p&gt;
&lt;p&gt;Ansible is an open-source software provisioning, configuration management, and application-deployment tool enabling infrastructure as code. It runs on many Unix-like systems, and can configure both Unix-like systems as well as Microsoft Windows. In layman’s terms, it lets you automate tasks in your infrastructure (One, or many EC2 instances at once, in our case) by defining a set of steps to execute, in &lt;a href=&#34;https://en.wikipedia.org/wiki/YAML&#34;&gt;YAML&lt;/a&gt; files called “playbooks”.&lt;/p&gt;
&lt;p&gt;I have wrote some Ansible playbooks to automate most of the installation process but leaving some room for you to configure the installation to your liking without having to modify the playbooks (which will require you to know how to edit them) via a config file. Although, if you want to have a basic understanding of how this tool works, there is a nice Ansible 101 series on &lt;a href=&#34;https://www.youtube.com/playlist?list=PL2_OBreMn7FqZkvMYt6ATmgC0KAGGJNAN&#34;&gt;Jeff Geerling’s YouTube channel&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In case you are not familiar with AWS, it is a cloud services provider that among many other things, it provides access to virtual servers hosted on the cloud, so you don’t have to take care of a physical infrastructure yourself, also, to follow along with this article, there are some AWS specific terms that we need to define in simple terms:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;EC2 Instance&lt;/strong&gt;: It refers to an individual instance of a virtual server.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Amazon Machine Images (AMI)&lt;/strong&gt;: It provides the information required to launch an instance, like the Operating System, pre-installed libraries and configurations required for a server to work. Note that you can make your own AMIs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Regions&lt;/strong&gt;: Amazon EC2 is hosted in multiple locations world-wide. These locations are composed of Regions, and each Region is a separate geographic area.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Security Group&lt;/strong&gt;: A security group acts as a virtual firewall for your instance to control inbound and outbound traffic.&lt;/li&gt;
&lt;/ul&gt;
&lt;div id=&#34;create-an-aws-account-and-security-credentials&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Create an AWS Account and Security Credentials&lt;/h2&gt;
&lt;p&gt;In order to use AWS services you need to have an account, if you already have one, you can skip this part, if not, to create one go to &lt;a href=&#34;https://aws.amazon.com/&#34;&gt;https://aws.amazon.com/&lt;/a&gt; and click on “Create an AWS Account”, fill in the required information and keep pressing “Continue”, you are going to be asked to provide your credit card information, but you are not going to be charged for using the products comprised on the “Free Tier” at least for a year.&lt;/p&gt;
&lt;p&gt;Once your account has been created, go to the “AWS Management Console” and log in, once there, click on the search button, type “EC2” and select “EC2 Virtual Servers in the Cloud”.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://andresrcs.rbind.io/post/2021-03-28-aws-server.en_files/aws_ec2.jpg&#34; width=&#34;700&#34; height=&#34;200&#34; /&gt;&lt;/p&gt;
&lt;p&gt;On the upper right corner choose a suitable region, the geographically closer to you the better. Remember your choice since you have to set this exact same location in the playbooks later.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://andresrcs.rbind.io/post/2021-03-28-aws-server.en_files/region.jpg&#34; width=&#34;400&#34; height=&#34;600&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Then in the left menu, look for “Network &amp;amp; Security -&amp;gt; Key Pairs” and click on it.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://andresrcs.rbind.io/post/2021-03-28-aws-server.en_files/aws_key_pair.jpg&#34; width=&#34;250&#34; height=&#34;600&#34; /&gt;&lt;/p&gt;
&lt;p&gt;On the right upper corner look for “Create Key Pair” and click on it.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://andresrcs.rbind.io/post/2021-03-28-aws-server.en_files/aws_create_key.jpg&#34; width=&#34;600&#34; height=&#34;200&#34; /&gt;&lt;/p&gt;
&lt;p&gt;You are going to see this dialog box, fill it this way, click on “Create Key Pair” and save the resulting file on this path, &lt;code&gt;~/.ssh/aws_server.pem&lt;/code&gt;, in your machine.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://andresrcs.rbind.io/post/2021-03-28-aws-server.en_files/key_pair.jpg&#34; width=&#34;600&#34; height=&#34;500&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Set propper permissions for your key file, the .ssh directory permissions should be 700 (rwx______) and the private key (aws_server.pem) should be 600 (rw_______).&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb1&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb1-1&#34;&gt;&lt;a href=&#34;#cb1-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; chmod 700 ~/.ssh/&lt;/span&gt;
&lt;span id=&#34;cb1-2&#34;&gt;&lt;a href=&#34;#cb1-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; chmod 600 ~/.ssh/aws_server.pem&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Next, you need to create an access key, so you can have access to your account programmatically, go to your account menu and select “My Security Credentials”.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://andresrcs.rbind.io/post/2021-03-28-aws-server.en_files/aws_security_settings.jpg&#34; width=&#34;300&#34; height=&#34;300&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Then select “Create New Access Key” and save the file with your credentials&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://andresrcs.rbind.io/post/2021-03-28-aws-server.en_files/aws_access_key.jpg&#34; width=&#34;600&#34; height=&#34;400&#34; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;⚠️ Keep the downloaded file safe and at hand, you are going to need it later. Be careful not to share this file since it could enable other people to generate charges to your credit card.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div id=&#34;install-ansible&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Install Ansible&lt;/h2&gt;
&lt;p&gt;It is possible to install Ansible locally on the EC2 instance itself and run playbooks directly on it with &lt;code&gt;connection: local&lt;/code&gt; but it wouldn’t be practical, because among other things it would require us to manually launch the EC2 instance, it is better to run the playbooks from a system other than your EC2 instance.&lt;/p&gt;
&lt;p&gt;For installing Ansible, if you have a Unix based system (i.e. Linux, macOS) at your disposal, you are golden, installing Ansible is very simple.&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb2&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb2-1&#34;&gt;&lt;a href=&#34;#cb2-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Install python3&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-2&#34;&gt;&lt;a href=&#34;#cb2-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; apt install python3 &lt;span class=&#34;co&#34;&gt;# On macOS use `brew install python3`&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-3&#34;&gt;&lt;a href=&#34;#cb2-3&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Install pip3&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-4&#34;&gt;&lt;a href=&#34;#cb2-4&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; apt install python3-pip &lt;/span&gt;
&lt;span id=&#34;cb2-5&#34;&gt;&lt;a href=&#34;#cb2-5&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Install Ansible version 9.5.1 (for reproducibility) with pip3 &lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-6&#34;&gt;&lt;a href=&#34;#cb2-6&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; pip3 install ansible==9.5.1 &lt;span class=&#34;at&#34;&gt;--break-system-packages&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you are on Windows, sadly, there is no way to run Ansible natively, your best bet is to enable WSL (Windows Subsystem for Linux), install a Linux distribution from the Microsoft Store (I recommend Ubuntu), and execute the previous steps in your Linux VM.&lt;/p&gt;
&lt;p&gt;A detailed guide for installing WSL can be found &lt;a href=&#34;https://docs.microsoft.com/en-us/windows/wsl/install-win10&#34;&gt;here&lt;/a&gt; and more information about installing Ansible can be found on the official &lt;a href=&#34;https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html&#34;&gt;documentation site&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Also, since we are going to be testing this with a low power EC2 instance (i.e. T2.Micro), some of these tasks are going to take a while and the &lt;code&gt;SSH&lt;/code&gt; connection might get automatically closed due to inactivity, to prevent this situation, activate the sending of “keep-alive” packets to the server by editing the &lt;code&gt;ssh_config&lt;/code&gt; file with &lt;code&gt;sudo nano /etc/ssh/ssh_config&lt;/code&gt; and adding this two lines under &lt;code&gt;Host *&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb3&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb3-1&#34;&gt;&lt;a href=&#34;#cb3-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;ex&#34;&gt;ServerAliveInterval&lt;/span&gt; 300&lt;/span&gt;
&lt;span id=&#34;cb3-2&#34;&gt;&lt;a href=&#34;#cb3-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;ex&#34;&gt;ServerAliveCountMax&lt;/span&gt; 2&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;⚠️ Is very important not to skip the previous step, otherwise, the ssh connection is going to silently fail while running long tasks in Ansible and you are going to be waiting pointlessly with your EC2 instance doing nothing in reality.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div id=&#34;download-and-configure-the-playbooks&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Download and Configure the Playbooks&lt;/h2&gt;
&lt;p&gt;The playbooks are on a public repository on GitHub, you can clone the repository with these commands:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb4&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb4-1&#34;&gt;&lt;a href=&#34;#cb4-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Install git if you don&amp;#39;t have it already&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-2&#34;&gt;&lt;a href=&#34;#cb4-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; apt install git &lt;span class=&#34;co&#34;&gt;# On macOS use `brew install git`&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-3&#34;&gt;&lt;a href=&#34;#cb4-3&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Clone the latest commit from the repository&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-4&#34;&gt;&lt;a href=&#34;#cb4-4&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;git&lt;/span&gt; clone https://github.com/andresrcs/aws_r_server.git &lt;span class=&#34;at&#34;&gt;--depth&lt;/span&gt; 1&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To start configuring the playbooks, you usually first need to define an “inventory” (a list of servers to connect to), but in this case, the &lt;code&gt;provision_ec2_instance.yml&lt;/code&gt; playbook is going to create one automatically for you when you run it and the other playbooks are going to get an updated inventory from AWS automatically using the &lt;code&gt;aws_ec2&lt;/code&gt; plugging when needed, this is one of the advantages of working with well supported cloud computing services like AWS, but in order for the &lt;code&gt;aws_ec2&lt;/code&gt; plugging to do its magic, you need to provide it with your AWS credentials and define your &lt;a href=&#34;https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html#concepts-available-regions&#34;&gt;AWS EC2 region&lt;/a&gt;, so edit the &lt;code&gt;aws_r_server/inventories/aws_ec2.yml&lt;/code&gt; file, and fill your credentials and region on the respective variables. Remember that you already created these credentials on a previous step and you saved a .csv file containing them, also the AWS Region you set here has to be the same one you selected when you started creating your credentials.&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb5&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb5-1&#34;&gt;&lt;a href=&#34;#cb5-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;---&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-2&#34;&gt;&lt;a href=&#34;#cb5-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;plugin:&lt;/span&gt; aws_ec2&lt;/span&gt;
&lt;span id=&#34;cb5-3&#34;&gt;&lt;a href=&#34;#cb5-3&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-4&#34;&gt;&lt;a href=&#34;#cb5-4&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;aws_access_key:&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;your_key_goes_here&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-5&#34;&gt;&lt;a href=&#34;#cb5-5&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;aws_secret_key:&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;your_secret_goes_here&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-6&#34;&gt;&lt;a href=&#34;#cb5-6&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-7&#34;&gt;&lt;a href=&#34;#cb5-7&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;regions:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-8&#34;&gt;&lt;a href=&#34;#cb5-8&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;ex&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;closest_aws_region&amp;#39;&lt;/span&gt; &lt;span class=&#34;co&#34;&gt;#  e.g. sa-east-1&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-9&#34;&gt;&lt;a href=&#34;#cb5-9&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-10&#34;&gt;&lt;a href=&#34;#cb5-10&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;hostnames:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-11&#34;&gt;&lt;a href=&#34;#cb5-11&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;ex&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;ip-address&amp;#39;&lt;/span&gt; &lt;span class=&#34;co&#34;&gt;# Do not change this&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-12&#34;&gt;&lt;a href=&#34;#cb5-12&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-13&#34;&gt;&lt;a href=&#34;#cb5-13&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;keyed_groups:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-14&#34;&gt;&lt;a href=&#34;#cb5-14&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;ex&#34;&gt;-&lt;/span&gt; key: tags.inventory_group&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, if you want to change the default installation settings, you can do it by editing the variables on the &lt;code&gt;aws_r_server/vars/config_vars.yml&lt;/code&gt; file, although, the default options are fine for most use case scenarios, including reasonable security settings to use on real-world applications. The only things you certainly need to change here are the AWS credentials, AWS region, AWS AMI (it changes constantly even for the same OS version) the personal user and password, and the password for the PostgreSQL main user.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;✏️ This post has been written as an example of applying this approach with cloud computing services so for simplicity’s sake, I have made it work only with the Ubuntu Server 22.04 LTS AMI, so to be clear, it is not OS-agnostic. If you want to use it with an RHEL based AMI you would need to modify the playbooks considerably.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb6&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb6-1&#34;&gt;&lt;a href=&#34;#cb6-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;---&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-2&#34;&gt;&lt;a href=&#34;#cb6-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# AWS Config Vars ##############################################################&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-3&#34;&gt;&lt;a href=&#34;#cb6-3&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-4&#34;&gt;&lt;a href=&#34;#cb6-4&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# AWS credentials&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-5&#34;&gt;&lt;a href=&#34;#cb6-5&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;aws_access_key:&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;your_key_goes_here&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-6&#34;&gt;&lt;a href=&#34;#cb6-6&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;aws_secret_key:&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;your_secret_goes_here&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-7&#34;&gt;&lt;a href=&#34;#cb6-7&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-8&#34;&gt;&lt;a href=&#34;#cb6-8&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# General AWS configurations&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-9&#34;&gt;&lt;a href=&#34;#cb6-9&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;aws_region:&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;closest_aws_region&amp;#39;&lt;/span&gt; &lt;span class=&#34;co&#34;&gt;#  e.g. sa-east-1&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-10&#34;&gt;&lt;a href=&#34;#cb6-10&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;aws_ec2_ami:&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;ami-08ae71fd7f1449df1&amp;#39;&lt;/span&gt; &lt;span class=&#34;co&#34;&gt;# Ubuntu 22.04 LTS&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-11&#34;&gt;&lt;a href=&#34;#cb6-11&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-12&#34;&gt;&lt;a href=&#34;#cb6-12&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# List of instances&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-13&#34;&gt;&lt;a href=&#34;#cb6-13&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;instances:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-14&#34;&gt;&lt;a href=&#34;#cb6-14&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;ex&#34;&gt;-&lt;/span&gt; name: rstudio&lt;/span&gt;
&lt;span id=&#34;cb6-15&#34;&gt;&lt;a href=&#34;#cb6-15&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;ex&#34;&gt;group:&lt;/span&gt; aws&lt;/span&gt;
&lt;span id=&#34;cb6-16&#34;&gt;&lt;a href=&#34;#cb6-16&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;ex&#34;&gt;security_group:&lt;/span&gt; [&lt;span class=&#34;st&#34;&gt;&amp;quot;default&amp;quot;&lt;/span&gt;, &lt;span class=&#34;st&#34;&gt;&amp;quot;public_server&amp;quot;&lt;/span&gt;]&lt;/span&gt;
&lt;span id=&#34;cb6-17&#34;&gt;&lt;a href=&#34;#cb6-17&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;ex&#34;&gt;ssh_key:&lt;/span&gt; aws_server&lt;/span&gt;
&lt;span id=&#34;cb6-18&#34;&gt;&lt;a href=&#34;#cb6-18&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;ex&#34;&gt;type:&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;t2.micro&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-19&#34;&gt;&lt;a href=&#34;#cb6-19&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-20&#34;&gt;&lt;a href=&#34;#cb6-20&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# AWS firewall settings&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-21&#34;&gt;&lt;a href=&#34;#cb6-21&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;security_groups:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-22&#34;&gt;&lt;a href=&#34;#cb6-22&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;ex&#34;&gt;-&lt;/span&gt; name: public_server&lt;/span&gt;
&lt;span id=&#34;cb6-23&#34;&gt;&lt;a href=&#34;#cb6-23&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;ex&#34;&gt;rules:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-24&#34;&gt;&lt;a href=&#34;#cb6-24&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;      &lt;span class=&#34;ex&#34;&gt;-&lt;/span&gt; proto: tcp &lt;span class=&#34;co&#34;&gt;# http&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-25&#34;&gt;&lt;a href=&#34;#cb6-25&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;from_port:&lt;/span&gt; 80&lt;/span&gt;
&lt;span id=&#34;cb6-26&#34;&gt;&lt;a href=&#34;#cb6-26&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;to_port:&lt;/span&gt; 80&lt;/span&gt;
&lt;span id=&#34;cb6-27&#34;&gt;&lt;a href=&#34;#cb6-27&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;cidr_ip:&lt;/span&gt; 0.0.0.0/0&lt;/span&gt;
&lt;span id=&#34;cb6-28&#34;&gt;&lt;a href=&#34;#cb6-28&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;      &lt;span class=&#34;ex&#34;&gt;-&lt;/span&gt; proto: tcp  &lt;span class=&#34;co&#34;&gt;# https&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-29&#34;&gt;&lt;a href=&#34;#cb6-29&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;from_port:&lt;/span&gt; 443&lt;/span&gt;
&lt;span id=&#34;cb6-30&#34;&gt;&lt;a href=&#34;#cb6-30&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;to_port:&lt;/span&gt; 443&lt;/span&gt;
&lt;span id=&#34;cb6-31&#34;&gt;&lt;a href=&#34;#cb6-31&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;cidr_ip:&lt;/span&gt; 0.0.0.0/0&lt;/span&gt;
&lt;span id=&#34;cb6-32&#34;&gt;&lt;a href=&#34;#cb6-32&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;      &lt;span class=&#34;ex&#34;&gt;-&lt;/span&gt; proto: tcp  &lt;span class=&#34;co&#34;&gt;# SSH TCP&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-33&#34;&gt;&lt;a href=&#34;#cb6-33&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;from_port:&lt;/span&gt; 22&lt;/span&gt;
&lt;span id=&#34;cb6-34&#34;&gt;&lt;a href=&#34;#cb6-34&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;to_port:&lt;/span&gt; 22&lt;/span&gt;
&lt;span id=&#34;cb6-35&#34;&gt;&lt;a href=&#34;#cb6-35&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;cidr_ip:&lt;/span&gt; 0.0.0.0/0&lt;/span&gt;
&lt;span id=&#34;cb6-36&#34;&gt;&lt;a href=&#34;#cb6-36&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;      &lt;span class=&#34;ex&#34;&gt;-&lt;/span&gt; proto: udp  &lt;span class=&#34;co&#34;&gt;# SSH UDP&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-37&#34;&gt;&lt;a href=&#34;#cb6-37&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;from_port:&lt;/span&gt; 22&lt;/span&gt;
&lt;span id=&#34;cb6-38&#34;&gt;&lt;a href=&#34;#cb6-38&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;to_port:&lt;/span&gt; 22&lt;/span&gt;
&lt;span id=&#34;cb6-39&#34;&gt;&lt;a href=&#34;#cb6-39&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;cidr_ip:&lt;/span&gt; 0.0.0.0/0&lt;/span&gt;
&lt;span id=&#34;cb6-40&#34;&gt;&lt;a href=&#34;#cb6-40&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;      &lt;span class=&#34;ex&#34;&gt;-&lt;/span&gt; proto: tcp  &lt;span class=&#34;co&#34;&gt;# PostgreSQL&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-41&#34;&gt;&lt;a href=&#34;#cb6-41&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;from_port:&lt;/span&gt; 5432&lt;/span&gt;
&lt;span id=&#34;cb6-42&#34;&gt;&lt;a href=&#34;#cb6-42&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;to_port:&lt;/span&gt; 5432&lt;/span&gt;
&lt;span id=&#34;cb6-43&#34;&gt;&lt;a href=&#34;#cb6-43&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;cidr_ip:&lt;/span&gt; 0.0.0.0/0&lt;/span&gt;
&lt;span id=&#34;cb6-44&#34;&gt;&lt;a href=&#34;#cb6-44&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;ex&#34;&gt;rules_egress:&lt;/span&gt; []&lt;/span&gt;
&lt;span id=&#34;cb6-45&#34;&gt;&lt;a href=&#34;#cb6-45&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-46&#34;&gt;&lt;a href=&#34;#cb6-46&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# System Configurations ########################################################&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-47&#34;&gt;&lt;a href=&#34;#cb6-47&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-48&#34;&gt;&lt;a href=&#34;#cb6-48&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Personal user&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-49&#34;&gt;&lt;a href=&#34;#cb6-49&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;personal_user:&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;your_linux_user&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-50&#34;&gt;&lt;a href=&#34;#cb6-50&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;personal_user_password:&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;very_secure_password&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-51&#34;&gt;&lt;a href=&#34;#cb6-51&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-52&#34;&gt;&lt;a href=&#34;#cb6-52&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Swap parameters&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-53&#34;&gt;&lt;a href=&#34;#cb6-53&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;swap_file_path:&lt;/span&gt; /var/swap&lt;/span&gt;
&lt;span id=&#34;cb6-54&#34;&gt;&lt;a href=&#34;#cb6-54&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Use any of the following suffixes&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-55&#34;&gt;&lt;a href=&#34;#cb6-55&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# c=1&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-56&#34;&gt;&lt;a href=&#34;#cb6-56&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# w=2&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-57&#34;&gt;&lt;a href=&#34;#cb6-57&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# b=512&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-58&#34;&gt;&lt;a href=&#34;#cb6-58&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# kB=1000&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-59&#34;&gt;&lt;a href=&#34;#cb6-59&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# K=1024&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-60&#34;&gt;&lt;a href=&#34;#cb6-60&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# MB=1000*1000&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-61&#34;&gt;&lt;a href=&#34;#cb6-61&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# M=1024*1024&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-62&#34;&gt;&lt;a href=&#34;#cb6-62&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# xM=M&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-63&#34;&gt;&lt;a href=&#34;#cb6-63&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# GB=1000*1000*1000&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-64&#34;&gt;&lt;a href=&#34;#cb6-64&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# G=1024*1024*1024&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-65&#34;&gt;&lt;a href=&#34;#cb6-65&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;swap_file_size:&lt;/span&gt; 3GB&lt;/span&gt;
&lt;span id=&#34;cb6-66&#34;&gt;&lt;a href=&#34;#cb6-66&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;swappiness:&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;10&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-67&#34;&gt;&lt;a href=&#34;#cb6-67&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-68&#34;&gt;&lt;a href=&#34;#cb6-68&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Language and locale&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-69&#34;&gt;&lt;a href=&#34;#cb6-69&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;language_pack:&lt;/span&gt; []                 &lt;span class=&#34;co&#34;&gt;#  e.g. language-pack-es-base&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-70&#34;&gt;&lt;a href=&#34;#cb6-70&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;default_locale:&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;en_US.UTF-8&amp;#39;&lt;/span&gt;     &lt;span class=&#34;co&#34;&gt;#  e.g. es_PE.UTF-8&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-71&#34;&gt;&lt;a href=&#34;#cb6-71&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-72&#34;&gt;&lt;a href=&#34;#cb6-72&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Security Configurations ######################################################&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-73&#34;&gt;&lt;a href=&#34;#cb6-73&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-74&#34;&gt;&lt;a href=&#34;#cb6-74&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Postgresql Password&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-75&#34;&gt;&lt;a href=&#34;#cb6-75&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;postgres_password:&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;very_secure_password&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-76&#34;&gt;&lt;a href=&#34;#cb6-76&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-77&#34;&gt;&lt;a href=&#34;#cb6-77&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Access rules for Postgresql&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-78&#34;&gt;&lt;a href=&#34;#cb6-78&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;postgresql_rules:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-79&#34;&gt;&lt;a href=&#34;#cb6-79&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;ex&#34;&gt;-&lt;/span&gt; { contype: local, users: all, address: samehost, method: trust }&lt;/span&gt;
&lt;span id=&#34;cb6-80&#34;&gt;&lt;a href=&#34;#cb6-80&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;ex&#34;&gt;-&lt;/span&gt; { contype: local, users: postgres, address: samehost, method: trust }&lt;/span&gt;
&lt;span id=&#34;cb6-81&#34;&gt;&lt;a href=&#34;#cb6-81&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;ex&#34;&gt;-&lt;/span&gt; { contype: host, users: all, address: 0.0.0.0/0, method: password }&lt;/span&gt;
&lt;span id=&#34;cb6-82&#34;&gt;&lt;a href=&#34;#cb6-82&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;ex&#34;&gt;-&lt;/span&gt; { contype: host, users: all, address: 127.0.0.1/32, method: md5 }&lt;/span&gt;
&lt;span id=&#34;cb6-83&#34;&gt;&lt;a href=&#34;#cb6-83&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;ex&#34;&gt;-&lt;/span&gt; { contype: host, users: all, address: &lt;span class=&#34;st&#34;&gt;&amp;#39;::1/128&amp;#39;&lt;/span&gt;, method: trust }&lt;/span&gt;
&lt;span id=&#34;cb6-84&#34;&gt;&lt;a href=&#34;#cb6-84&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-85&#34;&gt;&lt;a href=&#34;#cb6-85&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Main Software Versions #######################################################&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-86&#34;&gt;&lt;a href=&#34;#cb6-86&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-87&#34;&gt;&lt;a href=&#34;#cb6-87&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Shiny-server version to install&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-88&#34;&gt;&lt;a href=&#34;#cb6-88&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;shiny_server_version:&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;1.5.19.995&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-89&#34;&gt;&lt;a href=&#34;#cb6-89&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-90&#34;&gt;&lt;a href=&#34;#cb6-90&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# RStudio version to install&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-91&#34;&gt;&lt;a href=&#34;#cb6-91&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;rstudio_version:&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;2022.07.1+554&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-92&#34;&gt;&lt;a href=&#34;#cb6-92&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;preview_version:&lt;/span&gt; false&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&#34;run-the-playbooks&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Run the Playbooks&lt;/h2&gt;
&lt;p&gt;You could simply access the &lt;code&gt;aws_r_server&lt;/code&gt; folder and run the &lt;code&gt;main.yml&lt;/code&gt; playbook to install everything at once like this:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb7&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb7-1&#34;&gt;&lt;a href=&#34;#cb7-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;bu&#34;&gt;cd&lt;/span&gt; aws_r_server&lt;/span&gt;
&lt;span id=&#34;cb7-2&#34;&gt;&lt;a href=&#34;#cb7-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;ansible-playbook&lt;/span&gt; main.yml&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But to make the installation process more flexible, I have divided the process into four individual playbooks:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb8&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb8-1&#34;&gt;&lt;a href=&#34;#cb8-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;ansible-playbook&lt;/span&gt; provision_ec2_instance.yml&lt;/span&gt;
&lt;span id=&#34;cb8-2&#34;&gt;&lt;a href=&#34;#cb8-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;ansible-playbook&lt;/span&gt; install_basic_services.yml&lt;/span&gt;
&lt;span id=&#34;cb8-3&#34;&gt;&lt;a href=&#34;#cb8-3&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;ansible-playbook&lt;/span&gt; install_shiny_server.yml&lt;/span&gt;
&lt;span id=&#34;cb8-4&#34;&gt;&lt;a href=&#34;#cb8-4&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;ansible-playbook&lt;/span&gt; install_rstudio_server.yml&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;⚠️ When provisioning the ec2 instance the AWS API sometimes fails to return the instance IP causing the playbook to fail. This is a random error not caused by the playbook, you can safely ignore it if you are running individual playbooks and the instance has already been provisioned.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If you decide that you only need Shiny server or RStudio server but not the other, or you already have installed the support services you are going to use, then you can run only the playbooks you actually need.&lt;/p&gt;
&lt;p&gt;If you want to update something in the future, like RStudio, or Shiny server (I can’t guaranty this is always going to work out of the box), you can simply change the version in the config file and run the specific part of the playbook by taking advantage of the defined “tags”.&lt;/p&gt;
&lt;p&gt;For example, this will only install the RStudio version defined in the config file and nothing more:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb9&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb9-1&#34;&gt;&lt;a href=&#34;#cb9-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;ansible-playbook&lt;/span&gt; install_rstudio_server.yml &lt;span class=&#34;at&#34;&gt;--tags&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;rstudio&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The available tags are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;install_basic_services.yml
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;secure&lt;/code&gt;: Set security settings on the server&lt;/li&gt;
&lt;li&gt;&lt;code&gt;swap&lt;/code&gt;: Add swap memory to the server&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nginx&lt;/code&gt;: Install and configure Nginx + PHP&lt;/li&gt;
&lt;li&gt;&lt;code&gt;postgresql&lt;/code&gt;: Install and configure PostgreSQL&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r&lt;/code&gt;: Install R from the CRAN repository&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;install_shiny_server.yml
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;shiny-server&lt;/code&gt;: Install shiny-server&lt;/li&gt;
&lt;li&gt;&lt;code&gt;configure_shiny&lt;/code&gt;: Configure shiny-server&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;install_rstudio_server.yml
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;rstudio&lt;/code&gt;: Install RStudio server&lt;/li&gt;
&lt;li&gt;&lt;code&gt;configure_rstudio&lt;/code&gt;: Configure RStudio server&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can also go the other way and skip specific parts of the playbooks by using the &lt;code&gt;--skip-tags&lt;/code&gt; option, for example, if you don’t need PostgreSQL, you can avoid installing it by running the playbook this way:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb10&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb10-1&#34;&gt;&lt;a href=&#34;#cb10-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;ansible-playbook&lt;/span&gt; install_basic_services.yml &lt;span class=&#34;at&#34;&gt;--skip-tags&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;postgresql&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;After successfully running all the playbooks, you will have a fully functional installation ready to be used, so you could simply open an RStudio session at &lt;code&gt;http://your_server_ip/rstudio/&lt;/code&gt; and/or publish your Shiny apps in the &lt;code&gt;/srv/shiny-server&lt;/code&gt; folder and access them at &lt;code&gt;http://your_server_ip/shiny/your_app_name&lt;/code&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div id=&#34;final-notes&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Final Notes&lt;/h2&gt;
&lt;p&gt;To finish I just want to make you aware that there are other options for getting RStudio and Shiny server on AWS that you might consider to be simpler, like using a premade AMI or containers, but they are not as flexible and customizable as defining your own infrastructure in code with Ansible. Obviously, the example in this article is my conception of a basic installation for an R-based data science server but you can use it as a starting point to custom tailor your own infrastructure and make your workflow more efficient as you become more proficient with Ansible.&lt;/p&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Automatically installing Shiny and RStudio server on a Raspberry Pi with Ansible</title>
      <link>https://andresrcs.rbind.io/2021/01/13/raspberry_pi_server/</link>
      <pubDate>Wed, 13 Jan 2021 00:00:00 +0000</pubDate>
      
      <guid>https://andresrcs.rbind.io/2021/01/13/raspberry_pi_server/</guid>
      <description>
&lt;style type=&#34;text/css&#34;&gt;
pre &gt; code.sourceCode { white-space: pre; position: relative; }
pre &gt; code.sourceCode &gt; span { line-height: 1.25; }
pre &gt; code.sourceCode &gt; span:empty { height: 1.2em; }
.sourceCode { overflow: visible; }
code.sourceCode &gt; span { color: inherit; text-decoration: inherit; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
pre &gt; code.sourceCode { white-space: pre-wrap; }
pre &gt; code.sourceCode &gt; span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
  { counter-reset: source-line 0; }
pre.numberSource code &gt; span
  { position: relative; left: -4em; counter-increment: source-line; }
pre.numberSource code &gt; span &gt; a:first-child::before
  { content: counter(source-line);
    position: relative; left: -1em; text-align: right; vertical-align: baseline;
    border: none; display: inline-block;
    -webkit-touch-callout: none; -webkit-user-select: none;
    -khtml-user-select: none; -moz-user-select: none;
    -ms-user-select: none; user-select: none;
    padding: 0 4px; width: 4em;
  }
pre.numberSource { margin-left: 3em;  padding-left: 4px; }
div.sourceCode
  { color: #cccccc; background-color: #303030; }
@media screen {
pre &gt; code.sourceCode &gt; span &gt; a:first-child::before { text-decoration: underline; }
}
code span.al { color: #ffcfaf; } /* Alert */
code span.an { color: #7f9f7f; font-weight: bold; } /* Annotation */
code span.at { } /* Attribute */
code span.bn { color: #dca3a3; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #f0dfaf; } /* ControlFlow */
code span.ch { color: #dca3a3; } /* Char */
code span.cn { color: #dca3a3; font-weight: bold; } /* Constant */
code span.co { color: #7f9f7f; } /* Comment */
code span.cv { color: #7f9f7f; font-weight: bold; } /* CommentVar */
code span.do { color: #7f9f7f; } /* Documentation */
code span.dt { color: #dfdfbf; } /* DataType */
code span.dv { color: #dcdccc; } /* DecVal */
code span.er { color: #c3bf9f; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #c0bed1; } /* Float */
code span.fu { color: #efef8f; } /* Function */
code span.im { } /* Import */
code span.in { color: #7f9f7f; font-weight: bold; } /* Information */
code span.kw { color: #f0dfaf; } /* Keyword */
code span.op { color: #f0efd0; } /* Operator */
code span.ot { color: #efef8f; } /* Other */
code span.pp { color: #ffcfaf; font-weight: bold; } /* Preprocessor */
code span.sc { color: #dca3a3; } /* SpecialChar */
code span.ss { color: #cc9393; } /* SpecialString */
code span.st { color: #cc9393; } /* String */
code span.va { } /* Variable */
code span.vs { color: #cc9393; } /* VerbatimString */
code span.wa { color: #7f9f7f; font-weight: bold; } /* Warning */
&lt;/style&gt;

&lt;div id=&#34;TOC&#34;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#prepare-the-raspberry-pi&#34; id=&#34;toc-prepare-the-raspberry-pi&#34;&gt;Prepare the Raspberry Pi&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#install-ansible&#34; id=&#34;toc-install-ansible&#34;&gt;Install Ansible&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#download-and-configure-the-playbooks&#34; id=&#34;toc-download-and-configure-the-playbooks&#34;&gt;Download and Configure the Playbooks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#run-the-playbooks&#34; id=&#34;toc-run-the-playbooks&#34;&gt;Run the Playbooks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#final-notes&#34; id=&#34;toc-final-notes&#34;&gt;Final Notes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;

&lt;p&gt;I have a &lt;a href=&#34;https://andresrcs.rbind.io/2022/09/05/shiny_rstudio_server/&#34;&gt;related post&lt;/a&gt; about manually installing Shiny and RStudio server on a Raspberry Pi but even with the latest advancements in software support for the ARM architecture, this process is still considerably time-consuming and requires a lot of copy/pasting and watching the terminal waiting for one task to be completed to be able to start with the next one, so, I decided to come up with a better solution, and that is to automate the process so it can be left unattended and come back later when it’s done.&lt;/p&gt;
&lt;p&gt;To automate the installation and configuration process I decided to use &lt;a href=&#34;https://en.wikipedia.org/wiki/Ansible_(software)&#34;&gt;Ansible&lt;/a&gt;, those in DevOps must be familiar with the power of Ansible but even if you’ve never heard of it, don’t worry, you don’t need to know Ansible in order to take advantage of its automation capabilities, I’m not an Ansible expert myself and I’ve been capable of accomplishing this project with just basic knowledge of the tool, so if I can do it, so can you. I’m going to guide you through the process assuming you have no prior experience with this tool and just some basic Linux terminal skills.&lt;/p&gt;
&lt;p&gt;Ansible is an open-source software provisioning, configuration management, and application-deployment tool enabling infrastructure as code. It runs on many Unix-like systems, and can configure both Unix-like systems as well as Microsoft Windows. In layman’s terms, it lets you automate tasks in your infrastructure (One, or many Raspberry Pi SBCs at once in our case) by defining a set of steps to execute in &lt;a href=&#34;https://en.wikipedia.org/wiki/YAML&#34;&gt;YAML&lt;/a&gt; files called “playbooks”. I took one for the team and wrote some Ansible playbooks to automate most of the installation process but leaving some room for you to configure the installation to your liking via a config file, so you don’t need to modify the playbooks (which will require you to know how they work) . Although, if you want to have a basic understanding of how this tool works, there is a nice Ansible 101 series on &lt;a href=&#34;https://www.youtube.com/playlist?list=PL2_OBreMn7FqZkvMYt6ATmgC0KAGGJNAN&#34;&gt;Jeff Geerling’s YouTube channel&lt;/a&gt; and if you are the kind of people that prefer reading rather than seeing things, here is a nice &lt;a href=&#34;https://spacelift.io/blog/ansible-tutorial&#34;&gt;Ansible Tutorial for Beginners&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;✏️ Note that this has only been tested with the software versions specified in the &lt;code&gt;config_vars.yml&lt;/code&gt; file, it is very likely that it will still work out of the box with newer software versions, but in some cases, it might require some modifications to the playbooks that I will made as soon as I notice the problem.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div id=&#34;prepare-the-raspberry-pi&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Prepare the Raspberry Pi&lt;/h2&gt;
&lt;p&gt;Even if most of the process can be automated with Ansible, we still need at least one working Raspberry Pi to configure, so, we need to start by flashing an Operating System (OS) onto an SD card (I recommend at least 32GB class 10 HC1). Have in mind that RStudio Server is compatible only with arm64 operating systems, so if you want to be able to install it, you will have to choose a 64-bit OS, the playbooks work with Raspberry Pi OS, and Ubuntu as well.&lt;/p&gt;
&lt;p&gt;Download “Raspberry Pi Imager” from the &lt;a href=&#34;https://www.raspberrypi.com/software/&#34;&gt;official site&lt;/a&gt; and install it in your system, execute “Raspberry Pi Imager”, choose a suitable OS, choose the “SD Card” and press “Write”.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://andresrcs.rbind.io/post/2021-01-13-raspberry-pi-server.en_files/raspberri_pi_imager.jpg&#34; width=&#34;400&#34; height=&#34;300&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Once the process is done, you have a clean installation of an operating system on your micro SD card, insert the card into your Raspberry Pi, plug in a keyboard and a screen, and turn it on.&lt;/p&gt;
&lt;p&gt;Log into the system (the default user and password are &lt;code&gt;pi&lt;/code&gt; and &lt;code&gt;raspberry&lt;/code&gt; for Raspberry Pi OS, and in Ubuntu is &lt;code&gt;ubuntu&lt;/code&gt; for both user and password) and run an initial system update with these commands:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb1&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb1-1&#34;&gt;&lt;a href=&#34;#cb1-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; apt update&lt;/span&gt;
&lt;span id=&#34;cb1-2&#34;&gt;&lt;a href=&#34;#cb1-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; apt dist-upgrade&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Next, you need to set a static IP for the Pi so you can easily find it on your network later on.&lt;/p&gt;
&lt;p&gt;For setting a static IP on Raspberry Pi OS, run these commands. This is a sample IP configuration for a wired connection, modify accordingly with your own needs:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb2&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb2-1&#34;&gt;&lt;a href=&#34;#cb2-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Sample static IP configuration:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-2&#34;&gt;&lt;a href=&#34;#cb2-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; nmcli c mod &lt;span class=&#34;st&#34;&gt;&amp;#39;Wired connection 1&amp;#39;&lt;/span&gt; ipv4.addresses 192.168.3.101/24 ipv4.method manual&lt;/span&gt;
&lt;span id=&#34;cb2-3&#34;&gt;&lt;a href=&#34;#cb2-3&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; nmcli con mod &lt;span class=&#34;st&#34;&gt;&amp;#39;Wired connection 1&amp;#39;&lt;/span&gt; ipv4.gateway 192.168.3.1&lt;/span&gt;
&lt;span id=&#34;cb2-4&#34;&gt;&lt;a href=&#34;#cb2-4&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; nmcli con mod &lt;span class=&#34;st&#34;&gt;&amp;#39;Wired connection 1&amp;#39;&lt;/span&gt; ipv4.dns &lt;span class=&#34;st&#34;&gt;&amp;quot;192.168.3.1&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-5&#34;&gt;&lt;a href=&#34;#cb2-5&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; nmcli c down &lt;span class=&#34;st&#34;&gt;&amp;#39;Wired connection 1&amp;#39;&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; nmcli c up &lt;span class=&#34;st&#34;&gt;&amp;#39;Wired connection 1&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then you have to stablich a new SSH connection with your Pi since the IP has changed.&lt;/p&gt;
&lt;p&gt;And for setting the IP on Ubuntu, you have to create this file &lt;code&gt;sudo nano /etc/netplan/01-netcfg.yaml&lt;/code&gt;, add the content below (edit as needed), and apply the configuration with &lt;code&gt;sudo netplan apply&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb3&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb3-1&#34;&gt;&lt;a href=&#34;#cb3-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;network:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-2&#34;&gt;&lt;a href=&#34;#cb3-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;ex&#34;&gt;version:&lt;/span&gt; 2&lt;/span&gt;
&lt;span id=&#34;cb3-3&#34;&gt;&lt;a href=&#34;#cb3-3&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;ex&#34;&gt;renderer:&lt;/span&gt; networkd&lt;/span&gt;
&lt;span id=&#34;cb3-4&#34;&gt;&lt;a href=&#34;#cb3-4&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;ex&#34;&gt;ethernets:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-5&#34;&gt;&lt;a href=&#34;#cb3-5&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;ex&#34;&gt;eth0:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-6&#34;&gt;&lt;a href=&#34;#cb3-6&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;ex&#34;&gt;dhcp4:&lt;/span&gt; false&lt;/span&gt;
&lt;span id=&#34;cb3-7&#34;&gt;&lt;a href=&#34;#cb3-7&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;ex&#34;&gt;addresses:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-8&#34;&gt;&lt;a href=&#34;#cb3-8&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                &lt;span class=&#34;ex&#34;&gt;-&lt;/span&gt; 192.168.3.101/24&lt;/span&gt;
&lt;span id=&#34;cb3-9&#34;&gt;&lt;a href=&#34;#cb3-9&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;ex&#34;&gt;nameservers:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-10&#34;&gt;&lt;a href=&#34;#cb3-10&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                &lt;span class=&#34;ex&#34;&gt;addresses:&lt;/span&gt; [8.8.8.8, 8.8.4.4, 192.168.3.1]&lt;/span&gt;
&lt;span id=&#34;cb3-11&#34;&gt;&lt;a href=&#34;#cb3-11&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;ex&#34;&gt;routes:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-12&#34;&gt;&lt;a href=&#34;#cb3-12&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                &lt;span class=&#34;ex&#34;&gt;-&lt;/span&gt; to: default&lt;/span&gt;
&lt;span id=&#34;cb3-13&#34;&gt;&lt;a href=&#34;#cb3-13&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                  &lt;span class=&#34;ex&#34;&gt;via:&lt;/span&gt; 192.168.3.1&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then we need to set some basic configurations with &lt;code&gt;raspi-config&lt;/code&gt;. Run &lt;code&gt;sudo raspi-config&lt;/code&gt;, and perform the following tasks (In Ubuntu you need to install it first with &lt;code&gt;sudo apt install raspi-config&lt;/code&gt;):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Optionally, change the password for the “pi” user (System Options –&amp;gt; Password)&lt;/li&gt;
&lt;li&gt;Enable the SSH server (Interface Options –&amp;gt; SSH)&lt;/li&gt;
&lt;li&gt;Set your locale settings (Localization Options)&lt;/li&gt;
&lt;li&gt;Expand the filesystem to use the full capacity of your SD card (Advanced Options –&amp;gt; Expand Filesystem)&lt;/li&gt;
&lt;li&gt;Disable Predictable Network Interface Names (Advanced Options –&amp;gt; Network Interface Names)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&#34;https://andresrcs.rbind.io/post/2021-01-13-raspberry-pi-server.en_files/raspi_config.jpg&#34; width=&#34;600&#34; height=&#34;300&#34; /&gt;&lt;/p&gt;
&lt;p&gt;When you are done, exit the &lt;code&gt;raspi-config&lt;/code&gt; tool and reboot your Pi.&lt;/p&gt;
&lt;p&gt;If you don’t have one, you need to create an SSH key, even if it is possible to use Ansible by providing a password for your hosts interactively, a more convenient and secure way to do it is by using an SSH key pair. To create one run the following commands in the terminal:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb4&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb4-1&#34;&gt;&lt;a href=&#34;#cb4-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Create the .ssh folder&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-2&#34;&gt;&lt;a href=&#34;#cb4-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;bu&#34;&gt;cd&lt;/span&gt; ~&lt;/span&gt;
&lt;span id=&#34;cb4-3&#34;&gt;&lt;a href=&#34;#cb4-3&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;mkdir&lt;/span&gt; .ssh&lt;/span&gt;
&lt;span id=&#34;cb4-4&#34;&gt;&lt;a href=&#34;#cb4-4&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;bu&#34;&gt;cd&lt;/span&gt; .ssh&lt;/span&gt;
&lt;span id=&#34;cb4-5&#34;&gt;&lt;a href=&#34;#cb4-5&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Create the authorized_keys file&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-6&#34;&gt;&lt;a href=&#34;#cb4-6&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;touch&lt;/span&gt; authorized_keys&lt;/span&gt;
&lt;span id=&#34;cb4-7&#34;&gt;&lt;a href=&#34;#cb4-7&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-8&#34;&gt;&lt;a href=&#34;#cb4-8&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Set proper access permissions&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-9&#34;&gt;&lt;a href=&#34;#cb4-9&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;chmod&lt;/span&gt; 700 ~/.ssh&lt;/span&gt;
&lt;span id=&#34;cb4-10&#34;&gt;&lt;a href=&#34;#cb4-10&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;chmod&lt;/span&gt; 600 ~/.ssh/authorized_keys&lt;/span&gt;
&lt;span id=&#34;cb4-11&#34;&gt;&lt;a href=&#34;#cb4-11&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-12&#34;&gt;&lt;a href=&#34;#cb4-12&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Create the key pair&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-13&#34;&gt;&lt;a href=&#34;#cb4-13&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;ssh-keygen&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-14&#34;&gt;&lt;a href=&#34;#cb4-14&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Add the new key to the authorized_keys file&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-15&#34;&gt;&lt;a href=&#34;#cb4-15&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;cat&lt;/span&gt; id_rsa.pub &lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; authorized_keys&lt;/span&gt;
&lt;span id=&#34;cb4-16&#34;&gt;&lt;a href=&#34;#cb4-16&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-17&#34;&gt;&lt;a href=&#34;#cb4-17&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# If you use Putty as your SSH client (Windows), generate a ppk key, otherwise, ignore these steps&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-18&#34;&gt;&lt;a href=&#34;#cb4-18&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; apt install putty-tools&lt;/span&gt;
&lt;span id=&#34;cb4-19&#34;&gt;&lt;a href=&#34;#cb4-19&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;puttygen&lt;/span&gt; id_rsa &lt;span class=&#34;at&#34;&gt;-o&lt;/span&gt; id_rsa.ppk&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Copy the id_rsa and id_rsa.pub (and id_rsa.ppk if applicable) files to the machine you are going to use to execute the playbooks, I like to use &lt;code&gt;sftp&lt;/code&gt; but you can do it the way you prefer (e.g. with a USB memory). After you have copied the key files, delete them from your Pi with &lt;code&gt;rm ~/.ssh/id_rsa*&lt;/code&gt;. If you already have an SSH key, I trust you know how to add it to your OS at flashing time using the Raspberry Pi Imager software.&lt;/p&gt;
&lt;p&gt;Now your Pi is ready to go, disconnect the keyboard and monitor and plug the Pi into your network (I recommend using a wired connection).&lt;/p&gt;
&lt;/div&gt;
&lt;div id=&#34;install-ansible&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Install Ansible&lt;/h2&gt;
&lt;p&gt;In theory, you could install Ansible on the Raspberry Pi itself and run the playbooks directly on it with &lt;code&gt;connection: local&lt;/code&gt; but it wouldn’t be practical, it is better to run the playbooks from a computer other than your Pi.&lt;/p&gt;
&lt;p&gt;For installing Ansible, if you have a Unix based system (i.e. Linux, macOS) at your disposal, you are golden, installing Ansible is very simple:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb5&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb5-1&#34;&gt;&lt;a href=&#34;#cb5-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Install python3&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-2&#34;&gt;&lt;a href=&#34;#cb5-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; apt install python3 &lt;span class=&#34;co&#34;&gt;# On macOS use `brew install python3`&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-3&#34;&gt;&lt;a href=&#34;#cb5-3&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Install pip3&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-4&#34;&gt;&lt;a href=&#34;#cb5-4&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; apt install python3-pip &lt;/span&gt;
&lt;span id=&#34;cb5-5&#34;&gt;&lt;a href=&#34;#cb5-5&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Install Ansible version 9.5.1 (for reproducibility) with pip3 &lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-6&#34;&gt;&lt;a href=&#34;#cb5-6&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; pip3 install ansible==9.5.1 &lt;span class=&#34;at&#34;&gt;--break-system-packages&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you are on Windows, sadly, there is no way to run Ansible natively, your best bet is to enable WSL (Windows Subsystem for Linux), install a Linux distribution from the Microsoft Store (I recommend Ubuntu), and execute the previous steps in your Linux VM.&lt;/p&gt;
&lt;p&gt;A detailed guide for installing WSL can be found &lt;a href=&#34;https://docs.microsoft.com/en-us/windows/wsl/install-win10&#34;&gt;here&lt;/a&gt; and more information about installing Ansible can be found on the official &lt;a href=&#34;https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html&#34;&gt;documentation site&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Also, since we are going to be installing several packages from source on a low power SBC, some of these tasks are going to take a while and the &lt;code&gt;SSH&lt;/code&gt; connection might get automatically closed due to inactivity, to prevent this situation, activate the sending of “keep-alive” packets to the server by editing the &lt;code&gt;ssh_config&lt;/code&gt; file on the computer running Ansible, run &lt;code&gt;sudo nano /etc/ssh/ssh_config&lt;/code&gt; and add these two lines under &lt;code&gt;Host *&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb6&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb6-1&#34;&gt;&lt;a href=&#34;#cb6-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;ex&#34;&gt;ServerAliveInterval&lt;/span&gt; 300&lt;/span&gt;
&lt;span id=&#34;cb6-2&#34;&gt;&lt;a href=&#34;#cb6-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;ex&#34;&gt;ServerAliveCountMax&lt;/span&gt; 2&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;⚠️ Is very important not to skip the previous step, otherwise, the SSH connection migth silently fail while running long tasks in Ansible and you are going to be waiting pointlessly with your Raspberry Pi doing nothing in reality.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div id=&#34;download-and-configure-the-playbooks&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Download and Configure the Playbooks&lt;/h2&gt;
&lt;p&gt;The playbooks are on a public repository on GitHub, you can clone the repository with these commands:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb7&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb7-1&#34;&gt;&lt;a href=&#34;#cb7-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Install git if you don&amp;#39;t have it already&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb7-2&#34;&gt;&lt;a href=&#34;#cb7-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; apt install git&lt;/span&gt;
&lt;span id=&#34;cb7-3&#34;&gt;&lt;a href=&#34;#cb7-3&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Clone the latest commit from the repository&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb7-4&#34;&gt;&lt;a href=&#34;#cb7-4&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;git&lt;/span&gt; clone https://github.com/andresrcs/raspberry_pi_server.git &lt;span class=&#34;at&#34;&gt;--depth&lt;/span&gt; 1&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ansible doesn’t run playbooks in “world writable folders” so you need to set the &lt;code&gt;raspberry_pi_server&lt;/code&gt; folder permissions to &lt;code&gt;755&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb8&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb8-1&#34;&gt;&lt;a href=&#34;#cb8-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; chmod 755 raspberry_pi_server&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Have in mind that on WSL it is necessary to remount the &lt;code&gt;C&lt;/code&gt; drive in order to be able to change file permissions so you have to do this before changing permissions:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb9&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb9-1&#34;&gt;&lt;a href=&#34;#cb9-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; umount /mnt/c &lt;/span&gt;
&lt;span id=&#34;cb9-2&#34;&gt;&lt;a href=&#34;#cb9-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; mount &lt;span class=&#34;at&#34;&gt;-t&lt;/span&gt; drvfs C: /mnt/c &lt;span class=&#34;at&#34;&gt;-o&lt;/span&gt; metadata&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To configure the playbooks, you first need to define your “inventory”, this is a list of the hosts you are going to connect to, edit the &lt;code&gt;raspberry_pi_server/inventory.ini&lt;/code&gt; file and add the IP of your Raspberry Pi(s):&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb10&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb10-1&#34;&gt;&lt;a href=&#34;#cb10-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;[raspberries]&lt;/span&gt; &lt;span class=&#34;co&#34;&gt;# This represents a group of Raspberries&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb10-2&#34;&gt;&lt;a href=&#34;#cb10-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;raspberry_01&lt;/span&gt; ansible_host=192.168.18.101 &lt;span class=&#34;co&#34;&gt;# This is the hostname and IP for an individual Raspberry Pi&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb10-3&#34;&gt;&lt;a href=&#34;#cb10-3&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# You can add as many Raspberries as you need&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then set common variables for your &lt;code&gt;[raspberries]&lt;/code&gt; group by editing the &lt;code&gt;raspberry_pi_server/group_vars/raspberries.yml&lt;/code&gt; file, the most important things to check here are the path to your ssh key and the default user fot the operating system you are using.&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb11&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb11-1&#34;&gt;&lt;a href=&#34;#cb11-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;---&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb11-2&#34;&gt;&lt;a href=&#34;#cb11-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;ansible_user:&lt;/span&gt; pi &lt;span class=&#34;co&#34;&gt;# This is the default user for the operating system&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb11-3&#34;&gt;&lt;a href=&#34;#cb11-3&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;ansible_become_method:&lt;/span&gt; sudo&lt;/span&gt;
&lt;span id=&#34;cb11-4&#34;&gt;&lt;a href=&#34;#cb11-4&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;ansible_python_interpreter:&lt;/span&gt; /usr/bin/python3&lt;/span&gt;
&lt;span id=&#34;cb11-5&#34;&gt;&lt;a href=&#34;#cb11-5&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;ansible_ssh_private_key_file:&lt;/span&gt; ~/.ssh/raspberrypi_key &lt;span class=&#34;co&#34;&gt;# The location of the ssh key in the computer runing Ansible.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, you can set installation options by editing the variables in the &lt;code&gt;raspberry_pi_server/vars/config_vars.yml&lt;/code&gt; file, most of the already set options are fine for most use cases including reasonable security settings but at the bare minimum, you need to set your personal password for the PostgreSQL main user. You can also choose your preferred method for installing R, if you don’t want to use the default option, have in mind that using the &lt;a href=&#34;https://r4pi.org/&#34;&gt;R4Pi Project&lt;/a&gt; option is only possible with Raspberry Pi OS and it will always install the latest R version available.&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb12&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb12-1&#34;&gt;&lt;a href=&#34;#cb12-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# System Configurations ########################################################&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-2&#34;&gt;&lt;a href=&#34;#cb12-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-3&#34;&gt;&lt;a href=&#34;#cb12-3&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Swap parameters&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-4&#34;&gt;&lt;a href=&#34;#cb12-4&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;swap_file_path:&lt;/span&gt; /var/swap.1&lt;/span&gt;
&lt;span id=&#34;cb12-5&#34;&gt;&lt;a href=&#34;#cb12-5&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Use any of the following suffixes&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-6&#34;&gt;&lt;a href=&#34;#cb12-6&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# c=1&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-7&#34;&gt;&lt;a href=&#34;#cb12-7&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# w=2&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-8&#34;&gt;&lt;a href=&#34;#cb12-8&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# b=512&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-9&#34;&gt;&lt;a href=&#34;#cb12-9&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# kB=1000&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-10&#34;&gt;&lt;a href=&#34;#cb12-10&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# K=1024&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-11&#34;&gt;&lt;a href=&#34;#cb12-11&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# MB=1000*1000&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-12&#34;&gt;&lt;a href=&#34;#cb12-12&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# M=1024*1024&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-13&#34;&gt;&lt;a href=&#34;#cb12-13&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# xM=M&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-14&#34;&gt;&lt;a href=&#34;#cb12-14&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# GB=1000*1000*1000&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-15&#34;&gt;&lt;a href=&#34;#cb12-15&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# G=1024*1024*1024&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-16&#34;&gt;&lt;a href=&#34;#cb12-16&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;swap_file_size:&lt;/span&gt; 3GB&lt;/span&gt;
&lt;span id=&#34;cb12-17&#34;&gt;&lt;a href=&#34;#cb12-17&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;swappiness:&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;10&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-18&#34;&gt;&lt;a href=&#34;#cb12-18&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-19&#34;&gt;&lt;a href=&#34;#cb12-19&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Install Nginx?&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-20&#34;&gt;&lt;a href=&#34;#cb12-20&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;install_nginx:&lt;/span&gt; true&lt;/span&gt;
&lt;span id=&#34;cb12-21&#34;&gt;&lt;a href=&#34;#cb12-21&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-22&#34;&gt;&lt;a href=&#34;#cb12-22&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Install PostgreSQL?&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-23&#34;&gt;&lt;a href=&#34;#cb12-23&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;install_postgresql:&lt;/span&gt; true&lt;/span&gt;
&lt;span id=&#34;cb12-24&#34;&gt;&lt;a href=&#34;#cb12-24&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-25&#34;&gt;&lt;a href=&#34;#cb12-25&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Security Configurations ######################################################&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-26&#34;&gt;&lt;a href=&#34;#cb12-26&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-27&#34;&gt;&lt;a href=&#34;#cb12-27&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Ports to open&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-28&#34;&gt;&lt;a href=&#34;#cb12-28&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;exposed_ports:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-29&#34;&gt;&lt;a href=&#34;#cb12-29&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;ex&#34;&gt;-&lt;/span&gt; { rule: &lt;span class=&#34;st&#34;&gt;&amp;#39;allow&amp;#39;&lt;/span&gt;, port: 22, proto: &lt;span class=&#34;st&#34;&gt;&amp;#39;tcp&amp;#39;&lt;/span&gt; }     &lt;span class=&#34;co&#34;&gt;# ssh&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-30&#34;&gt;&lt;a href=&#34;#cb12-30&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;ex&#34;&gt;-&lt;/span&gt; { rule: &lt;span class=&#34;st&#34;&gt;&amp;#39;allow&amp;#39;&lt;/span&gt;, port: 22, proto: &lt;span class=&#34;st&#34;&gt;&amp;#39;udp&amp;#39;&lt;/span&gt; }     &lt;span class=&#34;co&#34;&gt;# ssh&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-31&#34;&gt;&lt;a href=&#34;#cb12-31&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;ex&#34;&gt;-&lt;/span&gt; { rule: &lt;span class=&#34;st&#34;&gt;&amp;#39;allow&amp;#39;&lt;/span&gt;, port: 80, proto: &lt;span class=&#34;st&#34;&gt;&amp;#39;tcp&amp;#39;&lt;/span&gt; }     &lt;span class=&#34;co&#34;&gt;# http&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-32&#34;&gt;&lt;a href=&#34;#cb12-32&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;ex&#34;&gt;-&lt;/span&gt; { rule: &lt;span class=&#34;st&#34;&gt;&amp;#39;allow&amp;#39;&lt;/span&gt;, port: 5432, proto: &lt;span class=&#34;st&#34;&gt;&amp;#39;tcp&amp;#39;&lt;/span&gt; }   &lt;span class=&#34;co&#34;&gt;# Postgresql (ommit if Postgresql is not installed)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-33&#34;&gt;&lt;a href=&#34;#cb12-33&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;ex&#34;&gt;-&lt;/span&gt; { rule: &lt;span class=&#34;st&#34;&gt;&amp;#39;allow&amp;#39;&lt;/span&gt;, port: 5432, proto: &lt;span class=&#34;st&#34;&gt;&amp;#39;udp&amp;#39;&lt;/span&gt; }   &lt;span class=&#34;co&#34;&gt;# Postgresql (ommit if Postgresql is not installed)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-34&#34;&gt;&lt;a href=&#34;#cb12-34&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;co&#34;&gt;# - { rule: &amp;#39;allow&amp;#39;, port: 8787, proto: &amp;#39;tcp&amp;#39; } # RStudio Server (uncomment if Nginx is not installed)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-35&#34;&gt;&lt;a href=&#34;#cb12-35&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;co&#34;&gt;# - { rule: &amp;#39;allow&amp;#39;, port: 3838, proto: &amp;#39;tcp&amp;#39; } # Shiny Server (uncomment if Nginx is not installed)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-36&#34;&gt;&lt;a href=&#34;#cb12-36&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-37&#34;&gt;&lt;a href=&#34;#cb12-37&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Password for the main PostgreSQL user (ignore if PostgreSQL is not installed)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-38&#34;&gt;&lt;a href=&#34;#cb12-38&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;postgres_password:&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;very_secure_password&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-39&#34;&gt;&lt;a href=&#34;#cb12-39&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-40&#34;&gt;&lt;a href=&#34;#cb12-40&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Access rules for Postgresql (ignore if PostgreSQL is not installed)&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-41&#34;&gt;&lt;a href=&#34;#cb12-41&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;postgresql_rules:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-42&#34;&gt;&lt;a href=&#34;#cb12-42&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;ex&#34;&gt;-&lt;/span&gt; { contype: local, users: postgres, address: samehost, method: trust }&lt;/span&gt;
&lt;span id=&#34;cb12-43&#34;&gt;&lt;a href=&#34;#cb12-43&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;ex&#34;&gt;-&lt;/span&gt; { contype: local, users: all, address: samehost, method: trust }&lt;/span&gt;
&lt;span id=&#34;cb12-44&#34;&gt;&lt;a href=&#34;#cb12-44&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;ex&#34;&gt;-&lt;/span&gt; { contype: hostssl, users: all, address: 0.0.0.0/0, method: scram-sha-256 }&lt;/span&gt;
&lt;span id=&#34;cb12-45&#34;&gt;&lt;a href=&#34;#cb12-45&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;ex&#34;&gt;-&lt;/span&gt; { contype: host, users: all, address: 0.0.0.0/0, method: scram-sha-256 }&lt;/span&gt;
&lt;span id=&#34;cb12-46&#34;&gt;&lt;a href=&#34;#cb12-46&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;ex&#34;&gt;-&lt;/span&gt; { contype: hostssl, users: all, address: &lt;span class=&#34;st&#34;&gt;&amp;#39;::0/0&amp;#39;&lt;/span&gt;, method: scram-sha-256 }&lt;/span&gt;
&lt;span id=&#34;cb12-47&#34;&gt;&lt;a href=&#34;#cb12-47&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;ex&#34;&gt;-&lt;/span&gt; { contype: host, users: all, address: &lt;span class=&#34;st&#34;&gt;&amp;#39;::0/0&amp;#39;&lt;/span&gt;, method: scram-sha-256 }&lt;/span&gt;
&lt;span id=&#34;cb12-48&#34;&gt;&lt;a href=&#34;#cb12-48&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;ex&#34;&gt;-&lt;/span&gt; { contype: host, users: all, address: 127.0.0.1/32, method: scram-sha-256 }&lt;/span&gt;
&lt;span id=&#34;cb12-49&#34;&gt;&lt;a href=&#34;#cb12-49&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;ex&#34;&gt;-&lt;/span&gt; { contype: host, users: all, address: &lt;span class=&#34;st&#34;&gt;&amp;#39;::1/128&amp;#39;&lt;/span&gt;, method: scram-sha-256 }&lt;/span&gt;
&lt;span id=&#34;cb12-50&#34;&gt;&lt;a href=&#34;#cb12-50&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-51&#34;&gt;&lt;a href=&#34;#cb12-51&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Main Software Versions #######################################################&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-52&#34;&gt;&lt;a href=&#34;#cb12-52&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-53&#34;&gt;&lt;a href=&#34;#cb12-53&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# R version to install&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-54&#34;&gt;&lt;a href=&#34;#cb12-54&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;use_r4pi:&lt;/span&gt; true &lt;span class=&#34;co&#34;&gt;# If set to true the latest R version will be installed, this is only compatible with&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-55&#34;&gt;&lt;a href=&#34;#cb12-55&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                &lt;span class=&#34;co&#34;&gt;# Raspberry Pi OS.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-56&#34;&gt;&lt;a href=&#34;#cb12-56&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;use_rig:&lt;/span&gt; false &lt;span class=&#34;co&#34;&gt;# Don&amp;#39;t forget to specify an R version in the following line&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-57&#34;&gt;&lt;a href=&#34;#cb12-57&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;r_version:&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt; &lt;span class=&#34;co&#34;&gt;# (e.g. &amp;#39;4.3.3&amp;#39;) Currently, you can only choose the R version if it&amp;#39;s going to be&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-58&#34;&gt;&lt;a href=&#34;#cb12-58&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                   &lt;span class=&#34;co&#34;&gt;# installed with rig or compiled (with both &amp;#39;use_r4pi&amp;#39; and &amp;#39;use_rig&amp;#39; set as false).&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-59&#34;&gt;&lt;a href=&#34;#cb12-59&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-60&#34;&gt;&lt;a href=&#34;#cb12-60&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Shiny-server version to install&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-61&#34;&gt;&lt;a href=&#34;#cb12-61&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;shiny_server_version:&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;v1.5.21.1012&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-62&#34;&gt;&lt;a href=&#34;#cb12-62&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-63&#34;&gt;&lt;a href=&#34;#cb12-63&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# RStudio version to install&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb12-64&#34;&gt;&lt;a href=&#34;#cb12-64&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;rstudio_version:&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;2024.04.0-daily+651&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&#34;run-the-playbooks&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Run the Playbooks&lt;/h2&gt;
&lt;p&gt;Under ideal conditions, like using the latest Raspberry Pi model with 8GB of RAM, booting from an SSD drive and connected to a stable network, you could simply access the &lt;code&gt;raspberry_pi_server&lt;/code&gt; folder and run the &lt;code&gt;site.yml&lt;/code&gt; playbook to install everything at once:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb13&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb13-1&#34;&gt;&lt;a href=&#34;#cb13-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;bu&#34;&gt;cd&lt;/span&gt; raspberry_pi_server&lt;/span&gt;
&lt;span id=&#34;cb13-2&#34;&gt;&lt;a href=&#34;#cb13-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;ansible-playbook&lt;/span&gt; site.yml&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But under less than ideal conditions it is very likely tha you will encounter some random erros caused by overloading the Pi or unestable network connections, so, to mitigate this issue and to make the installation process more flexible, I have divided the process into three individual playbooks:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb14&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb14-1&#34;&gt;&lt;a href=&#34;#cb14-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;bu&#34;&gt;cd&lt;/span&gt; raspberry_pi_server&lt;/span&gt;
&lt;span id=&#34;cb14-2&#34;&gt;&lt;a href=&#34;#cb14-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;ansible-playbook&lt;/span&gt; install_basic_services.yml&lt;/span&gt;
&lt;span id=&#34;cb14-3&#34;&gt;&lt;a href=&#34;#cb14-3&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;ansible-playbook&lt;/span&gt; install_shiny_server.yml&lt;/span&gt;
&lt;span id=&#34;cb14-4&#34;&gt;&lt;a href=&#34;#cb14-4&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;ansible-playbook&lt;/span&gt; install_rstudio_server.yml&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you decide that you only need Shiny server or RStudio server but not the other, or you already have installed the support services you want, you can run only the playbooks you need.&lt;/p&gt;
&lt;p&gt;If you want to update something in the future, like R, RStudio, or Shiny server (I can’t guaranty that is always going to work out of the box), you can simply change the version in the config file and run the specific part of the playbook by taking advantage of the defined “tags”.&lt;/p&gt;
&lt;p&gt;For example, this will only install the R version defined in the config file and nothing more:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb15&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb15-1&#34;&gt;&lt;a href=&#34;#cb15-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;bu&#34;&gt;cd&lt;/span&gt; raspberry_pi_server&lt;/span&gt;
&lt;span id=&#34;cb15-2&#34;&gt;&lt;a href=&#34;#cb15-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;ansible-playbook&lt;/span&gt; install_basic_services.yml &lt;span class=&#34;at&#34;&gt;--tags&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;r&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The available tags are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;install_basic_services.yml
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;secure&lt;/code&gt;: Set security settings on the server&lt;/li&gt;
&lt;li&gt;&lt;code&gt;swap&lt;/code&gt;: Add swap memory to the server&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nginx&lt;/code&gt;: Install and configure Nginx + PHP&lt;/li&gt;
&lt;li&gt;&lt;code&gt;postgresql&lt;/code&gt;: Install and configure PostgreSQL&lt;/li&gt;
&lt;li&gt;&lt;code&gt;r&lt;/code&gt;: Install R from source&lt;/li&gt;
&lt;li&gt;&lt;code&gt;disable_wifi&lt;/code&gt;: Disable Wifi and Bluetooth module&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;install_shiny_server.yml
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;shiny-server&lt;/code&gt;: Install shiny-server from source&lt;/li&gt;
&lt;li&gt;&lt;code&gt;configure_shiny&lt;/code&gt;: Configure shiny-server&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;install_rstudio_server.yml
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;rstudio&lt;/code&gt;: Install RStudio server from source&lt;/li&gt;
&lt;li&gt;&lt;code&gt;configure_rstudio&lt;/code&gt;: Configure RStudio server&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can also go the other way and skip specific parts of the playbooks by using the &lt;code&gt;--skip-tags&lt;/code&gt; option, for example, if you don’t need PostgreSQL, you can avoid installing it by running the playbook this way:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb16&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb16-1&#34;&gt;&lt;a href=&#34;#cb16-1&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;bu&#34;&gt;cd&lt;/span&gt; raspberry_pi_server&lt;/span&gt;
&lt;span id=&#34;cb16-2&#34;&gt;&lt;a href=&#34;#cb16-2&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;ansible-playbook&lt;/span&gt; install_basic_services.yml &lt;span class=&#34;at&#34;&gt;--skip-tags&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;postgresql&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;After successfully running all the playbooks, you will have a fully functional installation ready to be used, so you could simply open an RStudio session at &lt;code&gt;http://your_server_ip/rstudio&lt;/code&gt; and/or publish your Shiny apps in the &lt;code&gt;/srv/shiny-server&lt;/code&gt; folder and access them at &lt;code&gt;http://your_server_ip/shiny/your_app_name&lt;/code&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;⚠️ If the Nginx configuration hasn’t been set by the &lt;code&gt;install_basic_services.yml&lt;/code&gt; playbook because you have omitted it, you have to configure the reverse proxy manually or access the services with their specific port, e.g. &lt;code&gt;http://your_server_ip/3838/your_app_name&lt;/code&gt;, this would also require you to open the corresponding port in the firewall.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div id=&#34;final-notes&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Final Notes&lt;/h2&gt;
&lt;p&gt;Even with the automation, installing natively is still going to take much longer than, for example, using containers, especially if you are using a low RAM Raspberry Pi SBC (&amp;lt; 4GB) but since it is automatized, you can simply let it running and come back later, and you will enjoy the simpler manageability of a native installation.&lt;/p&gt;
&lt;p&gt;Also, be aware that the installation process is going to push your Raspberry Pi to its limits so you can expect some random errors, but that doesn’t mean it’s not going to work, just restart your Pi, rerun the problematic playbook and see if it works the second time. I have done my best to make this functional in the long run by setting specific software versions but it is still possible that a system library update might break the playbooks, if you find any issues, please go to the GitHub repository for the playbooks and file an issue report, or even better, if you know how to fix it, make a pull request.&lt;/p&gt;
&lt;p&gt;As a final comment, I want to point out that this approach can be further extended accordingly to your own needs, for example, you can implement automatic restoration of your server including deployed content. For example, I have an additional playbook to restore the applications, services, and databases I normally run on my Raspberry Pi, so in the event of a catastrophic failure, I can get back to a working state in a short period of time and with little effort, compared with doing a manual restoration of my system.&lt;/p&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Customizing your package-library location</title>
      <link>https://andresrcs.rbind.io/2020/10/26/customizing_library_path/</link>
      <pubDate>Mon, 26 Oct 2020 00:00:00 +0000</pubDate>
      
      <guid>https://andresrcs.rbind.io/2020/10/26/customizing_library_path/</guid>
      <description>
&lt;script src=&#34;https://andresrcs.rbind.io/rmarkdown-libs/header-attrs/header-attrs.js&#34;&gt;&lt;/script&gt;
&lt;link href=&#34;https://andresrcs.rbind.io/rmarkdown-libs/anchor-sections/anchor-sections.css&#34; rel=&#34;stylesheet&#34; /&gt;
&lt;script src=&#34;https://andresrcs.rbind.io/rmarkdown-libs/anchor-sections/anchor-sections.js&#34;&gt;&lt;/script&gt;
&lt;style type=&#34;text/css&#34;&gt;
pre &gt; code.sourceCode { white-space: pre; position: relative; }
pre &gt; code.sourceCode &gt; span { display: inline-block; line-height: 1.25; }
pre &gt; code.sourceCode &gt; span:empty { height: 1.2em; }
code.sourceCode &gt; span { color: inherit; text-decoration: inherit; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
pre &gt; code.sourceCode { white-space: pre-wrap; }
pre &gt; code.sourceCode &gt; span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
  { counter-reset: source-line 0; }
pre.numberSource code &gt; span
  { position: relative; left: -4em; counter-increment: source-line; }
pre.numberSource code &gt; span &gt; a:first-child::before
  { content: counter(source-line);
    position: relative; left: -1em; text-align: right; vertical-align: baseline;
    border: none; display: inline-block;
    -webkit-touch-callout: none; -webkit-user-select: none;
    -khtml-user-select: none; -moz-user-select: none;
    -ms-user-select: none; user-select: none;
    padding: 0 4px; width: 4em;
  }
pre.numberSource { margin-left: 3em;  padding-left: 4px; }
div.sourceCode
  { color: #cccccc; background-color: #303030; }
@media screen {
pre &gt; code.sourceCode &gt; span &gt; a:first-child::before { text-decoration: underline; }
}
code span.al { color: #ffcfaf; } /* Alert */
code span.an { color: #7f9f7f; font-weight: bold; } /* Annotation */
code span.at { } /* Attribute */
code span.bn { color: #dca3a3; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #f0dfaf; } /* ControlFlow */
code span.ch { color: #dca3a3; } /* Char */
code span.cn { color: #dca3a3; font-weight: bold; } /* Constant */
code span.co { color: #7f9f7f; } /* Comment */
code span.cv { color: #7f9f7f; font-weight: bold; } /* CommentVar */
code span.do { color: #7f9f7f; } /* Documentation */
code span.dt { color: #dfdfbf; } /* DataType */
code span.dv { color: #dcdccc; } /* DecVal */
code span.er { color: #c3bf9f; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #c0bed1; } /* Float */
code span.fu { color: #efef8f; } /* Function */
code span.im { } /* Import */
code span.in { color: #7f9f7f; font-weight: bold; } /* Information */
code span.kw { color: #f0dfaf; } /* Keyword */
code span.op { color: #f0efd0; } /* Operator */
code span.ot { color: #efef8f; } /* Other */
code span.pp { color: #ffcfaf; font-weight: bold; } /* Preprocessor */
code span.sc { color: #dca3a3; } /* SpecialChar */
code span.ss { color: #cc9393; } /* SpecialString */
code span.st { color: #cc9393; } /* String */
code span.va { } /* Variable */
code span.vs { color: #cc9393; } /* VerbatimString */
code span.wa { color: #7f9f7f; font-weight: bold; } /* Warning */
&lt;/style&gt;


&lt;p&gt;For reasonably experienced R users this simple topic might not seem worthy of a blog post, so if you are not an R beginner, you may want to skip this post. Having that said, I have had to explain this task so many times on R community forums that writing one becomes mandatory to avoid typing the same text yet once again.&lt;/p&gt;
&lt;p&gt;The reasons to customize your library path instead of going with the defaults could be varied, but for R beginners the most common one is to avoid package installation problems due to write permissions, non-ASCII characters on folder paths, cloud-synced folders, or network drives, which lead into error messages such as:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb1&#34;&gt;&lt;pre class=&#34;sourceCode r&#34;&gt;&lt;code class=&#34;sourceCode r&#34;&gt;&lt;span id=&#34;cb1-1&#34;&gt;&lt;a href=&#34;#cb1-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;Warning &lt;span class=&#34;cf&#34;&gt;in&lt;/span&gt; install.packages &lt;span class=&#34;sc&#34;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-2&#34;&gt;&lt;a href=&#34;#cb1-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;st&#34;&gt;&amp;#39;lib = &amp;quot;/path/to/your/library&amp;quot;&amp;#39;&lt;/span&gt; is not writable&lt;/span&gt;
&lt;span id=&#34;cb1-3&#34;&gt;&lt;a href=&#34;#cb1-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;Error &lt;span class=&#34;cf&#34;&gt;in&lt;/span&gt; install.packages &lt;span class=&#34;sc&#34;&gt;:&lt;/span&gt; unable to install packages&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb2&#34;&gt;&lt;pre class=&#34;sourceCode r&#34;&gt;&lt;code class=&#34;sourceCode r&#34;&gt;&lt;span id=&#34;cb2-1&#34;&gt;&lt;a href=&#34;#cb2-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;sc&#34;&gt;**&lt;/span&gt; byte&lt;span class=&#34;sc&#34;&gt;-&lt;/span&gt;compile and prepare package &lt;span class=&#34;cf&#34;&gt;for&lt;/span&gt; lazy loading&lt;/span&gt;
&lt;span id=&#34;cb2-2&#34;&gt;&lt;a href=&#34;#cb2-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;Error&lt;span class=&#34;sc&#34;&gt;:&lt;/span&gt; unexpected symbol &lt;span class=&#34;cf&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;setwd(&amp;#39;incomplete/path/to/your/library&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-3&#34;&gt;&lt;a href=&#34;#cb2-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;Execution halted&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Very often, the solution for these issues is to set your package library somewhere else in your system, where you have proper permissions and there are no known R incompatibilities. The way to change a package library location is to manually set it on a startup file i.e. &lt;code&gt;Rprofile.site&lt;/code&gt; and &lt;code&gt;Renviron.site&lt;/code&gt; files for R-version level (located at &lt;code&gt;R_HOME/etc/&lt;/code&gt;) or &lt;code&gt;.Rprofile&lt;/code&gt; and &lt;code&gt;.Renviron&lt;/code&gt; files, for user-level (located at your &lt;code&gt;HOME&lt;/code&gt; folder) or project-level (located at the current working directory).&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;✏️ For more information about R startup files, you can read the following &lt;a href=&#34;https://support.rstudio.com/hc/en-us/articles/360047157094-Managing-R-with-Rprofile-Renviron-Rprofile-site-Renviron-site-rsession-conf-and-repos-conf&#34;&gt;support article&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For &lt;code&gt;Renviron&lt;/code&gt; type files, the corresponding environmental variable must be specified, for example, if I want to change the R library trees on a Linux system I would add a line like this to the &lt;code&gt;Renviron.site&lt;/code&gt; file located at &lt;code&gt;/usr/lib/R/etc/&lt;/code&gt; (On this case the &lt;code&gt;R_HOME&lt;/code&gt; environmental variable gets translated to &lt;code&gt;/usr/lib/R/&lt;/code&gt;).&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb3&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb3-1&#34;&gt;&lt;a href=&#34;#cb3-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;va&#34;&gt;R_LIBS_SITE=&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;&amp;quot;/usr/lib/R/site-library:/usr/lib/R/library&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Being the first location from the left the default one, which gets used by &lt;code&gt;install.packages()&lt;/code&gt; if the &lt;code&gt;lib&lt;/code&gt; argument is not specified, and all of them (which are colon-separated) are scanned for packages at startup in order. Have in mind that only directories that exist at the time will be included.&lt;/p&gt;
&lt;p&gt;For &lt;code&gt;Rprofile&lt;/code&gt; type files, the &lt;code&gt;.libPaths()&lt;/code&gt; function must be used, since these files must contain valid R code to be executed at startup, the equivalent R command to the previous example would be:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb4&#34;&gt;&lt;pre class=&#34;sourceCode r&#34;&gt;&lt;code class=&#34;sourceCode r&#34;&gt;&lt;span id=&#34;cb4-1&#34;&gt;&lt;a href=&#34;#cb4-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;.libPaths&lt;/span&gt;(&lt;span class=&#34;fu&#34;&gt;c&lt;/span&gt;(&lt;span class=&#34;st&#34;&gt;&amp;quot;/usr/lib/R/site-library&amp;quot;&lt;/span&gt;, &lt;span class=&#34;st&#34;&gt;&amp;quot;/usr/lib/R/library&amp;quot;&lt;/span&gt;))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Obviously, the folder paths are going to be different depending on your specific operating system and setup, but I hope you get the general idea that you have to specify a folder path that is suitable for your specific needs, for example, on a Windows system the equivalent would be:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb5&#34;&gt;&lt;pre class=&#34;sourceCode r&#34;&gt;&lt;code class=&#34;sourceCode r&#34;&gt;&lt;span id=&#34;cb5-1&#34;&gt;&lt;a href=&#34;#cb5-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;.libPaths&lt;/span&gt;(&lt;span class=&#34;fu&#34;&gt;c&lt;/span&gt;(&lt;span class=&#34;st&#34;&gt;&amp;quot;C:/Program Files/R/R-4.0.3/library&amp;quot;&lt;/span&gt;))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;By default, the default package-library is set at the user-level (&lt;code&gt;HOME&lt;/code&gt; folder), which, in some cases, can cause the aforementioned issues. Now, this is opinionated advice, but for simple individual use, I find it more practical to set the default package-library at R-version level (&lt;code&gt;R_HOME/library/&lt;/code&gt; folder) and explicitly make use of other locations, selectively, and accordingly to specific use cases. Be aware that depending on your security settings and operating system, you might need to run your R session with “administrator” rights or from a user with “sudo” rights in order for this to work.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Alternatives for retrieving sensor data from Arduino compatible microcontrollers into R</title>
      <link>https://andresrcs.rbind.io/2020/02/09/arduino_microcontroller_r/</link>
      <pubDate>Sun, 09 Feb 2020 00:00:00 +0000</pubDate>
      
      <guid>https://andresrcs.rbind.io/2020/02/09/arduino_microcontroller_r/</guid>
      <description>
&lt;style type=&#34;text/css&#34;&gt;
pre &gt; code.sourceCode { white-space: pre; position: relative; }
pre &gt; code.sourceCode &gt; span { display: inline-block; line-height: 1.25; }
pre &gt; code.sourceCode &gt; span:empty { height: 1.2em; }
.sourceCode { overflow: visible; }
code.sourceCode &gt; span { color: inherit; text-decoration: inherit; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
pre &gt; code.sourceCode { white-space: pre-wrap; }
pre &gt; code.sourceCode &gt; span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
  { counter-reset: source-line 0; }
pre.numberSource code &gt; span
  { position: relative; left: -4em; counter-increment: source-line; }
pre.numberSource code &gt; span &gt; a:first-child::before
  { content: counter(source-line);
    position: relative; left: -1em; text-align: right; vertical-align: baseline;
    border: none; display: inline-block;
    -webkit-touch-callout: none; -webkit-user-select: none;
    -khtml-user-select: none; -moz-user-select: none;
    -ms-user-select: none; user-select: none;
    padding: 0 4px; width: 4em;
  }
pre.numberSource { margin-left: 3em;  padding-left: 4px; }
div.sourceCode
  { color: #cccccc; background-color: #303030; }
@media screen {
pre &gt; code.sourceCode &gt; span &gt; a:first-child::before { text-decoration: underline; }
}
code span.al { color: #ffcfaf; } /* Alert */
code span.an { color: #7f9f7f; font-weight: bold; } /* Annotation */
code span.at { } /* Attribute */
code span.bn { color: #dca3a3; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #f0dfaf; } /* ControlFlow */
code span.ch { color: #dca3a3; } /* Char */
code span.cn { color: #dca3a3; font-weight: bold; } /* Constant */
code span.co { color: #7f9f7f; } /* Comment */
code span.cv { color: #7f9f7f; font-weight: bold; } /* CommentVar */
code span.do { color: #7f9f7f; } /* Documentation */
code span.dt { color: #dfdfbf; } /* DataType */
code span.dv { color: #dcdccc; } /* DecVal */
code span.er { color: #c3bf9f; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #c0bed1; } /* Float */
code span.fu { color: #efef8f; } /* Function */
code span.im { } /* Import */
code span.in { color: #7f9f7f; font-weight: bold; } /* Information */
code span.kw { color: #f0dfaf; } /* Keyword */
code span.op { color: #f0efd0; } /* Operator */
code span.ot { color: #efef8f; } /* Other */
code span.pp { color: #ffcfaf; font-weight: bold; } /* Preprocessor */
code span.sc { color: #dca3a3; } /* SpecialChar */
code span.ss { color: #cc9393; } /* SpecialString */
code span.st { color: #cc9393; } /* String */
code span.va { } /* Variable */
code span.vs { color: #cc9393; } /* VerbatimString */
code span.wa { color: #7f9f7f; font-weight: bold; } /* Warning */
&lt;/style&gt;

&lt;div id=&#34;TOC&#34;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#serial-connection&#34; id=&#34;toc-serial-connection&#34;&gt;Serial Connection&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#writing-to-a-sql-server&#34; id=&#34;toc-writing-to-a-sql-server&#34;&gt;Writing to a SQL server&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#using-the-mqtt-protocol&#34; id=&#34;toc-using-the-mqtt-protocol&#34;&gt;Using the MQTT protocol&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#disclaimer&#34; id=&#34;toc-disclaimer&#34;&gt;Disclaimer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;

&lt;p&gt;Have you ever wanted to get your own real-world data using sensors? With the advent of the &lt;a href=&#34;https://en.wikipedia.org/wiki/Open-source_hardware&#34;&gt;Open-Source Hardware&lt;/a&gt; movement, this has become more accessible for the general public, microcontrollers and sensors have become cheaper and easier to program with human-friendly languages like Arduino (C++) and MicroPython (Python), so now anybody can produce its own real-world sensorial data, but, there is still a problem, How do we get this data into R so we can analyze it?&lt;/p&gt;
&lt;p&gt;Depending on your application’s requirements you could choose among a plethora of options. For example, if you only need data on batches and you can have easy physical access to your device, you could simply add an SD card module to your project and log the data to a .csv file on an SD card but, that wouldn’t be fun, isn’t it? A much cooler solution would be to retrieve data remotely and preferably wirelessly, don’t you think?. Let’s explore some options.&lt;/p&gt;
&lt;div id=&#34;serial-connection&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Serial Connection&lt;/h2&gt;
&lt;p&gt;If you have never thought about getting data from microcontrollers before, I bet the first thought that comes to your mind, is to somehow directly connect the microcontroller with R to get the data, but this is currently the most technically challenging option, it can be done using a serial connection between the microcontroller and your computer, but as far as I know, there is only one &lt;a href=&#34;https://github.com/r-arduino/arduinor&#34;&gt;R package implementing this&lt;/a&gt; and only runs on POSIX-compatible systems (so no Windows).&lt;/p&gt;
&lt;p&gt;I can’t test this approach myself since I don’t have a physical Linux or macOS machine to connect a microcontroller to, so for this case, I’m just going to link to a &lt;a href=&#34;https://zhuhao.org/post/connect-arduino-chips-with-r/&#34;&gt;blog post&lt;/a&gt; by &lt;a href=&#34;https://twitter.com/haozhu233&#34;&gt;@haozhu233&lt;/a&gt; (the package author) showcasing its functionality.&lt;/p&gt;
&lt;p&gt;If your application requires real-time data acquisition or very low latency this might be your only option and you may want to dive deeper into this.&lt;/p&gt;
&lt;blockquote class=&#34;twitter-tweet&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;Streaming arduino sensor signals right into &lt;a href=&#34;https://twitter.com/rstudio?ref_src=twsrc%5Etfw&#34;&gt;@rstudio&lt;/a&gt;! I wonder if there is really anything &lt;a href=&#34;https://twitter.com/hashtag/rstats?src=hash&amp;amp;ref_src=twsrc%5Etfw&#34;&gt;#rstats&lt;/a&gt; can’t do 😎😎😎 &lt;a href=&#34;https://t.co/nT6q6TT6xc&#34;&gt;pic.twitter.com/nT6q6TT6xc&lt;/a&gt;&lt;/p&gt;&amp;mdash; Hao Zhu (@haozhu233) &lt;a href=&#34;https://twitter.com/haozhu233/status/1088851449096880128?ref_src=twsrc%5Etfw&#34;&gt;January 25, 2019&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async src=&#34;https://platform.twitter.com/widgets.js&#34; charset=&#34;utf-8&#34;&gt;&lt;/script&gt;


&lt;/div&gt;
&lt;div id=&#34;writing-to-a-sql-server&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Writing to a SQL server&lt;/h2&gt;
&lt;p&gt;There are two ways of doing this, one is to directly connect the microcontroller to the database and the other is to use another service to pull data from the microcontroller and write it into the database.&lt;/p&gt;
&lt;p&gt;The first option is harder to accomplish, as far as I know, there is only one &lt;a href=&#34;https://www.arduinolibraries.info/libraries/my-sql-connector-arduino&#34;&gt;Arduino library&lt;/a&gt; that provides a SQL connector for MySQL servers but, there are no already-made solutions for other SQL servers and although you could write your own connector for other Open Source SQL servers (like PostgreSQL), that would require a considerable amount of technical skills.&lt;/p&gt;
&lt;p&gt;The second option is easier to implement, and my personal favorite.&lt;/p&gt;
&lt;p&gt;The first step is to broadcast the data from the microcontroller, one way of doing this is to implement a simple web server on the microcontroller itself and serve the data on a suitable format like HTML, JSON or CSV.&lt;/p&gt;
&lt;p&gt;This is a simple example of an Arduino Sketch for an ESP8266 board (Wemos D1 mini) and DS18B20 temperature probe sensors, that serves HTML and JSON outputs over a web server.&lt;/p&gt;
&lt;script type=&#34;application/javascript&#34; src=&#34;https://gist.github.com/andresrcs/fa631e15f2f665335b0592fdeba20992.js&#34;&gt;&lt;/script&gt;

&lt;p&gt;The second step is to pull the data out of the microcontroller and into a SQL server, there are a lot of approaches and languages you can use to implement this part but obviously we are going to use R. You can write an R script that connects to the microcontroller, retrieves the data and writes it into a SQL server, and schedule the script with a &lt;code&gt;cron&lt;/code&gt; job.&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb1&#34;&gt;&lt;pre class=&#34;sourceCode r&#34;&gt;&lt;code class=&#34;sourceCode r&#34;&gt;&lt;span id=&#34;cb1-1&#34;&gt;&lt;a href=&#34;#cb1-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;#! /usr/bin/env Rscript&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-2&#34;&gt;&lt;a href=&#34;#cb1-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-3&#34;&gt;&lt;a href=&#34;#cb1-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# DATA ADQUISITION##############################################################&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-4&#34;&gt;&lt;a href=&#34;#cb1-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;raw_data &lt;span class=&#34;ot&#34;&gt;&amp;lt;-&lt;/span&gt; rjson&lt;span class=&#34;sc&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;fromJSON&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;file=&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;&amp;quot;http://192.168.0.102/reading.json&amp;quot;&lt;/span&gt;) &lt;/span&gt;
&lt;span id=&#34;cb1-5&#34;&gt;&lt;a href=&#34;#cb1-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;current_time &lt;span class=&#34;ot&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;as.character&lt;/span&gt;(&lt;span class=&#34;fu&#34;&gt;Sys.time&lt;/span&gt;())&lt;/span&gt;
&lt;span id=&#34;cb1-6&#34;&gt;&lt;a href=&#34;#cb1-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-7&#34;&gt;&lt;a href=&#34;#cb1-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# PARAMETERS ###################################################################&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-8&#34;&gt;&lt;a href=&#34;#cb1-8&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;current_location &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;some_place&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-9&#34;&gt;&lt;a href=&#34;#cb1-9&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;point_names &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;c&lt;/span&gt;(&lt;span class=&#34;st&#34;&gt;&amp;quot;probe0&amp;quot;&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;measurement_point_0&amp;quot;&lt;/span&gt;, &lt;/span&gt;
&lt;span id=&#34;cb1-10&#34;&gt;&lt;a href=&#34;#cb1-10&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                &lt;span class=&#34;st&#34;&gt;&amp;quot;probe1&amp;quot;&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;measurement_point_1&amp;quot;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb1-11&#34;&gt;&lt;a href=&#34;#cb1-11&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                &lt;span class=&#34;st&#34;&gt;&amp;quot;probe2&amp;quot;&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;measurement_point_2&amp;quot;&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb1-12&#34;&gt;&lt;a href=&#34;#cb1-12&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-13&#34;&gt;&lt;a href=&#34;#cb1-13&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# LIBRARIES ####################################################################&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-14&#34;&gt;&lt;a href=&#34;#cb1-14&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;library&lt;/span&gt;(dplyr)&lt;/span&gt;
&lt;span id=&#34;cb1-15&#34;&gt;&lt;a href=&#34;#cb1-15&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-16&#34;&gt;&lt;a href=&#34;#cb1-16&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# DATA CLEANING ################################################################&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-17&#34;&gt;&lt;a href=&#34;#cb1-17&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;tidy_data &lt;span class=&#34;ot&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;as_tibble&lt;/span&gt;(raw_data) &lt;span class=&#34;sc&#34;&gt;%&amp;gt;%&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-18&#34;&gt;&lt;a href=&#34;#cb1-18&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    tidyr&lt;span class=&#34;sc&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;gather&lt;/span&gt;(measurement_point, value) &lt;span class=&#34;sc&#34;&gt;%&amp;gt;%&lt;/span&gt; &lt;/span&gt;
&lt;span id=&#34;cb1-19&#34;&gt;&lt;a href=&#34;#cb1-19&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;fu&#34;&gt;mutate&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;time =&lt;/span&gt; current_time,&lt;/span&gt;
&lt;span id=&#34;cb1-20&#34;&gt;&lt;a href=&#34;#cb1-20&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;           &lt;span class=&#34;at&#34;&gt;location =&lt;/span&gt; current_location,&lt;/span&gt;
&lt;span id=&#34;cb1-21&#34;&gt;&lt;a href=&#34;#cb1-21&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;           &lt;span class=&#34;at&#34;&gt;variable =&lt;/span&gt; stringr&lt;span class=&#34;sc&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;str_extract&lt;/span&gt;(measurement_point, &lt;span class=&#34;st&#34;&gt;&amp;quot;^.+(?=-)&amp;quot;&lt;/span&gt;),&lt;/span&gt;
&lt;span id=&#34;cb1-22&#34;&gt;&lt;a href=&#34;#cb1-22&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;           &lt;span class=&#34;at&#34;&gt;measurement_point =&lt;/span&gt; stringr&lt;span class=&#34;sc&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;str_extract&lt;/span&gt;(measurement_point, &lt;span class=&#34;st&#34;&gt;&amp;quot;(?&amp;lt;=-).+$&amp;quot;&lt;/span&gt;),&lt;/span&gt;
&lt;span id=&#34;cb1-23&#34;&gt;&lt;a href=&#34;#cb1-23&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;           &lt;span class=&#34;at&#34;&gt;measurement_point =&lt;/span&gt; stringr&lt;span class=&#34;sc&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;str_replace_all&lt;/span&gt;(measurement_point, point_names)&lt;/span&gt;
&lt;span id=&#34;cb1-24&#34;&gt;&lt;a href=&#34;#cb1-24&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;           ) &lt;span class=&#34;sc&#34;&gt;%&amp;gt;%&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-25&#34;&gt;&lt;a href=&#34;#cb1-25&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;fu&#34;&gt;select&lt;/span&gt;(time, location, variable, measurement_point, value)&lt;/span&gt;
&lt;span id=&#34;cb1-26&#34;&gt;&lt;a href=&#34;#cb1-26&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-27&#34;&gt;&lt;a href=&#34;#cb1-27&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# LOAD DATA ####################################################################&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-28&#34;&gt;&lt;a href=&#34;#cb1-28&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;con &lt;span class=&#34;ot&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;dbConnect&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;drv =&lt;/span&gt; odbc&lt;span class=&#34;sc&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;odbc&lt;/span&gt;(),&lt;/span&gt;
&lt;span id=&#34;cb1-29&#34;&gt;&lt;a href=&#34;#cb1-29&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                 &lt;span class=&#34;at&#34;&gt;driver =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;PostgreSQL ANSI&amp;#39;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb1-30&#34;&gt;&lt;a href=&#34;#cb1-30&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                 &lt;span class=&#34;at&#34;&gt;server =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;localhost&amp;#39;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb1-31&#34;&gt;&lt;a href=&#34;#cb1-31&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                 &lt;span class=&#34;at&#34;&gt;database =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;sensors&amp;#39;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb1-32&#34;&gt;&lt;a href=&#34;#cb1-32&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                 &lt;span class=&#34;at&#34;&gt;port =&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;5432&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb1-33&#34;&gt;&lt;a href=&#34;#cb1-33&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                 &lt;span class=&#34;at&#34;&gt;uid =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;Sys.getenv&lt;/span&gt;(&lt;span class=&#34;st&#34;&gt;&amp;#39;MY_UID&amp;#39;&lt;/span&gt;),&lt;/span&gt;
&lt;span id=&#34;cb1-34&#34;&gt;&lt;a href=&#34;#cb1-34&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                 &lt;span class=&#34;at&#34;&gt;pwd =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;Sys.getenv&lt;/span&gt;(&lt;span class=&#34;st&#34;&gt;&amp;#39;MY_PWD&amp;#39;&lt;/span&gt;),&lt;/span&gt;
&lt;span id=&#34;cb1-35&#34;&gt;&lt;a href=&#34;#cb1-35&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                 &lt;span class=&#34;at&#34;&gt;encoding =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;utf8&amp;#39;&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb1-36&#34;&gt;&lt;a href=&#34;#cb1-36&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-37&#34;&gt;&lt;a href=&#34;#cb1-37&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;DBI&lt;span class=&#34;sc&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;dbAppendTable&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;conn =&lt;/span&gt; con,&lt;/span&gt;
&lt;span id=&#34;cb1-38&#34;&gt;&lt;a href=&#34;#cb1-38&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                   &lt;span class=&#34;at&#34;&gt;name =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;sensors_data&amp;#39;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb1-39&#34;&gt;&lt;a href=&#34;#cb1-39&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                   &lt;span class=&#34;at&#34;&gt;value =&lt;/span&gt; tidy_data)&lt;/span&gt;
&lt;span id=&#34;cb1-40&#34;&gt;&lt;a href=&#34;#cb1-40&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-41&#34;&gt;&lt;a href=&#34;#cb1-41&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;odbc&lt;span class=&#34;sc&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;dbDisconnect&lt;/span&gt;(con)&lt;/span&gt;
&lt;span id=&#34;cb1-42&#34;&gt;&lt;a href=&#34;#cb1-42&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb1-43&#34;&gt;&lt;a href=&#34;#cb1-43&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;unlink&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;x =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;*.log&amp;quot;&lt;/span&gt;, &lt;span class=&#34;at&#34;&gt;force =&lt;/span&gt; &lt;span class=&#34;cn&#34;&gt;TRUE&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now that you have the data into a SQL server, you are at one SQL query away of getting it into R&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb2&#34;&gt;&lt;pre class=&#34;sourceCode r&#34;&gt;&lt;code class=&#34;sourceCode r&#34;&gt;&lt;span id=&#34;cb2-1&#34;&gt;&lt;a href=&#34;#cb2-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;library&lt;/span&gt;(odbc)&lt;/span&gt;
&lt;span id=&#34;cb2-2&#34;&gt;&lt;a href=&#34;#cb2-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-3&#34;&gt;&lt;a href=&#34;#cb2-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;con &lt;span class=&#34;ot&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;dbConnect&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;drv =&lt;/span&gt; odbc&lt;span class=&#34;sc&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;odbc&lt;/span&gt;(),&lt;/span&gt;
&lt;span id=&#34;cb2-4&#34;&gt;&lt;a href=&#34;#cb2-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                 &lt;span class=&#34;at&#34;&gt;driver =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;PostgreSQL ANSI&amp;#39;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb2-5&#34;&gt;&lt;a href=&#34;#cb2-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                 &lt;span class=&#34;at&#34;&gt;server =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;localhost&amp;#39;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb2-6&#34;&gt;&lt;a href=&#34;#cb2-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                 &lt;span class=&#34;at&#34;&gt;database =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;sensors&amp;#39;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb2-7&#34;&gt;&lt;a href=&#34;#cb2-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                 &lt;span class=&#34;at&#34;&gt;port =&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;5432&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb2-8&#34;&gt;&lt;a href=&#34;#cb2-8&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                 &lt;span class=&#34;at&#34;&gt;uid =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;Sys.getenv&lt;/span&gt;(&lt;span class=&#34;st&#34;&gt;&amp;#39;MY_UID&amp;#39;&lt;/span&gt;),&lt;/span&gt;
&lt;span id=&#34;cb2-9&#34;&gt;&lt;a href=&#34;#cb2-9&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                 &lt;span class=&#34;at&#34;&gt;pwd =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;Sys.getenv&lt;/span&gt;(&lt;span class=&#34;st&#34;&gt;&amp;#39;MY_PWD&amp;#39;&lt;/span&gt;),&lt;/span&gt;
&lt;span id=&#34;cb2-10&#34;&gt;&lt;a href=&#34;#cb2-10&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                 &lt;span class=&#34;at&#34;&gt;encoding =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;utf8&amp;#39;&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb2-11&#34;&gt;&lt;a href=&#34;#cb2-11&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-12&#34;&gt;&lt;a href=&#34;#cb2-12&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;query &lt;span class=&#34;ot&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-13&#34;&gt;&lt;a href=&#34;#cb2-13&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;st&#34;&gt;    SELECT * &lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-14&#34;&gt;&lt;a href=&#34;#cb2-14&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;st&#34;&gt;    FROM public.sensors_data&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-15&#34;&gt;&lt;a href=&#34;#cb2-15&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;st&#34;&gt;    &amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-16&#34;&gt;&lt;a href=&#34;#cb2-16&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-17&#34;&gt;&lt;a href=&#34;#cb2-17&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;raw_data &lt;span class=&#34;ot&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;dbGetQuery&lt;/span&gt;(&lt;/span&gt;
&lt;span id=&#34;cb2-18&#34;&gt;&lt;a href=&#34;#cb2-18&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;at&#34;&gt;conn =&lt;/span&gt; con,&lt;/span&gt;
&lt;span id=&#34;cb2-19&#34;&gt;&lt;a href=&#34;#cb2-19&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;at&#34;&gt;statement =&lt;/span&gt; query&lt;/span&gt;
&lt;span id=&#34;cb2-20&#34;&gt;&lt;a href=&#34;#cb2-20&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;)&lt;/span&gt;
&lt;span id=&#34;cb2-21&#34;&gt;&lt;a href=&#34;#cb2-21&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-22&#34;&gt;&lt;a href=&#34;#cb2-22&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;dbDisconnect&lt;/span&gt;(con)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;What makes this approach my personal favorite is that it is fairly easy to implement, very flexible and allows you to implement almost any security measure you might need.&lt;/p&gt;
&lt;/div&gt;
&lt;div id=&#34;using-the-mqtt-protocol&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Using the MQTT protocol&lt;/h2&gt;
&lt;p&gt;For more resource-constrained applications you can use a similar approach to the previous one, but with a different technology, the MQTT protocol is ideal for low power devices over slow and unreliable connections, moreover, this is also a way to get data from LoRa networks like the publicly available &lt;a href=&#34;https://www.thethingsnetwork.org/&#34;&gt;TTN (The Things Network)&lt;/a&gt; which provides an API over MQTT, giving you access to a &lt;a href=&#34;https://en.wikipedia.org/wiki/LPWAN&#34;&gt;low-power wide-area network&lt;/a&gt; for remote sensor deployment over greater distances.&lt;/p&gt;
&lt;p&gt;This approach also allows you to write data to a SQL server like in the previous example but, a more interesting application for this would be to get instant status updates to show on dashboards or shiny apps. Consider this simple shiny app that receives a message from a simulated remote sensor and updates the color of a circle accordingly, you can update the temperature value of the simulated sensor by sending an MQTT message to the test topic from a system terminal on any computer with this command &lt;code&gt;mosquitto_pub -h test.mosquitto.org -t simulated_sensor -q 1 -m 25.9 -r&lt;/code&gt; and see how the color changes.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;✏️ In order for this to work you need to have the &lt;code&gt;mosquitto&lt;/code&gt; client installed in your system.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;sudo apt install mosquitto-clients&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb4&#34;&gt;&lt;pre class=&#34;sourceCode r&#34;&gt;&lt;code class=&#34;sourceCode r&#34;&gt;&lt;span id=&#34;cb4-1&#34;&gt;&lt;a href=&#34;#cb4-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;library&lt;/span&gt;(shiny)&lt;/span&gt;
&lt;span id=&#34;cb4-2&#34;&gt;&lt;a href=&#34;#cb4-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;library&lt;/span&gt;(ggplot2)&lt;/span&gt;
&lt;span id=&#34;cb4-3&#34;&gt;&lt;a href=&#34;#cb4-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;library&lt;/span&gt;(rmqtt)  &lt;span class=&#34;co&#34;&gt;# This package is just a simple wrapper for an MQTT client using&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-4&#34;&gt;&lt;a href=&#34;#cb4-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                &lt;span class=&#34;co&#34;&gt;# system() calls, you need to have the mosquitto client installed&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-5&#34;&gt;&lt;a href=&#34;#cb4-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                &lt;span class=&#34;co&#34;&gt;# in your system for this to work.&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-6&#34;&gt;&lt;a href=&#34;#cb4-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-7&#34;&gt;&lt;a href=&#34;#cb4-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Initialize Simulated Sensor&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-8&#34;&gt;&lt;a href=&#34;#cb4-8&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;mqtt_topic_publish&lt;/span&gt;(&lt;/span&gt;
&lt;span id=&#34;cb4-9&#34;&gt;&lt;a href=&#34;#cb4-9&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;at&#34;&gt;topic =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;simulated_sensor&amp;quot;&lt;/span&gt;, &lt;/span&gt;
&lt;span id=&#34;cb4-10&#34;&gt;&lt;a href=&#34;#cb4-10&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;at&#34;&gt;message_to_send =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;24.9&amp;quot;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb4-11&#34;&gt;&lt;a href=&#34;#cb4-11&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;at&#34;&gt;host =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;test.mosquitto.org&amp;quot;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb4-12&#34;&gt;&lt;a href=&#34;#cb4-12&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;at&#34;&gt;port =&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;1883&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb4-13&#34;&gt;&lt;a href=&#34;#cb4-13&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;at&#34;&gt;qos =&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;, &lt;/span&gt;
&lt;span id=&#34;cb4-14&#34;&gt;&lt;a href=&#34;#cb4-14&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;at&#34;&gt;retain_message =&lt;/span&gt; &lt;span class=&#34;cn&#34;&gt;TRUE&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-15&#34;&gt;&lt;a href=&#34;#cb4-15&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;)&lt;/span&gt;
&lt;span id=&#34;cb4-16&#34;&gt;&lt;a href=&#34;#cb4-16&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-17&#34;&gt;&lt;a href=&#34;#cb4-17&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;ui &lt;span class=&#34;ot&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;fluidPage&lt;/span&gt;(&lt;/span&gt;
&lt;span id=&#34;cb4-18&#34;&gt;&lt;a href=&#34;#cb4-18&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;fu&#34;&gt;titlePanel&lt;/span&gt;(&lt;span class=&#34;st&#34;&gt;&amp;quot;Dashboard&amp;quot;&lt;/span&gt;),&lt;/span&gt;
&lt;span id=&#34;cb4-19&#34;&gt;&lt;a href=&#34;#cb4-19&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;fu&#34;&gt;mainPanel&lt;/span&gt;(&lt;/span&gt;
&lt;span id=&#34;cb4-20&#34;&gt;&lt;a href=&#34;#cb4-20&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;fu&#34;&gt;h2&lt;/span&gt;(&lt;span class=&#34;st&#34;&gt;&amp;quot;Temperature Indicator&amp;quot;&lt;/span&gt;),&lt;/span&gt;
&lt;span id=&#34;cb4-21&#34;&gt;&lt;a href=&#34;#cb4-21&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;fu&#34;&gt;plotOutput&lt;/span&gt;(&lt;span class=&#34;st&#34;&gt;&amp;quot;status_indicator&amp;quot;&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb4-22&#34;&gt;&lt;a href=&#34;#cb4-22&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    )&lt;/span&gt;
&lt;span id=&#34;cb4-23&#34;&gt;&lt;a href=&#34;#cb4-23&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;)&lt;/span&gt;
&lt;span id=&#34;cb4-24&#34;&gt;&lt;a href=&#34;#cb4-24&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-25&#34;&gt;&lt;a href=&#34;#cb4-25&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;server &lt;span class=&#34;ot&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;cf&#34;&gt;function&lt;/span&gt;(input, output, session) {&lt;/span&gt;
&lt;span id=&#34;cb4-26&#34;&gt;&lt;a href=&#34;#cb4-26&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;/span&gt;
&lt;span id=&#34;cb4-27&#34;&gt;&lt;a href=&#34;#cb4-27&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    get_color &lt;span class=&#34;ot&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;cf&#34;&gt;function&lt;/span&gt;() {&lt;/span&gt;
&lt;span id=&#34;cb4-28&#34;&gt;&lt;a href=&#34;#cb4-28&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        message &lt;span class=&#34;ot&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;mqtt_topic_subscribe&lt;/span&gt;(&lt;/span&gt;
&lt;span id=&#34;cb4-29&#34;&gt;&lt;a href=&#34;#cb4-29&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;at&#34;&gt;topic =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;simulated_sensor&amp;quot;&lt;/span&gt;, &lt;/span&gt;
&lt;span id=&#34;cb4-30&#34;&gt;&lt;a href=&#34;#cb4-30&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;at&#34;&gt;host =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;test.mosquitto.org&amp;quot;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb4-31&#34;&gt;&lt;a href=&#34;#cb4-31&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;at&#34;&gt;port =&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;1883&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb4-32&#34;&gt;&lt;a href=&#34;#cb4-32&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;at&#34;&gt;qos =&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb4-33&#34;&gt;&lt;a href=&#34;#cb4-33&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;at&#34;&gt;intern =&lt;/span&gt; &lt;span class=&#34;cn&#34;&gt;TRUE&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb4-34&#34;&gt;&lt;a href=&#34;#cb4-34&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;at&#34;&gt;num.messages =&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-35&#34;&gt;&lt;a href=&#34;#cb4-35&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        )&lt;/span&gt;
&lt;span id=&#34;cb4-36&#34;&gt;&lt;a href=&#34;#cb4-36&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;/span&gt;
&lt;span id=&#34;cb4-37&#34;&gt;&lt;a href=&#34;#cb4-37&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;cf&#34;&gt;if&lt;/span&gt; (&lt;span class=&#34;fu&#34;&gt;as.numeric&lt;/span&gt;(message) &lt;span class=&#34;sc&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;25&lt;/span&gt;) {&lt;/span&gt;
&lt;span id=&#34;cb4-38&#34;&gt;&lt;a href=&#34;#cb4-38&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;            color &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;red&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-39&#34;&gt;&lt;a href=&#34;#cb4-39&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        } &lt;span class=&#34;cf&#34;&gt;else&lt;/span&gt; {&lt;/span&gt;
&lt;span id=&#34;cb4-40&#34;&gt;&lt;a href=&#34;#cb4-40&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;            color &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;green&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-41&#34;&gt;&lt;a href=&#34;#cb4-41&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        }&lt;/span&gt;
&lt;span id=&#34;cb4-42&#34;&gt;&lt;a href=&#34;#cb4-42&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;/span&gt;
&lt;span id=&#34;cb4-43&#34;&gt;&lt;a href=&#34;#cb4-43&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;fu&#34;&gt;return&lt;/span&gt;(color)&lt;/span&gt;
&lt;span id=&#34;cb4-44&#34;&gt;&lt;a href=&#34;#cb4-44&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    }&lt;/span&gt;
&lt;span id=&#34;cb4-45&#34;&gt;&lt;a href=&#34;#cb4-45&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;/span&gt;
&lt;span id=&#34;cb4-46&#34;&gt;&lt;a href=&#34;#cb4-46&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    pollData &lt;span class=&#34;ot&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;reactivePoll&lt;/span&gt;(&lt;span class=&#34;dv&#34;&gt;100&lt;/span&gt;, session,&lt;/span&gt;
&lt;span id=&#34;cb4-47&#34;&gt;&lt;a href=&#34;#cb4-47&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                             &lt;span class=&#34;at&#34;&gt;checkFunc =&lt;/span&gt; get_color,&lt;/span&gt;
&lt;span id=&#34;cb4-48&#34;&gt;&lt;a href=&#34;#cb4-48&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                             &lt;span class=&#34;at&#34;&gt;valueFunc =&lt;/span&gt; get_color&lt;/span&gt;
&lt;span id=&#34;cb4-49&#34;&gt;&lt;a href=&#34;#cb4-49&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    )&lt;/span&gt;
&lt;span id=&#34;cb4-50&#34;&gt;&lt;a href=&#34;#cb4-50&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;/span&gt;
&lt;span id=&#34;cb4-51&#34;&gt;&lt;a href=&#34;#cb4-51&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    output&lt;span class=&#34;sc&#34;&gt;$&lt;/span&gt;status_indicator &lt;span class=&#34;ot&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;renderPlot&lt;/span&gt;({&lt;/span&gt;
&lt;span id=&#34;cb4-52&#34;&gt;&lt;a href=&#34;#cb4-52&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;        &lt;span class=&#34;fu&#34;&gt;ggplot&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;data =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;data.frame&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;x =&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;, &lt;span class=&#34;at&#34;&gt;y =&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;), &lt;span class=&#34;fu&#34;&gt;aes&lt;/span&gt;(x, y)) &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-53&#34;&gt;&lt;a href=&#34;#cb4-53&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;fu&#34;&gt;geom_point&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;size =&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;50&lt;/span&gt;, &lt;span class=&#34;at&#34;&gt;color =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;pollData&lt;/span&gt;()) &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-54&#34;&gt;&lt;a href=&#34;#cb4-54&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;fu&#34;&gt;scale_x_discrete&lt;/span&gt;() &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-55&#34;&gt;&lt;a href=&#34;#cb4-55&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;fu&#34;&gt;scale_y_discrete&lt;/span&gt;() &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-56&#34;&gt;&lt;a href=&#34;#cb4-56&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;fu&#34;&gt;theme_void&lt;/span&gt;() &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-57&#34;&gt;&lt;a href=&#34;#cb4-57&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;fu&#34;&gt;theme&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;axis.title =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;element_blank&lt;/span&gt;())&lt;/span&gt;
&lt;span id=&#34;cb4-58&#34;&gt;&lt;a href=&#34;#cb4-58&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    })&lt;/span&gt;
&lt;span id=&#34;cb4-59&#34;&gt;&lt;a href=&#34;#cb4-59&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;}&lt;/span&gt;
&lt;span id=&#34;cb4-60&#34;&gt;&lt;a href=&#34;#cb4-60&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-61&#34;&gt;&lt;a href=&#34;#cb4-61&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;shinyApp&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;ui =&lt;/span&gt; ui, &lt;span class=&#34;at&#34;&gt;server =&lt;/span&gt; server)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;img src=&#34;https://andresrcs.rbind.io/post/2020-01-25-arduino-compatible-microcontrollers-r.en_files/shinyapp_mqtt.jpg&#34; width=&#34;400&#34; height=&#34;300&#34; /&gt;&lt;/p&gt;
&lt;p&gt;If you are interested in testing this, here is a GitHub Gist with the &lt;a href=&#34;https://gist.github.com/andresrcs/a2000bf54bf98be64351bbad34bdb838&#34;&gt;Arduino Sketch&lt;/a&gt; for an ESP8266 board whit a DS18B20 temperature probe sensor that can update the values in the example app.&lt;/p&gt;
&lt;p&gt;I know this doesn’t look very interesting right now but consider the implications. You could be getting instant updates in your dashboard from sensors deployed at kilometers downrange and you could even control remote actuators from your shiny app by sending an MQTT message from it with the click of a button!&lt;/p&gt;
&lt;p&gt;The downside of this method is that you need to set an MQTT broker (you should not abuse the publicly available ones that are intended for testing), but it can be done for no or little money on a Raspberry Pi or an EC2 AWS instance.&lt;/p&gt;
&lt;/div&gt;
&lt;div id=&#34;disclaimer&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Disclaimer&lt;/h2&gt;
&lt;p&gt;I want to make clear that this is by no means an exhaustive list, there are other alternatives and countless variations of the ones presented here so if none of these fitts your particular project’s needs, just keep looking, very likely someone has come up with a more suitable method.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;✏️ If you want to see a detailed step by step example of any of these options, write it on the comments and I’ll try to make a blog post about it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Keeping track of your actual internet speed over time, using R and Speedtest-CLI</title>
      <link>https://andresrcs.rbind.io/2020/01/21/speed_test/</link>
      <pubDate>Tue, 21 Jan 2020 00:00:00 +0000</pubDate>
      
      <guid>https://andresrcs.rbind.io/2020/01/21/speed_test/</guid>
      <description>
&lt;style type=&#34;text/css&#34;&gt;
pre &gt; code.sourceCode { white-space: pre; position: relative; }
pre &gt; code.sourceCode &gt; span { display: inline-block; line-height: 1.25; }
pre &gt; code.sourceCode &gt; span:empty { height: 1.2em; }
.sourceCode { overflow: visible; }
code.sourceCode &gt; span { color: inherit; text-decoration: inherit; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
pre &gt; code.sourceCode { white-space: pre-wrap; }
pre &gt; code.sourceCode &gt; span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
  { counter-reset: source-line 0; }
pre.numberSource code &gt; span
  { position: relative; left: -4em; counter-increment: source-line; }
pre.numberSource code &gt; span &gt; a:first-child::before
  { content: counter(source-line);
    position: relative; left: -1em; text-align: right; vertical-align: baseline;
    border: none; display: inline-block;
    -webkit-touch-callout: none; -webkit-user-select: none;
    -khtml-user-select: none; -moz-user-select: none;
    -ms-user-select: none; user-select: none;
    padding: 0 4px; width: 4em;
  }
pre.numberSource { margin-left: 3em;  padding-left: 4px; }
div.sourceCode
  { color: #cccccc; background-color: #303030; }
@media screen {
pre &gt; code.sourceCode &gt; span &gt; a:first-child::before { text-decoration: underline; }
}
code span.al { color: #ffcfaf; } /* Alert */
code span.an { color: #7f9f7f; font-weight: bold; } /* Annotation */
code span.at { } /* Attribute */
code span.bn { color: #dca3a3; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #f0dfaf; } /* ControlFlow */
code span.ch { color: #dca3a3; } /* Char */
code span.cn { color: #dca3a3; font-weight: bold; } /* Constant */
code span.co { color: #7f9f7f; } /* Comment */
code span.cv { color: #7f9f7f; font-weight: bold; } /* CommentVar */
code span.do { color: #7f9f7f; } /* Documentation */
code span.dt { color: #dfdfbf; } /* DataType */
code span.dv { color: #dcdccc; } /* DecVal */
code span.er { color: #c3bf9f; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #c0bed1; } /* Float */
code span.fu { color: #efef8f; } /* Function */
code span.im { } /* Import */
code span.in { color: #7f9f7f; font-weight: bold; } /* Information */
code span.kw { color: #f0dfaf; } /* Keyword */
code span.op { color: #f0efd0; } /* Operator */
code span.ot { color: #efef8f; } /* Other */
code span.pp { color: #ffcfaf; font-weight: bold; } /* Preprocessor */
code span.sc { color: #dca3a3; } /* SpecialChar */
code span.ss { color: #cc9393; } /* SpecialString */
code span.st { color: #cc9393; } /* String */
code span.va { } /* Variable */
code span.vs { color: #cc9393; } /* VerbatimString */
code span.wa { color: #7f9f7f; font-weight: bold; } /* Warning */
&lt;/style&gt;

&lt;div id=&#34;TOC&#34;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#getting-your-setup-ready&#34; id=&#34;toc-getting-your-setup-ready&#34;&gt;Getting Your Setup Ready&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#gathering-data&#34; id=&#34;toc-gathering-data&#34;&gt;Gathering Data&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#visualizing-the-data&#34; id=&#34;toc-visualizing-the-data&#34;&gt;Visualizing the Data&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;

&lt;p&gt;I thought this only happened in my country (Perú), but it turns out it happens to people around the globe, you contract an Internet Service Plan that offers &lt;strong&gt;up to&lt;/strong&gt; &lt;code&gt;X&lt;/code&gt; Mbps, where &lt;code&gt;X&lt;/code&gt; is an impressive value (relative to each country’s context), but the catch is in that word, &lt;strong&gt;Up to&lt;/strong&gt;.&lt;/p&gt;
&lt;blockquote class=&#34;twitter-tweet&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;If it makes you feel better, it could be worse if you lived in another country, trust me, I know... &lt;a href=&#34;https://t.co/Rm3J2J2Cdz&#34;&gt;pic.twitter.com/Rm3J2J2Cdz&lt;/a&gt;&lt;/p&gt;&amp;mdash; Andrés Castro Socolich (@Andresrcs) &lt;a href=&#34;https://twitter.com/Andresrcs/status/1217915622023147542?ref_src=twsrc%5Etfw&#34;&gt;January 16, 2020&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async src=&#34;https://platform.twitter.com/widgets.js&#34; charset=&#34;utf-8&#34;&gt;&lt;/script&gt;


&lt;p&gt;In reality, you end up getting far slower download speeds than advertised, and ISPs (Internet Service Providers) get away with this because they only test download speed with you once when they install the service (suspiciously it works great at that moment) and most people don’t bother to keep track of their download speeds over time because it would be impractical to manually perform speed tests every short period of time, luckily there is a better way, &lt;a href=&#34;https://www.speedtest.net/&#34;&gt;Ookla’s Speedtest&lt;/a&gt; service provides a &lt;em&gt;&lt;strong&gt;Command Line Interface (CLI)&lt;/strong&gt;&lt;/em&gt; that allows you to perform tests from your system terminal enabling you to set up automated scripts to collect connection performance data.&lt;/p&gt;
&lt;p&gt;In the next lines, I’m going to show you how to do this from R and get the results in the form of nice plots you can tweet to your ISP to annoy them a little bit. 😆&lt;/p&gt;
&lt;div id=&#34;getting-your-setup-ready&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Getting Your Setup Ready&lt;/h2&gt;
&lt;p&gt;We have to set up our working environment for this project. First, we need a machine that is constantly powered on and connected to the same internet connection you want to test so it can perform the tests and store the data, it could be any computer connected to your local network but the most practical (and cost-effective) solution I have found is using a Raspberry Pi SBC so I’m going to use one for this project.&lt;/p&gt;
&lt;p&gt;Since you are reading an R related article I’m going to assume you already have your basic R environment set, so we are going to focus on the additional stuff, we need to install the Speedtest Command Line Interface (CLI), if you are in a Linux machine, you can do it with this commands on a system terminal:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;✏️ There are &lt;a href=&#34;https://www.speedtest.net/apps/cli&#34;&gt;installation instructions for other OSs&lt;/a&gt; on the Speedtest web site&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb1&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb1-1&#34;&gt;&lt;a href=&#34;#cb1-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; apt-get install curl&lt;/span&gt;
&lt;span id=&#34;cb1-2&#34;&gt;&lt;a href=&#34;#cb1-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;ex&#34;&gt;curl&lt;/span&gt; &lt;span class=&#34;at&#34;&gt;-s&lt;/span&gt; https://packagecloud.io/install/repositories/ookla/speedtest-cli/script.deb.sh &lt;span class=&#34;kw&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; bash&lt;/span&gt;
&lt;span id=&#34;cb1-3&#34;&gt;&lt;a href=&#34;#cb1-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; apt-get install speedtest&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;✏️ Check if you have an older python version of the CLI installed in your system and make sure to uninstall it with this command &lt;code&gt;sudo pip uninstall speedtes-cli&lt;/code&gt;, since it could cause conflicts with the newer official version. This happened to me and I didn’t notice 😳, thanks to &lt;a href=&#34;https://twitter.com/jasongrahn&#34;&gt;@jasongrahn&lt;/a&gt; for the heads up.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div id=&#34;gathering-data&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Gathering Data&lt;/h2&gt;
&lt;p&gt;Now we can write an R script that retrieves the test output, parses the content and stores the data. In this example I’m going to store it into a PostgreSQL database but you could choose other options like another SQL server, Google Sheets, a CSV file, etc. I have called this script file &lt;code&gt;speedtest_job.R&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb2&#34;&gt;&lt;pre class=&#34;sourceCode r&#34;&gt;&lt;code class=&#34;sourceCode r&#34;&gt;&lt;span id=&#34;cb2-1&#34;&gt;&lt;a href=&#34;#cb2-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;#! /usr/bin/env Rscript&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-2&#34;&gt;&lt;a href=&#34;#cb2-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-3&#34;&gt;&lt;a href=&#34;#cb2-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Data adquisition&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-4&#34;&gt;&lt;a href=&#34;#cb2-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;output &lt;span class=&#34;ot&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;read.csv&lt;/span&gt;(&lt;/span&gt;
&lt;span id=&#34;cb2-5&#34;&gt;&lt;a href=&#34;#cb2-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;at&#34;&gt;text =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;system&lt;/span&gt;(&lt;/span&gt;
&lt;span id=&#34;cb2-6&#34;&gt;&lt;a href=&#34;#cb2-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;at&#34;&gt;command =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;speedtest -f csv --output-header --accept-license&amp;quot;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb2-7&#34;&gt;&lt;a href=&#34;#cb2-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;at&#34;&gt;intern =&lt;/span&gt; &lt;span class=&#34;cn&#34;&gt;TRUE&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-8&#34;&gt;&lt;a href=&#34;#cb2-8&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  )&lt;/span&gt;
&lt;span id=&#34;cb2-9&#34;&gt;&lt;a href=&#34;#cb2-9&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;)&lt;/span&gt;
&lt;span id=&#34;cb2-10&#34;&gt;&lt;a href=&#34;#cb2-10&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-11&#34;&gt;&lt;a href=&#34;#cb2-11&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;results &lt;span class=&#34;ot&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;data.frame&lt;/span&gt;(&lt;/span&gt;
&lt;span id=&#34;cb2-12&#34;&gt;&lt;a href=&#34;#cb2-12&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;at&#34;&gt;stringsAsFactors =&lt;/span&gt; &lt;span class=&#34;cn&#34;&gt;FALSE&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb2-13&#34;&gt;&lt;a href=&#34;#cb2-13&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;at&#34;&gt;time =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;as.POSIXct&lt;/span&gt;(&lt;span class=&#34;fu&#34;&gt;Sys.time&lt;/span&gt;()),&lt;/span&gt;
&lt;span id=&#34;cb2-14&#34;&gt;&lt;a href=&#34;#cb2-14&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;at&#34;&gt;ip =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;system&lt;/span&gt;(&lt;span class=&#34;st&#34;&gt;&amp;quot;curl ifconfig.me&amp;quot;&lt;/span&gt;, &lt;span class=&#34;at&#34;&gt;intern =&lt;/span&gt; &lt;span class=&#34;cn&#34;&gt;TRUE&lt;/span&gt;), &lt;span class=&#34;co&#34;&gt;# This field is no longer provided on the new CLI version&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-15&#34;&gt;&lt;a href=&#34;#cb2-15&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;at&#34;&gt;ping =&lt;/span&gt; output&lt;span class=&#34;sc&#34;&gt;$&lt;/span&gt;latency,&lt;/span&gt;
&lt;span id=&#34;cb2-16&#34;&gt;&lt;a href=&#34;#cb2-16&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;at&#34;&gt;download =&lt;/span&gt; output&lt;span class=&#34;sc&#34;&gt;$&lt;/span&gt;download &lt;span class=&#34;sc&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;fl&#34;&gt;7.629395E-6&lt;/span&gt;, &lt;span class=&#34;co&#34;&gt;# Convert to Mbps&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-17&#34;&gt;&lt;a href=&#34;#cb2-17&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;at&#34;&gt;upload =&lt;/span&gt; output&lt;span class=&#34;sc&#34;&gt;$&lt;/span&gt;upload &lt;span class=&#34;sc&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;fl&#34;&gt;7.629395E-6&lt;/span&gt;, &lt;span class=&#34;co&#34;&gt;# Convert to Mbps&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-18&#34;&gt;&lt;a href=&#34;#cb2-18&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;at&#34;&gt;isp =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;movistar&amp;quot;&lt;/span&gt; &lt;span class=&#34;co&#34;&gt;# This field is not provided on CSV format&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-19&#34;&gt;&lt;a href=&#34;#cb2-19&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;)&lt;/span&gt;
&lt;span id=&#34;cb2-20&#34;&gt;&lt;a href=&#34;#cb2-20&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-21&#34;&gt;&lt;a href=&#34;#cb2-21&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Data storing&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-22&#34;&gt;&lt;a href=&#34;#cb2-22&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;con &lt;span class=&#34;ot&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;dbConnect&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;drv =&lt;/span&gt; odbc&lt;span class=&#34;sc&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;odbc&lt;/span&gt;(),&lt;/span&gt;
&lt;span id=&#34;cb2-23&#34;&gt;&lt;a href=&#34;#cb2-23&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                 &lt;span class=&#34;at&#34;&gt;driver =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;PostgreSQL ANSI&amp;#39;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb2-24&#34;&gt;&lt;a href=&#34;#cb2-24&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                 &lt;span class=&#34;at&#34;&gt;server =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;localhost&amp;#39;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb2-25&#34;&gt;&lt;a href=&#34;#cb2-25&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                 &lt;span class=&#34;at&#34;&gt;database =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;internet&amp;#39;&lt;/span&gt;, &lt;span class=&#34;co&#34;&gt;# Name of the database on the sql server&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-26&#34;&gt;&lt;a href=&#34;#cb2-26&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                 &lt;span class=&#34;at&#34;&gt;port =&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;5432&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb2-27&#34;&gt;&lt;a href=&#34;#cb2-27&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                 &lt;span class=&#34;at&#34;&gt;uid =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;Sys.getenv&lt;/span&gt;(&lt;span class=&#34;st&#34;&gt;&amp;#39;MY_UID&amp;#39;&lt;/span&gt;),&lt;/span&gt;
&lt;span id=&#34;cb2-28&#34;&gt;&lt;a href=&#34;#cb2-28&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                 &lt;span class=&#34;at&#34;&gt;pwd =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;Sys.getenv&lt;/span&gt;(&lt;span class=&#34;st&#34;&gt;&amp;#39;MY_PWD&amp;#39;&lt;/span&gt;),&lt;/span&gt;
&lt;span id=&#34;cb2-29&#34;&gt;&lt;a href=&#34;#cb2-29&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                 &lt;span class=&#34;at&#34;&gt;encoding =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;utf8&amp;#39;&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb2-30&#34;&gt;&lt;a href=&#34;#cb2-30&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-31&#34;&gt;&lt;a href=&#34;#cb2-31&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;DBI&lt;span class=&#34;sc&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;dbAppendTable&lt;/span&gt;(&lt;/span&gt;
&lt;span id=&#34;cb2-32&#34;&gt;&lt;a href=&#34;#cb2-32&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;at&#34;&gt;conn =&lt;/span&gt; con,&lt;/span&gt;
&lt;span id=&#34;cb2-33&#34;&gt;&lt;a href=&#34;#cb2-33&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;at&#34;&gt;name =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;speed_test&amp;quot;&lt;/span&gt;, &lt;span class=&#34;co&#34;&gt;# Table name on the sql server&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-34&#34;&gt;&lt;a href=&#34;#cb2-34&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;at&#34;&gt;value =&lt;/span&gt; results&lt;/span&gt;
&lt;span id=&#34;cb2-35&#34;&gt;&lt;a href=&#34;#cb2-35&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;)&lt;/span&gt;
&lt;span id=&#34;cb2-36&#34;&gt;&lt;a href=&#34;#cb2-36&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-37&#34;&gt;&lt;a href=&#34;#cb2-37&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;odbc&lt;span class=&#34;sc&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;dbDisconnect&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;conn =&lt;/span&gt; con)&lt;/span&gt;
&lt;span id=&#34;cb2-38&#34;&gt;&lt;a href=&#34;#cb2-38&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-39&#34;&gt;&lt;a href=&#34;#cb2-39&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# Cleaning log files&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb2-40&#34;&gt;&lt;a href=&#34;#cb2-40&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;unlink&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;x =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;*.log&amp;quot;&lt;/span&gt;, &lt;span class=&#34;at&#34;&gt;force =&lt;/span&gt; &lt;span class=&#34;cn&#34;&gt;TRUE&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we can schedule a &lt;code&gt;cron&lt;/code&gt; job to run this script on regular intervals, I’m going to set it to run once every hour running this commands on a system terminal:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;✏️ This can also be done from R using the &lt;code&gt;cronR&lt;/code&gt; package.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb3&#34;&gt;&lt;pre class=&#34;sourceCode bash&#34;&gt;&lt;code class=&#34;sourceCode bash&#34;&gt;&lt;span id=&#34;cb3-1&#34;&gt;&lt;a href=&#34;#cb3-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;env&lt;/span&gt; EDITOR=nano crontab &lt;span class=&#34;at&#34;&gt;-e&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-2&#34;&gt;&lt;a href=&#34;#cb3-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;co&#34;&gt;# Add this line&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-3&#34;&gt;&lt;a href=&#34;#cb3-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;ex&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;pp&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;pp&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;pp&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;pp&#34;&gt;*&lt;/span&gt; /usr/local/lib/R/bin/Rscript &lt;span class=&#34;st&#34;&gt;&amp;#39;/home/pi/speedtest_job.R&amp;#39;&lt;/span&gt; &lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;/dev/null&amp;#39;&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;op&#34;&gt;&amp;gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;co&#34;&gt;# Change the file path as needed&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb3-4&#34;&gt;&lt;a href=&#34;#cb3-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;sudo&lt;/span&gt; service cron reload&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;After letting some time to pass for registers to accumulate, we can fetch data from the server with a SQL query:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb4&#34;&gt;&lt;pre class=&#34;sourceCode r&#34;&gt;&lt;code class=&#34;sourceCode r&#34;&gt;&lt;span id=&#34;cb4-1&#34;&gt;&lt;a href=&#34;#cb4-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;library&lt;/span&gt;(odbc)&lt;/span&gt;
&lt;span id=&#34;cb4-2&#34;&gt;&lt;a href=&#34;#cb4-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-3&#34;&gt;&lt;a href=&#34;#cb4-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;con &lt;span class=&#34;ot&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;dbConnect&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;drv =&lt;/span&gt; odbc&lt;span class=&#34;sc&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;odbc&lt;/span&gt;(),&lt;/span&gt;
&lt;span id=&#34;cb4-4&#34;&gt;&lt;a href=&#34;#cb4-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                 &lt;span class=&#34;at&#34;&gt;driver =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;PostgreSQL ANSI&amp;#39;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb4-5&#34;&gt;&lt;a href=&#34;#cb4-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                 &lt;span class=&#34;at&#34;&gt;server =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;Sys.getenv&lt;/span&gt;(&lt;span class=&#34;st&#34;&gt;&amp;#39;MY_REMOTE&amp;#39;&lt;/span&gt;),&lt;/span&gt;
&lt;span id=&#34;cb4-6&#34;&gt;&lt;a href=&#34;#cb4-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                 &lt;span class=&#34;at&#34;&gt;database =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;internet&amp;#39;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb4-7&#34;&gt;&lt;a href=&#34;#cb4-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                 &lt;span class=&#34;at&#34;&gt;port =&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;5432&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb4-8&#34;&gt;&lt;a href=&#34;#cb4-8&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                 &lt;span class=&#34;at&#34;&gt;uid =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;Sys.getenv&lt;/span&gt;(&lt;span class=&#34;st&#34;&gt;&amp;#39;MY_UID&amp;#39;&lt;/span&gt;),&lt;/span&gt;
&lt;span id=&#34;cb4-9&#34;&gt;&lt;a href=&#34;#cb4-9&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                 &lt;span class=&#34;at&#34;&gt;pwd =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;Sys.getenv&lt;/span&gt;(&lt;span class=&#34;st&#34;&gt;&amp;#39;MY_PWD&amp;#39;&lt;/span&gt;),&lt;/span&gt;
&lt;span id=&#34;cb4-10&#34;&gt;&lt;a href=&#34;#cb4-10&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                 &lt;span class=&#34;at&#34;&gt;encoding =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;utf8&amp;#39;&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb4-11&#34;&gt;&lt;a href=&#34;#cb4-11&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-12&#34;&gt;&lt;a href=&#34;#cb4-12&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;query &lt;span class=&#34;ot&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-13&#34;&gt;&lt;a href=&#34;#cb4-13&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;st&#34;&gt;    SELECT * &lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-14&#34;&gt;&lt;a href=&#34;#cb4-14&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;st&#34;&gt;    FROM public.speed_test &lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-15&#34;&gt;&lt;a href=&#34;#cb4-15&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;st&#34;&gt;    ORDER BY time&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-16&#34;&gt;&lt;a href=&#34;#cb4-16&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;st&#34;&gt;    &amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-17&#34;&gt;&lt;a href=&#34;#cb4-17&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-18&#34;&gt;&lt;a href=&#34;#cb4-18&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;raw_data &lt;span class=&#34;ot&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;dbGetQuery&lt;/span&gt;(&lt;/span&gt;
&lt;span id=&#34;cb4-19&#34;&gt;&lt;a href=&#34;#cb4-19&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;at&#34;&gt;conn =&lt;/span&gt; con,&lt;/span&gt;
&lt;span id=&#34;cb4-20&#34;&gt;&lt;a href=&#34;#cb4-20&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;at&#34;&gt;statement =&lt;/span&gt; query&lt;/span&gt;
&lt;span id=&#34;cb4-21&#34;&gt;&lt;a href=&#34;#cb4-21&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;)&lt;/span&gt;
&lt;span id=&#34;cb4-22&#34;&gt;&lt;a href=&#34;#cb4-22&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb4-23&#34;&gt;&lt;a href=&#34;#cb4-23&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;dbDisconnect&lt;/span&gt;(con)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&#34;visualizing-the-data&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Visualizing the Data&lt;/h2&gt;
&lt;p&gt;Now that we have some data to work with we can start making some plots. Since this is not an article about &lt;code&gt;ggplopt2&lt;/code&gt; I’m not going to get much into details about this part, I’m just going to show you some interesting plots you can get about your internet connection speed.&lt;/p&gt;
&lt;p&gt;In Figure &lt;a href=&#34;#fig:histogram&#34;&gt;1&lt;/a&gt; we can see how observed download speeds distribute, letting aside the fact that the advertised speed is already slow (for developed countries standards), this reveals a pattern that is very common, most of the time you get download speeds that are much slower than advertised by the ISP and even so slow that defaults the terms of your contract, like in my case (I actually used this image to file a complaint).&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb5&#34;&gt;&lt;pre class=&#34;sourceCode r&#34;&gt;&lt;code class=&#34;sourceCode r&#34;&gt;&lt;span id=&#34;cb5-1&#34;&gt;&lt;a href=&#34;#cb5-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;library&lt;/span&gt;(tidyverse)&lt;/span&gt;
&lt;span id=&#34;cb5-2&#34;&gt;&lt;a href=&#34;#cb5-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;library&lt;/span&gt;(xkcd)&lt;/span&gt;
&lt;span id=&#34;cb5-3&#34;&gt;&lt;a href=&#34;#cb5-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;library&lt;/span&gt;(lubridate)&lt;/span&gt;
&lt;span id=&#34;cb5-4&#34;&gt;&lt;a href=&#34;#cb5-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;library&lt;/span&gt;(tibbletime)&lt;/span&gt;
&lt;span id=&#34;cb5-5&#34;&gt;&lt;a href=&#34;#cb5-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;library&lt;/span&gt;(scales)&lt;/span&gt;
&lt;span id=&#34;cb5-6&#34;&gt;&lt;a href=&#34;#cb5-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-7&#34;&gt;&lt;a href=&#34;#cb5-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;co&#34;&gt;# These are my personal theme settings you can ignore them if you prefer&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-8&#34;&gt;&lt;a href=&#34;#cb5-8&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;span class=&#34;fu&#34;&gt;theme_set&lt;/span&gt;(&lt;/span&gt;
&lt;span id=&#34;cb5-9&#34;&gt;&lt;a href=&#34;#cb5-9&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;theme_gray&lt;/span&gt;() &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-10&#34;&gt;&lt;a href=&#34;#cb5-10&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;fu&#34;&gt;theme_xkcd&lt;/span&gt;() &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-11&#34;&gt;&lt;a href=&#34;#cb5-11&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;fu&#34;&gt;theme&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;legend.position =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;right&amp;quot;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb5-12&#34;&gt;&lt;a href=&#34;#cb5-12&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;          &lt;span class=&#34;at&#34;&gt;plot.title.position =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;plot&amp;quot;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb5-13&#34;&gt;&lt;a href=&#34;#cb5-13&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;          &lt;span class=&#34;at&#34;&gt;axis.title.x =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;element_text&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;margin =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;margin&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;t =&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;10&lt;/span&gt;)),&lt;/span&gt;
&lt;span id=&#34;cb5-14&#34;&gt;&lt;a href=&#34;#cb5-14&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;          &lt;span class=&#34;at&#34;&gt;axis.title.y =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;element_text&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;margin =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;margin&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;r =&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;10&lt;/span&gt;)),&lt;/span&gt;
&lt;span id=&#34;cb5-15&#34;&gt;&lt;a href=&#34;#cb5-15&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;          &lt;span class=&#34;at&#34;&gt;axis.text.x =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;element_text&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;angle =&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;20&lt;/span&gt;, &lt;span class=&#34;at&#34;&gt;hjust =&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;, &lt;span class=&#34;at&#34;&gt;vjust =&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;),&lt;/span&gt;
&lt;span id=&#34;cb5-16&#34;&gt;&lt;a href=&#34;#cb5-16&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;          &lt;span class=&#34;at&#34;&gt;plot.margin =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;margin&lt;/span&gt;(&lt;span class=&#34;dv&#34;&gt;10&lt;/span&gt;, &lt;span class=&#34;dv&#34;&gt;10&lt;/span&gt;, &lt;span class=&#34;dv&#34;&gt;10&lt;/span&gt;, &lt;span class=&#34;dv&#34;&gt;10&lt;/span&gt;),&lt;/span&gt;
&lt;span id=&#34;cb5-17&#34;&gt;&lt;a href=&#34;#cb5-17&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;          &lt;span class=&#34;at&#34;&gt;text =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;element_text&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;family =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;Cloud Calligraphy&amp;quot;&lt;/span&gt;))&lt;/span&gt;
&lt;span id=&#34;cb5-18&#34;&gt;&lt;a href=&#34;#cb5-18&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;)&lt;/span&gt;
&lt;span id=&#34;cb5-19&#34;&gt;&lt;a href=&#34;#cb5-19&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-20&#34;&gt;&lt;a href=&#34;#cb5-20&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;color &lt;span class=&#34;ot&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;c&lt;/span&gt;(&lt;span class=&#34;st&#34;&gt;&amp;quot;Mode&amp;quot;&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;#008B00&amp;quot;&lt;/span&gt;, &lt;span class=&#34;st&#34;&gt;&amp;quot;Parameters&amp;quot;&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;orange&amp;quot;&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb5-21&#34;&gt;&lt;a href=&#34;#cb5-21&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-22&#34;&gt;&lt;a href=&#34;#cb5-22&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;raw_data &lt;span class=&#34;sc&#34;&gt;%&amp;gt;%&lt;/span&gt; &lt;/span&gt;
&lt;span id=&#34;cb5-23&#34;&gt;&lt;a href=&#34;#cb5-23&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;ggplot&lt;/span&gt;(&lt;span class=&#34;fu&#34;&gt;aes&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;x =&lt;/span&gt; download)) &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-24&#34;&gt;&lt;a href=&#34;#cb5-24&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;geom_histogram&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;binwidth =&lt;/span&gt; &lt;span class=&#34;fl&#34;&gt;0.1&lt;/span&gt;, &lt;span class=&#34;at&#34;&gt;fill =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;#00B2EE&amp;quot;&lt;/span&gt;) &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-25&#34;&gt;&lt;a href=&#34;#cb5-25&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;geom_vline&lt;/span&gt;(&lt;span class=&#34;fu&#34;&gt;aes&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;xintercept =&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;20&lt;/span&gt;, &lt;span class=&#34;at&#34;&gt;color =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;Parameters&amp;quot;&lt;/span&gt;),  &lt;span class=&#34;at&#34;&gt;linetype =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;dashed&amp;quot;&lt;/span&gt;) &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-26&#34;&gt;&lt;a href=&#34;#cb5-26&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;geom_vline&lt;/span&gt;(&lt;span class=&#34;fu&#34;&gt;aes&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;xintercept =&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;8&lt;/span&gt;, &lt;span class=&#34;at&#34;&gt;color =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;Parameters&amp;quot;&lt;/span&gt;),  &lt;span class=&#34;at&#34;&gt;linetype =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;dashed&amp;quot;&lt;/span&gt;) &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-27&#34;&gt;&lt;a href=&#34;#cb5-27&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;stat_bin&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;geom =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;vline&amp;quot;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb5-28&#34;&gt;&lt;a href=&#34;#cb5-28&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;           &lt;span class=&#34;fu&#34;&gt;aes&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;xintercept =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;stat&lt;/span&gt;(&lt;span class=&#34;fu&#34;&gt;ifelse&lt;/span&gt;(count &lt;span class=&#34;sc&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;max&lt;/span&gt;(count), x, &lt;span class=&#34;cn&#34;&gt;NA&lt;/span&gt;)),&lt;/span&gt;
&lt;span id=&#34;cb5-29&#34;&gt;&lt;a href=&#34;#cb5-29&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;               &lt;span class=&#34;at&#34;&gt;color =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;Mode&amp;quot;&lt;/span&gt;),&lt;/span&gt;
&lt;span id=&#34;cb5-30&#34;&gt;&lt;a href=&#34;#cb5-30&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;           &lt;span class=&#34;at&#34;&gt;binwidth =&lt;/span&gt; &lt;span class=&#34;fl&#34;&gt;0.1&lt;/span&gt;) &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-31&#34;&gt;&lt;a href=&#34;#cb5-31&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;annotate&lt;/span&gt;(&lt;span class=&#34;st&#34;&gt;&amp;quot;text&amp;quot;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb5-32&#34;&gt;&lt;a href=&#34;#cb5-32&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;           &lt;span class=&#34;at&#34;&gt;x =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;c&lt;/span&gt;(&lt;span class=&#34;fl&#34;&gt;8.4&lt;/span&gt;, &lt;span class=&#34;fl&#34;&gt;20.4&lt;/span&gt;),&lt;/span&gt;
&lt;span id=&#34;cb5-33&#34;&gt;&lt;a href=&#34;#cb5-33&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;           &lt;span class=&#34;at&#34;&gt;y =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;c&lt;/span&gt;(&lt;span class=&#34;dv&#34;&gt;8&lt;/span&gt;, &lt;span class=&#34;dv&#34;&gt;8&lt;/span&gt;),&lt;/span&gt;
&lt;span id=&#34;cb5-34&#34;&gt;&lt;a href=&#34;#cb5-34&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;           &lt;span class=&#34;at&#34;&gt;label =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;c&lt;/span&gt;(&lt;span class=&#34;st&#34;&gt;&amp;quot;Guaranteed Minimum Speed&amp;quot;&lt;/span&gt;, &lt;span class=&#34;st&#34;&gt;&amp;quot;Advertised Speed&amp;quot;&lt;/span&gt;),&lt;/span&gt;
&lt;span id=&#34;cb5-35&#34;&gt;&lt;a href=&#34;#cb5-35&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;           &lt;span class=&#34;at&#34;&gt;family =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;Cloud Calligraphy&amp;quot;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb5-36&#34;&gt;&lt;a href=&#34;#cb5-36&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;           &lt;span class=&#34;at&#34;&gt;size =&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;5&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb5-37&#34;&gt;&lt;a href=&#34;#cb5-37&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;           &lt;span class=&#34;at&#34;&gt;angle =&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;90&lt;/span&gt;) &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-38&#34;&gt;&lt;a href=&#34;#cb5-38&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;stat_bin&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;geom =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;label&amp;quot;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb5-39&#34;&gt;&lt;a href=&#34;#cb5-39&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;           &lt;span class=&#34;fu&#34;&gt;aes&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;label =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;stat&lt;/span&gt;(&lt;span class=&#34;fu&#34;&gt;ifelse&lt;/span&gt;(count &lt;span class=&#34;sc&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;max&lt;/span&gt;(count), &lt;span class=&#34;fu&#34;&gt;round&lt;/span&gt;(x, &lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;), &lt;span class=&#34;cn&#34;&gt;NA&lt;/span&gt;))),&lt;/span&gt;
&lt;span id=&#34;cb5-40&#34;&gt;&lt;a href=&#34;#cb5-40&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;           &lt;span class=&#34;at&#34;&gt;binwidth =&lt;/span&gt; &lt;span class=&#34;fl&#34;&gt;0.1&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb5-41&#34;&gt;&lt;a href=&#34;#cb5-41&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;           &lt;span class=&#34;at&#34;&gt;family =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;xkcd&amp;quot;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb5-42&#34;&gt;&lt;a href=&#34;#cb5-42&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;           &lt;span class=&#34;at&#34;&gt;color =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;#008B00&amp;quot;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb5-43&#34;&gt;&lt;a href=&#34;#cb5-43&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;           &lt;span class=&#34;at&#34;&gt;vjust =&lt;/span&gt; &lt;span class=&#34;sc&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;fl&#34;&gt;0.2&lt;/span&gt;) &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-44&#34;&gt;&lt;a href=&#34;#cb5-44&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;labs&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;title =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;HISTOGRAM OF OBSERVED DOWNLOAD SPEEDS&amp;#39;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb5-45&#34;&gt;&lt;a href=&#34;#cb5-45&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;       &lt;span class=&#34;at&#34;&gt;subtitle =&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;&amp;#39;ISP: MOVISTAR 20 Mbps&amp;#39;&lt;/span&gt;, &lt;/span&gt;
&lt;span id=&#34;cb5-46&#34;&gt;&lt;a href=&#34;#cb5-46&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;       &lt;span class=&#34;at&#34;&gt;x =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;Speed (Mbps)&amp;#39;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb5-47&#34;&gt;&lt;a href=&#34;#cb5-47&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;       &lt;span class=&#34;at&#34;&gt;y =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;Frequency&amp;#39;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb5-48&#34;&gt;&lt;a href=&#34;#cb5-48&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;       &lt;span class=&#34;at&#34;&gt;colour =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;) &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-49&#34;&gt;&lt;a href=&#34;#cb5-49&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;scale_x_continuous&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;breaks =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;seq&lt;/span&gt;(&lt;span class=&#34;dv&#34;&gt;0&lt;/span&gt;, &lt;span class=&#34;dv&#34;&gt;22&lt;/span&gt;, &lt;span class=&#34;at&#34;&gt;by =&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;),&lt;/span&gt;
&lt;span id=&#34;cb5-50&#34;&gt;&lt;a href=&#34;#cb5-50&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                     &lt;span class=&#34;at&#34;&gt;limits =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;c&lt;/span&gt;(&lt;span class=&#34;dv&#34;&gt;0&lt;/span&gt;, &lt;span class=&#34;dv&#34;&gt;23&lt;/span&gt;)) &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-51&#34;&gt;&lt;a href=&#34;#cb5-51&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;scale_colour_manual&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;values =&lt;/span&gt; color) &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-52&#34;&gt;&lt;a href=&#34;#cb5-52&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;coord_cartesian&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;clip =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;off&amp;#39;&lt;/span&gt;) &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb5-53&#34;&gt;&lt;a href=&#34;#cb5-53&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;cn&#34;&gt;NULL&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&#34;figure&#34; style=&#34;text-align: center&#34;&gt;&lt;span style=&#34;display:block;&#34; id=&#34;fig:histogram&#34;&gt;&lt;/span&gt;
&lt;img src=&#34;https://andresrcs.rbind.io/post/2020-01-20-internet-speed-test.en_files/figure-html/histogram-1.png&#34; alt=&#34;Histogram of Observed Download Speeds&#34; width=&#34;768&#34; /&gt;
&lt;p class=&#34;caption&#34;&gt;
Figure 1: Histogram of Observed Download Speeds
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;With figures &lt;a href=&#34;#fig:line&#34;&gt;2&lt;/a&gt; and &lt;a href=&#34;#fig:box&#34;&gt;3&lt;/a&gt;, we can show how often the download speeds fall below the minimum guaranteed speed.&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb6&#34;&gt;&lt;pre class=&#34;sourceCode r&#34;&gt;&lt;code class=&#34;sourceCode r&#34;&gt;&lt;span id=&#34;cb6-1&#34;&gt;&lt;a href=&#34;#cb6-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-2&#34;&gt;&lt;a href=&#34;#cb6-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;colors &lt;span class=&#34;ot&#34;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;c&lt;/span&gt;(&lt;span class=&#34;st&#34;&gt;&amp;quot;Mean Speed&amp;quot;&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;blue&amp;quot;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb6-3&#34;&gt;&lt;a href=&#34;#cb6-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;st&#34;&gt;&amp;quot;Parameters&amp;quot;&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;orange&amp;quot;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb6-4&#34;&gt;&lt;a href=&#34;#cb6-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;st&#34;&gt;&amp;quot;Fault&amp;quot;&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;red&amp;quot;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb6-5&#34;&gt;&lt;a href=&#34;#cb6-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;            &lt;span class=&#34;st&#34;&gt;&amp;quot;Download Speed&amp;quot;&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;#00B2EE&amp;quot;&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb6-6&#34;&gt;&lt;a href=&#34;#cb6-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-7&#34;&gt;&lt;a href=&#34;#cb6-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;plot_data &lt;span class=&#34;ot&#34;&gt;&amp;lt;-&lt;/span&gt; raw_data &lt;span class=&#34;sc&#34;&gt;%&amp;gt;%&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-8&#34;&gt;&lt;a href=&#34;#cb6-8&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;as_tbl_time&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;index =&lt;/span&gt; time) &lt;span class=&#34;sc&#34;&gt;%&amp;gt;%&lt;/span&gt; &lt;/span&gt;
&lt;span id=&#34;cb6-9&#34;&gt;&lt;a href=&#34;#cb6-9&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;collapse_by&lt;/span&gt;(&lt;span class=&#34;st&#34;&gt;&amp;#39;1 hour&amp;#39;&lt;/span&gt;, &lt;span class=&#34;at&#34;&gt;side =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;start&amp;#39;&lt;/span&gt;, &lt;span class=&#34;at&#34;&gt;clean =&lt;/span&gt; &lt;span class=&#34;cn&#34;&gt;TRUE&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb6-10&#34;&gt;&lt;a href=&#34;#cb6-10&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-11&#34;&gt;&lt;a href=&#34;#cb6-11&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;mean_speed &lt;span class=&#34;ot&#34;&gt;&amp;lt;-&lt;/span&gt; plot_data &lt;span class=&#34;sc&#34;&gt;%&amp;gt;%&lt;/span&gt; &lt;/span&gt;
&lt;span id=&#34;cb6-12&#34;&gt;&lt;a href=&#34;#cb6-12&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;pull&lt;/span&gt;(download) &lt;span class=&#34;sc&#34;&gt;%&amp;gt;%&lt;/span&gt; &lt;/span&gt;
&lt;span id=&#34;cb6-13&#34;&gt;&lt;a href=&#34;#cb6-13&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;mean&lt;/span&gt;() &lt;span class=&#34;sc&#34;&gt;%&amp;gt;%&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-14&#34;&gt;&lt;a href=&#34;#cb6-14&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;round&lt;/span&gt;(&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb6-15&#34;&gt;&lt;a href=&#34;#cb6-15&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-16&#34;&gt;&lt;a href=&#34;#cb6-16&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;plot_data &lt;span class=&#34;sc&#34;&gt;%&amp;gt;%&lt;/span&gt; &lt;/span&gt;
&lt;span id=&#34;cb6-17&#34;&gt;&lt;a href=&#34;#cb6-17&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;ggplot&lt;/span&gt;(&lt;span class=&#34;fu&#34;&gt;aes&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;x =&lt;/span&gt; time, &lt;span class=&#34;at&#34;&gt;y =&lt;/span&gt; download)) &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-18&#34;&gt;&lt;a href=&#34;#cb6-18&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;geom_line&lt;/span&gt;(&lt;span class=&#34;fu&#34;&gt;aes&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;color =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;Download Speed&amp;quot;&lt;/span&gt;)) &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-19&#34;&gt;&lt;a href=&#34;#cb6-19&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;geom_point&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;data =&lt;/span&gt; plot_data &lt;span class=&#34;sc&#34;&gt;%&amp;gt;%&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;filter&lt;/span&gt;(download &lt;span class=&#34;sc&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;8&lt;/span&gt;),&lt;/span&gt;
&lt;span id=&#34;cb6-20&#34;&gt;&lt;a href=&#34;#cb6-20&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;             &lt;span class=&#34;fu&#34;&gt;aes&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;color =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;Fault&amp;quot;&lt;/span&gt;)) &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-21&#34;&gt;&lt;a href=&#34;#cb6-21&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;geom_point&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;data =&lt;/span&gt; plot_data &lt;span class=&#34;sc&#34;&gt;%&amp;gt;%&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;filter&lt;/span&gt;(download &lt;span class=&#34;sc&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;8&lt;/span&gt;),&lt;/span&gt;
&lt;span id=&#34;cb6-22&#34;&gt;&lt;a href=&#34;#cb6-22&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;             &lt;span class=&#34;at&#34;&gt;shape =&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb6-23&#34;&gt;&lt;a href=&#34;#cb6-23&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;             &lt;span class=&#34;at&#34;&gt;color =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;red&amp;quot;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb6-24&#34;&gt;&lt;a href=&#34;#cb6-24&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;             &lt;span class=&#34;at&#34;&gt;size =&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;5&lt;/span&gt;) &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-25&#34;&gt;&lt;a href=&#34;#cb6-25&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;geom_hline&lt;/span&gt;(&lt;span class=&#34;fu&#34;&gt;aes&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;yintercept =&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;20&lt;/span&gt;, &lt;span class=&#34;at&#34;&gt;color =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;Parameters&amp;quot;&lt;/span&gt;),  &lt;span class=&#34;at&#34;&gt;linetype =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;dashed&amp;quot;&lt;/span&gt;) &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-26&#34;&gt;&lt;a href=&#34;#cb6-26&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;geom_hline&lt;/span&gt;(&lt;span class=&#34;fu&#34;&gt;aes&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;yintercept =&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;8&lt;/span&gt;, &lt;span class=&#34;at&#34;&gt;color =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;Parameters&amp;quot;&lt;/span&gt;),  &lt;span class=&#34;at&#34;&gt;linetype =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;dashed&amp;quot;&lt;/span&gt;) &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-27&#34;&gt;&lt;a href=&#34;#cb6-27&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;geom_hline&lt;/span&gt;(&lt;span class=&#34;fu&#34;&gt;aes&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;yintercept =&lt;/span&gt; mean_speed, &lt;span class=&#34;at&#34;&gt;color =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;Mean Speed&amp;quot;&lt;/span&gt;)) &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-28&#34;&gt;&lt;a href=&#34;#cb6-28&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;annotate&lt;/span&gt;(&lt;span class=&#34;st&#34;&gt;&amp;quot;text&amp;quot;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb6-29&#34;&gt;&lt;a href=&#34;#cb6-29&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;           &lt;span class=&#34;at&#34;&gt;x =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;as.POSIXct&lt;/span&gt;(&lt;span class=&#34;fu&#34;&gt;c&lt;/span&gt;(&lt;span class=&#34;st&#34;&gt;&amp;quot;2019-06-24 11:00:00 UTC&amp;quot;&lt;/span&gt;, &lt;span class=&#34;st&#34;&gt;&amp;quot;2019-06-24 11:00:00 UTC&amp;quot;&lt;/span&gt;)),&lt;/span&gt;
&lt;span id=&#34;cb6-30&#34;&gt;&lt;a href=&#34;#cb6-30&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;           &lt;span class=&#34;at&#34;&gt;y =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;c&lt;/span&gt;(&lt;span class=&#34;dv&#34;&gt;7&lt;/span&gt;, &lt;span class=&#34;dv&#34;&gt;19&lt;/span&gt;),&lt;/span&gt;
&lt;span id=&#34;cb6-31&#34;&gt;&lt;a href=&#34;#cb6-31&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;           &lt;span class=&#34;at&#34;&gt;label =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;c&lt;/span&gt;(&lt;span class=&#34;st&#34;&gt;&amp;quot;Guaranteed Minimum Speed&amp;quot;&lt;/span&gt;, &lt;span class=&#34;st&#34;&gt;&amp;quot;Advertised Speed&amp;quot;&lt;/span&gt;),&lt;/span&gt;
&lt;span id=&#34;cb6-32&#34;&gt;&lt;a href=&#34;#cb6-32&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;           &lt;span class=&#34;at&#34;&gt;family =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;Cloud Calligraphy&amp;quot;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb6-33&#34;&gt;&lt;a href=&#34;#cb6-33&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;           &lt;span class=&#34;at&#34;&gt;size=&lt;/span&gt;&lt;span class=&#34;dv&#34;&gt;5&lt;/span&gt;) &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-34&#34;&gt;&lt;a href=&#34;#cb6-34&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;geom_label&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;x =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;as.POSIXct&lt;/span&gt;(&lt;span class=&#34;st&#34;&gt;&amp;quot;2019-08-01 11:00:00 UTC&amp;quot;&lt;/span&gt;),&lt;/span&gt;
&lt;span id=&#34;cb6-35&#34;&gt;&lt;a href=&#34;#cb6-35&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;             &lt;span class=&#34;at&#34;&gt;y =&lt;/span&gt; mean_speed,&lt;/span&gt;
&lt;span id=&#34;cb6-36&#34;&gt;&lt;a href=&#34;#cb6-36&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;             &lt;span class=&#34;at&#34;&gt;label =&lt;/span&gt; mean_speed,&lt;/span&gt;
&lt;span id=&#34;cb6-37&#34;&gt;&lt;a href=&#34;#cb6-37&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;             &lt;span class=&#34;at&#34;&gt;family =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;xkcd&amp;quot;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb6-38&#34;&gt;&lt;a href=&#34;#cb6-38&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;             &lt;span class=&#34;at&#34;&gt;show.legend =&lt;/span&gt; &lt;span class=&#34;cn&#34;&gt;FALSE&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb6-39&#34;&gt;&lt;a href=&#34;#cb6-39&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;             &lt;span class=&#34;at&#34;&gt;inherit.aes =&lt;/span&gt; &lt;span class=&#34;cn&#34;&gt;FALSE&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb6-40&#34;&gt;&lt;a href=&#34;#cb6-40&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;             &lt;span class=&#34;at&#34;&gt;color =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;blue&amp;quot;&lt;/span&gt;)  &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-41&#34;&gt;&lt;a href=&#34;#cb6-41&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;labs&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;title =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;OBSERVED DOWNLOAD SPEEDS&amp;#39;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb6-42&#34;&gt;&lt;a href=&#34;#cb6-42&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;       &lt;span class=&#34;at&#34;&gt;subtitle =&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;&amp;#39;ISP: MOVISTAR 20 Mbps&amp;#39;&lt;/span&gt;, &lt;/span&gt;
&lt;span id=&#34;cb6-43&#34;&gt;&lt;a href=&#34;#cb6-43&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;       &lt;span class=&#34;at&#34;&gt;x =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;Date&amp;#39;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb6-44&#34;&gt;&lt;a href=&#34;#cb6-44&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;       &lt;span class=&#34;at&#34;&gt;y =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;Speed (Mbps)&amp;#39;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb6-45&#34;&gt;&lt;a href=&#34;#cb6-45&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;       &lt;span class=&#34;at&#34;&gt;color =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;Legend:&amp;#39;&lt;/span&gt;) &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-46&#34;&gt;&lt;a href=&#34;#cb6-46&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;scale_x_datetime&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;date_breaks =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;5 days&amp;quot;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb6-47&#34;&gt;&lt;a href=&#34;#cb6-47&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                   &lt;span class=&#34;at&#34;&gt;labels =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;label_date_short&lt;/span&gt;(), &lt;/span&gt;
&lt;span id=&#34;cb6-48&#34;&gt;&lt;a href=&#34;#cb6-48&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                   &lt;span class=&#34;at&#34;&gt;expand =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;expansion&lt;/span&gt;(&lt;span class=&#34;fu&#34;&gt;c&lt;/span&gt;(&lt;span class=&#34;dv&#34;&gt;0&lt;/span&gt;, &lt;span class=&#34;fl&#34;&gt;0.04&lt;/span&gt;))) &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-49&#34;&gt;&lt;a href=&#34;#cb6-49&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;scale_y_continuous&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;breaks =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;seq&lt;/span&gt;(&lt;span class=&#34;dv&#34;&gt;0&lt;/span&gt;, &lt;span class=&#34;dv&#34;&gt;22&lt;/span&gt;, &lt;span class=&#34;at&#34;&gt;by =&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;), &lt;span class=&#34;at&#34;&gt;limits =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;c&lt;/span&gt;(&lt;span class=&#34;dv&#34;&gt;0&lt;/span&gt;, &lt;span class=&#34;dv&#34;&gt;23&lt;/span&gt;)) &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-50&#34;&gt;&lt;a href=&#34;#cb6-50&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;scale_colour_manual&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;values =&lt;/span&gt; colors) &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-51&#34;&gt;&lt;a href=&#34;#cb6-51&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;coord_cartesian&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;clip =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;off&amp;#39;&lt;/span&gt;) &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb6-52&#34;&gt;&lt;a href=&#34;#cb6-52&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;cn&#34;&gt;NULL&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&#34;figure&#34; style=&#34;text-align: center&#34;&gt;&lt;span style=&#34;display:block;&#34; id=&#34;fig:line&#34;&gt;&lt;/span&gt;
&lt;img src=&#34;https://andresrcs.rbind.io/post/2020-01-20-internet-speed-test.en_files/figure-html/line-1.png&#34; alt=&#34;Observed Download Speeds&#34; width=&#34;768&#34; /&gt;
&lt;p class=&#34;caption&#34;&gt;
Figure 2: Observed Download Speeds
&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb7&#34;&gt;&lt;pre class=&#34;sourceCode r&#34;&gt;&lt;code class=&#34;sourceCode r&#34;&gt;&lt;span id=&#34;cb7-1&#34;&gt;&lt;a href=&#34;#cb7-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;faults &lt;span class=&#34;ot&#34;&gt;&amp;lt;-&lt;/span&gt; plot_data &lt;span class=&#34;sc&#34;&gt;%&amp;gt;%&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb7-2&#34;&gt;&lt;a href=&#34;#cb7-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;mutate&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;event_type =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;ifelse&lt;/span&gt;(download &lt;span class=&#34;sc&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;8&lt;/span&gt;, &lt;span class=&#34;st&#34;&gt;&amp;#39;fault&amp;#39;&lt;/span&gt;, &lt;span class=&#34;st&#34;&gt;&amp;#39;normal&amp;#39;&lt;/span&gt;)) &lt;span class=&#34;sc&#34;&gt;%&amp;gt;%&lt;/span&gt; &lt;/span&gt;
&lt;span id=&#34;cb7-3&#34;&gt;&lt;a href=&#34;#cb7-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;filter&lt;/span&gt;(event_type &lt;span class=&#34;sc&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;fault&amp;#39;&lt;/span&gt;) &lt;span class=&#34;sc&#34;&gt;%&amp;gt;%&lt;/span&gt; &lt;/span&gt;
&lt;span id=&#34;cb7-4&#34;&gt;&lt;a href=&#34;#cb7-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;mutate&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;tbf =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;as.numeric&lt;/span&gt;(&lt;span class=&#34;fu&#34;&gt;as.period&lt;/span&gt;(&lt;span class=&#34;fu&#34;&gt;interval&lt;/span&gt;(&lt;span class=&#34;fu&#34;&gt;lag&lt;/span&gt;(time), time),&lt;/span&gt;
&lt;span id=&#34;cb7-5&#34;&gt;&lt;a href=&#34;#cb7-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                                    &lt;span class=&#34;at&#34;&gt;unit =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;seconds&amp;#39;&lt;/span&gt;)) &lt;span class=&#34;sc&#34;&gt;/&lt;/span&gt; (&lt;span class=&#34;dv&#34;&gt;3600&lt;/span&gt;)) &lt;span class=&#34;sc&#34;&gt;%&amp;gt;%&lt;/span&gt; &lt;/span&gt;
&lt;span id=&#34;cb7-6&#34;&gt;&lt;a href=&#34;#cb7-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;tail&lt;/span&gt;(&lt;span class=&#34;sc&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;)&lt;/span&gt;
&lt;span id=&#34;cb7-7&#34;&gt;&lt;a href=&#34;#cb7-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb7-8&#34;&gt;&lt;a href=&#34;#cb7-8&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;faults &lt;span class=&#34;sc&#34;&gt;%&amp;gt;%&lt;/span&gt; &lt;/span&gt;
&lt;span id=&#34;cb7-9&#34;&gt;&lt;a href=&#34;#cb7-9&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;ggplot&lt;/span&gt;(&lt;span class=&#34;fu&#34;&gt;aes&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;x =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;, &lt;span class=&#34;at&#34;&gt;y =&lt;/span&gt; tbf)) &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb7-10&#34;&gt;&lt;a href=&#34;#cb7-10&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;geom_boxplot&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;fill =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;#FF303094&amp;#39;&lt;/span&gt;) &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb7-11&#34;&gt;&lt;a href=&#34;#cb7-11&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;coord_flip&lt;/span&gt;() &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb7-12&#34;&gt;&lt;a href=&#34;#cb7-12&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;geom_label&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;y =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;median&lt;/span&gt;(faults&lt;span class=&#34;sc&#34;&gt;$&lt;/span&gt;tbf),&lt;/span&gt;
&lt;span id=&#34;cb7-13&#34;&gt;&lt;a href=&#34;#cb7-13&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;             &lt;span class=&#34;at&#34;&gt;label =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;paste&lt;/span&gt;(&lt;span class=&#34;fu&#34;&gt;round&lt;/span&gt;(&lt;span class=&#34;fu&#34;&gt;median&lt;/span&gt;(faults&lt;span class=&#34;sc&#34;&gt;$&lt;/span&gt;tbf),&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;), &lt;span class=&#34;st&#34;&gt;&amp;#39;h&amp;#39;&lt;/span&gt;),&lt;/span&gt;
&lt;span id=&#34;cb7-14&#34;&gt;&lt;a href=&#34;#cb7-14&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;             &lt;span class=&#34;at&#34;&gt;family =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;xkcd&amp;quot;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb7-15&#34;&gt;&lt;a href=&#34;#cb7-15&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;             &lt;span class=&#34;at&#34;&gt;show.legend =&lt;/span&gt; &lt;span class=&#34;cn&#34;&gt;FALSE&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb7-16&#34;&gt;&lt;a href=&#34;#cb7-16&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;             &lt;span class=&#34;at&#34;&gt;color =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;blue&amp;quot;&lt;/span&gt;) &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb7-17&#34;&gt;&lt;a href=&#34;#cb7-17&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;labs&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;title =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;BOXPLOT OF TIME BETWEEN FAILURES&amp;#39;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb7-18&#34;&gt;&lt;a href=&#34;#cb7-18&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;       &lt;span class=&#34;at&#34;&gt;subtitle =&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;&amp;#39;ISP: MOVISTAR 20 Mbps&amp;#39;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb7-19&#34;&gt;&lt;a href=&#34;#cb7-19&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;       &lt;span class=&#34;at&#34;&gt;x =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb7-20&#34;&gt;&lt;a href=&#34;#cb7-20&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;       &lt;span class=&#34;at&#34;&gt;y =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;Hours&amp;#39;&lt;/span&gt;) &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb7-21&#34;&gt;&lt;a href=&#34;#cb7-21&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;cn&#34;&gt;NULL&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&#34;figure&#34; style=&#34;text-align: center&#34;&gt;&lt;span style=&#34;display:block;&#34; id=&#34;fig:box&#34;&gt;&lt;/span&gt;
&lt;img src=&#34;https://andresrcs.rbind.io/post/2020-01-20-internet-speed-test.en_files/figure-html/box-1.png&#34; alt=&#34;Boxplot of Time Between Failures&#34; width=&#34;672&#34; /&gt;
&lt;p class=&#34;caption&#34;&gt;
Figure 3: Boxplot of Time Between Failures
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;And with Figure &lt;a href=&#34;#fig:boxes&#34;&gt;4&lt;/a&gt; we can find out when the peak hours occur, so we can know at what time of the day is more likely for us to experience slow internet speeds.&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34; id=&#34;cb8&#34;&gt;&lt;pre class=&#34;sourceCode r&#34;&gt;&lt;code class=&#34;sourceCode r&#34;&gt;&lt;span id=&#34;cb8-1&#34;&gt;&lt;a href=&#34;#cb8-1&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;hour_data &lt;span class=&#34;ot&#34;&gt;&amp;lt;-&lt;/span&gt; plot_data &lt;span class=&#34;sc&#34;&gt;%&amp;gt;%&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb8-2&#34;&gt;&lt;a href=&#34;#cb8-2&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;fu&#34;&gt;as_data_frame&lt;/span&gt;() &lt;span class=&#34;sc&#34;&gt;%&amp;gt;%&lt;/span&gt; &lt;/span&gt;
&lt;span id=&#34;cb8-3&#34;&gt;&lt;a href=&#34;#cb8-3&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;    &lt;span class=&#34;fu&#34;&gt;mutate&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;time =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;format&lt;/span&gt;(time, &lt;span class=&#34;st&#34;&gt;&amp;quot;%H:%M&amp;quot;&lt;/span&gt;))&lt;/span&gt;
&lt;span id=&#34;cb8-4&#34;&gt;&lt;a href=&#34;#cb8-4&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span id=&#34;cb8-5&#34;&gt;&lt;a href=&#34;#cb8-5&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;hour_data &lt;span class=&#34;sc&#34;&gt;%&amp;gt;%&lt;/span&gt; &lt;/span&gt;
&lt;span id=&#34;cb8-6&#34;&gt;&lt;a href=&#34;#cb8-6&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;ggplot&lt;/span&gt;(&lt;span class=&#34;fu&#34;&gt;aes&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;x =&lt;/span&gt; time, &lt;span class=&#34;at&#34;&gt;y =&lt;/span&gt; download)) &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb8-7&#34;&gt;&lt;a href=&#34;#cb8-7&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;geom_boxplot&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;fill =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;#00B2EE&amp;quot;&lt;/span&gt;) &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb8-8&#34;&gt;&lt;a href=&#34;#cb8-8&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;geom_point&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;data =&lt;/span&gt; hour_data &lt;span class=&#34;sc&#34;&gt;%&amp;gt;%&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;filter&lt;/span&gt;(download &lt;span class=&#34;sc&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;8&lt;/span&gt;),&lt;/span&gt;
&lt;span id=&#34;cb8-9&#34;&gt;&lt;a href=&#34;#cb8-9&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;             &lt;span class=&#34;at&#34;&gt;shape =&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb8-10&#34;&gt;&lt;a href=&#34;#cb8-10&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;             &lt;span class=&#34;at&#34;&gt;color =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;red&amp;quot;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb8-11&#34;&gt;&lt;a href=&#34;#cb8-11&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;             &lt;span class=&#34;at&#34;&gt;size =&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;5&lt;/span&gt;) &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb8-12&#34;&gt;&lt;a href=&#34;#cb8-12&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;geom_hline&lt;/span&gt;(&lt;span class=&#34;fu&#34;&gt;aes&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;yintercept =&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;20&lt;/span&gt;), &lt;span class=&#34;at&#34;&gt;color =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;orange&amp;quot;&lt;/span&gt;,  &lt;span class=&#34;at&#34;&gt;linetype =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;dashed&amp;quot;&lt;/span&gt;) &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb8-13&#34;&gt;&lt;a href=&#34;#cb8-13&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;geom_hline&lt;/span&gt;(&lt;span class=&#34;fu&#34;&gt;aes&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;yintercept =&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;8&lt;/span&gt;), &lt;span class=&#34;at&#34;&gt;color =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;orange&amp;quot;&lt;/span&gt;,  &lt;span class=&#34;at&#34;&gt;linetype =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;dashed&amp;quot;&lt;/span&gt;) &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb8-14&#34;&gt;&lt;a href=&#34;#cb8-14&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;annotate&lt;/span&gt;(&lt;span class=&#34;st&#34;&gt;&amp;quot;text&amp;quot;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb8-15&#34;&gt;&lt;a href=&#34;#cb8-15&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;           &lt;span class=&#34;at&#34;&gt;x =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;c&lt;/span&gt;(&lt;span class=&#34;st&#34;&gt;&amp;quot;04:00&amp;quot;&lt;/span&gt;, &lt;span class=&#34;st&#34;&gt;&amp;quot;04:00&amp;quot;&lt;/span&gt;),&lt;/span&gt;
&lt;span id=&#34;cb8-16&#34;&gt;&lt;a href=&#34;#cb8-16&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;           &lt;span class=&#34;at&#34;&gt;y =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;c&lt;/span&gt;(&lt;span class=&#34;dv&#34;&gt;7&lt;/span&gt;, &lt;span class=&#34;dv&#34;&gt;19&lt;/span&gt;),&lt;/span&gt;
&lt;span id=&#34;cb8-17&#34;&gt;&lt;a href=&#34;#cb8-17&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;           &lt;span class=&#34;at&#34;&gt;label =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;c&lt;/span&gt;(&lt;span class=&#34;st&#34;&gt;&amp;quot;Guaranteed Minimum Speed&amp;quot;&lt;/span&gt;, &lt;span class=&#34;st&#34;&gt;&amp;quot;Advertised Speed&amp;quot;&lt;/span&gt;),&lt;/span&gt;
&lt;span id=&#34;cb8-18&#34;&gt;&lt;a href=&#34;#cb8-18&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;           &lt;span class=&#34;at&#34;&gt;family =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;Cloud Calligraphy&amp;quot;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb8-19&#34;&gt;&lt;a href=&#34;#cb8-19&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;           &lt;span class=&#34;at&#34;&gt;size =&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;5&lt;/span&gt;) &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb8-20&#34;&gt;&lt;a href=&#34;#cb8-20&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;labs&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;title =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;BOXPLOT OF OBSERVED DOWNLOAD SPEEDS BY HOUR OF THE DAY&amp;#39;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb8-21&#34;&gt;&lt;a href=&#34;#cb8-21&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;       &lt;span class=&#34;at&#34;&gt;subtitle =&lt;/span&gt;&lt;span class=&#34;st&#34;&gt;&amp;#39;ISP: MOVISTAR 20 Mbps&amp;#39;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb8-22&#34;&gt;&lt;a href=&#34;#cb8-22&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;       &lt;span class=&#34;at&#34;&gt;x =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;Hour&amp;#39;&lt;/span&gt;,&lt;/span&gt;
&lt;span id=&#34;cb8-23&#34;&gt;&lt;a href=&#34;#cb8-23&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;       &lt;span class=&#34;at&#34;&gt;y =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;Speed (Mbps)&amp;#39;&lt;/span&gt;) &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb8-24&#34;&gt;&lt;a href=&#34;#cb8-24&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;scale_y_continuous&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;breaks =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;seq&lt;/span&gt;(&lt;span class=&#34;dv&#34;&gt;0&lt;/span&gt;, &lt;span class=&#34;dv&#34;&gt;22&lt;/span&gt;, &lt;span class=&#34;at&#34;&gt;by =&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;),&lt;/span&gt;
&lt;span id=&#34;cb8-25&#34;&gt;&lt;a href=&#34;#cb8-25&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;                     &lt;span class=&#34;at&#34;&gt;limits =&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;c&lt;/span&gt;(&lt;span class=&#34;dv&#34;&gt;0&lt;/span&gt;, &lt;span class=&#34;dv&#34;&gt;22&lt;/span&gt;)) &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb8-26&#34;&gt;&lt;a href=&#34;#cb8-26&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;fu&#34;&gt;coord_cartesian&lt;/span&gt;(&lt;span class=&#34;at&#34;&gt;clip =&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;#39;off&amp;#39;&lt;/span&gt;) &lt;span class=&#34;sc&#34;&gt;+&lt;/span&gt;&lt;/span&gt;
&lt;span id=&#34;cb8-27&#34;&gt;&lt;a href=&#34;#cb8-27&#34; aria-hidden=&#34;true&#34; tabindex=&#34;-1&#34;&gt;&lt;/a&gt;  &lt;span class=&#34;cn&#34;&gt;NULL&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&#34;figure&#34; style=&#34;text-align: center&#34;&gt;&lt;span style=&#34;display:block;&#34; id=&#34;fig:boxes&#34;&gt;&lt;/span&gt;
&lt;img src=&#34;https://andresrcs.rbind.io/post/2020-01-20-internet-speed-test.en_files/figure-html/boxes-1.png&#34; alt=&#34;Boxplot of Observer Download Speeds by Hour of the Day&#34; width=&#34;768&#34; /&gt;
&lt;p class=&#34;caption&#34;&gt;
Figure 4: Boxplot of Observer Download Speeds by Hour of the Day
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Once you have data, plotting possibilities are only limited by your imagination, so I’m going to stop here, I hope you have enjoyed reading this article and you are motivated now to start monitoring your own internet speed. Have fun! see you soon!.&lt;/p&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>About</title>
      <link>https://andresrcs.rbind.io/about/</link>
      <pubDate>Sat, 18 Jan 2020 00:00:00 +0000</pubDate>
      
      <guid>https://andresrcs.rbind.io/about/</guid>
      <description>&lt;figure class=&#34;figure&#34;&gt;
    &lt;a href=&#34;https://andresrcs.rbind.io/images/andres_about.jpg&#34; class=&#34;d-block&#34; data-toggle=&#34;lightbox&#34; data-gallery=&#34;post-gallery&#34;&gt;
        &lt;img src=&#34;https://andresrcs.rbind.io/images/andres_about.jpg&#34; width=&#34;275&#34; height=&#34;400&#34;class=&#34;figure-img img-fluid&#34;
        /&gt; 
    &lt;/a&gt;&lt;figcaption class=&#34;figure-caption text-center&#34;&gt;
            Andrés Castro Socolich
        &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Hello! my name is Andrés I&amp;rsquo;m from Arequipa-Perú, I&amp;rsquo;m an Industrial Engineer with a specialization in Data Science and my favorite tool is R, mostly because of its friendly and supportive community, so I have made this blog to share my personal, data projects with the data science community.&lt;/p&gt;
&lt;p&gt;Posts here are going to have a broad variety of topics but all are going to be data-driven, I hope you enjoy reading my posts and find them useful.&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>