<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Kapil Pau</title>
    <description>The latest articles on DEV Community by Kapil Pau (@kapilpau).</description>
    <link>https://dev.to/kapilpau</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F621951%2Fe5e8316f-1ee6-4dd1-9601-cd6f028779bd.jpeg</url>
      <title>DEV Community: Kapil Pau</title>
      <link>https://dev.to/kapilpau</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kapilpau"/>
    <language>en</language>
    <item>
      <title>Building a Go Mod CLI to generate dependency trees</title>
      <dc:creator>Kapil Pau</dc:creator>
      <pubDate>Tue, 15 Jun 2021 21:49:22 +0000</pubDate>
      <link>https://dev.to/kapilpau/building-a-go-mod-cli-to-generate-dependency-trees-6cb</link>
      <guid>https://dev.to/kapilpau/building-a-go-mod-cli-to-generate-dependency-trees-6cb</guid>
      <description>&lt;p&gt;So, picture the scene, you have a Go project and then get a security alert saying a vulnerability has been detected. You look at your go.mod to see if you're using it and it's nowhere to be seen, but then you see it in your go.sum. How do you find where it is coming from?&lt;/p&gt;

&lt;p&gt;Sound familiar? Well that's the situation I found myself in last week. So obviously, I tried to find a tool that would do it but couldn't find one, so like any programmer would do, I decided to build one.&lt;/p&gt;

&lt;p&gt;The tool can be found &lt;a href="https://github.com/kapilpau/go-mod-dependency-tree" rel="noopener noreferrer"&gt;here&lt;/a&gt;, with amd64 binaries for Linux, Windows and Mac available in the releases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstorage.googleapis.com%2Fmarkdium-image%2Fb2297d6dfefa5b226a886b6d452c461f" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstorage.googleapis.com%2Fmarkdium-image%2Fb2297d6dfefa5b226a886b6d452c461f" alt="installation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To install, simply download the appropriate binary for your operating system from the latest release, at the time of writing this, it was &lt;a href="https://github.com/kapilpau/go-mod-dependency-tree/releases/tag/v1.2.0" rel="noopener noreferrer"&gt;v1.2.0&lt;/a&gt;. Once downloaded, make sure the binary is executable and moved to be in your PATH, with the name &lt;code&gt;go-tree&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use it
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstorage.googleapis.com%2Fmarkdium-image%2Fc8ff1bb5a6b4dec23822bfa2970433d7" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstorage.googleapis.com%2Fmarkdium-image%2Fc8ff1bb5a6b4dec23822bfa2970433d7" alt="usage"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The tool only works with go mod projects, and requires the environment variable &lt;code&gt;GOPATH&lt;/code&gt; to be set (by default, it will be &lt;code&gt;$HOME/go&lt;/code&gt;). You can either run it from within the root directory of your go project (where you go.mod is located), or you can use the &lt;code&gt;-modulePath&lt;/code&gt; flag to pass in a relative or absolute path to the project you want to scan.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ go-tree -modulePath $GOPATH/src/path/to/module/to/scan
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also use the &lt;code&gt;-maxDepth&lt;/code&gt; flag to set the maximum recursion level, i.e. how far down the tree to scan. The options are either -1 or an integer above 0, -1 is to indicate no limit and is the default value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ go-tree -maxDepth -1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The final flag you can use is the &lt;code&gt;-find&lt;/code&gt; flag, which is the whole reason this tool exists. If you specify this flag with the module you would like to find, it will print the full tree for all of the instances of that package in the dependency tree. Note that if you use &lt;code&gt;-find&lt;/code&gt;, the &lt;code&gt;-maxDepth&lt;/code&gt; will be ignored.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ go-tree -find github.com/kapilpau/go-mod-dependency-tree
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;None of these flags are required.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstorage.googleapis.com%2Fmarkdium-image%2Fb68ba130ff3b3f7f1dcd648532948105" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstorage.googleapis.com%2Fmarkdium-image%2Fb68ba130ff3b3f7f1dcd648532948105" alt="working"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As this is a single function cli tool, the whole code is contained within a &lt;a href="https://github.com/kapilpau/go-mod-dependency-tree/blob/main/dependency-tree.go" rel="noopener noreferrer"&gt;single file&lt;/a&gt;. The code has two main pathways, both of which work in a similar way.&lt;/p&gt;

