<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>gitlab on tkainrad</title>
    <link>https://tkainrad.dev/tags/gitlab/</link>
    <description>Recent content in gitlab on tkainrad</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <lastBuildDate>Sun, 05 Jan 2020 00:00:00 +0000</lastBuildDate>
    
        <atom:link href="https://tkainrad.dev/tags/gitlab/index.xml" rel="self" type="application/rss+xml" />
    
    
    <item>
      <title>Managing my personal knowledge base</title>
      <link>https://tkainrad.dev/posts/managing-my-personal-knowledge-base/</link>
      <pubDate>Sun, 05 Jan 2020 00:00:00 +0000</pubDate>
      
      <guid>https://tkainrad.dev/posts/managing-my-personal-knowledge-base/</guid>
      <description>&lt;h1 id=&#34;introduction&#34;&gt;Introduction&lt;/h1&gt;
&lt;p&gt;It is hard to imagine any other field where lifelong learning is more important than in software engineering. Another unique characteristic is the degree to which learning material is available for free on the internet. On top of that, we create various resources ourselves by documenting issues, submitting bug reports, writing notes, creating documentation, and many others. The sum of all these resources can be called a knowledge base.
You could argue that every developer has a system to manage their personal knowledge base, whether they know it or not. In this post, I explain my knowledge management practices.&lt;/p&gt;

&lt;div class=&#34;notices warning&#34;&gt;
    &lt;p&gt;A software engineer&amp;rsquo;s personal knowledge base is likely to overlap with the knowledge of their employers and project partners. Be sure to carefully study your data protection obligations. A good basis is to keep your personal knowledge base strictly technical and to never include data that is related to customers, or people in general.&lt;/p&gt;

&lt;/div&gt;
&lt;p&gt;I chose this topic mainly because of three reasons:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Fun:&lt;/strong&gt;&lt;br&gt;
I enjoy thinking about my workflows and trying to improve them. Maybe a little too much, some friends have started to roll their eyes when I try to recommend a new tool to them.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Improving my system and workflows:&lt;/strong&gt;&lt;br&gt;
Writing &lt;a href=&#34;https://tkainrad.dev/posts/setting-up-linux-workstation/&#34;&gt;a post about my Linux setup&lt;/a&gt; has been very rewarding for me. While documenting my configuration, especially my command-line workflows, I identified some shortcomings that I have since eliminated. After writing this article, I can already say that my knowledge management workflows have improved similarly.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Relevance:&lt;/strong&gt;&lt;br&gt;
Knowledge management in all its forms is integral to software engineering.&lt;/li&gt;
&lt;/ol&gt;
&lt;figure class=&#34;center-figure&#34;&gt;
    &lt;img src=&#34;https://imgs.xkcd.com/comics/is_it_worth_the_time.png&#34;
         alt=&#34;Knowledge management tasks are done frequently. It pays off to do them efficiently. (Source: xkcd.com)&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;Knowledge management tasks are done frequently. It pays off to do them efficiently. (Source: xkcd.com)&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Much of this post comes down to describing my usage of software tools. The stars will be&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.notion.so/?r=cb45b9cefd824015a044b3336009be32&#34;&gt;Notion&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gitlab.com/&#34;&gt;GitLab&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://workona.com/&#34;&gt;Workona&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gitlab.com/&#34;&gt;Dropbox&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/albertlauncher/albert&#34;&gt;Albert&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&#34;notices info&#34;&gt;
    &lt;p&gt;Copying all of my practices will likely not serve you well. I invite you to try out things at your own pace and revisit this post whenever you are looking for new ideas.&lt;/p&gt;

&lt;/div&gt;
&lt;h1 id=&#34;bookmarking&#34;&gt;Bookmarking&lt;/h1&gt;
&lt;p&gt;Even though everybody loves books, or at least says so, myself included, the reality is that we rely on digital resources most of the time.
The challenge is to organize this knowledge efficiently without creating too much overhead.&lt;/p&gt;
&lt;p&gt;There are some naive approaches that I do not deem sufficient. Until a few years ago, I relied mainly on browser bookmarks, but for some reason, browsers do not provide proper organizing features.
Another way is to just copy the URLs into notes, project issues, documentation and all other kinds of manually created content. This is viable and we all do it regularly, but it has nothing to do with what I think is bookmark management.&lt;/p&gt;
&lt;p&gt;My current setup is a little more complex, but in the end, it does not require more work than keeping bookmarks solely in the browser.
I organize my bookmarks in multiple layers, depending on how often I want to access them and how long they should persist.&lt;/p&gt;
&lt;p&gt;Maybe you are thinking of caching now, but fortunately, bookmarking layers are not caching levels. This would be hard to manage because as we all know, there are &lt;a href=&#34;https://martinfowler.com/bliki/TwoHardThings.html&#34;&gt;two hard problems in computer science&lt;/a&gt;: cache invalidation, naming things, and off-by-1 errors.
In contrast to cache entries, a bookmark is not supposed to move between layers. Instead, it gets inserted at the right place and stays there.&lt;/p&gt;
&lt;p&gt;The following figure illustrates my layers:&lt;/p&gt;
&lt;figure class=&#34;center-figure&#34;&gt;
    &lt;img src=&#34;https://tkainrad.dev/images/managing-my-personal-knowledge-base/bookmarking-layers.png&#34;
         alt=&#34;Bookmarking layers&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;Bookmarking layers&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;h2 id=&#34;1-chrome-bookmarks&#34;&gt;1. Chrome Bookmarks&lt;/h2&gt;
