<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>devops on tkainrad</title>
    <link>https://tkainrad.dev/tags/devops/</link>
    <description>Recent content in devops on tkainrad</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <lastBuildDate>Fri, 18 Oct 2019 00:00:00 +0000</lastBuildDate>
    
        <atom:link href="https://tkainrad.dev/tags/devops/index.xml" rel="self" type="application/rss+xml" />
    
    
    <item>
      <title>Copy-paste ready commands to set up SGE, PBS/TORQUE, or SLURM clusters</title>
      <link>https://tkainrad.dev/posts/copy-paste-ready-instructions-to-set-up-1-node-clusters/</link>
      <pubDate>Fri, 18 Oct 2019 00:00:00 +0000</pubDate>
      
      <guid>https://tkainrad.dev/posts/copy-paste-ready-instructions-to-set-up-1-node-clusters/</guid>
      <description>&lt;h1 id=&#34;introduction&#34;&gt;Introduction&lt;/h1&gt;
&lt;p&gt;Local HPC clusters continue to play a vital role in scientific research. Many universities, research institutions, and companies continue to maintain on-site clusters despite the efforts of the big cloud providers to expand their offerings into this area.&lt;/p&gt;
&lt;p&gt;The software systems responsible for making these clusters of computers work together can be called &lt;em&gt;Distributed Research Management System.&lt;/em&gt; The most commonly used ones are SGE, PBS/TORQUE, and SLURM. Unfortunately, setting those up can be very painful. There is a lot of outdated information on the internet. It is required to fight with several different configuration files and minor issues can mean that no command will run properly.&lt;/p&gt;
&lt;figure&gt;
    &lt;img src=&#34;https://tkainrad.dev/images/drms.svg&#34;
         alt=&#34;Operating principle of a traditional resource-manager based computing cluster.&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;Operating principle of a traditional resource-manager based computing cluster.&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;If your task is to set up a large system that will be used for many years and you have got several days to do this perfectly, this might not be a problem. However, if you just want to play around with the different systems, spending several hours until you can submit your first job is a very bleak outlook.&lt;/p&gt;