&lt;p&gt;The first is the straight tree dump, i.e. where you don't specify the &lt;code&gt;-find&lt;/code&gt; flag. This route recursively searches each dependency's go.mod to find all of the dependencies for that module and prints out the name and version of the dependency. For this, we read in the go.mod file for your project, find all of the modules in the &lt;code&gt;requires&lt;/code&gt; section and look for the module in the &lt;code&gt;src&lt;/code&gt; or &lt;code&gt;pkg&lt;/code&gt; folders, in your &lt;code&gt;GOPATH&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If they have exist and have a &lt;code&gt;go.mod&lt;/code&gt; file, we continue through the chains and look for their dependencies. If we can't find a dependency in either location, or it doesn't have a &lt;code&gt;go.mod&lt;/code&gt; file, we end that branch there and move on.&lt;/p&gt;

&lt;p&gt;The other pathway is for when a user is searching for a specific module in the chain. In this case, it is slightly more complicated as we need to decide what to print out later on. For this, we use a custom tree struct, named &lt;code&gt;dependencyChain&lt;/code&gt;. This struct has two fields, &lt;code&gt;module&lt;/code&gt; (the name of the module currently being scanned) and &lt;code&gt;children&lt;/code&gt; (the dependencies of the current module).&lt;/p&gt;

&lt;p&gt;We do a similar recursive search to the one detailed above, however, rather than just simply printing out the values as we find them, we have to perform head recursion, so we can look at the outputs of the later recurssions before deciding what to do. So, if we find the module we're looking for, we end the branch of the tree there, as it would be wasteful to carry on, and we populate the &lt;code&gt;dependencyChain&lt;/code&gt; object to pass back. Then, when we have the list of &lt;code&gt;dependencyChain&lt;/code&gt;s for each module, we check the size of the &lt;code&gt;children&lt;/code&gt; field and if it is not empty, we pass it upwards, otherwise we ignore it. The reason we do this check is because we only want to see the branches that end in the module we're looking for.&lt;/p&gt;

&lt;p&gt;Once we have completed this head recursive search, we perform a tail recursive print, to loop through the &lt;code&gt;children&lt;/code&gt; of each &lt;code&gt;dependencyChain&lt;/code&gt; and display it as a tree.&lt;/p&gt;

&lt;p&gt;If the module you are looking for does not exist in the chain, or it cannot be found (as it may be in a non-go mod enabled project), then a message is printed out at the end to say so.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons learned
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstorage.googleapis.com%2Fmarkdium-image%2F4e6b1cbf958653686ee4d1351510f53f" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstorage.googleapis.com%2Fmarkdium-image%2F4e6b1cbf958653686ee4d1351510f53f" alt="learned"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I learned a lot from this project, namely how easy it is to create and build cli binaries in Go, even being able to build for different operating systems and architectures, without having to natively use an instance of them. This is definitely just the first of many more to come.&lt;/p&gt;

&lt;p&gt;I got to apply the principles of recursion, that we spent so long learning at uni, to a real-life scenario.&lt;/p&gt;

&lt;p&gt;I gained a deeper understanding of how Go stores dependencies, and where to find them when I need them.&lt;/p&gt;

</description>
      <category>go</category>
    </item>
    <item>
      <title>Docker vs Kubernetes, which should I use?</title>
      <dc:creator>Kapil Pau</dc:creator>
      <pubDate>Tue, 27 Apr 2021 19:34:54 +0000</pubDate>
      <link>https://dev.to/kapilpau/docker-vs-kubernetes-which-should-i-use-3pdm</link>
      <guid>https://dev.to/kapilpau/docker-vs-kubernetes-which-should-i-use-3pdm</guid>
      <description>&lt;p&gt;Ok before going any further with this blog, I have to confess something. The title is a bit catfishy but it's a question I see a lot online so hopefully I will be able to answer it for anyone who has thought about it.&lt;/p&gt;