&lt;p&gt;Chrome bookmarks have some nice benefits. They are synchronized between devices, new ones can be added easily, and organizing them in folders brings at least some structure. Another advantage for me is the &lt;a href=&#34;https://albertlauncher.github.io/docs/extensions/chromium/&#34;&gt;Albert Chromium extension&lt;/a&gt; that lets me access and open my Chrome bookmarks from Albert:&lt;/p&gt;
&lt;figure class=&#34;center-figure&#34;&gt;
    &lt;img src=&#34;https://tkainrad.dev/images/managing-my-personal-knowledge-base/albert-chrome-bookmarks.gif&#34;
         alt=&#34;Searching through Chrome bookmarks directly from Albert. Pressing enter opens the selected entry in Chrome.&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;Searching through Chrome bookmarks directly from Albert. Pressing enter opens the selected entry in Chrome.&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Because of these advantages, Chrome bookmarks are ideal for things that I need often and want to have accessible somewhat independent of context. They are, however, not well suited for keeping extensive bookmark libraries. There is no tagging, it is not possible to add comments, and browsers do not even save a timestamp for when a page was bookmarked. It is further not possible to filter and search Chrome bookmarks using complex queries. In my experience, browser bookmark libraries are hard to manage if they grow beyond a certain size.&lt;/p&gt;
&lt;p&gt;Some examples of well-suited Chrome bookmarks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AWS EC2 dashboard&lt;/li&gt;
&lt;li&gt;Google cloud platform console&lt;/li&gt;
&lt;li&gt;Slack workspaces&lt;/li&gt;
&lt;li&gt;GitLab boards&lt;/li&gt;
&lt;li&gt;Content sites, such as &lt;a href=&#34;https://news.ycombinator.com/&#34;&gt;Hacker News&lt;/a&gt;, &lt;a href=&#34;https://www.infoq.com/&#34;&gt;InfoQ&lt;/a&gt;, and &lt;a href=&#34;https://dzone.com/&#34;&gt;DZone&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Examples of things that &lt;strong&gt;should not be&lt;/strong&gt; Chrome bookmarks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Blog posts to be read later&lt;/li&gt;
&lt;li&gt;Links to Open Source Projects&lt;/li&gt;
&lt;li&gt;Stack Overflow questions&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;2-workona&#34;&gt;2. Workona&lt;/h2&gt;
&lt;p&gt;Workona is a relatively new addition to my toolbox. I have mixed feelings about it, mainly because it can feel a little slow at times.
There are some things it does very well though.&lt;/p&gt;
&lt;p&gt;Workona lets you create browser workspaces that come with their own list of bookmarks. This works nicely when you have multiple projects that you work on for longer periods. It will also remember which tabs you had open in a specific workspace and synchronize this information across devices. It is, therefore, a nice place for things that I need often &lt;em&gt;dependent&lt;/em&gt; on context.&lt;/p&gt;
&lt;figure class=&#34;&amp;#39;center-figure&amp;#39;&#34;&gt;
    &lt;img src=&#34;https://tkainrad.dev/images/managing-my-personal-knowledge-base/workona-workspace.jpg&#34;
         alt=&#34;Screenshot of a Workona Workspace (Source)&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;Screenshot of a Workona Workspace (&lt;a href=&#34;https://workona.com/tour/&#34;&gt;Source&lt;/a&gt;)&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Workona further allows you to add apps and will then collect links and even features for those apps to be quickly accessible. For example, I use it to access my different GitLab and GitHub projects, Slack Workspaces, and sometimes even StackOverflow questions. These entries are automatically created by Workona and therefore I do not see them as bookmarks. It is also possible to access features of these apps directly from Workona, mainly to create new resources, such as GitLab/GitHub projects, Google Docs, DropBox Files and so on. It feels a little bit like &lt;a href=&#34;https://getstation.com/&#34;&gt;Station&lt;/a&gt; built directly into the browser.&lt;/p&gt;
&lt;p&gt;The selling point for me is that Workona &lt;strong&gt;lets me do all of the described things via shortcuts&lt;/strong&gt; and it is even possible to customize these shortcuts at &lt;code&gt;chrome://extensions/shortcuts&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;3-notion&#34;&gt;3. Notion&lt;/h2&gt;
&lt;p&gt;Finally, we arrive at the layer that is suited for maintaining a large library of bookmarks. For this, and many other use cases, I use &lt;a href=&#34;https://www.notion.so/?r=cb45b9cefd824015a044b3336009be32&#34;&gt;Notion&lt;/a&gt;. It has become the core of my personal knowledge base.&lt;/p&gt;

&lt;div class=&#34;notices warning&#34;&gt;
    &lt;p&gt;Notion&amp;rsquo;s free tier comes with a hard limit on the number of blocks you can create. This means that you will have to switch to the paid version if you use it seriously for a while. It is free for &lt;a href=&#34;https://www.notion.so/Notion-for-students-teachers-adc631df15ee4ab9a7a33dd50f4c16fe&#34;&gt;students and teachers&lt;/a&gt;.&lt;br&gt;
All links to Notion in this post are affiliate links. If you sign up for an account through these links, you will get 10$ of free Notion credit and I will get 5$. This works even if you create a free account.&lt;/p&gt;