&lt;p&gt;Therefore, I present copy-paste-ready instructions for setting up SGE, PBS/TORQUE, or SLURM on a single machine, which will act as the master and a compute node at the same time. All guides are tested on Ubuntu 18.04, but should work with little modification on most recent Linux installations. These commands can also serve to create container images or other automated setup workflows.&lt;/p&gt;
&lt;p&gt;Naturally, caution is warranted when executing commands as a super user. If you apply the listed commands on a production system, please make sure you understand everything that is done.&lt;/p&gt;
&lt;h1 id=&#34;slurm&#34;&gt;Slurm&lt;/h1&gt;
&lt;p&gt;Trying to set up SLURM on my development machine in order to run some test suites that need to interface with SLURM cost me quite a bit of time. There are plenty of extensive tutorials available. In contrast to SGE and PBS, there is even an up-to-date &lt;a href=&#34;https://slurm.schedmd.com/quickstart_admin.html&#34;&gt;official documentation&lt;/a&gt;. However, those resources cover much more than is needed for a single-node cluster and it is easy to get lost in the many configuration options that you will not need at first.&lt;/p&gt;
&lt;p&gt;Fortunately, I found &lt;a href=&#34;https://ubuntuforums.org/showthread.php?t=2404746&#34;&gt;this thread&lt;/a&gt; in the Ubuntu forums, which is the basis for my SLURM instructions.&lt;/p&gt;
&lt;p&gt;Start by installing munge and slurm:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;sudo apt install munge slurm-wlm
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then, create a new file at &lt;code&gt;/etc/slurm-llnl/slurm.conf&lt;/code&gt; with the following content:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;
&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;width:auto;overflow:auto;display:block;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;
&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 1
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 2
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 3
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 4
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 5
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 6
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 7
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 8
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 9
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;10
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;11
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;12
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;13
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;14
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;15
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;16
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;17
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;18
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;19
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;20
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;21
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;22
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;23
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;24
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;25
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;26
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;27
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;28
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;29
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;
&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-PacmanConf&#34; data-lang=&#34;PacmanConf&#34;&gt;&lt;span style=&#34;color:#309&#34;&gt;ControlMachine&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt;&amp;lt;YOUR-HOST-NAME&amp;gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#309&#34;&gt;MpiDefault&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt;none&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#309&#34;&gt;ProctrackType&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt;proctrack/pgid&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#309&#34;&gt;ReturnToService&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt;1&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#309&#34;&gt;SlurmctldPidFile&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt;/var/run/slurm-llnl/slurmctld.pid&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#309&#34;&gt;SlurmdPidFile&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt;/var/run/slurm-llnl/slurmd.pid&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#309&#34;&gt;SlurmdSpoolDir&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt;/var/lib/slurm-llnl/slurmd&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#309&#34;&gt;SlurmUser&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt;slurm&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#309&#34;&gt;StateSaveLocation&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt;/var/lib/slurm-llnl/slurmctld&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#309&#34;&gt;SwitchType&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt;switch/none&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#309&#34;&gt;TaskPlugin&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt;task/none&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;#&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;# SCHEDULING&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#309&#34;&gt;FastSchedule&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt;1&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#309&#34;&gt;SchedulerType&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt;sched/builtin&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#309&#34;&gt;SelectType&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt;select/linear&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;#&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;# LOGGING AND ACCOUNTING&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#309&#34;&gt;AccountingStorageType&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt;accounting_storage/none&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#309&#34;&gt;ClusterName&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt;&amp;lt;YOUR-HOST-NAME&amp;gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#309&#34;&gt;JobAcctGatherType&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt;jobacct_gather/none&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#309&#34;&gt;SlurmctldLogFile&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt;/var/log/slurm-llnl/slurmctld.log&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#309&#34;&gt;SlurmdLogFile&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt;/var/log/slurm-llnl/slurmd.log&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;#&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;# COMPUTE NODES&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#309&#34;&gt;NodeName&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt;&amp;lt;YOUR-HOST-NAME&amp;gt; &lt;span style=&#34;color:#309&#34;&gt;CPUs&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt;4 &lt;span style=&#34;color:#309&#34;&gt;Sockets&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt;1 &lt;span style=&#34;color:#309&#34;&gt;CoresPerSocket&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt;4 &lt;span style=&#34;color:#309&#34;&gt;ThreadsPerCore&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt;2 &lt;span style=&#34;color:#309&#34;&gt;State&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt;UNKNOWN&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#309&#34;&gt;PartitionName&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt;long &lt;span style=&#34;color:#309&#34;&gt;Nodes&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt;&amp;lt;YOUR-HOST-NAME&amp;gt; &lt;span style=&#34;color:#309&#34;&gt;Default&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt;YES &lt;span style=&#34;color:#309&#34;&gt;MaxTime&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt;INFINITE &lt;span style=&#34;color:#309&#34;&gt;State&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt;UP&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;You only need to replace &lt;code&gt;&amp;lt;YOUR-HOST-NAME&amp;gt;&lt;/code&gt; with your actual hostname. Simply execute the &lt;code&gt;hostname&lt;/code&gt; command if you are not sure what it is. Of course, you can also modify other settings, such as the number of CPUs, but the basic configuration from above should be enough for our 1-node cluster.&lt;/p&gt;
&lt;p&gt;We are almost finished, just enable and start the manager slurmctld:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;sudo systemctl &lt;span style=&#34;color:#366&#34;&gt;enable&lt;/span&gt; slurmctld
sudo systemctl start slurmctld
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Finally, enable and start the agent &lt;code&gt;slurmd&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;sudo systemctl &lt;span style=&#34;color:#366&#34;&gt;enable&lt;/span&gt; slurmd
sudo systemctl start slurmd
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Congratulations, your Slurm system should be up an running! Use &lt;code&gt;sinfo&lt;/code&gt; to check the status of the manager and the agent. The command &lt;code&gt;scontrol show node&lt;/code&gt; will give you information about your node setup.&lt;/p&gt;
&lt;p&gt;If Slurm did not start, fear not, there is likely only a small fix required. Start by looking for an error message with&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;systemctl status slurmd.service
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Does it say that the &lt;code&gt;slurmd.pid&lt;/code&gt; file coud not be opened? If so, your &lt;code&gt;slurm.conf&lt;/code&gt; file probably has different values for &lt;code&gt;SlurmctldPidFile&lt;/code&gt; and &lt;code&gt;SlurmdPidFile&lt;/code&gt; than your &lt;code&gt;slurmctld.service&lt;/code&gt; file. Check by printing the latter:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;less /usr/lib/systemd/system/slurmctld.service
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It might show &lt;code&gt;PIDFile=/run/slurmctld.pid&lt;/code&gt;, which means that we need to change &lt;code&gt;SlurmctldPidFile&lt;/code&gt; and &lt;code&gt;SlurmdPidFile&lt;/code&gt; in our &lt;code&gt;/etc/slurm-llnl/slurm.conf&lt;/code&gt; to the following:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;color:#033&#34;&gt;SlurmctldPidFile&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt;/run/slurmctld.pid
&lt;span style=&#34;color:#033&#34;&gt;SlurmdPidFile&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt;/run/slurmd.pid
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;After that, try again to start &lt;code&gt;slurmctld&lt;/code&gt; and &lt;code&gt;slurmd&lt;/code&gt; with the above commands.&lt;/p&gt;
&lt;h1 id=&#34;sge&#34;&gt;SGE&lt;/h1&gt;
&lt;p&gt;This one is not so simple.&lt;/p&gt;
&lt;p&gt;Some parts of the following setup are taken from a public &lt;a href=&#34;https://github.com/robsyme/docker-sge/blob/master/Dockerfile&#34;&gt;Dockerfile&lt;/a&gt; created by &lt;a href=&#34;https://github.com/robsyme&#34;&gt;Robert Syme&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;First, gain root permissions. On Ubuntu you can type &lt;code&gt;sudo -i&lt;/code&gt;. All commands have to be executed with root permissions.&lt;/p&gt;
&lt;p&gt;Then, create a new folder, let&amp;rsquo;s say via &lt;code&gt;mkdir /opt/sge/installfolder&lt;/code&gt;. Set the new folder&amp;rsquo;s location as an environment variable in the current shell via&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;color:#366&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#033&#34;&gt;INSTALLFOLDER&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt;/opt/sge/installfolder.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then, execute the following commands:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;color:#366&#34;&gt;cd&lt;/span&gt; &lt;span style=&#34;color:#033&#34;&gt;$INSTALLFOLDER&lt;/span&gt;
wget https://arc.liv.ac.uk/downloads/SGE/releases/8.1.9/sge-common_8.1.9_all.deb .
wget https://arc.liv.ac.uk/downloads/SGE/releases/8.1.9/sge-doc_8.1.9_all.deb .
wget https://arc.liv.ac.uk/downloads/SGE/releases/8.1.9/sge_8.1.9_amd64.deb .
dpkg -i ./*.deb
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then, download the following 4 files and place them also into the created folder, in our case into &lt;code&gt;/opt/sge/installfolder&lt;/code&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;https://tkainrad.dev/other/sge_init.sh&#34; download&gt;sge_init.sh&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://tkainrad.dev/other/sge_auto_install.conf&#34; download&gt;sge_auto_install.conf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://tkainrad.dev/other/sge_hostgrp.conf&#34; download&gt;sge_hostgrp.conf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://tkainrad.dev/other/sge_exec_host.conf&#34; download&gt;sge_exec_host.conf&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Most of the magic will happen through those scripts and configuration files. After the download, we need to set some environment variables in the current shell:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;color:#366&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#033&#34;&gt;SGE_ROOT&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt;/opt/sge
&lt;span style=&#34;color:#366&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#033&#34;&gt;SGE_CELL&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt;default
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We also need to set a new &lt;code&gt;profile.d&lt;/code&gt; config via&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;ln -s &lt;span style=&#34;color:#033&#34;&gt;$SGE_ROOT&lt;/span&gt;/&lt;span style=&#34;color:#033&#34;&gt;$SGE_CELL&lt;/span&gt;/common/settings.sh /etc/profile.d/sge_settings.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then, execute the following to install SGE and perform setup operations:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;color:#366&#34;&gt;cd&lt;/span&gt; &lt;span style=&#34;color:#033&#34;&gt;$SGE_ROOT&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; ./inst_sge -m -x -s -auto &lt;span style=&#34;color:#033&#34;&gt;$INSTALLFOLDER&lt;/span&gt;/sge_auto_install.conf &lt;span style=&#34;color:#c30;font-weight:bold&#34;&gt;\\&lt;/span&gt;
&lt;span style=&#34;color:#555&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; sleep &lt;span style=&#34;color:#f60&#34;&gt;10&lt;/span&gt; &lt;span style=&#34;color:#c30;font-weight:bold&#34;&gt;\\&lt;/span&gt;
&lt;span style=&#34;color:#555&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; /etc/init.d/sgemaster.sge-cluster restart &lt;span style=&#34;color:#c30;font-weight:bold&#34;&gt;\\&lt;/span&gt;
&lt;span style=&#34;color:#555&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; /etc/init.d/sgeexecd.sge-cluster restart &lt;span style=&#34;color:#c30;font-weight:bold&#34;&gt;\\&lt;/span&gt;
&lt;span style=&#34;color:#555&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; sed -i &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;s/HOSTNAME/`hostname`/&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#033&#34;&gt;$INSTALLFOLDER&lt;/span&gt;/sge_exec_host.conf &lt;span style=&#34;color:#c30;font-weight:bold&#34;&gt;\\&lt;/span&gt;
&lt;span style=&#34;color:#555&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; sed -i &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;s/HOSTNAME/`hostname`/&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#033&#34;&gt;$INSTALLFOLDER&lt;/span&gt;/sge_hostgrp.conf &lt;span style=&#34;color:#c30;font-weight:bold&#34;&gt;\\&lt;/span&gt;
&lt;span style=&#34;color:#555&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; /opt/sge/bin/lx-amd64/qconf -Me &lt;span style=&#34;color:#033&#34;&gt;$INSTALLFOLDER&lt;/span&gt;/sge_exec_host.conf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now, our new cluster is already up and running. However, we still need to add users to the &lt;code&gt;sgeusers&lt;/code&gt; group, which was defined in the &lt;code&gt;sge_hostgrp.conf&lt;/code&gt; file you  just applied. Only users from this group are allowed to submit jobs. Therefore, we run the following:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;/opt/sge/bin/lx-amd64/qconf -au &amp;lt;USER&amp;gt; sgeusers
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Finally, run &lt;code&gt;$INSTALLFOLDER/sge_init.sh&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You can now delete the complete &lt;code&gt;$INSTALLFOLDER&lt;/code&gt;, or at least run&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;rm &lt;span style=&#34;color:#033&#34;&gt;$INSTALLFOLDER&lt;/span&gt;/*.deb
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;After a restart to load the new &lt;code&gt;profile.d&lt;/code&gt; settings, all users that were added to &lt;code&gt;sgeusers&lt;/code&gt; should be able to submit jobs. Test this via:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;color:#366&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;echo Running test from &lt;/span&gt;&lt;span style=&#34;color:#033&#34;&gt;$HOSTNAME&lt;/span&gt;&lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;&lt;/span&gt; | qsub
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id=&#34;pbs--torque&#34;&gt;PBS / Torque&lt;/h1&gt;
&lt;p&gt;This is a little simpler again. Most of the setup is taken from &lt;a href=&#34;https://jabriffa.wordpress.com/2015/02/11/installing-torquepbs-job-scheduler-on-ubuntu-14-04-lts/&#34;&gt;another blog&lt;/a&gt;. Some inspiration is also from a public Dockerfile available at &lt;a href=&#34;https://hub.docker.com/r/agaveapi/torque/&#34;&gt;Docker Hub&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;First, gain root permissions. On Ubuntu you can type &lt;code&gt;sudo -i&lt;/code&gt;. All commands have to be executed with root permissions.&lt;/p&gt;
&lt;p&gt;We start by installing the relevant packages:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;apt-get install torque-server torque-client torque-mom torque-pam
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Installing these packages will create a default setup. Unfortunately, this is complex and would require complex changes to get to a working cluster. Instead, we stop all torque services and create a clean setup:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;/etc/init.d/torque-mom stop
/etc/init.d/torque-scheduler stop
/etc/init.d/torque-server stop
pbs_server -t create
killall pbs_server
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We start by setting &lt;code&gt;localhost&lt;/code&gt; as the server host and allowing root to change the database configuration:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;color:#366&#34;&gt;echo&lt;/span&gt; localhost &amp;gt; /etc/torque/server_name
&lt;span style=&#34;color:#366&#34;&gt;echo&lt;/span&gt; localhost &amp;gt; /var/spool/torque/server_priv/acl_svr/acl_hosts
&lt;span style=&#34;color:#366&#34;&gt;echo&lt;/span&gt; root@localhost &amp;gt; /var/spool/torque/server_priv/acl_svr/operators
&lt;span style=&#34;color:#366&#34;&gt;echo&lt;/span&gt; root@localhost &amp;gt; /var/spool/torque/server_priv/acl_svr/managers
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;With the following commands, we set &lt;code&gt;localhost&lt;/code&gt; also as compute node with 4 cores available:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;color:#366&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;SERVER.DOMAIN np=4&amp;#34;&lt;/span&gt; &amp;gt; /var/spool/torque/server_priv/nodes
&lt;span style=&#34;color:#366&#34;&gt;echo&lt;/span&gt; localhost &amp;gt; /var/spool/torque/mom_priv/config
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now, we can already start the daemon processes again:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;/etc/init.d/torque-server start
/etc/init.d/torque-scheduler start
/etc/init.d/torque-mom start
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;After this &lt;code&gt;qmgr&lt;/code&gt; is ready to start the scheduler:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;qmgr -c &lt;span style=&#34;color:#c30&#34;&gt;&amp;#39;set server scheduling = true&amp;#39;&lt;/span&gt;
qmgr -c &lt;span style=&#34;color:#c30&#34;&gt;&amp;#39;set server keep_completed = 300&amp;#39;&lt;/span&gt;
qmgr -c &lt;span style=&#34;color:#c30&#34;&gt;&amp;#39;set server mom_job_sync = true&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The following commands are to create a default queue and to configure it:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;qmgr -c &lt;span style=&#34;color:#c30&#34;&gt;&amp;#39;create queue batch&amp;#39;&lt;/span&gt;
qmgr -c &lt;span style=&#34;color:#c30&#34;&gt;&amp;#39;set queue batch queue_type = execution&amp;#39;&lt;/span&gt;
qmgr -c &lt;span style=&#34;color:#c30&#34;&gt;&amp;#39;set queue batch started = true&amp;#39;&lt;/span&gt;
qmgr -c &lt;span style=&#34;color:#c30&#34;&gt;&amp;#39;set queue batch enabled = true&amp;#39;&lt;/span&gt;
qmgr -c &lt;span style=&#34;color:#c30&#34;&gt;&amp;#39;set queue batch resources_default.walltime = 3:00:00&amp;#39;&lt;/span&gt;
qmgr -c &lt;span style=&#34;color:#c30&#34;&gt;&amp;#39;set queue batch resources_default.nodes = 1&amp;#39;&lt;/span&gt;
qmgr -c &lt;span style=&#34;color:#c30&#34;&gt;&amp;#39;set server default_queue = batch&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Finally, we allow our machine to submit to the new cluster:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;qmgr -c &lt;span style=&#34;color:#c30&#34;&gt;&amp;#39;set server submit_hosts = &amp;lt;hostname&amp;gt;&amp;#39;&lt;/span&gt;
qmgr -c &lt;span style=&#34;color:#c30&#34;&gt;&amp;#39;set server allow_node_submit = true&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To test the setup, you can use the following command:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;color:#366&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;echo Running test from &lt;/span&gt;&lt;span style=&#34;color:#033&#34;&gt;$HOSTNAME&lt;/span&gt;&lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;&lt;/span&gt; | qsub
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;The target audience for this post is probably very small. I decided to do it anyway, as there might be someone that can benefit immensely. Personally, I would have saved a lot of time if I found such a blog post a year ago. Also, I might need it again myself at some point.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Setting up a Linux Workstation for Software Development</title>
      <link>https://tkainrad.dev/posts/setting-up-linux-workstation/</link>
      <pubDate>Tue, 13 Aug 2019 00:00:00 +0000</pubDate>
      
      <guid>https://tkainrad.dev/posts/setting-up-linux-workstation/</guid>
      <description>&lt;h1 id=&#34;introduction&#34;&gt;Introduction&lt;/h1&gt;
&lt;p&gt;In my opinion, Linux is the best operating system for a software engineer, except they develop explicitly for Windows or macOS. Whenever I read about new features for the &lt;a href=&#34;https://docs.microsoft.com/en-us/windows/wsl/about&#34;&gt;Windows Subsystem for Linux&lt;/a&gt;, I wonder why people settle for anything less than the real thing. Linux aids many of my workflows with its customizability, superior command-line experience, native support for containerization platforms, a dependable package management system, and many other features that I will describe in this blog post. macOS comes close, but, in my opinion, falls short due to exorbitant hardware costs and less room for customization.&lt;/p&gt;
&lt;p&gt;Still, as with any other operating system, optimizing a Linux workstation for software development requires some configuration. In this post, I will present tools and concepts that I think are very helpful, but overlooked by many. I will try to show only things that are not specific to my workflows, but rather useful for almost any software engineer, DevOps specialist, or just regular productivity enthusiast. Naturally, many of the configuration options and tools covered in this post are subjective. Nevertheless, I am confident that my suggestions are a good place to start. They have served me well over the years and I continually try to optimize my setup. Hence, I very much appreciate any improvement you might suggest.&lt;/p&gt;
&lt;h1 id=&#34;prerequisites&#34;&gt;Prerequisites&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;A Linux machine&lt;/strong&gt;&lt;br&gt;
For this guide, I will use Ubuntu 20.04, which is the current LTS release. I am very happy with Ubuntu. Anything I don&amp;rsquo;t like can easily be changed. The biggest advantage over many other distributions is probably that the Ubuntu community is very large and it is usually easy to find people with similar problems. There is also a very active &lt;a href=&#34;https://askubuntu.com/&#34;&gt;StackExchange community&lt;/a&gt;.  However, most of the things covered in this post will apply to pretty much any Linux distribution and even macOS.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Some command-line experience&lt;/strong&gt;&lt;br&gt;
Much of this post is intended for people who feel right at home when they see a &lt;code&gt;~&lt;/code&gt;- character. If you are not comfortable working with command-lines and have no intention to change this, you can still read the other sections though.&lt;/p&gt;
&lt;h1 id=&#34;tweaking-ubuntu&#34;&gt;Tweaking Ubuntu&lt;/h1&gt;
&lt;p&gt;Before we start any serious work, I will point out some changes to Ubuntu itself that I apply on all my machines.&lt;/p&gt;
&lt;h2 id=&#34;appearance&#34;&gt;Appearance&lt;/h2&gt;
&lt;p&gt;One of the first things I do after installing Ubuntu is to install the &lt;em&gt;GNOME Tweak Tool&lt;/em&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;sudo apt-get install gnome-tweak-tool
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It enables complex modifications of the GNOME desktop environment. I recommend you play around with some of its options. For this guide, we will only consider the &lt;em&gt;Appearance&lt;/em&gt; section. Specifically, we want to change the default Ubuntu theme to another one that provides better contrasts and an overall cleaner experience, namely the &lt;a href=&#34;https://github.com/adapta-project/adapta-gtk-theme&#34;&gt;Adapta-gtk-theme&lt;/a&gt;, which is based on the Material Design guidelines.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;sudo apt-get install adapta-gtk-theme
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;After installing the theme, you should restart the &lt;em&gt;GNOME Tweak Tool&lt;/em&gt;, and you can then select &lt;em&gt;Adapta-Eta&lt;/em&gt; as your new theme. The theme comes with some nice benefits that you wouldn&amp;rsquo;t think of at first. For example, it fixes the ridiculously small toolbar icons in the Eclipse IDE.&lt;/p&gt;
&lt;figure class=&#34;center-figure&#34;&gt;
    &lt;img src=&#34;https://tkainrad.dev/images/5/adapta-elements.png&#34;
         alt=&#34;Adapta Theme elements (Source).&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;Adapta Theme elements (&lt;a href=&#34;https://github.com/adapta-project/adapta-gtk-theme&#34;&gt;Source&lt;/a&gt;).&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;


&lt;div class=&#34;notices warning&#34;&gt;
    &lt;p&gt;Unfortunately, the Adapta theme is no longer actively maintained. It is still a perfectly fine theme to use and if you notice any glitches, you can always switch themes with a couple clicks. A possible alternative is &lt;a href=&#34;https://github.com/nana-4/materia-theme&#34;&gt;Materia&lt;/a&gt;, which also works well with the remainder of this blog post.&lt;/p&gt;

&lt;/div&gt;
&lt;h2 id=&#34;nautilus-type-ahead-search&#34;&gt;Nautilus Type-Ahead Search&lt;/h2&gt;
&lt;p&gt;The next thing I suggest is to change the Nautilus search behavior. With recent Ubuntu distributions, there is no type-ahead search in the standard file explorer. This means you can not start to type some letters and jump between files that start with these letters. Instead, Nautilus will enter a dedicated search mode that is confusing and quite slow for folders with a large number of files.&lt;/p&gt;
&lt;p&gt;Fortunately, we can easily get the old behavior back:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;sudo add-apt-repository ppa:lubomir-brindza/nautilus-typeahead
sudo apt dist-upgrade
killall nautilus &lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;# to force a restart&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;figure class=&#34;center-figure&#34;&gt;
    &lt;img src=&#34;https://tkainrad.dev/images/5/type-ahead-search.gif&#34;
         alt=&#34;Searching through my /bin folder by typing ahead (Source).&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;Searching through my &lt;code&gt;/bin&lt;/code&gt; folder by typing ahead (&lt;a href=&#34;https://github.com/adapta-project/adapta-gtk-theme&#34;&gt;Source&lt;/a&gt;).&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;There is a &lt;a href=&#34;https://askubuntu.com/a/278553/188679&#34;&gt;StackExchange answer&lt;/a&gt; that provides further details.&lt;/p&gt;
&lt;h2 id=&#34;hibernation&#34;&gt;Hibernation&lt;/h2&gt;
&lt;p&gt;Another thing that is essential for me is hibernation. Usually, I will only shutdown my computer once a week or even less. However, I am not a big fan of suspending for long periods of time. Power outages could have unforeseen consequences and I simply feel a little better if my machines are off the grid altogether.&lt;/p&gt;
&lt;p&gt;Unfortunately, setting up hibernation is tricky and can depend on your hardware. I updated this section multiple times already to contain the most robust solution, but you never quite know.
If you don&amp;rsquo;t care about hibernation, you should probably skip this section and spare yourself the trouble.&lt;/p&gt;
&lt;p&gt;In principle, hibernation is possible out of the box. Just type &lt;code&gt;sudo systemctl hibernate&lt;/code&gt;. However, this is likely to fail with an error. My fix for this relies on a mixture of &lt;a href=&#34;https://linuxize.com/post/how-to-add-swap-space-on-ubuntu-20-04/#creating-a-swap-file&#34;&gt;this&lt;/a&gt; and &lt;a href=&#34;https://rephlex.de/blog/2019/12/27/how-to-hibernate-and-resume-from-swap-file-in-ubuntu-20-04-using-full-disk-encryption/&#34;&gt;that&lt;/a&gt; blog post. First, we need to find out the current size of our swap file:&lt;/p&gt;

&lt;div class=&#34;notices warning&#34;&gt;
    &lt;p&gt;The below instructions assume that you use Ubuntu 20.04 with a swap file. This is the default for new installations. However, if you upgraded from a previous version, you might still have a swap partition. In this case, the process is similar, but not covered here.&lt;/p&gt;

&lt;/div&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;sudo swapon --show &lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;# or `cat /proc/swaps`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If this is less than your main memory (RAM), you will need to increase it:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;sudo swapoff -a
sudo fallocate -l &amp;lt;SIZE&amp;gt;G /swapfile
sudo chmod &lt;span style=&#34;color:#f60&#34;&gt;600&lt;/span&gt; /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
sudo swapon --show &lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;# to verify changed size&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Next, we need to find out the UUID and offset of our now large enough swapfile:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;sudo swap-offset /swapfile
&amp;gt; &amp;lt;OFFSET&amp;gt;
sudo findmnt -no SOURCE,UUID -T /swapfile 
&amp;gt; &amp;lt;UUID&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;With this, we are almost done. Using the UUID and the file offset, we edit the following line in &lt;code&gt;/etc/default/grub&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;color:#c30&#34;&gt;`&lt;/span&gt;&lt;span style=&#34;color:#033&#34;&gt;GRUB_CMDLINE_LINUX_DEFAULT&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;quiet splash resume=UUID=&amp;lt;UUID&amp;gt; resume_offset=&amp;lt;OFFSET&amp;gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#c30&#34;&gt;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then, we create a &lt;code&gt;conf.d&lt;/code&gt; resume file. Simply do &lt;code&gt;sudo nano /etc/initramfs-tools/conf.d/resume&lt;/code&gt; and add the content &lt;code&gt;RESUME=UUID=&amp;lt;UUID&amp;gt;&lt;/code&gt; to the file. At last, we need to update grup and initramfs:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;sudo update-grub
sudo update-initramfs -u -k all
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And finally, you should be able to do &lt;code&gt;sudo systemctl hibernate&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Please let me know if this approach doesn&amp;rsquo;t work on your system. I would like to include potential problems in this post, if there are any.&lt;/p&gt;
&lt;h1 id=&#34;boosting-command-line-productivity&#34;&gt;Boosting Command-Line Productivity&lt;/h1&gt;
&lt;p&gt;I believe that command-line proficiency can significantly boost developer productivity. This is especially true in times of DevOps and NoOps, where developers are supposed to handle deployment pipelines and cloud infrastructure. Fortunately, there are some tools that can help you become a command-line wizard.&lt;/p&gt;
&lt;h2 id=&#34;shortcuts&#34;&gt;Shortcuts&lt;/h2&gt;
&lt;p&gt;Before going forward, I would suggest to set up some general terminal shortcuts. Simply go to &lt;em&gt;Edit -&amp;gt; Preferences -&amp;gt; Shortcuts&lt;/em&gt;. I like to replicate web browser shortcuts for opening new tabs and windows, closing tabs, and cycling between tabs.&lt;/p&gt;

&lt;div class=&#34;notices tip&#34;&gt;
    &lt;p&gt;Did you know that all common terminal emulators have an Undo shortcuts with &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;Shift&lt;/kbd&gt;+&lt;kbd&gt;-&lt;/kbd&gt;?
Among many other things, my side-project &lt;a href=&#34;https://keycombiner.com&#34;&gt;KeyCombiner&lt;/a&gt; has a public &lt;a href=&#34;https://keycombiner.com/collecting/collections/public/136&#34;&gt;collection of terminal shortcuts&lt;/a&gt;, many of which are barely known and still very useful.&lt;/p&gt;

&lt;/div&gt;
&lt;p&gt;However, using this interface, it is not possible to set up &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;Tab&lt;/kbd&gt; and &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;Shift&lt;/kbd&gt;+&lt;kbd&gt;Tab&lt;/kbd&gt; as tab switching shortcuts. Gnome has some issues with using the &lt;kbd&gt;Tab&lt;/kbd&gt; key in shortcut configurations. Thanks to &lt;a href=&#34;https://askubuntu.com/a/875482/188679&#34;&gt;this answer from the Ubuntu community&lt;/a&gt;, we can get around this. Simply execute the following in your terminal:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;gsettings &lt;span style=&#34;color:#366&#34;&gt;set&lt;/span&gt; org.gnome.Terminal.Legacy.Keybindings:/org/gnome/terminal/legacy/keybindings/ next-tab &lt;span style=&#34;color:#c30&#34;&gt;&amp;#39;&amp;lt;Primary&amp;gt;Tab&amp;#39;&lt;/span&gt;
gsettings &lt;span style=&#34;color:#366&#34;&gt;set&lt;/span&gt; org.gnome.Terminal.Legacy.Keybindings:/org/gnome/terminal/legacy/keybindings/ prev-tab &lt;span style=&#34;color:#c30&#34;&gt;&amp;#39;&amp;lt;Primary&amp;gt;&amp;lt;Shift&amp;gt;Tab&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;switching-from-bash-to-zsh&#34;&gt;Switching from Bash to Zsh&lt;/h2&gt;
&lt;p&gt;A couple of months ago, I made an important change in my life. I switched from Bash to Zsh.&lt;/p&gt;
&lt;p&gt;There are a lot of blog posts, threads, and articles that compare Bash and Zsh, e.g.:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.howtogeek.com/362409/what-is-zsh-and-why-should-you-use-it-instead-of-Bash/&#34;&gt;What is ZSH, and Why Should You Use It Instead of Bash?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://stackabuse.com/zsh-vs-bash/&#34;&gt;Zsh vs Bash&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://medium.com/wearetheledger/oh-my-zsh-made-for-cli-lovers-installation-guide-3131ca5491fb&#34;&gt;Oh-My-Zsh! A Work of CLI Magic — Tutorial for Ubuntu&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At the end it boils down to one thing: &lt;strong&gt;Plugin and theme support&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Zsh has an amazing themes and plugins ecosystem. Theme support allows you to easily get a beautiful shell. Plugins range from simple auto-completion for all kinds of applications and tools(git, mvn, hugo, &amp;hellip;) to complex stuff like improved search capabilities. Because of this fact alone, Zsh is superior to Bash.&lt;/p&gt;
&lt;p&gt;However, chances are that you grew fond of Bash and that you get a bad feeling when somebody tells you that there is something better. I understand, it was the same for me. Still, I urge you to give it a shot. The transition is very painless since pretty much everything you like about Bash still works with Zsh. You will not have to learn new commands.&lt;/p&gt;
&lt;h3 id=&#34;installing-zsh&#34;&gt;Installing Zsh&lt;/h3&gt;
&lt;p&gt;Installing Zsh on Ubuntu is very easy. We can use the regular package manager:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;sudo apt install zsh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then, we set Zsh as our new default shell:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;chsh -s &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;$(&lt;/span&gt;which zsh&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&#34;notices info&#34;&gt;
    &lt;p&gt;The &lt;code&gt;chsh&lt;/code&gt; command updates the &lt;code&gt;/etc/passwd&lt;/code&gt; file, but does not affect the current session. You need to log out and log in again to have zsh as your default shell.&lt;/p&gt;

&lt;/div&gt;
&lt;h3 id=&#34;configuring-zsh-history&#34;&gt;Configuring Zsh History&lt;/h3&gt;
&lt;p&gt;For me there are few things worse than searching for an old shell command only to find out that the shell&amp;rsquo;s history size was set to a ridiculously low default number and that, because of this, the command was not saved.&lt;/p&gt;
&lt;p&gt;Therefore, we extend the Zsh history size by putting this at the end of the &lt;code&gt;~/.zshrc&lt;/code&gt; configuration file:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;color:#033&#34;&gt;HISTSIZE&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#f60&#34;&gt;10000000&lt;/span&gt;
&lt;span style=&#34;color:#033&#34;&gt;SAVEHIST&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#f60&#34;&gt;10000000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For me, the command history is a tool to search for previous commands I might need now. I do not use it as a protocol for what I did when and in which exact order. Therefore, I use the following options to get rid of all duplicates in my history automatically:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;## History command configuration&lt;/span&gt;
    
setopt HIST_IGNORE_ALL_DUPS &lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;# ignore duplicated commands history list&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Also, I like to use multiple terminal sessions in parallel, potentially working on the same problem. For this, it helps a lot to share the same history among all sessions. It can be accomplished by&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;setopt SHARE_HISTORY &lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;# share command history data&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you are transitioning from Bash to Zsh, you probably want to keep your existing Bash history. In contrast to Bash, Zsh stores timestamps in its history file. Therefore, re-using the Bash history file does not work out of the box. Fortunately, all we need to do is to append some timestamp to all the commands from our previous Bash history and put them into the new Zsh history file. You could easily script this yourself or use one of the many good scripts that other people wrote, &lt;a href=&#34;https://gist.github.com/goyalankit/a1c88bfc69107f93cda1&#34;&gt;such as this one&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;zsh-features-that-are-not-in-bash&#34;&gt;Zsh Features that are not in Bash&lt;/h3&gt;
&lt;p&gt;Once we have Zsh installed and finished our basic history configuration, we can start to take a look at some out-of-the-box features that make it stand out in comparison with Bash. If these do not impress you, keep in mind that the real big thing is plugin support, which I cover &lt;a href=&#34;#installing-zsh-plugins&#34;&gt;below&lt;/a&gt;.&lt;/p&gt;
&lt;h4 id=&#34;recursive-path-expansion&#34;&gt;Recursive Path Expansion&lt;/h4&gt;
&lt;p&gt;Zsh can do much more sophisticated expansions than Bash. This is documented in detail in &lt;a href=&#34;http://zsh.sourceforge.net/Doc/Release/Expansion.html&#34;&gt;the Zsh manual&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;One feature that you can easily start to use is recursive path expansion. If you type &lt;code&gt;cd /usr/local/b&lt;/code&gt; in Bash, you can then press &lt;code&gt;Tab&lt;/code&gt; to expand this to &lt;code&gt;cd /usr/local/bin&lt;/code&gt;. With Zsh, you can also type &lt;code&gt;cd /u/lo/b&lt;/code&gt; and then press &lt;code&gt;Tab&lt;/code&gt;. Zsh will recursively expand all path elements:&lt;/p&gt;
&lt;figure class=&#34;center-figure&#34;&gt;
    &lt;img src=&#34;https://tkainrad.dev/images/5/recursive-path-expansion.gif&#34;/&gt; 
&lt;/figure&gt;

&lt;p&gt;The above animation shows also that you can omit &lt;code&gt;cd&lt;/code&gt; when changing directories.&lt;/p&gt;
&lt;h4 id=&#34;calculator-zcalc&#34;&gt;Calculator: zcalc&lt;/h4&gt;
&lt;p&gt;Before switching to Zsh, I was often using the Python Shell as a calculator. However, this has a few downsides. Obviously, the Python Shell is not primarily developed to be a good calculator app. For example,  simple operations, such as &lt;code&gt;sqrt&lt;/code&gt;, require import statements, and there are no convenient ways to access results of previous lines.&lt;/p&gt;
&lt;p&gt;The calculator script shipped with Zsh is a very simple and efficient solution. Before using it, it has to be loaded:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;autoload -Uz zcalc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you plan to use it often, you can add the &lt;code&gt;autoload&lt;/code&gt; command to your &lt;code&gt;~/.zshrc&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Then, start the calculator with &lt;code&gt;zcalc&lt;/code&gt; and do some calculations:&lt;/p&gt;
&lt;figure class=&#34;center-figure&#34;&gt;
    &lt;img src=&#34;https://tkainrad.dev/images/5/zcalc.gif&#34;
         alt=&#34;Results of previous operations can be accessed with the $-character.&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;Results of previous operations can be accessed with the &lt;code&gt;$&lt;/code&gt;-character.&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;h4 id=&#34;advanced-aliasing&#34;&gt;Advanced Aliasing&lt;/h4&gt;
&lt;p&gt;Zsh has some unique aliasing capabilities.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Suffix Aliases&lt;/strong&gt;&lt;br&gt;
This means you can assign applications to file suffixes, e.g. &lt;code&gt;alias -s txt=vscode&lt;/code&gt; will allow you to open a &lt;code&gt;.txt&lt;/code&gt; file with Visual Studio Code by just typing &lt;code&gt;file.txt&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Global Aliases&lt;/strong&gt;&lt;br&gt;
Global aliases are set with the &lt;code&gt;-g&lt;/code&gt; flag and allow to specify a replacement for any part of a command. For example, if you set &lt;code&gt;alias -g G=&#39; | grep&#39; &lt;/code&gt; you will be able to do the following:
&lt;figure class=&#34;center-figure&#34;&gt;
    &lt;img src=&#34;https://tkainrad.dev/images/5/global-alias.gif&#34;/&gt; 
&lt;/figure&gt;
&lt;/p&gt;

&lt;div class=&#34;notices info&#34;&gt;
    &lt;p&gt;To make aliases permanent, it is required to add them to your &lt;code&gt;~/.zshrc&lt;/code&gt;.&lt;/p&gt;

&lt;/div&gt;
&lt;h3 id=&#34;installing-zsh-plugins&#34;&gt;Installing ZSH plugins&lt;/h3&gt;
&lt;p&gt;Finally, it is time to explore the real strength of Zsh, which means installing plugins to boost our productivity above anything this anime character has ever seen before:&lt;/p&gt;
&lt;figure class=&#34;center-figure&#34;&gt;
    &lt;img src=&#34;https://tkainrad.dev/images/5/vegeta.gif&#34;/&gt; 
&lt;/figure&gt;

&lt;h4 id=&#34;package-manager-oh-my-zsh&#34;&gt;Package Manager: Oh my Zsh&lt;/h4&gt;
&lt;p&gt;A good place to start is to install &lt;a href=&#34;https://github.com/robbyrussell/oh-my-zsh&#34;&gt;Oh my Zsh&lt;/a&gt;, &amp;ldquo;a community-driven framework for managing your Zsh configuration.&amp;rdquo; Simply do:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;wget https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh -O - | zsh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Copy the template configuration file &lt;code&gt;.zshrc.zsh-template&lt;/code&gt; in the .&lt;code&gt;zshrc&lt;/code&gt; home directory and apply the configuration by executing the source command. Both can be done at once by executing the following line:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;cp ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;em&gt;Oh my Zsh&lt;/em&gt; comes with many themes and plugins that we only have to enable in the configuration file in order to use them. In the next section, we will start by selecting a pretty theme.&lt;/p&gt;
&lt;h4 id=&#34;theme-agnoster&#34;&gt;Theme: Agnoster&lt;/h4&gt;
&lt;p&gt;Personally, I like the &lt;em&gt;agnoster&lt;/em&gt; theme. It works well with the Adapta-Eta Gnome theme we have set &lt;a href=&#34;#appearance&#34;&gt;previously&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To enable a theme, set ZSH_THEME to the name of the theme in your &lt;code&gt;~/.zshrc&lt;/code&gt;, in my case this is  &lt;code&gt;ZSH_THEME=agnoster&lt;/code&gt;. If you have troubles with special characters not being shown properly, install the Powerline font package:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;sudo apt-get install fonts-powerline
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;em&gt;Oh my Zsh&lt;/em&gt; GitHub wiki provides a &lt;a href=&#34;https://github.com/robbyrussell/oh-my-zsh/wiki/Themes&#34;&gt;well curated list of available themes along with screenshots&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;All pictures and animations of terminals you see in this post show the Agnoster theme with slight modifications to the prompt. In particular, I removed the git-part of the prompt and added a newline part instead. If you would like to replicate this, edit your  &lt;code&gt;~/.oh-my-zsh/themes/agnoster.zsh-theme&lt;/code&gt; and replace the &lt;code&gt;## Main prompt&lt;/code&gt; part close to the end with the following:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;
&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;width:auto;overflow:auto;display:block;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;
&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 1
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 2
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 3
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 4
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 5
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 6
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 7
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 8
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 9
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;10
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;11
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;12
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;13
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;14
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;15
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;16
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;17
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;18
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;19
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;20
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;21
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;22
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;23
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;24
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;25
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;
&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;prompt_newline&lt;span style=&#34;color:#555&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;{&lt;/span&gt;
  &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;[[&lt;/span&gt; -n &lt;span style=&#34;color:#033&#34;&gt;$CURRENT_BG&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;]]&lt;/span&gt;; &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;then&lt;/span&gt;
    &lt;span style=&#34;color:#366&#34;&gt;echo&lt;/span&gt; -n &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34; %{%k%F{&lt;/span&gt;&lt;span style=&#34;color:#033&#34;&gt;$CURRENT_BG&lt;/span&gt;&lt;span style=&#34;color:#c30&#34;&gt;}%}&lt;/span&gt;&lt;span style=&#34;color:#033&#34;&gt;$SEGMENT_SEPARATOR&lt;/span&gt;&lt;span style=&#34;color:#c30&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#c30&#34;&gt;%{%k%F{&lt;/span&gt;&lt;span style=&#34;color:#033&#34;&gt;$CURRENT_BG&lt;/span&gt;&lt;span style=&#34;color:#c30&#34;&gt;}%}&lt;/span&gt;&lt;span style=&#34;color:#033&#34;&gt;$SEGMENT_SEPARATOR&lt;/span&gt;&lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;&lt;/span&gt;
  &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;else&lt;/span&gt;
    &lt;span style=&#34;color:#366&#34;&gt;echo&lt;/span&gt; -n &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34; %{%k%}&amp;#34;&lt;/span&gt;
  &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;fi&lt;/span&gt;

  &lt;span style=&#34;color:#366&#34;&gt;echo&lt;/span&gt; -n &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34; %{%f%}&amp;#34;&lt;/span&gt;
  &lt;span style=&#34;color:#033&#34;&gt;CURRENT_BG&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#c30&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;
&lt;span style=&#34;color:#555&#34;&gt;}&lt;/span&gt;

&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;## Main prompt&lt;/span&gt;
build_prompt&lt;span style=&#34;color:#555&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;{&lt;/span&gt;
  &lt;span style=&#34;color:#033&#34;&gt;RETVAL&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#033&#34;&gt;$?&lt;/span&gt;
  prompt_status
  prompt_virtualenv
  prompt_aws
  prompt_context
  prompt_dir
  prompt_bzr
  prompt_hg
  prompt_newline
  prompt_end
&lt;span style=&#34;color:#555&#34;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Additionally, I recommend changing the font color of the directory part of the prompt from black to white. In my opinion, this provides better contrast with the dark blue background:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;# Dir: current working directory&lt;/span&gt;
prompt_dir&lt;span style=&#34;color:#555&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;{&lt;/span&gt;
  prompt_segment blue white &lt;span style=&#34;color:#c30&#34;&gt;&amp;#39;%~&amp;#39;&lt;/span&gt;
&lt;span style=&#34;color:#555&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;basic-plugins&#34;&gt;Basic Plugins&lt;/h4&gt;
&lt;p&gt;Next, you should enable some included plugins via adding them to your &lt;code&gt;plugins&lt;/code&gt; setting in your &lt;code&gt;~/.zshrc&lt;/code&gt; file. After this step, it might look like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;color:#033&#34;&gt;plugins&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=(&lt;/span&gt;colored-man-pages git python django mvn aws docker vscode&lt;span style=&#34;color:#555&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You can browse all the plugins that come with &lt;em&gt;Oh my Zsh&lt;/em&gt; in the official &lt;a href=&#34;https://github.com/robbyrussell/oh-my-zsh/tree/master/plugins&#34;&gt;GitHub repository&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The above listed plugins are rather trivial, they provide command completion and define a set of aliases and shortcuts that come in handy when working with the respective tool. Nevertheless, this provides a real productivity boost. For example, finding out which git commands start with &lt;code&gt;r&lt;/code&gt; becomes much simpler:&lt;/p&gt;
&lt;figure class=&#34;center-figure&#34;&gt;
    &lt;img src=&#34;https://tkainrad.dev/images/5/git-r.gif&#34;/&gt; 
&lt;/figure&gt;

&lt;h4 id=&#34;jump-to-frequently-used-directories&#34;&gt;Jump to Frequently Used Directories&lt;/h4&gt;
&lt;p&gt;Most command-line work happens in just a handful of directories. For me, these are primarily the root folders of various software development projects. Of course, I could manually set aliases for these folders so that I can quickly switch between them, but this would be tedious.&lt;/p&gt;
&lt;p&gt;Fortunately, there is a better solution with &lt;a href=&#34;https://github.com/rupa/z&#34;&gt;z&lt;/a&gt;. It tracks your most used directories and will take you to them via &lt;code&gt;z &amp;lt;query&amp;gt;&lt;/code&gt;. The &lt;code&gt;query&lt;/code&gt; can be any part of target directory&amp;rsquo;s path:&lt;/p&gt;
&lt;figure class=&#34;center-figure&#34;&gt;
    &lt;img src=&#34;https://tkainrad.dev/images/gifs/z.gif&#34;/&gt; 
&lt;/figure&gt;

&lt;p&gt;The software is already bundled with &lt;em&gt;Oh my Zsh&lt;/em&gt;, simply add z to the list of plugins:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;color:#033&#34;&gt;plugins&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=(&lt;/span&gt;z colored-man-pages git python django mvn aws docker vscode&lt;span style=&#34;color:#555&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I could have probably included this one in the list of basic plugins above, but I wanted to highlight it because I find it particularly useful.&lt;/p&gt;
&lt;h4 id=&#34;supercharging-history-search&#34;&gt;Supercharging History Search&lt;/h4&gt;
&lt;p&gt;The original Bash history search always bothered me. Repeatedly pressing &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;r&lt;/kbd&gt; and hoping to get lucky at some point is very cumbersome if you have lots of similar commands containing the query. To be fair, there are also great additions for Bash that improve this situation, such as &lt;a href=&#34;https://github.com/cantino/mcfly&#34;&gt;McFly&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;However, this is about improving history search with Zsh. I believe the best solution is using &lt;a href=&#34;https://github.com/jimeh/zsh-peco-history&#34;&gt;peco-history&lt;/a&gt;. It is a Zsh plugin that relies on &lt;a href=&#34;https://github.com/peco/peco&#34;&gt;peco&lt;/a&gt; to interactively filter through your history file. Peco is a general-purpose interactive filtering tool that you can (and should!) also use as a stand-alone tool in your terminal. On Ubuntu, we can install it from the official repositories:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;sudo apt-get install peco
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Afterwards clone &lt;a href=&#34;https://github.com/jimeh/zsh-peco-history&#34;&gt;zsh-peco-history&lt;/a&gt; into the &lt;code&gt;$ZSH_CUSTOM/plugins&lt;/code&gt; directory. Zsh will automatically resolve the pre-set shell variable:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;git clone https://github.com/jimeh/zsh-peco-history.git &lt;span style=&#34;color:#033&#34;&gt;$ZSH_CUSTOM&lt;/span&gt;/plugins/zsh-peco-history
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then, add &lt;code&gt;zsh-peco-history&lt;/code&gt; to the list of plugins:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;color:#033&#34;&gt;plugins&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=(&lt;/span&gt;zsh-peco-history z colored-man-pages git python django mvn aws docker vscode&lt;span style=&#34;color:#555&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The plugin will be ready once you start a new terminal session.&lt;/p&gt;
&lt;p&gt;The following animation shows that this improved history search was very helpful for writing this blog post. It allowed me to easily search for the exact commands I used when I set up my current machine:&lt;/p&gt;
&lt;figure class=&#34;center-figure&#34;&gt;
    &lt;img src=&#34;https://tkainrad.dev/images/gifs/peco-search.gif&#34;
         alt=&#34;Searching shell history with peco.&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;Searching shell history with &lt;a href=&#34;https://github.com/peco/peco&#34;&gt;peco&lt;/a&gt;.&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;h4 id=&#34;autosuggestions&#34;&gt;Autosuggestions&lt;/h4&gt;
&lt;p&gt;Our new history search is great. The bad news is that we will not use it very often, because there is something that is even better in most cases: &lt;a href=&#34;https://github.com/zsh-users/zsh-autosuggestions/blob/master/INSTALL.md&#34;&gt;zsh-autosuggestions&lt;/a&gt;&lt;br&gt;
This plugin suggests completions for your commands as you type. By default, the suggested completion will be the first match in your history. This is how it looks like:&lt;/p&gt;
&lt;figure class=&#34;center-figure&#34;&gt;
    &lt;img src=&#34;https://tkainrad.dev/images/gifs/autosuggestions.gif&#34;
         alt=&#34;Using a suggested git command-line.&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;Using a suggested &lt;code&gt;git&lt;/code&gt; command-line.&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;git clone https://github.com/zsh-users/zsh-autosuggestions &lt;span style=&#34;color:#a00&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#033&#34;&gt;ZSH_CUSTOM&lt;/span&gt;&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;:-&lt;/span&gt;~/.oh-my-zsh/custom&lt;span style=&#34;color:#a00&#34;&gt;}&lt;/span&gt;/plugins/zsh-autosuggestions
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Afterward, add &lt;code&gt;zsh-autosuggestions&lt;/code&gt; to your plugins setting in your &lt;code&gt;~/.zshrc&lt;/code&gt; file:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;color:#033&#34;&gt;plugins&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=(&lt;/span&gt;zsh-autosuggestions zsh-peco-history z colored-man-pages git python django mvn aws docker vscode&lt;span style=&#34;color:#555&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;syntax-highlighting&#34;&gt;Syntax Highlighting&lt;/h4&gt;
&lt;p&gt;Another great plugin is &lt;a href=&#34;https://github.com/zsh-users/zsh-syntax-highlighting&#34;&gt;zsh-syntax-highlighting&lt;/a&gt;. It highlights commands while you are typing them. This is especially useful for catching syntax errors. Once again, install via git:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;git clone https://github.com/zsh-users/zsh-syntax-highlighting.git &lt;span style=&#34;color:#a00&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#033&#34;&gt;ZSH_CUSTOM&lt;/span&gt;&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;:-&lt;/span&gt;~/.oh-my-zsh/custom&lt;span style=&#34;color:#a00&#34;&gt;}&lt;/span&gt;/plugins/zsh-syntax-highlighting
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then, add &lt;code&gt;zsh-syntax-highlighting&lt;/code&gt; to your plugins setting in your &lt;code&gt;~/.zshrc&lt;/code&gt; file:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;color:#033&#34;&gt;plugins&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=(&lt;/span&gt;zsh-syntax-highlighting zsh-autosuggestions zsh-peco-history z colored-man-pages git python django mvn aws docker vscode&lt;span style=&#34;color:#555&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;figure class=&#34;center-figure&#34;&gt;
    &lt;img src=&#34;https://tkainrad.dev/images/5/syntax-highlighting.gif&#34;
         alt=&#34;Syntax highlighting also indicates whether a command is typed correctly.&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;Syntax highlighting also indicates whether a command is typed correctly.&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;h4 id=&#34;clipboard-tool&#34;&gt;Clipboard Tool&lt;/h4&gt;
&lt;p&gt;This one is not really a full-blown plugin. &lt;em&gt;Oh my Zsh&lt;/em&gt; comes with a script called &lt;code&gt;clipcopy&lt;/code&gt; out of the box. It is a simple tool that enables clipboard copy and past operations from the command-line:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&amp;lt;command&amp;gt; | clipcopy    &lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;# copies stdin to clipboard&lt;/span&gt;
clipcopy &amp;lt;file&amp;gt;         &lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;# copies the content of a file to clipboard&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If this doesn&amp;rsquo;t work, you are probably missing &lt;code&gt;xclip&lt;/code&gt;. Install it via&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;sudo apt-get install xclip 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Somehow, I have a hard time remembering the name &lt;em&gt;clipcopy&lt;/em&gt;, therefore I set a global alias as &lt;a href=&#34;https://tkainrad.dev/posts/setting-up-linux-workstation/#advanced-aliasing&#34;&gt;described above&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;color:#366&#34;&gt;alias&lt;/span&gt; -g &lt;span style=&#34;color:#033&#34;&gt;ctrlc&lt;/span&gt;&lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#c30&#34;&gt;&amp;#39; | clipcopy&amp;#39;&lt;/span&gt;
&lt;span style=&#34;color:#366&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;copythisinclipboard&amp;#34;&lt;/span&gt; ctrlc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&#34;notices info&#34;&gt;
    &lt;p&gt;If you don&amp;rsquo;t use &lt;em&gt;Oh my Zsh&lt;/em&gt;, you can get the functionality of &lt;em&gt;clipcopy&lt;/em&gt; via &lt;a href=&#34;https://github.com/twang817/zsh-clipboard&#34;&gt;an actual plugin&lt;/a&gt;.&lt;/p&gt;

&lt;/div&gt;
&lt;h1 id=&#34;ssh-setup&#34;&gt;SSH Setup&lt;/h1&gt;
&lt;p&gt;One of the great advantages of using Linux instead of Windows is the out-of-the-box SSH support. Immediately after installing your distribution, you can start to access remote servers.&lt;/p&gt;
&lt;p&gt;However, there is some room for streamlining your SSH tasks. You can avoid lots of repetitive typing if you modify your &lt;code&gt;.ssh/config&lt;/code&gt; file and setup meaningful defaults for the machines you access regularly:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;Host ec2-instance &lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;# you can freely chose a name here that will act as alias for this host&lt;/span&gt;
    HostName &amp;lt;ip-address or hostname&amp;gt;
    User tkainrad


Host cluster &lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;# you can freely chose a name here that will act as alias for this host&lt;/span&gt;
    HostName &amp;lt;ip-address or hostname&amp;gt;
    User tkainrad
    IdentityFile &lt;span style=&#34;color:#c30&#34;&gt;`&lt;/span&gt;/home/tkainrad/cluster_rsa.pub&lt;span style=&#34;color:#c30&#34;&gt;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For more sophisticated settings, look up the &lt;a href=&#34;https://linux.die.net/man/5/ssh_config&#34;&gt;&lt;code&gt;ssh_config&lt;/code&gt; man page&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you want to go one step further, you can set up public key authentication so you can login to your most-used remote hosts without having to re-enter your password each time.
With &lt;a href=&#34;https://www.ssh.com/ssh/copy-id&#34;&gt;&lt;code&gt;ssh-copy-id&lt;/code&gt;&lt;/a&gt;, there is a simple tool that streamlines this process. If you have your hosts already configured via the &lt;code&gt;.ssh/config&lt;/code&gt; file, just do&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;ssh-copy-id ec2-instance
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;By default, &lt;code&gt;ssh-copy-id&lt;/code&gt; will take your public key in &lt;code&gt;~.ssh/id_rsa.pub&lt;/code&gt;. If you want to use different keys for each of your remote hosts, check out the &lt;a href=&#34;http://manpages.ubuntu.com/manpages/trusty/man1/ssh-copy-id.1.html&#34;&gt;man page&lt;/a&gt; page or &lt;a href=&#34;https://www.howtogeek.com/tips/bypass-ssh-logins-by-adding-your-key-to-a-remote-server-in-a-single-command/&#34;&gt;this more extensive guide&lt;/a&gt;. If you use keys other than &lt;code&gt;~.ssh/id_rsa.pub&lt;/code&gt; you also have to add an &lt;code&gt;IdentityFile&lt;/code&gt; entry to your &lt;code&gt;.ssh/config&lt;/code&gt; settings. Afterwards, you will be able to access the machine by simply doing:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;ssh ec2-instance
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id=&#34;additional-tools&#34;&gt;Additional Tools&lt;/h1&gt;
&lt;p&gt;A great terminal gets you a long way. However, some additional tools can help make your workstation more complete. In this section, I try to present some of my favorites that could be useful to almost anyone.&lt;/p&gt;
&lt;h2 id=&#34;text-editing-vscodehttpscodevisualstudiocom&#34;&gt;Text Editing: &lt;a href=&#34;https://code.visualstudio.com/&#34;&gt;VSCode&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For most of my more extensive software engineering projects, I use JetBrains products or Eclipse. I will not describe setting up those in this post, as this would easily mandate a separate article. However, I present a more lightweight editing environment that is often a better choice than to start up a full-blown IDE. For a software engineer, especially for one that deals also with DevOps workloads, it is the daily business to edit and view all kinds of text-based files, such as .&lt;code&gt;txt&lt;/code&gt;, &lt;code&gt;.csv&lt;/code&gt;, &lt;code&gt;.md&lt;/code&gt;, &lt;code&gt;xml&lt;/code&gt;, &lt;code&gt;.yml&lt;/code&gt;, and &lt;code&gt;.json&lt;/code&gt;. For this, it is essential to have a fast text editor which can deal with large files and still provides sophisticated editing features.&lt;/p&gt;
&lt;p&gt;Previously, I used Sublime. For a couple of months now, I have switched to Visual Studio Code and I am still amazed by it. Comparing it to Sublime makes little sense in my opinion, because VSCode is just on a whole other level. Even for software projects with relatively simple technology stacks, such as this blog website, I now prefer VSCode over Eclipse or the JetBrains suite.&lt;/p&gt;
&lt;figure class=&#34;center-figure&#34;&gt;
    &lt;img src=&#34;https://tkainrad.dev/images/5/vscode.png&#34;
         alt=&#34;Screenshot of VSCode showing the default light theme (Light&amp;#43;) (Source).&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;Screenshot of VSCode showing the default light theme (Light+) (&lt;a href=&#34;https://superdevresources.com/best-vscode-light-themes/&#34;&gt;Source&lt;/a&gt;).&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;The easiest way to install Visual Studio Code on Ubuntu is to visit the &lt;a href=&#34;https://code.visualstudio.com/&#34;&gt;official website&lt;/a&gt; and to download the Debian package. You could have probably figured out how to do this yourself, but do you also know how to set VSCode as the default application for all text files? Simply do&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;xdg-mime default code.desktop text/plain
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This will spare you the headache of doing &lt;em&gt;Right-Click -&amp;gt; Properties -&amp;gt; Open With -&amp;gt; Set as default&lt;/em&gt; on every file type separately.&lt;/p&gt;
&lt;p&gt;Switching to VSCode from Sublime (or any other editor) is a surprisingly pleasant experience. VSCode will recommend the most relevant plugins as you go. For example, if you open a &lt;code&gt;.py&lt;/code&gt; file, some extensions for Python development will be recommended. Installing them is then just a click away and doesn&amp;rsquo;t even require a restart of the application. After some days of following VSCode&amp;rsquo;s recommendations and occasionally searching for some extensions manually, my setup was more complete and efficient than it ever was with Sublime.&lt;/p&gt;
&lt;h3 id=&#34;vscode-terminal-with-agnoster&#34;&gt;VSCode Terminal with Agnoster&lt;/h3&gt;

&lt;div class=&#34;notices info&#34;&gt;
    &lt;p&gt;If you don&amp;rsquo;t intend to use the integrated VSCode terminal, you can safely skip this section.&lt;/p&gt;

&lt;/div&gt;
&lt;p&gt;If you followed this guide until here and you now open an integrated Terminal in VSCode, you will likely be a bit disappointed. There are several problems. With our current setup, we need a monospace font, and the coloring does not work nicely with VSCode&amp;rsquo;s light theme.&lt;/p&gt;
&lt;p&gt;Fortunately, we can fix these things:&lt;/p&gt;
&lt;p&gt;First, install the &lt;a href=&#34;https://github.com/abertsch/Menlo-for-Powerline&#34;&gt;Menlo for Powerline&lt;/a&gt; font:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;git clone https://github.com/abertsch/Menlo-for-Powerline.git
sudo mv &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;Menlo for Powerline.ttf&amp;#34;&lt;/span&gt; /usr/share/fonts/
sudo fc-cache -vf /usr/share/fonts/ &lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;# Refresh fonts cache&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then, we change our terminal prompt colors a little bit to be compatible with both light and dark themes. Open &lt;code&gt;~/.oh-my-zsh/themes/agnoster.zsh-theme&lt;/code&gt; and change &lt;code&gt;prompt_context&lt;/code&gt; to the following:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;# Context: user@hostname (who am I and where am I)&lt;/span&gt;
prompt_context&lt;span style=&#34;color:#555&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;{&lt;/span&gt;
  &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;[[&lt;/span&gt; &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#033&#34;&gt;$USER&lt;/span&gt;&lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;&lt;/span&gt; !&lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#033&#34;&gt;$DEFAULT_USER&lt;/span&gt;&lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;||&lt;/span&gt; -n &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#033&#34;&gt;$SSH_CLIENT&lt;/span&gt;&lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;]]&lt;/span&gt;; &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;then&lt;/span&gt;
    prompt_segment cyan default &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;%(!.%{%F{yellow}%}.)%n@%m&amp;#34;&lt;/span&gt;
  &lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;fi&lt;/span&gt;
&lt;span style=&#34;color:#555&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Finally, we apply the new font and the new colors in the VSCode settings. Press &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;Shift&lt;/kbd&gt;+&lt;kbd&gt;P&lt;/kbd&gt; and start to type &lt;code&gt;Preferences: Open Settings (JSON)&lt;/code&gt;. We can now add the following lines to &lt;code&gt;settings.json&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;    &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;terminal.integrated.fontFamily&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;Menlo for Powerline&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;,&lt;/span&gt; 
    &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;workbench.colorCustomizations&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;:&lt;/span&gt; {
        &lt;span style=&#34;color:#309;font-weight:bold&#34;&gt;&amp;#34;terminal.ansiBlue&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;#01A0E4&amp;#34;&lt;/span&gt;,
        &lt;span style=&#34;color:#309;font-weight:bold&#34;&gt;&amp;#34;terminal.ansiCyan&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;#B5E4F4&amp;#34;&lt;/span&gt;,
    }&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;,&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The integrated VSCode terminal now looks nice and has all the functionality of all of our Zsh plugins.&lt;/p&gt;
&lt;figure class=&#34;center-figure&#34;&gt;
    &lt;img src=&#34;https://tkainrad.dev/images/5/vscode-terminal.png&#34;/&gt; 
&lt;/figure&gt;

&lt;h2 id=&#34;sync-configuration-files-mackuphttpsgithubcomlramackup&#34;&gt;Sync Configuration Files: &lt;a href=&#34;https://github.com/lra/mackup&#34;&gt;Mackup&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;So you just set up your desktop workstation, modified a bunch of configuration files, manually adjusted your VSCode keyboard shortcuts and now you want to do this also with your notebook?&lt;/p&gt;
&lt;p&gt;The solution to this is one of my favorite tools of all: &lt;a href=&#34;https://github.com/lra/mackup&#34;&gt;Mackup&lt;/a&gt;&lt;br&gt;
It will use any software that can sync a folder, such as Dropbox, to keep your application settings in sync.&lt;/p&gt;
&lt;p&gt;You can install it with &lt;code&gt;pip&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;pip install --upgrade mackup
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&#34;notices tip&#34;&gt;
    &lt;p&gt;If you have versioning troubles with &lt;code&gt;pip&lt;/code&gt; or Python on Ubuntu 20.04, I recommend to do &lt;code&gt;sudo apt install python-is-python3&lt;/code&gt;. It will symlink &lt;code&gt;/usr/bin/python&lt;/code&gt; to &lt;code&gt;python3&lt;/code&gt; and hence make your transition to a world without Python 2 easier.&lt;/p&gt;

&lt;/div&gt;
&lt;p&gt;Once Mackup is installed, you can copy your application settings to Dropbox (per default) doing&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;mackup backup
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To apply them at a different machine, just use&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;mackup restore
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Behind the scenes, Mackup copies your configuration files to your Dropbox and then replaces the originals with symbolic links. Have a look at the &lt;a href=&#34;https://github.com/lra/mackup#bullsht-what-does-it-really-do-to-my-files&#34;&gt;GitHub Readme&lt;/a&gt; for more details.&lt;/p&gt;
&lt;h2 id=&#34;advanced-screenshots-shutterhttpslaunchpadnetshutter&#34;&gt;Advanced Screenshots: &lt;a href=&#34;https://launchpad.net/shutter&#34;&gt;Shutter&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you are coming from Windows, you probably use the Snipping Tool on a regular basis. With &lt;em&gt;Screenshot&lt;/em&gt;, Ubuntu has a similar tool installed by default. However, there is another option that is superior to both the Windows Snipping Tool and the Ubuntu default: &lt;a href=&#34;https://launchpad.net/shutter&#34;&gt;Shutter&lt;/a&gt;&lt;br&gt;
Unfortunately, it is no longer included in the default package repositories since Ubuntu 18.10. So, we have to add a third-party PPA first:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;sudo add-apt-repository ppa:linuxuprising/shutter
sudo apt-get install shutter
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It is very simple to use and does not force you to become familiar with its advanced features. There are a few alternatives that are still actively developed, such as &lt;a href=&#34;https://github.com/flameshot-org/flameshot&#34;&gt;Flameshot&lt;/a&gt;. Unfortunately, those are missing a lot of Shutter&amp;rsquo;s more advanced features. So, I will stick with Shutter for as long as I can make it run on Ubuntu.&lt;/p&gt;
&lt;figure class=&#34;center-figure&#34;&gt;
    &lt;img src=&#34;https://tkainrad.dev/images/5/shutter.png&#34;/&gt; 
&lt;/figure&gt;

&lt;h2 id=&#34;pick-colors-pickhttpswwwkryogenixorgcodepick&#34;&gt;Pick Colors: &lt;a href=&#34;https://www.kryogenix.org/code/pick/&#34;&gt;Pick&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you do front-end development, chances are you need a color picking tool on your computer. The most commonly used tool on Ubuntu is GPick. However, it drives me crazy. Usually, I just want to pick a color and get the hex code into my clipboard. GPick makes this very hard. So instead, I recommend &lt;a href=&#34;https://www.kryogenix.org/code/pick/&#34;&gt;Pick&lt;/a&gt;, a simple and functional alternative.&lt;/p&gt;
&lt;figure class=&#34;center-figure&#34;&gt;
    &lt;img src=&#34;https://tkainrad.dev/images/5/pick.png&#34;/&gt; 
&lt;/figure&gt;

&lt;h2 id=&#34;cheatsheet-keycombiner-desktophttpskeycombinercomdesktop&#34;&gt;Cheatsheet: &lt;a href=&#34;https://keycombiner.com/desktop/&#34;&gt;KeyCombiner Desktop&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Most people know KeyCombiner as a tool for browsing and learning shortcuts. However, its desktop app serves an additioanl purpose with its instant lookup feature: It is a context-aware cheatsheet that can show the shortcuts of the currently active application in addition to whatever key combinations and text snippets I have in my personal KeyCombiner collections.&lt;/p&gt;
&lt;p&gt;To trigger it, I only have to press &lt;kbd&gt;Super&lt;/kbd&gt;+&lt;kbd&gt;Alt&lt;/kbd&gt;+&lt;kbd&gt;C&lt;/kbd&gt;. The main advantage is that I don&amp;rsquo;t have to leave the current context and can resume work right after looking up the required piece of information:&lt;/p&gt;
&lt;figure class=&#34;center-figure&#34;&gt;
    &lt;img src=&#34;https://tkainrad.dev/images/keycombiner/lookup-three-apps2.gif&#34;
         alt=&#34;KeyCombiner&amp;amp;rsquo;s instant shortcut lookup for VSCode, Terminal, and Chrome.&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;KeyCombiner&amp;rsquo;s instant shortcut lookup for VSCode, Terminal, and Chrome.&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;h2 id=&#34;communication-hub-ferdihttpsgetferdicom&#34;&gt;Communication Hub: &lt;a href=&#34;https://getferdi.com/&#34;&gt;Ferdi&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Did you ever see someone using their phone while sitting in front of their personal computer? Chances are, they were using a communication app that they could have used much more efficiently from their larger device with an actual keyboard. To get the benefit of receiving all notifications from all my communication tools, and to be able to respond easily, I use &lt;a href=&#34;https://getferdi.com/&#34;&gt;Ferdi&lt;/a&gt;. It is particularly useful if you have to monitor several Slack teams.&lt;/p&gt;
&lt;p&gt;In contrast to most of its competitors (Rambox, Wavebox, Franz 5), Ferdi is completely free and open-source.&lt;/p&gt;

&lt;div class=&#34;notices tip&#34;&gt;
    &lt;p&gt;If you want Ferdi or any other software that is distributed via an AppImage to show up properly in the dock, have a look at &lt;a href=&#34;https://github.com/AppImage/appimaged&#34;&gt;appimaged&lt;/a&gt;. It is open-source software that monitors specific directories for AppImage files and installs them properly in the system.&lt;/p&gt;

&lt;/div&gt;

&lt;div class=&#34;notices info&#34;&gt;
    &lt;p&gt;Previous versions of this article recommended &lt;a href=&#34;https://getstation.com/&#34;&gt;Station&lt;/a&gt; instead of Ferdi. However, Station pivoted to become a browser extension and is no longer an option for bundling communication channels outside of your regular browser.&lt;/p&gt;

&lt;/div&gt;
&lt;h2 id=&#34;record-short-screencasts-peekhttpsgithubcomphwpeek&#34;&gt;Record Short Screencasts: &lt;a href=&#34;https://github.com/phw/peek&#34;&gt;Peek&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Did you wonder how I created those fancy gifs showing my terminal? I thought so.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/phw/peek&#34;&gt;Peek&lt;/a&gt; is a very lightweight and simple tool to record short screencasts. To install it on Ubuntu do&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;sudo add-apt-repository ppa:peek-developers/stable
sudo apt update
sudo apt install peek
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;figure class=&#34;center-figure&#34;&gt;
    &lt;img src=&#34;https://tkainrad.dev/images/5/peek-recording-itself.gif&#34;
         alt=&#34;Peek in action. (Source).&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;Peek in action. (&lt;a href=&#34;https://github.com/phw/peek&#34;&gt;Source&lt;/a&gt;).&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;During the creation of this article, I was made aware by a &lt;a href=&#34;https://knasmueller.net/&#34;&gt;good friend and fellow software engineer&lt;/a&gt; of dedicated terminal recording tools, such as &lt;a href=&#34;https://terminalizer.com/&#34;&gt;Terminalizer&lt;/a&gt; and &lt;a href=&#34;https://asciinema.org/&#34;&gt;asciinema&lt;/a&gt;. However, these require some initial setup work, especially if you want to show off a theme and require that your animated terminal looks exactly like your actual terminal.&lt;br&gt;
Since I already recorded most of the animations, I decided to stay with Peek for this post. Nevertheless, if your use case is terminal recording, you should probably go with one of the linked projects instead of Peek.&lt;/p&gt;
&lt;h2 id=&#34;mail-client-thunderbirdhttpswwwthunderbirdneten-us&#34;&gt;Mail Client: &lt;a href=&#34;https://www.thunderbird.net/en-US/&#34;&gt;Thunderbird&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For mail, I use &lt;a href=&#34;https://www.thunderbird.net/en-US/&#34;&gt;Thunderbird&lt;/a&gt;. I don&amp;rsquo;t particularly like it, but to my knowledge it is still the best desktop email client for Linux. Unfortunately, some minor design decisions make the program almost unusable for me in its default state. The reason I include this section about software that everyone knows already is mainly to highlight three changes I always make to the default setup:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;By default, Thunderbird sorts messages by date ascending. I think that&amp;rsquo;s an unfortunate default. Who wants to scroll down constantly to see the newest messages? To change the sort order to descending (newest first), go to &lt;em&gt;Preferences -&amp;gt; General -&amp;gt; Config Editor&lt;/em&gt; and set &lt;em&gt;mailnews.default_sort_order&lt;/em&gt; to value 2. See &lt;a href=&#34;https://superuser.com/a/13551/573438&#34;&gt;this StackExchange answer&lt;/a&gt; for more details about default sorting orders and other options.&lt;/li&gt;
&lt;li&gt;Install the &lt;a href=&#34;https://addons.thunderbird.net/en-US/thunderbird/addon/no-message-pane-sort-by-mouse/&#34;&gt;No Message Pane Sort by Mouse&lt;/a&gt; add-on.
With this extension, a click on the mail list table header will no longer change the defined sort order. Without it, misclicks while trying to select the first mail in the list are very annoying. Personally, I never want to change the sort order at all. However, it is still possible by holding &lt;kbd&gt;Ctrl&lt;/kbd&gt; while clicking.&lt;/li&gt;
&lt;li&gt;Finally, go to &lt;em&gt;Preferences -&amp;gt; Composition&lt;/em&gt; and uncheck the &lt;em&gt;Use Paragraph format instead of Body Text by default&lt;/em&gt; to prevent Thunderbird       from adding absurd amounts of whitespace whenever you press the Enter key while composing a mail.&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&#34;notices tip&#34;&gt;
    &lt;p&gt;Are you already using Thunderbird on another computer? Fortunately, there is an easy way to migrate all your mail accounts and settings. Essentially, you can copy a hidden folder where Thunderbird stores all its data and move it to the new machine, &lt;a href=&#34;https://support.mozilla.org/en-US/kb/moving-thunderbird-data-to-a-new-computer&#34;&gt;as described in Mozilla&amp;rsquo;s official documentation&lt;/a&gt;.&lt;/p&gt;

&lt;/div&gt;
&lt;p&gt;If you know of a new fancy alternative to Thunderbird that handles parallel usage of several mail accounts well, please let me know.&lt;/p&gt;
&lt;h1 id=&#34;bonus-tip&#34;&gt;Bonus Tip&lt;/h1&gt;
&lt;p&gt;If you have read this far, I am willing to share my most secret Linux hack with you. Joking aside, it is very helpful to know what to do when your Linux workstation freezes. For some reason, I did not know until a couple years ago. Maybe the following trick can help you to avoid some forced restarts in the future.&lt;/p&gt;
&lt;p&gt;The most flexible way to re-gain control of a system that has frozen completely is pressing &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;Alt&lt;/kbd&gt;+&lt;kbd&gt;F3&lt;/kbd&gt;. Then, use top and other process monitoring tools to find the process IDs of the faulty processes. Then, simply kill them (e.g. type &lt;code&gt;kill &amp;lt;pid&amp;gt;&lt;/code&gt;, &lt;code&gt;killall&lt;/code&gt;, or &lt;code&gt;kill -9&lt;/code&gt;). Afterward, you can get back to your work using &lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;Alt&lt;/kbd&gt;+&lt;kbd&gt;F1&lt;/kbd&gt;. (&lt;a href=&#34;https://askubuntu.com/questions/547290/how-do-i-get-out-of-ctrl-alt-f3&#34;&gt;Source&lt;/a&gt;).&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;I hope this post showed you some tools or practices that you didn&amp;rsquo;t know yet. I have had a good experience with all of them. Especially switching from Bash to Zsh and installing &lt;a href=&#34;http://localhost:1313/posts/setting-up-linux-machine/#installing-zsh-plugins&#34;&gt;the described plugins&lt;/a&gt; came with a real productivity boost. If you feel that I left out something important, I&amp;rsquo;d be very interested to hear your suggestions.&lt;/p&gt;
&lt;p&gt;If you are not mainly using Linux yet, the length of this post might give the impression that it is still a pain to set up a proper Linux workstation. However, you do not necessarily need all of the things I showed here. Also, everything covered in this post is very easy to install with minimal configuration overhead. I strongly believe that you would have a much harder time setting up a comparable Windows development workstation.&lt;/p&gt;
&lt;figure class=&#34;center-figure&#34;&gt;
    &lt;img src=&#34;https://imgs.xkcd.com/comics/cautionary.png&#34;
         alt=&#34;You can still spend your life setting up Linux. However, if you use a popular, well-supported distribution you definitely don&amp;amp;rsquo;t have to. (Source: xkcd.com)&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;You can still spend your life setting up Linux. However, if you use a popular, well-supported distribution you definitely don&amp;rsquo;t have to. (Source: xkcd.com)&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;

</description>
    </item>
    
    <item>
      <title>Using Hugo, GitLab Pages, and Cloudflare to create and run this Website</title>
      <link>https://tkainrad.dev/posts/using-hugo-gitlab-pages-and-cloudflare-to-create-and-run-this-website/</link>
      <pubDate>Sat, 01 Jun 2019 00:00:00 +0000</pubDate>
      
      <guid>https://tkainrad.dev/posts/using-hugo-gitlab-pages-and-cloudflare-to-create-and-run-this-website/</guid>
      <description>&lt;p&gt;In this post, I outline how I develop and run this blog site. I briefly explain my technology choices and give detailed instructions about how to use the resulting stack to create such a project. If you stick with me until the end, you will know how to run a beautiful, easily customizable static website for free.&lt;/p&gt;
&lt;p&gt;When I decided to start this blog for the reasons outlined in &lt;a href=&#34;../writing-a-swe-blog/&#34;&gt;my first post&lt;/a&gt;, I was already familiar with GitLab Pages, and the &lt;a href=&#34;https://www.mkdocs.org/&#34;&gt;MkDocs&lt;/a&gt; static site generator. I am using this combination for creating documentation websites, and it is working very well.&lt;/p&gt;
&lt;p&gt;Therefore, it was an easy choice for me to also rely on GitLab Pages for this site. I will cover its features in a &lt;a href=&#34;#hosting-with-gitlab-pages&#34;&gt;later section&lt;/a&gt; of this post. With hosting already covered, I just needed to create the actual site.&lt;/p&gt;
&lt;h1 id=&#34;creating-the-site-with-hugohttpsgohugoio&#34;&gt;Creating the site with &lt;a href=&#34;https://gohugo.io/&#34;&gt;Hugo&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Before starting this blog, the only static site generator I used in production environments was MkDocs, which is intended for documentation and clearly not a good choice for creating a personal blog site.&lt;/p&gt;
&lt;p&gt;A good overview of more appropriate alternatives is given on &lt;a href=&#34;https://www.staticgen.com/&#34;&gt;staticgen.com&lt;/a&gt;. For my purpose, probably all the popular projects would have been good choices. I decided to go with Hugo for two reasons:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;It is written in Go, a language with a promising future that I wanted to try out for a while already.&lt;/li&gt;
&lt;li&gt;There is a very well-curated list of open-source themes directly &lt;a href=&#34;https://themes.gohugo.io/&#34;&gt;on the official website&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So let&amp;rsquo;s get to work.&lt;/p&gt;
&lt;p&gt;To get started on Ubuntu, we can execute just two commands to install hugo and create a new project:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;# install hugo&lt;/span&gt;
sudo snap install hugo

&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;# create a new project&lt;/span&gt;
hugo new site personal-blog
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you are not using Ubuntu, your system&amp;rsquo;s package manager likely provides a similarly easy experience. Refer to &lt;a href=&#34;https://gohugo.io/getting-started/installing&#34;&gt;the official documentation&lt;/a&gt; for installation instructions for other operating systems.&lt;/p&gt;
&lt;p&gt;Before we start to work on our site, we want to install a theme:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;# install the theme&lt;/span&gt;
&lt;span style=&#34;color:#366&#34;&gt;cd&lt;/span&gt; personal-blog
git init
git submodule add https://github.com/luizdepra/hugo-coder.git themes/hugo-coder
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I like that Hugo is very forward about using &lt;a href=&#34;https://git-scm.com/book/en/v2/Git-Tools-Submodules&#34;&gt;GIT submodules&lt;/a&gt; to install themes. This makes it easy to apply changes to the theme while keeping the connection to the original theme project. In an upcoming blog post, I will detail which changes I made to the theme itself. For now, we are perfectly fine with the default &lt;a href=&#34;https://github.com/luizdepra/hugo-coder/&#34;&gt;Hugo-Coder&lt;/a&gt; theme.&lt;/p&gt;
&lt;p&gt;We only need to apply some basic configuration. Simply replace the content of &lt;code&gt;config.toml&lt;/code&gt; with the following:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;
&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;width:auto;overflow:auto;display:block;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;
&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 1
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 2
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 3
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 4
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 5
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 6
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 7
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 8
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 9
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;10
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;11
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;12
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;13
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;14
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;15
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;16
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;17
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;18
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;19
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;20
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;21
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;
&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;baseurl = &amp;#34;http://www.example.com&amp;#34;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;title = &amp;#34;johndoe&amp;#34;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;theme = &amp;#34;hugo-coder&amp;#34;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;[params]&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;author = &amp;#34;John Doe&amp;#34;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;description = &amp;#34;John Doe&amp;#39;s personal website&amp;#34;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;keywords = &amp;#34;blog,developer,personal&amp;#34;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;info = &amp;#34;Full Stack Magician&amp;#34;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;avatarurl = &amp;#34;images/avatar.jpg&amp;#34;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;footercontent = &amp;#34;Enter a text here.&amp;#34;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;[taxonomies]&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;series = &amp;#34;series&amp;#34;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#09f;font-style:italic&#34;&gt;# Menu links&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;[[menu.main]]&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;name = &amp;#34;Blog&amp;#34;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;weight = 1&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;url  = &amp;#34;/posts/&amp;#34;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Then, we create the first post:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;hugo new posts/my-first-post.md
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For the theme to properly recognize the new blog post, we have to replace the content of the newly created &lt;code&gt;/content/posts/my-first-post.md&lt;/code&gt; with the following:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;
&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;width:auto;overflow:auto;display:block;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;
&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;3
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;4
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;5
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;6
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;7
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;
&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;+++&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;date = &amp;#34;2019-01-01&amp;#34;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;title = &amp;#34;My first Post&amp;#34;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;slug = &amp;#34;my-first-post&amp;#34; &lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;tags = []&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;categories = []&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;series = []&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;+++&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Finally, we can get a first look at our new personal portfolio and blogging site, by starting up the Hugo development server. Simply type&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;hugo server
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then go to &lt;a href=&#34;http://localhost:1313/&#34;&gt;http://localhost:1313/&lt;/a&gt; to see your new site:&lt;/p&gt;
&lt;figure&gt;
    &lt;img src=&#34;https://tkainrad.dev/images/hugo-coder-default-page.png&#34;
         alt=&#34;Hugo coder default page.&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;Hugo coder default page.&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Testing your site locally is great, but showing the whole world that you are &lt;em&gt;John Doe, the Full Stack Magician&lt;/em&gt; is something else entirely. Luckily, we are very close to doing just that.&lt;/p&gt;
&lt;h1 id=&#34;hosting-with-gitlab-pageshttpsdocsgitlabcomeeuserprojectpages&#34;&gt;Hosting with &lt;a href=&#34;https://docs.gitlab.com/ee/user/project/pages/&#34;&gt;GitLab Pages&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;GitLab Pages is similar to GitHub Pages.
Both allow free hosting of static websites. GitLab Pages enables you to build the hosted static content via GitLab&amp;rsquo;s CI/CD features. This means that your site will automatically be rebuilt on every commit to the repository. Until the release of GitHub Actions, GitHub could not do this. Instead, you had to build the site locally and commit the static files to the repository. Nowadays, both GitLab and GitHub are perfectly fine choices to host your static site.&lt;/p&gt;
&lt;p&gt;Naturally, we start by creating a new repository.  Before pushing anything to this repository, you might want to perform some usual GIT maintenance tasks, such as creating a &lt;code&gt;.gitignore&lt;/code&gt; file. If you do not know it yet, you should have a look at the &lt;a href=&#34;https://www.toptal.com/developers/gitignore&#34;&gt;gitignore.io service&lt;/a&gt; service. The site generates &lt;code&gt;.gitignore&lt;/code&gt; files depending on your technology stack. For Hugo, it will for example exclude the &lt;code&gt;/public/&lt;/code&gt; folder, which is very much what we want, because we will build this folder via a GitLab CI pipeline on every push to the repository.&lt;/p&gt;
&lt;p&gt;Once everything is in order, we can simply follow GitLab&amp;rsquo;s instructions for pushing our existing project folder:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;
&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;width:auto;overflow:auto;display:block;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;
&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;3
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;4
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;
&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-Bash&#34; data-lang=&#34;Bash&#34;&gt;&lt;span style=&#34;color:#366&#34;&gt;cd&lt;/span&gt; personal-blog
git remote add origin git@gitlab.com:&amp;lt;path-to-your-repository&amp;gt;
git add .
git commit -m &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;Initial commit&amp;#34;&lt;/span&gt;
git push -u origin master&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Finally, we get to the exciting part: Having our site built and published on every new commit to the repository. If you are not yet familiar with GitLab&amp;rsquo;s CI/CD features, check out &lt;a href=&#34;https://docs.gitlab.com/ee/ci/&#34;&gt;their docs&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Fortunately, getting started is very simple. Simply put a file called &lt;code&gt;.gitlab-ci.yml&lt;/code&gt; in the root of your project. This YAML configuration file holds all CI/CD configuration. For our Hugo-powered blog, the following file content is sufficient:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;
&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;width:auto;overflow:auto;display:block;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;
&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 1
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 2
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 3
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 4
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 5
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 6
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 7
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 8
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 9
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;
&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;color:#309;font-weight:bold&#34;&gt;image&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;monachus/hugo&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#309;font-weight:bold&#34;&gt;pages&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#309;font-weight:bold&#34;&gt;script&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- hugo&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#309;font-weight:bold&#34;&gt;artifacts&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;&lt;span style=&#34;color:#309;font-weight:bold&#34;&gt;paths&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;        &lt;/span&gt;- public&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#309;font-weight:bold&#34;&gt;only&lt;/span&gt;:&lt;span style=&#34;color:#bbb&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;    &lt;/span&gt;- master&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The first line specifies the docker base image to use for our pipeline. For this brief tutorial, we will not use any testing stages, instead, we have just one simple job called &lt;code&gt;pages&lt;/code&gt;. It executes the &lt;code&gt;hugo&lt;/code&gt; command, which will build the static site content in the &lt;code&gt;public&lt;/code&gt; directory. Somewhat incidentally, this is also where GitLab Pages expects to find our static site content. The only thing left to do is publishing the &lt;code&gt;public&lt;/code&gt; directory as &lt;a href=&#34;https://docs.gitlab.com/ee/user/project/pipelines/job_artifacts.html&#34;&gt;a job artifact&lt;/a&gt;. The last two lines are optional and state that the site should only be built and published on commits to the &lt;code&gt;master&lt;/code&gt; branch.&lt;/p&gt;
&lt;p&gt;Once you push this file to your repository&amp;rsquo;s master branch, the static site will be built and published within a few minutes. Go to &lt;em&gt;Settings-&amp;gt;Pages&lt;/em&gt; to verify that everything is in order and to see the default URL of your new website. If you own a domain you would like to use rather than the default *.gitlab.io one, you can head &lt;a href=&#34;https://docs.gitlab.com/ee/user/project/pages/getting_started_part_three.html&#34;&gt;to the docs&lt;/a&gt; or check out this &lt;a href=&#34;https://about.gitlab.com/2016/04/07/gitlab-pages-setup/&#34;&gt;more detailed tutorial&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;However, before you do this, you may want to read the next section of this blog post, as the information given there could spare you some headaches.&lt;/p&gt;
&lt;h1 id=&#34;speeding-up-load-times-and-configuring-url-redirections-with-cloudflarehttpswwwcloudflarecom&#34;&gt;Speeding up load times and configuring URL redirections with &lt;a href=&#34;https://www.cloudflare.com/&#34;&gt;Cloudflare&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Initially, I configured SSL for this site via Let&amp;rsquo;s Encrypt. In principle, this is a perfectly fine way to do it. There is a &lt;a href=&#34;https://docs.gitlab.com/ee/user/project/pages/lets_encrypt_for_gitlab_pages.html&#34;&gt;good tutorial in the official GitLab Docs&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;However, it is a little bit tedious, as it requires frequent renewals, a process that can not be automated easily. Furthermore, I had problems redirecting from www. to non-www URLs with Namecheap, which is my domain name registrar. The issue was complicated by the fact that this site uses a .dev domain which is by default on the &lt;a href=&#34;https://opensource.google.com/projects/hstspreload&#34;&gt;HSTS preload list&lt;/a&gt;. Namecheap seems to prefer selling their own SSL certificates rather than fully support and document working with Let&amp;rsquo;s Encrypt.&lt;/p&gt;
&lt;p&gt;I solved all those issues at once by simply signing up to Cloudflare. The free version is perfectly fine for me. After signing up, Cloudflare provides very simple and precise instructions for getting started. Basically, you have to configure your domain to use their nameservers instead of the ones provided by your original domain name registrar.&lt;/p&gt;
&lt;p&gt;Once your site is configured to run with Cloudflare, you can use their &lt;em&gt;Page Rules&lt;/em&gt; feature to easily redirect traffic from the www. subdomain to your canonical non-www URL or the other way around.&lt;/p&gt;
&lt;p&gt;Furthermore, Cloudflare provides SSL encryption out of the box from their servers to your clients. All your static sites hosted with GitLab Pages and served via Cloudflare will be accessible over HTTPS without any additional configuration. Of course, we also want to encrypt the traffic from Cloudflare to the origin GitLab Pages host. For this, Cloudflare offers &lt;em&gt;Origin Certificates&lt;/em&gt;. I will not explain this further, as there is an excellent &lt;a href=&#34;https://about.gitlab.com/2017/02/07/setting-up-gitlab-pages-with-cloudflare-certificates/&#34;&gt;tutorial on this provided directly by GitLab&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Edit:&lt;/strong&gt;
&lt;em&gt;&lt;a href=&#34;https://about.gitlab.com/2019/07/22/gitlab-12-1-released/&#34;&gt;With GitLab 12.1&lt;/a&gt;, released on July 22, 2019, it is possible to automatically get HTTPS certificates for GitLab Pages using Let’s Encrypt. Using Cloudflare Origin Certificates is still a perfectly fine approach, however, it is no longer more convenient than just using GitLab&amp;rsquo;s Let&amp;rsquo;s Encrypt integration.&lt;/em&gt;&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;The biggest advantage of this setup is its financial cost. Apart from buying the &lt;a href=&#34;http://tkainrad.dev&#34;&gt;tkainrad.dev&lt;/a&gt; domain, creating this site did not cost any money. Furthermore, the page is now running at absolutely zero cost. This is not restricted to a limited timeframe, thanks to GitLab Pages.&lt;/p&gt;
&lt;figure class=&#34;center-figure&#34;&gt;
    &lt;img src=&#34;https://imgs.xkcd.com/comics/reduce_your_payments.png&#34;
         alt=&#34;Fortunately, we do not have to resort to chemistry puns to reduce our hosting bills. (Source: xkcd.com)&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;Fortunately, we do not have to resort to &lt;a href=&#34;https://www.explainxkcd.com/wiki/index.php/1426:_Reduce_Your_Payments&#34;&gt;chemistry puns&lt;/a&gt; to reduce our hosting bills. (Source: xkcd.com)&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;If you have basic programming skills, I highly recommend hosting your static sites with this free service instead of paying a monthly fee to a hosting provider.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>High-performance Computing with AWS Parallelcluster</title>
      <link>https://tkainrad.dev/posts/aws-parallelcluster/</link>
      <pubDate>Tue, 07 May 2019 00:00:00 +0000</pubDate>
      
      <guid>https://tkainrad.dev/posts/aws-parallelcluster/</guid>
      <description>&lt;h1 id=&#34;overview&#34;&gt;Overview&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;AWS ParallelCluster&lt;/em&gt; is a toolkit for automating the process of building, configuring,
and managing clusters of virtual machines on the Amazon Elastic Compute Cloud (EC2)
cloud. These clusters can be used similar to traditional HPC clusters, as illustrated below.&lt;/p&gt;
&lt;figure&gt;
    &lt;img src=&#34;https://tkainrad.dev/images/drms.svg&#34;
         alt=&#34;Operating principle of a traditional resource-manager based computing cluster.&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;Operating principle of a traditional resource-manager based computing cluster.&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;The software is essentially a command-line tool written in Python that
provides simple commands for creating, updating, stopping, starting, and deleting HPC
clusters in the AWS EC2 cloud. Naturally, to provide these functionalities, the locally
installed CLI has to use the web APIs of existing AWS services. The most important
one of these services is AWS Cloudformation. It facilitates the creation
and management of a collection of related AWS resources. A set of nodes belonging to a
specific HPC cluster can be such a collection. Another essential service is Auto Scaling,
providing dynamic elastic scaling of the number of compute nodes depending on the
current workload. As a consequence, ParallelCluster can be configured to automatically add
nodes when jobs are pending and not able to run due to the cluster being fully utilized.&lt;/p&gt;
&lt;figure&gt;
    &lt;img src=&#34;https://tkainrad.dev/images/elasticity.svg&#34;
         alt=&#34;Cloud elasticity allows automated addition and deletion of nodes depending on the current job queue size.&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;Cloud elasticity allows automated addition and deletion of nodes depending on the current job queue size.&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;ParallelCluster is maintained directly by Amazon Web Services (AWS) and developed
as an open source project &lt;a href=&#34;https://github.com/aws/aws-parallelcluster&#34;&gt;accessible on GitHub&lt;/a&gt;. While the restriction to AWS is
certainly disadvantageous, the official support from and for a specific cloud provider
results in a stable and regularly updated product. The latter is especially important
for any framework facilitating cluster computing in the cloud, because the tool has to
be able to deal with new versions of operating systems, updates to cluster computing
software and changes in the product palette of the supported cloud providers.&lt;/p&gt;
&lt;h1 id=&#34;performance-compared-to-on-site-clusters&#34;&gt;Performance Compared to On-Site Clusters&lt;/h1&gt;
&lt;p&gt;HPC in the cloud faces complex challenges that have to be overcome in order to compete
with on-site clusters. Specifically, these include the interconnection
networks between machines in the cloud datacenters, which are most often not built for supporting HPC applications, and secondly, a performance decrease due to virtualization.&lt;/p&gt;
&lt;p&gt;Already in 2009, &lt;a href=&#34;https://doi.org/10.1145/1531666.1531671&#34;&gt;Napper et al.&lt;/a&gt; have used the &lt;a href=&#34;https://doi.org/10.1002/cpe.728&#34;&gt;LINPACK benchmark&lt;/a&gt; to assess
the performance of HPC clusters allocated in the Amazon EC2 cloud. The sobering
conclusion has been that, at least for communication intensive problems, HPC in the
cloud can not yet make use of its potential strengths regarding scalability and cost saving.
To the contrary, it has been shown that the achieved floating point operations per second
(FLOPS) per dollar spent decrease exponentially as the allocated cluster grows. This is,
as expected, due to the slow interconnection network and limited memory available on
single nodes.
One year later, in 2010, &lt;a href=&#34;https://doi.org/10.1109/CloudCom.2010.69&#34;&gt;Jackson et al.&lt;/a&gt; have performed similar experiments and also
encountered the familiar problem of slow network connections. They observed a clear
correlation between the runtime of different distributed applications and the amount
of time spent communicating. However, Jackson et al. have also shown that for
applications requiring little communication between computing nodes, HPC cloud clusters
can scale well.&lt;/p&gt;
&lt;p&gt;The situation has since progressed further. Real world problems are often embarrassingly
parallel or come close to it, enabling all benefits of cloud computing, even with sub-par
interconnection networks. This development is illustrated by various case studies of
different scientific fields, especially the computational life sciences. &lt;a href=&#34;https://aws.amazon.com/solutions/case-studies/novartis/&#34;&gt;Novartis used the Amazon EC2 cloud&lt;/a&gt; with 87 000 on-demand CPU cores to vastly decrease computation
time for a VS experiment, a scientific technique explained in detail in Section 2.5.
&lt;a href=&#34;https://cyclecomputing.com/hgst-buys-70000-core-cloud-hpc-cluster-breaks-record-8-hours/&#34;&gt;HGST built a similarly strong cloud cluster&lt;/a&gt; of 70 000 cores to run a simulation for finding
an optimal hard drive head design.&lt;/p&gt;
&lt;h1 id=&#34;getting-started&#34;&gt;Getting Started&lt;/h1&gt;
&lt;p&gt;Perhaps the most important benefit of using a cloud cluster is the possibility to set it up in a couple of minutes. Provisioning a physical HPC cluster requires competent system administrators, air conditioned space for the machines, a large up-front hardware investement, etc. etc.&lt;/p&gt;
&lt;p&gt;Getting started with AWS Parallelcluster only requires an AWS account and the ParallelCluster software. Detailed instructions for creating an account can be found at the &lt;a href=&#34;https://docs.inteligand.com/ls-remote/working-with-aws/#creating-your-aws-account&#34;&gt;official AWS website&lt;/a&gt;. The installation procedure for ParallelCluster is also well described at &lt;a href=&#34;https://aws-parallelcluster.readthedocs.io/en/latest/getting_started.html&#34;&gt;the official docs&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Before you can configure ParallelCluster, it is need to create an AWS Access Key. To do this, click on your Account name in the top right of the AWS management console browser application. There is an option &lt;em&gt;My Security Credentials&lt;/em&gt;. Additionally, you should create an AWS EC2 Key Pair via &lt;em&gt;Services -&amp;gt; EC2 -&amp;gt; Key Pairs -&amp;gt; Create Key Pair&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Finally, you can set up your local ParallelCluster installation. Simply type&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;pcluster configure
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;in a terminal window. ParallelCluster will ask for the access key you just created. This automated configuration process will further be able to retrieve default values for &lt;code&gt;master_subnet_id&lt;/code&gt; and &lt;code&gt;vpc_id&lt;/code&gt;. These are otherwise a little tedious to find out. In general, you can just press enter on all questions except &lt;code&gt;aws_access_key_id&lt;/code&gt; and &lt;code&gt;aws_secret_access_key&lt;/code&gt;. More sophisticated configuration can easily be applied later by directly modifying the file &lt;code&gt;~/.parallelcluster/config&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The following is a basic configuration for an elastic cluster with one to five compute nodes:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;
&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;width:auto;overflow:auto;display:block;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;
&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 1
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 2
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 3
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 4
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 5
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 6
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 7
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 8
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 9
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;10
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;11
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;12
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;13
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;14
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;15
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;16
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;17
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;18
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;19
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;20
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;21
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;22
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;23
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;24
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;25
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;26
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;27
&lt;/span&gt;&lt;span style=&#34;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;28
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;
&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-PacmanConf&#34; data-lang=&#34;PacmanConf&#34;&gt;&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;[aws]&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#309&#34;&gt;aws_region_name&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; eu-central-1&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#309&#34;&gt;aws_access_key_id&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &amp;lt;AWS_ACCESS_KEY_ID&amp;gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#309&#34;&gt;aws_secret_access_key&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &amp;lt;AWS_SECRET_ACCESS_KEY&amp;gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;[cluster default]&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#309&#34;&gt;vpc_settings&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; public&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#309&#34;&gt;key_name&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &amp;lt;AWS_KEY_NAME&amp;gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#309&#34;&gt;ebs_settings&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; custom&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#309&#34;&gt;post_install&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &amp;lt;POST_INSTALL_SCRIPT_DOWNLOAD_PATH&amp;gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#309&#34;&gt;base_os&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; ubuntu1604&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#309&#34;&gt;maintain_initial_size&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; true&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#309&#34;&gt;compute_instance_type&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; c4.2xlarge&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#309&#34;&gt;initial_queue_size&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; 1&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#309&#34;&gt;max_queue_size&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; 5&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;[vpc public]&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#309&#34;&gt;master_subnet_id&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &amp;lt;AWS_MASTER_SUBNET_ID&amp;gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#309&#34;&gt;vpc_id&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &amp;lt;AWS_VPC_ID&amp;gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;[global]&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#309&#34;&gt;update_check&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; true&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#309&#34;&gt;sanity_check&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; true&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#309&#34;&gt;cluster_template&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; default&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#069;font-weight:bold&#34;&gt;[ebs custom]&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#309&#34;&gt;ebs_snapshot_id&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; &amp;lt;SNAPSHOT_ID&amp;gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a00;background-color:#faa&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#309&#34;&gt;volume_type&lt;/span&gt; &lt;span style=&#34;color:#555&#34;&gt;=&lt;/span&gt; gp2&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Once your configuration is finished, you can create your first cloud cluster with a simple:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f0f3f3;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;pcluster create &amp;lt;cluster-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Naturally, for working with AWS and ParallelCluster, you will want to also look at the official documentation. In the following I list some of the most important resources:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/aws/aws-parallelcluster&#34;&gt;AWS ParallelCluster GitHub page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://aws-parallelcluster.readthedocs.io/en/latest/&#34;&gt;AWS ParallelCluster documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://aws.amazon.com/ec2/pricing/on-demand/&#34;&gt;Amazon EC2 on-demand instance pricing list&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://aws.amazon.com/ebs/pricing/&#34;&gt;Amazon EBS pricing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://aws.amazon.com/aws-cost-management/&#34;&gt;General documentation for managing costs with AWS&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;Parts of this blog post have been taken from my thesis on &lt;em&gt;Providing Transparent Remote Access to HPC Resources for Graphical Desktop Applications&lt;/em&gt;. If you are further interested in working with AWS Parallelcluster you can freely download it &lt;a href=&#34;https://www.dropbox.com/s/424pyrixr1vn6xz/Kainrad_Diplomarbeit_Thesis.pdf?dl=0&#34;&gt;here&lt;/a&gt;. For a brief description of an in-production AWS Parallelcluster use case, check out the &lt;a href=&#34;https://www.doi.org/10.1021/acs.jcim.8b00716&#34;&gt;journal article&lt;/a&gt; that has emerged from the thesis.&lt;/p&gt;
&lt;/blockquote&gt;
</description>
    </item>
    
  </channel>
</rss>