&lt;p&gt;Let me start by initially defining what they both are.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstorage.googleapis.com%2Fmarkdium-image%2Fce18f9b86926532554815781e804aeae" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstorage.googleapis.com%2Fmarkdium-image%2Fce18f9b86926532554815781e804aeae" alt="Docker"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Docker
&lt;/h2&gt;

&lt;p&gt;Docker is a type of containerisation technology which allows for standardisation of packaging and shipping of products. Containers, as with Virtual Machines, run a virtual computer within your computer, however, unlike VMs, which run in parallel with the host OS and isolate resources, containers run within the host OS and are therefore much smaller, lightweight and quicker to spin up.&lt;/p&gt;

&lt;p&gt;As with a traditional VM, containers are spun up using an image and that image contains the OS and the applications and libraries required for the container to perform whatever task is needed. Images are created using Dockerfiles, which contain a number of steps for the Docker engine to complete in order to build the image.&lt;/p&gt;

&lt;p&gt;Docker images are typically in the 100s of MB in size and are stored in registries. Registries can be public or private, depending on the sensitivity of the images, and can be self-hosted or 3rd party hosted.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstorage.googleapis.com%2Fmarkdium-image%2Ff38ddf466fae5285cf9b84bffe6db9d8" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstorage.googleapis.com%2Fmarkdium-image%2Ff38ddf466fae5285cf9b84bffe6db9d8" alt="Kube"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Kubernetes
&lt;/h2&gt;

&lt;p&gt;Kubernetes is the industry standard container orchestration system, this is where you'll start to work out why the title is catfishy. A container orchestration tool manages the deployment, networking, availability and scaling on containers and services.&lt;/p&gt;

&lt;p&gt;Kubernetes, often referred to as kube or k8s, is a service every cloud provider provides, with some providing their own custom Kubernetes services, like Google Kubernetes Engine (GKE) or RedHat's OpenShift Container Platform (OCP).&lt;/p&gt;

&lt;p&gt;Kubernetes allows users to decoratively deploy their applications by telling Kubernetes what they want and letting the engine handle the deployment, maintenance and upgrade. This is done through the creation of a YAML representation of resources. The resources can be for deployment of containers, network and DNS management or auto-scalers for their deployments.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstorage.googleapis.com%2Fmarkdium-image%2F823830ef7edd88c9569048c94bc628e8" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstorage.googleapis.com%2Fmarkdium-image%2F823830ef7edd88c9569048c94bc628e8" alt="Decisions"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Which should I use?
&lt;/h2&gt;

&lt;p&gt;The key aspect at the heart of this question is that it's a false dilemma, it's not necessarily a question of &lt;em&gt;"or"&lt;/em&gt;, because one is fundamentally dependant upon the other. Kubernetes is a tool for augmenting containers, of which Docker is the industry standard. You can have Docker without Kubernetes, but not the other way round.&lt;/p&gt;

&lt;p&gt;There are lots of use-cases where Docker will do the job needed, and Kubernetes is over-kill. A Kubernetes cluster requires as least two computers, or nodes, to run and, generally, requires more maintenance than a normal server. If you don't have multiple microservices which need inter-connectivity and only want one instance of your container running, then running containers natively in Docker will suffice. Using the &lt;code&gt;--restart&lt;/code&gt; flag when starting the container will achieve the same results as a Kubernetes cluster.&lt;/p&gt;

&lt;p&gt;On the flip side, if you are running a number of microservices, with a service mesh, and require high availability and firewalls, then Kubernetes will simplify this and require very little infrastructure knowledge. The number of required nodes for a Kubernetes cluster means that they will cost more than just using Docker natively, and if you want someone to manage the infrastructure for you, it will drive the cost up even more.&lt;/p&gt;

&lt;h2&gt;
  
  
  tl;dr
&lt;/h2&gt;

&lt;p&gt;If you have a large, multi-microservice, production application, I'd advise Kubernetes.&lt;/p&gt;

&lt;p&gt;If you are only using one or two containers, with limited communication between them, you should be fine with native Docker.&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>docker</category>
      <category>devops</category>
      <category>cloud</category>
    </item>
  </channel>
</rss>