&lt;/div&gt;
&lt;p&gt;The killer feature for me is the database. It is amazingly flexible and is single-handedly able to replace multiple other tools for me. For my bookmark collection, I use a single large database. Adding new items can be done via the &lt;a href=&#34;https://chrome.google.com/webstore/detail/notion-web-clipper/knheggckgoiihginacbkhaalnibhilkk&#34;&gt;Notion Web Clipper&lt;/a&gt;. I am a little annoyed that the web clipper doesn&amp;rsquo;t let me add properties and tags directly, but other than that, it works well. Previously, I used Trello, which was also quite good at keeping bookmarks. However, to limit the number of different tools I use, I replaced it with Notion.&lt;/p&gt;
&lt;figure class=&#34;center-figure&#34;&gt;
    &lt;img src=&#34;https://tkainrad.dev/images/managing-my-personal-knowledge-base/notion-bookmark-database.png&#34;
         alt=&#34;My bookmarks database filtered to show only entries related to this post.&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;My bookmarks database filtered to show only entries related to this post.&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;The goal with this database is that I can find something years from now with only a vague memory that it should be there. This is possible because Notion automatically stores metadata, such as a creation timestamp. Even more important, I can add tags and arbitrary properties.&lt;/p&gt;
&lt;p&gt;Things get really exciting once you use relations between different Notion databases. As an example, I have a database of my blog posts that has a relation to my bookmarks. I can now filter my bookmarks by blog posts and quickly see which sources influenced a particular post.&lt;/p&gt;

&lt;div class=&#34;notices info&#34;&gt;
    &lt;p&gt;I cannot cover all Notion database features in this post. I think this is something you have to see for yourself. The &lt;a href=&#34;https://www.notion.so/Intro-to-databases-fd8cd2d212f74c50954c11086d85997e&#34;&gt;Notion docs page about the topic&lt;/a&gt; might give you some further impressions though.&lt;/p&gt;

&lt;/div&gt;
&lt;p&gt;The downside of this rich feature palette is that it requires some discipline. I tag and annotate new entries, that I added via the web clipper, about twice a month. Often, I just delete new items because they do not seem important anymore. If I can not think of appropriate tags or relations for an item, this often means that it is not very relevant to me.&lt;/p&gt;
&lt;p&gt;Another important lesson I had to learn the hard way:&lt;br&gt;
Do not use too many databases in parallel. Notion provides excellent methods for filtering, and searching tables. You can even define different views onto the same database that only shows a specific part of the data. It is therefore not required to separate all kinds of things into different databases. For example, at first, I had three different databases for Python resources, Django resources, and Wagtail resources. This was a bad solution. Now, these all live in the same database with appropriate tags.&lt;/p&gt;
&lt;p&gt;I hope that someday I will be able to search through my Notion databases from &lt;a href=&#34;https://github.com/albertlauncher/albert&#34;&gt;Albert&lt;/a&gt;. Maybe I will build an extension myself once the Notion API is finally released.&lt;/p&gt;
&lt;p&gt;To illustrate what I have described in probably too many words, you can have a look at a &lt;a href=&#34;https://www.notion.so/tkpersonal/047517457f70471a91a9dac793b8d51b?v=802c2ec373fa43d0b7caf16ed8bfccda&#34;&gt;public fraction of my bookmarks database&lt;/a&gt; containing all the resources that were helpful for writing this post. The post-column in this public database appears empty because the related table is not public.&lt;/p&gt;
&lt;h2 id=&#34;4-native-bookmark-sources&#34;&gt;4. Native Bookmark Sources&lt;/h2&gt;
&lt;p&gt;The last layer does not require any work at all. It only means to be aware of native bookmark sources when trying to find something, and also when thinking about adding new bookmarks. For example, it is quite easy to search through questions you have answered on Stack Overflow. It is also not a problem to go back to your Hacker News posts or search through projects you starred on GitHub. Keeping those things in your own bookmark sources adds redundancy and noise.&lt;br&gt;
These are some of my most commonly used native bookmark sources:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://news.ycombinator.com/&#34;&gt;https://news.ycombinator.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://twitter.com/&#34;&gt;https://twitter.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/&#34;&gt;https://github.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gitlab.com/&#34;&gt;https://gitlab.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://tkainrad.dev/posts/&#34;&gt;https://tkainrad.dev/posts/&lt;/a&gt; ;-)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;I am aware that this sounds immensely complicated. However, I stick to my statement that it does not actually require more work than keeping all bookmarks in the browser. You still have to add every bookmark only once. If you internalize your system, you will not have problems searching for bookmarks as it will be quite obvious where a specific resource could be. Admittedly, it does require some maintenance to keep a large bookmark collection in Notion, but it pays off soon and the pay-off accumulates over time.&lt;/p&gt;
&lt;h1 id=&#34;organizing-self-written-resources&#34;&gt;Organizing Self-Written Resources&lt;/h1&gt;
&lt;p&gt;Having a proper system for external resources is great, but it does not help much if everything you write yourself is a mess. Therefore, it is essential to organize self-written resources.&lt;/p&gt;
&lt;h2 id=&#34;blog-posts&#34;&gt;Blog Posts&lt;/h2&gt;
&lt;p&gt;My most successful blog post is about &lt;a href=&#34;https://tkainrad.dev/posts/using-hugo-gitlab-pages-and-cloudflare-to-create-and-run-this-website/&#34;&gt;how I run and host this website for free&lt;/a&gt;. However, the post does not cover the most work-intensive part about running this site: Writing and maintaining blog posts. For this, I heavily rely on Notion. I have a database with all my past blog posts and ideas for future posts. It is simple to add tags like &lt;code&gt;done&lt;/code&gt;, &lt;code&gt;doing&lt;/code&gt;, &lt;code&gt;idea&lt;/code&gt;, and to view the database as a kanban board with lanes based on those tags.&lt;/p&gt;
&lt;h3 id=&#34;drafting-posts&#34;&gt;Drafting Posts&lt;/h3&gt;
&lt;p&gt;All posts that are published on this blog have been drafted in &lt;a href=&#34;https://www.notion.so/?r=cb45b9cefd824015a044b3336009be32&#34;&gt;Notion&lt;/a&gt;. When they are more or less finished, I use the markdown export and copy the content into a new text file in my &lt;a href=&#34;https://gohugo.io/&#34;&gt;Hugo&lt;/a&gt; project. There are some minor issues with this. Usually, I have to adjust code formattings and links, but overall it works very well and has some nice benefits:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Edit on all devices&lt;/strong&gt;&lt;br&gt;
Using notion, I can easily edit my drafts on all devices, even on my phone when I am moving.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use existing notion content&lt;/strong&gt;&lt;br&gt;
I can quickly add code snippets, links, and other stuff that I keep in Notion. This can be done via database relations or just by dragging the respective blocks into the draft page.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lightweight version control&lt;/strong&gt;&lt;br&gt;
As developers, we love GIT. However, for adding a couple of lines to a blog post, it is an overkill. Notion has versioning features build-in and keeps track of all changes automatically. Naturally, it does not offer sophisticated merging options, but it&amp;rsquo;s easy to stay clear of conflicts when you are writing a personal blog.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once a post is released, I move the post from &lt;code&gt;doing&lt;/code&gt; to &lt;code&gt;released&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;keeping-track-of-update-ideas&#34;&gt;Keeping Track of Update Ideas&lt;/h3&gt;
&lt;p&gt;You may have noticed that some of my blog posts are quite long. Keeping them up-to-date is a little challenging. Fortunately, I have Notion to assist me with this. I have a database where I add proposals for updating my existing posts. Using a relation, I link these ideas to the respective posts in my posts database:&lt;/p&gt;
&lt;figure class=&#34;center-figure&#34;&gt;
    &lt;img src=&#34;https://tkainrad.dev/images/managing-my-personal-knowledge-base/notion-blog-update-proposals.png&#34;
         alt=&#34;It is hard to know when you are finished setting up the perfect Linux workstation.&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;It is hard to know when you are finished &lt;a href=&#34;https://tkainrad.dev/posts/setting-up-linux-workstation/&#34;&gt;setting up the perfect Linux workstation&lt;/a&gt;.&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;h3 id=&#34;tracking-sources&#34;&gt;Tracking Sources&lt;/h3&gt;
&lt;p&gt;To keep track of third-party resources that were helpful in creating a post, I add them to my bookmarks database and link them to my posts database.&lt;/p&gt;
&lt;figure class=&#34;center-figure&#34;&gt;
    &lt;img src=&#34;https://tkainrad.dev/images/managing-my-personal-knowledge-base/notion-blog-sources.png&#34;
         alt=&#34;My bookmarks database filtered to show only entries related to this post.&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;My bookmarks database filtered to show only entries related to this post.&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;You can also have a look at the full list of sources for this post via a &lt;a href=&#34;https://www.notion.so/tkpersonal/047517457f70471a91a9dac793b8d51b?v=802c2ec373fa43d0b7caf16ed8bfccda&#34;&gt;public fraction of my bookmarks database&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;taking-notes&#34;&gt;Taking Notes&lt;/h2&gt;
&lt;p&gt;I suppose every software engineer takes notes to some extent, even if they do not have a system and just casually write stuff into text files.
There is also a large amount of free and paid software for taking and organizing notes. Some people even like to use physical paper with the &lt;a href=&#34;https://en.wikipedia.org/wiki/Bullet_Journal&#34;&gt;BuJo&lt;/a&gt; system.&lt;/p&gt;
&lt;p&gt;No matter which method you prefer, you have to think about when, why, and how to take notes.&lt;/p&gt;
&lt;h3 id=&#34;when-to-take-notes&#34;&gt;When to take Notes&lt;/h3&gt;
&lt;p&gt;I thought quite a bit about this question, and previously I did not adhere to any predefined rules regarding this matter. To gain a better understanding of my habits and to decide what worked best in the past, I looked through my notes from the last years that were spread over multiple applications and lots of files. I tried to find common patterns:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Capturing information from audio sources&lt;/strong&gt;&lt;br&gt;
I am a visual learner and prefer written content over audio. However, there are many types of audio sources that everybody encounters:
&lt;ul&gt;
&lt;li&gt;Meetings&lt;/li&gt;
&lt;li&gt;Presentations&lt;/li&gt;
&lt;li&gt;Meetups&lt;/li&gt;
&lt;li&gt;Conferences&lt;/li&gt;
&lt;li&gt;Informal Discussions&lt;/li&gt;
&lt;li&gt;Videos&lt;/li&gt;
&lt;li&gt;Podcasts&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Preserving information that is often needed but doesn&amp;rsquo;t fit in any proper documentation project&lt;/strong&gt;&lt;br&gt;
In my case, these are things like the following:
&lt;ul&gt;
&lt;li&gt;Command-lines with multiple parameters, complex options, and paths. I keep them in my notes so that I can quickly copy-paste them in the potentially distant future.&lt;/li&gt;
&lt;li&gt;Instructions for tasks that will likely have to be repeated in the future, for example
&lt;ul&gt;
&lt;li&gt;setting up a development environment for a specific tech stack&lt;/li&gt;
&lt;li&gt;deploying a project on a specific hosting service.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Questions&lt;/strong&gt;&lt;br&gt;
Sometimes I think of a question that I would like to ask someone specific, who is not available at the moment. The question and its eventual answer are a nice use case for a note.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&#34;notices tip&#34;&gt;
    &lt;p&gt;Thanks to a more sophisticated command-line setup with Zsh and various plugins for auto-completion and history-search, preserving command-lines has become much less important for me. If you are still using Bash with its default &lt;code&gt;Ctl&lt;/code&gt; -  &lt;code&gt;r&lt;/code&gt; search, I think you would profit from my &lt;a href=&#34;https://tkainrad.dev/posts/setting-up-linux-workstation/&#34;&gt;post on setting up a Linux workstation&lt;/a&gt;.&lt;/p&gt;

&lt;/div&gt;
&lt;p&gt;On the other hand, it is important to make clear also what &lt;strong&gt;should not be a note&lt;/strong&gt; in this system:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Project-specific knowledge&lt;/strong&gt;&lt;br&gt;
Everything that is directly related to a specific software project, should not be a note in your personal knowledge base. Instead, it should go into whichever system is used to keep track of issues, merge requests, documentation, and so on. This post includes a &lt;a href=&#34;#project-specific-knowledge&#34;&gt;separate section on this below&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Information that is needed for a very short time&lt;/strong&gt;
Sometimes I need to take notes during a conversation that I will need only immediately afterward. For this, I just open VSCode and type ahead. Once the information is no longer needed, the file can be deleted completely.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In general, don&amp;rsquo;t overdo and don&amp;rsquo;t underdo it. If you take notes all the time, you create overhead and redundancy. If you never take notes, well, you will not have notes.&lt;/p&gt;
&lt;h3 id=&#34;why-take-notes&#34;&gt;Why Take Notes&lt;/h3&gt;
&lt;p&gt;The obvious answer is to remember things. This does not mean that note-taking should replace your memory. To the contrary, taking notes provides structure and context and therefore helps your brain build up a map of your knowledge. I believe that taking notes &lt;em&gt;increases&lt;/em&gt; the amount of data that you can recall from memory.&lt;/p&gt;
&lt;p&gt;Additionally, some things are just very hard to remember, such as complex tech stacks presented at meetups, command-lines with several opaque options, numbers, and so on. Writing these things down can extend your knowledge base significantly. Notes are also very helpful when writing documentation in the future, or for writing blog posts like this one ;-)&lt;/p&gt;
&lt;h3 id=&#34;how-to-take-notes&#34;&gt;How to Take Notes&lt;/h3&gt;
&lt;p&gt;It can be tempting to just type ahead during a talk. Noting down whatever seems interesting at the moment. However, you should meet basic formal requirements and write down some context. Otherwise, you will have trouble extracting useful information from your notes in the future. If you take notes regularly, it is also important to organize them by assigning tags and properties, having a creation date, being able to filter and search through them, and so on. Software can help with these things.&lt;/p&gt;
&lt;p&gt;Until about a year ago I kept notes mainly on my local machines, syncing them with Dropbox. Applications that focus almost exclusively on note-taking, such as &lt;a href=&#34;https://evernote.com/&#34;&gt;Evernote&lt;/a&gt;, never had that much appeal to me, even though I used Google Keep/Notes. It is not so bad, supports e.g. labeling and works with little friction on mobile. However, there is not even basic formatting support, let alone markdown formatting or code syntax highlighting.&lt;/p&gt;
&lt;p&gt;Then, I discovered &lt;a href=&#34;https://www.notion.so/?r=cb45b9cefd824015a044b3336009be32&#34;&gt;Notion&lt;/a&gt;.
At first, It wasn&amp;rsquo;t really about note-taking for me. I liked it mainly because of its database concept and for organizing third-party resources as described in the &lt;a href=&#34;#bookmarking&#34;&gt;bookmarking section&lt;/a&gt;. However, by now, I use it heavily for almost all of my notes and other types of self-written content. I think Notion&amp;rsquo;s mix of markdown syntax support, slash commands, and WYSIWYG makes for a great writing experience.&lt;/p&gt;
&lt;p&gt;I strongly recommend organizing all your notes in a single database with appropriate tags, such as &lt;code&gt;meeting&lt;/code&gt;, &lt;code&gt;presentation&lt;/code&gt;, &lt;code&gt;tc&lt;/code&gt;, and &lt;code&gt;question&lt;/code&gt;. Similar to the bookmarks database described above, Notion will automatically provide a column with the creation time of the note. If you have frequent meetings with the same people, you can think about adding a &lt;em&gt;Participants&lt;/em&gt; column.&lt;/p&gt;
&lt;p&gt;A notes database is the perfect use case for another great Notion feature: &lt;a href=&#34;https://www.notion.so/Database-templates-454ed5ab5bd24226b58d176697bd7e10&#34;&gt;Templates&lt;/a&gt;. This feature will allow you to created templates for your different types of notes and then, for example, add a new meeting note with one click. Depending on the template, the new note comes with a pre-defined layout and might include fields for the meeting&amp;rsquo;s participants and agenda. This is what opens when I click to add new meeting notes in my database:&lt;/p&gt;
&lt;figure class=&#34;center-figure&#34;&gt;
    &lt;img src=&#34;https://tkainrad.dev/images/managing-my-personal-knowledge-base/notion-meeting-notes.png&#34;
         alt=&#34;My basic meeting notes template.&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;My basic meeting notes template.&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;h1 id=&#34;project-specific-knowledge&#34;&gt;Project-specific Knowledge&lt;/h1&gt;
&lt;p&gt;In my experience, it is best to keep project information as closely together as possible. For me, this means that issue tracking, merge requests (i.e. pull requests), documentation, and everything else that comes with a software project should live alongside the source code.&lt;/p&gt;
&lt;p&gt;This practice guarantees that anyone who works on the code now, or in the future, has access to all the information. My solution for this is to use GitLab for everything related to a specific project. This includes pretty much everything except some quick notes that I sometimes write in Notion because I do not want anyone else to see them.&lt;/p&gt;
&lt;p&gt;To do this, GitLab offers a lot of project management and documentation features, such as issue management, a project wiki, a Code snippet space for all projects and accounts, and more.
A project wiki is a great place for all documentation that is not specific to an issue. This can include the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Instructions for setting up the development environment&lt;/li&gt;
&lt;li&gt;Instructions for manual deployment&lt;/li&gt;
&lt;li&gt;Architecture descriptions and diagrams. I am a big fan of &lt;a href=&#34;https://mermaidjs.github.io/#/&#34;&gt;mermaid&lt;/a&gt;, which allows creating UML diagrams with Markdown and is supported by GitLab.&lt;/li&gt;
&lt;li&gt;Guidelines regarding naming conventions, design paradigms, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&#34;notices info&#34;&gt;
    &lt;p&gt;If you have read my post on &lt;a href=&#34;https://tkainrad.dev/posts/using-hugo-gitlab-pages-and-cloudflare-to-create-and-run-this-website/&#34;&gt;running and hosting this website&lt;/a&gt;, you know that I use GitLab also for this personal blog project. Nevertheless, I use Notion for much of the project documentation and management tasks, because it comes with some unique benefits for this use case, as described &lt;a href=&#34;#blog-posts&#34;&gt;above&lt;/a&gt;.&lt;/p&gt;

&lt;/div&gt;
&lt;p&gt;Of course, there are alternatives. GitHub has caught up in the past and offers a very similar feature set. I have only limited experience with Atlassian products, but I suppose you can achieve the same thing by using a mix of BitBucket, Confluence, and Jira.&lt;br&gt;
On a side note, writing in Confluence feels a lot like writing in Notion. Both recognize markdown syntax and offer slash commands to quickly insert complex content types.&lt;/p&gt;
&lt;h1 id=&#34;managing-files&#34;&gt;Managing Files&lt;/h1&gt;
&lt;p&gt;This one is relatively straightforward. I think the most important thing is to use some form of cloud storage. Personally, I use Dropbox.&lt;br&gt;
Next, you should think about a proper folder structure. Finally, you should be able to search for your files quickly.&lt;/p&gt;
&lt;p&gt;I use &lt;a href=&#34;https://tkainrad.dev/posts/setting-up-linux-workstation/&#34;&gt;Linux&lt;/a&gt; and rely on Albert for searching through files. If this doesn&amp;rsquo;t work I use &lt;a href=&#34;https://linuxize.com/post/locate-command-in-linux/&#34;&gt;the &lt;code&gt;locate&lt;/code&gt; command&lt;/a&gt; and, my last resort are command-line tools, such as &lt;code&gt;find&lt;/code&gt;, and &lt;code&gt;grep&lt;/code&gt;. They are still king for complex search requirements, such as regex matching and including also file content.&lt;/p&gt;
&lt;p&gt;If you can tick the three boxes&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;availability on all devices&lt;/li&gt;
&lt;li&gt;structure&lt;/li&gt;
&lt;li&gt;searchable&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;you should be all set.&lt;/p&gt;

&lt;div class=&#34;notices tip&#34;&gt;
    &lt;p&gt;Notion databases support file columns. This means you can upload a different file to each cell. I have not yet found a use case related directly to software engineering for this. However, it is great for managing invoices.&lt;/p&gt;

&lt;/div&gt;
&lt;h1 id=&#34;additional-use-cases&#34;&gt;Additional Use Cases&lt;/h1&gt;
&lt;p&gt;In this section, I want to present some special kinds of knowledge management use cases that are unique to software engineering. Most of them I have picked up properly only after starting to use &lt;a href=&#34;https://www.notion.so/?r=cb45b9cefd824015a044b3336009be32&#34;&gt;Notion&lt;/a&gt;. By no means, I want to say that you should copy all of them, but you are very welcome to try out what you think looks interesting.&lt;/p&gt;
&lt;h2 id=&#34;code-snippets&#34;&gt;Code Snippets&lt;/h2&gt;
&lt;p&gt;Currently, I have two ways of collecting code snippets. I hope I can eventually integrate them somehow.&lt;/p&gt;
&lt;h3 id=&#34;vscode-user-snippets&#34;&gt;VSCode User Snippets&lt;/h3&gt;
&lt;p&gt;The first one are &lt;a href=&#34;https://code.visualstudio.com/&#34;&gt;VSCode&lt;/a&gt; User Snippets. VSCode does many things right and snippet management is one of them. It is very easy to define new snippets and use them by typing a predefined string. Simply press &lt;code&gt;Ctrl&lt;/code&gt;-&lt;code&gt;Shift&lt;/code&gt;-&lt;code&gt;p&lt;/code&gt; and choose &lt;em&gt;Preferences: Configure User Snippets&lt;/em&gt;. Then, you can split your snippets into multiple files or just put all of them together in the &lt;code&gt;global-snipptes.code-snippets&lt;/code&gt; file. These are some of my snippets for writing blog posts with markdown and Hugo:&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-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;figure&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;scope&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;markdown&amp;#34;&lt;/span&gt;,
    &lt;span style=&#34;color:#309;font-weight:bold&#34;&gt;&amp;#34;prefix&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;fig&amp;#34;&lt;/span&gt;,
    &lt;span style=&#34;color:#309;font-weight:bold&#34;&gt;&amp;#34;body&amp;#34;&lt;/span&gt;: [
        &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;{{&amp;lt; figure src=\&amp;#34;/images/\&amp;#34;  class=\&amp;#34;center-figure\&amp;#34;  caption=\&amp;#34;\&amp;#34; &amp;gt;}}&amp;#34;&lt;/span&gt;
    ],
    &lt;span style=&#34;color:#309;font-weight:bold&#34;&gt;&amp;#34;description&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;Insert hugo figure shortcode&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;callout&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;scope&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;markdown&amp;#34;&lt;/span&gt;,
    &lt;span style=&#34;color:#309;font-weight:bold&#34;&gt;&amp;#34;prefix&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;callout&amp;#34;&lt;/span&gt;,
    &lt;span style=&#34;color:#309;font-weight:bold&#34;&gt;&amp;#34;body&amp;#34;&lt;/span&gt;: [
        &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;{{% callout \&amp;#34;warning info tip note\&amp;#34; %}}&amp;#34;&lt;/span&gt;,
        &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;,
        &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;{{%/callout %}}&amp;#34;&lt;/span&gt;
    ],
    &lt;span style=&#34;color:#309;font-weight:bold&#34;&gt;&amp;#34;description&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;Insert hugo callout shortcode&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;code&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;scope&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;markdown&amp;#34;&lt;/span&gt;,
    &lt;span style=&#34;color:#309;font-weight:bold&#34;&gt;&amp;#34;prefix&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;code&amp;#34;&lt;/span&gt;,
    &lt;span style=&#34;color:#309;font-weight:bold&#34;&gt;&amp;#34;body&amp;#34;&lt;/span&gt;: [
        &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;{{&amp;lt; highlight bash \&amp;#34;linenos=table\&amp;#34;&amp;gt;}}&amp;#34;&lt;/span&gt;,
        &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;,
        &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;{{&amp;lt; / highlight &amp;gt;}}&amp;#34;&lt;/span&gt;
    ],
    &lt;span style=&#34;color:#309;font-weight:bold&#34;&gt;&amp;#34;description&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#c30&#34;&gt;&amp;#34;Insert hugo code shortcode&amp;#34;&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;The snippets can then be used by typing the prefix and pressing &lt;code&gt;Ctrl&lt;/code&gt;+&lt;code&gt;Space&lt;/code&gt;:
&lt;figure class=&#34;center-figure&#34;&gt;
    &lt;img src=&#34;https://tkainrad.dev/images/managing-my-personal-knowledge-base/vscode-insert-snippet.gif&#34;/&gt; 
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 id=&#34;notion-snippet-database&#34;&gt;Notion Snippet database&lt;/h3&gt;
&lt;p&gt;The second use case concerns small pieces of code that I have written myself and that I would like to remember. This is not necessarily for productivity reasons, but rather for nostalgia. It is ideal for small algorithms, for example when you manage to substantially increase the performance of something by applying some clever technique.&lt;/p&gt;
&lt;p&gt;I keep those snippets in a Notion database, which works great because I can tag them and add arbitrary properties. A nice benefit of this habit is that it&amp;rsquo;s not a problem if you don&amp;rsquo;t do it for a while. Your database will not look messy all of a sudden.&lt;/p&gt;
&lt;figure class=&#34;center-figure&#34;&gt;
    &lt;img src=&#34;https://tkainrad.dev/images/managing-my-personal-knowledge-base/notion-snippet.database.png&#34;
         alt=&#34;An exemplary entry of my code snippets database in Notion.&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;An exemplary entry of my code snippets database in Notion.&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;h2 id=&#34;shortcut-database&#34;&gt;Shortcut Database&lt;/h2&gt;
&lt;p&gt;I believe that typing proficiency is important for a software engineer. It is easier to stay in flow if you can type fast and navigate around your IDE and tools with shortcuts. As my set of tools grew, I realized that I have a hard time to keep track of which shortcuts I am using, which of them work in which application, and whether I can change them so that they work across as many tools as possible.&lt;/p&gt;
&lt;p&gt;Therefore, I started to keep track of some shortcuts I would like to use everywhere. These are things like creating new tabs, creating new windows, opening the respective tool&amp;rsquo;s search feature and more.&lt;/p&gt;
&lt;p&gt;This database helps me identify overlaps and motivates me to think about which task could fit for a specific key-combination that I use often. For example, I use &lt;code&gt;Ctrl&lt;/code&gt; - &lt;code&gt;Shift&lt;/code&gt; - &lt;code&gt;T&lt;/code&gt; in IDEs to search for type definitions and  &lt;code&gt;Ctrl&lt;/code&gt; - &lt;code&gt;Shift&lt;/code&gt; - &lt;code&gt;R&lt;/code&gt; to search for resources in general. Since I have these key combinations memorized for years and can use it very quickly, I want to make use of it wherever possible. Therefore, I try to set up my applications so that some kind of search opens whenever I use one of these combinations. My Notion database makes it easy to see which applications offer search features and which of them I can modify.&lt;/p&gt;
&lt;p&gt;For example, my Browser now forwards &lt;code&gt;Ctrl&lt;/code&gt; - &lt;code&gt;Shift&lt;/code&gt; - &lt;code&gt;T&lt;/code&gt; / &lt;code&gt;R&lt;/code&gt; to &lt;a href=&#34;https://code.visualstudio.com/&#34;&gt;Workona&lt;/a&gt; and allows me to switch/search workspaces or use the general search, respectively.&lt;/p&gt;
&lt;figure&gt;
    &lt;img src=&#34;https://tkainrad.dev/images/managing-my-personal-knowledge-base/shortcuts-database.png&#34;
         alt=&#34;Screenshot of my Notion shortcut database&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;Screenshot of my Notion shortcut database&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Notion&amp;rsquo;s filtering and search capabilities are great for identifying problems with your setup. For me, a problem is when two applications use different shortcuts for a very similar operation. Unfortunately, Notion is negative example of an application that doesn&amp;rsquo;t let you customize its shortcuts and therefore reduces the usefulness of my database. If someone from the Notion team reads this at some point, I kindly ask you to lobby on my behalf to prioritize personalized keyboard shortcuts.&lt;/p&gt;
&lt;p&gt;I am excited about this use case and will talk about it in much more detail in a future blog post.&lt;/p&gt;

&lt;div class=&#34;notices info&#34;&gt;
    &lt;p&gt;As of June 3rd, 2020, there is still no dedicated blog post for this. However, there is something more valuable:&lt;br&gt;
This post gave me the idea for &lt;a href=&#34;https://keycombiner.com&#34;&gt;https://keycombiner.com&lt;/a&gt;.&lt;br&gt;
It is a web application to track the keyboard shortcuts you use, get better at using them, and to learn new ones.
It is in open beta and I would love to hear your feedback!&lt;/p&gt;

&lt;/div&gt;
&lt;h2 id=&#34;tools-database&#34;&gt;Tools Database&lt;/h2&gt;
&lt;p&gt;I also have a Notion database to keep track of small web tools that I use. This serves little purpose for things that are used frequently as you will remember them anyway. However, for minor things that are only needed once in a while, such as color palette generators, detecting handwriting as LaTeX symbols, and checking SSL certificates this is quite handy. Usually, you can find these tools via google, but sometimes there are many tools for a task and it is nice to keep track of the ones that work best.&lt;/p&gt;
&lt;figure&gt;
    &lt;img src=&#34;https://tkainrad.dev/images/managing-my-personal-knowledge-base/tools-database.png&#34;
         alt=&#34;Screenshot of my software tools database in Notion.&#34;/&gt; &lt;figcaption&gt;
            &lt;p&gt;Screenshot of my software tools database in Notion.&lt;/p&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Again, the important thing here is to not overdo it. There are extensive publicly available lists of such tools. Your list should not be a copy of those but rather a small collection of the things you like and need from time to time.&lt;/p&gt;
&lt;h2 id=&#34;collecting-ideas-for-new-projects&#34;&gt;Collecting Ideas for new Projects&lt;/h2&gt;
&lt;p&gt;Like many software engineers in these golden times, I sometimes think about starting new software projects, maybe even bootstrapping a small business.&lt;br&gt;
You probably guessed it already, I keep ideas for possible projects in a Notion database. The main benefit is, once again, that it allows me to easily link it with other databases, such as my bookmarks.&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;Similar posts often conclude with warnings that you should be very careful not to spend too much time on organizing and maintaining your knowledge and workflows. In principle, I agree with this sentiment. After all, you want to &lt;em&gt;increase&lt;/em&gt; your productivity.&lt;/p&gt;
&lt;p&gt;I do believe, however, that it is worth it to spend some time thinking about your knowledge management &lt;em&gt;system&lt;/em&gt;. The most important part about conceptualizing a system is to decide exactly which types of information you want to maintain in your knowledge base. If you get this right you will benefit for the rest of your career. Even if the tools might change in the future, the system will stay.&lt;/p&gt;
&lt;p&gt;Please don&amp;rsquo;t hesitate to share your own experiences in the comments below. I am sure that my workflows are not perfect, but they might get closer with your tips.&lt;/p&gt;

&lt;div class=&#34;notices info&#34;&gt;
    &lt;p&gt;This post is released together with &lt;a href=&#34;https://tkainrad.dev/posts/reading-list-organizing-knowledge/&#34;&gt;a new post in my &lt;em&gt;Reading List&lt;/em&gt; series&lt;/a&gt;, which lists related resources. If you want to dive even deeper into knowledge management concepts, you might want to have a look.&lt;/p&gt;

&lt;/div&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>
    
  </channel>
</rss>