<?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: Ganessh Kumar</title>
    <description>The latest articles on DEV Community by Ganessh Kumar (@ganesshkumar).</description>
    <link>https://dev.to/ganesshkumar</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%2F126116%2Fc1177a48-937a-46b8-9835-ed87b7b5d621.jpg</url>
      <title>DEV Community: Ganessh Kumar</title>
      <link>https://dev.to/ganesshkumar</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ganesshkumar"/>
    <language>en</language>
    <item>
      <title>My Notes on React</title>
      <dc:creator>Ganessh Kumar</dc:creator>
      <pubDate>Tue, 05 Nov 2024 20:47:11 +0000</pubDate>
      <link>https://dev.to/ganesshkumar/my-notes-on-react-1nji</link>
      <guid>https://dev.to/ganesshkumar/my-notes-on-react-1nji</guid>
      <description>&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.ganesshkumar.com/articles/2024-10-30-bossting-react-performance-with-lazy-loading-and-memoization" rel="noopener noreferrer"&gt;Boosting Your React App’s Performance with Lazy Loading and Memoization&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
    </item>
    <item>
      <title>Learn, unlearn and relearn</title>
      <dc:creator>Ganessh Kumar</dc:creator>
      <pubDate>Fri, 01 May 2020 17:08:18 +0000</pubDate>
      <link>https://dev.to/ganesshkumar/learn-unlearn-and-relearn-5bo8</link>
      <guid>https://dev.to/ganesshkumar/learn-unlearn-and-relearn-5bo8</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;The illiterate of the 21st century will not be those who cannot read and write, but those who cannot learn, unlearn, and relearn - Alvin Toffler&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Schools and Colleges play a vital role in teaching us. These institutions often tend to force their students to learn more and more, without mastering the fundamentals. Students who love their subjects and enjoy their books are becoming hard to find day by day. Industries view degree holders as an abstracted and tuned resources for their need.&lt;/p&gt;

&lt;p&gt;So, “learning” has not been given the due respect by all the players: students, educational institutions and industries.&lt;/p&gt;

&lt;p&gt;What about unlearning and relearning? Do they really make sense in our existing system?&lt;/p&gt;

&lt;p&gt;Unlearning and relearning are tightly coupled and usually happens together.&lt;/p&gt;

&lt;p&gt;Unlearning and relearning do not mean that one should forget the things he had learnt and learn it again at some point of time in his life. This is a very common misinterpretation I find among the people who know this quote. I have even seen people quoting “Tower of Hanoi” as an example where you have to decouple the things you have built to arrive at the final solution. I call this as a fictional example where they try to unlearn by demolishing something that is there.&lt;/p&gt;

&lt;p&gt;Unlearning happens when you are open to new prospective to the things you already know. Relearning happens when you accept a new perspective and appreciate your knowledge from that perspective. Together they will help you to overcome your misconception and misunderstanding that was there from the time you learnt something new.&lt;/p&gt;

&lt;p&gt;When we learn something for the first time, we will be focusing to get a bigger and abstracted view of it. We ignore small and important features. After learning something, a small discussion with friends or teaching someone or trying to summarize your learning will make you realize the minute details that you have missed when you learnt it.&lt;/p&gt;

&lt;p&gt;Unlearning and relearning applies not only for education; but also to any form of knowledge or skill that we acquire. Our knowledge and skill can to be improved day by day.&lt;/p&gt;

&lt;p&gt;Be open to thoughts. Keep learning, unlearning and relearning.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TL; DR&lt;/strong&gt;: Be open to new perspective – clear out your misunderstandings – improve your understanding.&lt;/p&gt;

</description>
      <category>learn</category>
      <category>unlearn</category>
      <category>relearn</category>
    </item>
    <item>
      <title>Pi-hole in Azure Container Instances</title>
      <dc:creator>Ganessh Kumar</dc:creator>
      <pubDate>Fri, 01 May 2020 12:55:50 +0000</pubDate>
      <link>https://dev.to/ganesshkumar/pi-hole-in-azure-container-instances-4abf</link>
      <guid>https://dev.to/ganesshkumar/pi-hole-in-azure-container-instances-4abf</guid>
      <description>&lt;p&gt;A simple guide to deploy &lt;a href="https://pi-hole.net/"&gt;Pi-hole&lt;/a&gt;, a black hole for Internet advertisements, in &lt;a href="https://azure.microsoft.com/en-in/services/container-instances/"&gt;Azure Container Instances&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We use pi-hole's docker image.&lt;/li&gt;
&lt;li&gt;We persist configurations and data across the container instances. To do so, we will use Azure Storage to mount file volumes in the containers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;1. Install &lt;a href="https://docs.microsoft.com/en-us/cli/azure/install-azure-cli-windows?view=azure-cli-latest"&gt;Azure CLI&lt;/a&gt; and set your subscription&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; az login

&amp;gt; az account set --subscription &amp;lt;subscription_id&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;2. Create a Resource Group&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; az group create --name &amp;lt;rg_name&amp;gt; --location &amp;lt;location&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;3. Create a Storage account&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; az storage account create --resource-group &amp;lt;rg_name&amp;gt; --name &amp;lt;storage_name&amp;gt; --location &amp;lt;location&amp;gt; --sku Standard_LRS
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;4. Create two file shares in the storage account created in the last step&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;az storage share create --account-name &amp;lt;storage_name&amp;gt; --name etc-pihole

az storage share create --account-name &amp;lt;storage_name&amp;gt; --name etc-dnsmasq
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;5. Obtain the storage account key&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;STORAGE_KEY=$(az storage account keys list --resource-group &amp;lt;rg_name&amp;gt; --account-name &amp;lt;storage_name&amp;gt; --query "[0].value" --output tsv)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;5. Since our container will require a good number of configuration, let's use a yaml file&lt;/p&gt;

&lt;p&gt;deploy-pi-hole.yaml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: &amp;lt;container_group_name&amp;gt;
apiVersion: '2018-10-01'
location: &amp;lt;location&amp;gt;
tags: {}
properties:
  containers:
  - name: &amp;lt;container_name&amp;gt;
    properties:
      image: pihole/pihole:latest
      ports:
      - protocol: UDP
        port: 53
      - protocol: UDP
        port: 67
      - protocol: TCP
        port: 80
      - protocol: TCP
        port: 443
      environmentVariables:
      - name: TZ
        value: Asia/Kolkata
      - name: WEBPASSWORD
        value: &amp;lt;custom_large_string&amp;gt;
      resources:
        requests:
          memoryInGB: 1
          cpu: 1
      volumeMounts:
      - name: pihole
        mountPath: /etc/pihole/
        readOnly: false
      - name: dnsmasq
        mountPath: /etc/dnsmasq.d/
        readOnly: false
  restartPolicy: Always
  ipAddress:
    ports:
    - protocol: UDP
      port: 53
    - protocol: UDP
      port: 67
    - protocol: TCP
      port: 80
    - protocol: TCP
      port: 443
    type: public
    dnsNameLabel: &amp;lt;custom_dnsname&amp;gt;
  osType: Linux
  volumes:
  - name: pihole
    azureFile:
      shareName: etc-pihole
      readOnly: false
      storageAccountName: &amp;lt;storage_name&amp;gt;
      storageAccountKey: &amp;lt;value of $STORAGE_KEY&amp;gt;
  - name: dnsmasq
    azureFile:
      shareName: etc-dnsmasq
      readOnly: false
      storageAccountName: &amp;lt;storage_name&amp;gt;
      storageAccountKey: &amp;lt;value of $STORAGE_KEY&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Replace the place holders in the yaml file.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; will be used as the password when you log in to pi-hole's dashboard.&lt;/li&gt;
&lt;li&gt; will be used in the generated FQDN in the following format &lt;code&gt;&amp;lt;custom_dnsname&amp;gt;.&amp;lt;location&amp;gt;.azurecontainer.io&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;6. Create the container instance&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;az container create --resource-group &amp;lt;rg_name&amp;gt; --file deploy-pi-hole.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;7. Get the IP address of the pi-hole running as container instance.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;az container show --resource-group &amp;lt;rg_name&amp;gt; --name &amp;lt;container_group_name&amp;gt; --query ipAddress.ip --output tsv
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;: It has been 10 days since I started using pi-hole and it has blocked ~31% of my DNS queries so far.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PIW6Uq5v--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/fll6rchtxuoum05zqk7c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PIW6Uq5v--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/fll6rchtxuoum05zqk7c.png" alt="Pi-hole stats"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you found this article useful, check out my other articles from my blog, &lt;a href="https://ganesshkumar.com/blog"&gt;https://ganesshkumar.com/blog&lt;/a&gt;. Thank you for reading!&lt;/p&gt;

</description>
      <category>docker</category>
      <category>azure</category>
      <category>containers</category>
      <category>pihole</category>
    </item>
    <item>
      <title>Self-hosting multiple applications in a single machine</title>
      <dc:creator>Ganessh Kumar</dc:creator>
      <pubDate>Wed, 14 Aug 2019 20:39:11 +0000</pubDate>
      <link>https://dev.to/ganesshkumar/self-hosting-multiple-applications-in-a-single-machine-1l3o</link>
      <guid>https://dev.to/ganesshkumar/self-hosting-multiple-applications-in-a-single-machine-1l3o</guid>
      <description>&lt;p&gt;I love self-hosting personal applications. I spun a machine on cloud and started hosting my applications. As I wanted to host my second application, I got struck routing both the application's request to the same machine without needing to specify a port number in the URL. Specifying a port number in the URL like &lt;a href="http://miniflux.ganesshkumar.com:5000"&gt;http://miniflux.ganesshkumar.com:5000&lt;/a&gt; and &lt;a href="http://blog.ganesshkumar.com:4000"&gt;http://blog.ganesshkumar.com:4000&lt;/a&gt; made the URL look ugly.  &lt;/p&gt;

&lt;p&gt;After searching for a while, I found that reverse proxy using nginx can come in handy. At this point, I also wanted to enforce SSL to the applications as my application needed login. &lt;a href="https://letsencrypt.org/"&gt;Let's Encrypt&lt;/a&gt; provides free SSL certificates. Now I needed to put together nginx, certificates and my applications to work together. To reduce setup procedures, I opted to use Docker. In this post let's see how I put all the pieces together.&lt;/p&gt;

&lt;p&gt;The first application I want to host in &lt;a href="https://miniflux.app/"&gt;miniflux&lt;/a&gt;, a minimalist feed reader.&lt;/p&gt;

&lt;p&gt;Let's create two folders in the home directory. &lt;code&gt;data&lt;/code&gt; to hold all the volumes that will be mounted in docker and &lt;code&gt;docker-compose&lt;/code&gt; to hold docker-compose files to launch the services and applications.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mkdir data docker-compose
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  1. Let's start our first application
&lt;/h3&gt;

&lt;p&gt;Create the folders for data and docker-compose&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mkdir data/miniflux docker-compose/miniflux
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then create &lt;em&gt;docker-compose.yml&lt;/em&gt; file in the docker-compose/miniflux folder with the following content&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: '3'
services:
  miniflux:
    image: miniflux/miniflux:latest
    ports:
      - "8000:8080"
    depends_on:
      - db
    environment:
      - DATABASE_URL=postgres://&amp;lt;username&amp;gt;:&amp;lt;password&amp;gt;@db/miniflux?sslmode=disable
  db:
    image: postgres:10.1
    environment:
      - POSTGRES_USER=&amp;lt;username&amp;gt;
      - POSTGRES_PASSWORD=&amp;lt;password&amp;gt;
    volumes:
      - ${HOME}/data/miniflux:/var/lib/postgresql/data
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now running &lt;code&gt;docker-compose up -d&lt;/code&gt; in the docker-compose folder will run this application in the background. We can reach the server on &lt;em&gt;localhost:8000&lt;/em&gt;. Our first application is up and running now.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Starting nginx
&lt;/h3&gt;

&lt;p&gt;Create the folders for data and docker-compose&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mkdir data/nginx docker-compose/nginx
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We will be mounting SSL certificates in nginx container, so that our applications will be served over a secured layer. Create folders for holding the certificates&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mkdir -p data/letsencrypt/certs data/letsencrypt/certs-data
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then create &lt;em&gt;docker-compose.yml&lt;/em&gt; file with the following contents&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: '3'
services:
  nginx:
    image: nginx:alpine
    container_name: nginx
    restart: always
    network_mode: host
    volumes:
      - ${HOME}/data/letsencrypt/certs:/etc/letsencrypt
      - ${HOME}/data/letsencrypt/certs-data:/data/letsencrypt
      - ${HOME}/data/nginx:/etc/nginx
    ports:
      - 80:80
      - 443:443
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Before string the ngix container, we have to create a config file for nginx. Create &lt;code&gt;data/nginx/nginx.conf&lt;/code&gt; file with the following content&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;events {
}

http {
    server {
        listen      80;
        listen [::]:80;
        server_name miniflux.ganesshkumar.com;

         location / {
                rewrite ^ https://$host$request_uri? permanent;
        }

        location ^~ /.well-known {
                allow all;
                root  /data/letsencrypt/;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This config dictates to redirect any request to &lt;code&gt;miniflux.ganesshkumar.com&lt;/code&gt; to &lt;code&gt;https://ganesshkumar.com&lt;/code&gt;. Also serve the request to &lt;em&gt;/.well-known&lt;/em&gt; to be served from &lt;em&gt;/data/letscrypt&lt;/em&gt; directory. This .well-known endpoint will be used by Let's Encrypt to verify our DNS entry for miniflux.&lt;/p&gt;

&lt;p&gt;Now, we can run &lt;code&gt;docker-compose up -d&lt;/code&gt; from the docker-compose directory to start the nginx server. The request to miniflux will not reach the application yet, as we haven't routed it to localhost:8000 but still the nginx server will help set up the SSL certificates for the miniflux domain.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Setting up SSL certificates
&lt;/h3&gt;

&lt;p&gt;Let's Encrypt provides to tool certbot to create our SSL certificates. Let's use the docker image of certbot to do that. Run the following docker command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker run -it --rm \
        -v certs:/etc/letsencrypt \
        -v certs-data:/data/letsencrypt \
        deliverous/certbot \
        certonly \
        --webroot --webroot-path=/data/letsencrypt
        -d miniflux.ganesshkumar.com
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The above command will generate a challage and tries to solve it at &lt;code&gt;miniflux.ganesshkumar.com/.well-known&lt;/code&gt;. Our nginx server has enough configuration to host the contents of .well-known folder generated by the certbot.&lt;/p&gt;

&lt;p&gt;On successful execution of the above command, you will have your certificates generated at data/letsencrypt/certs-data directory.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Routing the request to the application
&lt;/h3&gt;

&lt;p&gt;Now let's modify the contents of &lt;em&gt;nginx.conf&lt;/em&gt; file, to route the requests to miniflux.ganesshkumar.com to localhost:8000.&lt;/p&gt;

&lt;p&gt;Add the following code to the http section of &lt;em&gt;nginx.conf&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    server {
        listen      443           ssl http2;
        listen [::]:443           ssl http2;
        server_name               miniflux.ganesshkumar.com;

        ssl                       on;

        add_header                Strict-Transport-Security "max-age=31536000" always;

        ssl_session_cache         shared:SSL:20m;
        ssl_session_timeout       10m;

        ssl_protocols             TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;
        ssl_ciphers               "ECDH+AESGCM:ECDH+AES256:ECDH+AES128:!ADH:!AECDH:!MD5;";

        ssl_stapling              on;
        ssl_stapling_verify       on;
        resolver                  8.8.8.8 8.8.4.4;

        ssl_certificate           /etc/letsencrypt/live/miniflux.ganesshkumar.com/fullchain.pem;
        ssl_certificate_key       /etc/letsencrypt/live/miniflux.ganesshkumar.com/privkey.pem;
        ssl_trusted_certificate   /etc/letsencrypt/live/miniflux.ganesshkumar.com/chain.pem;

        access_log                /dev/stdout;
        error_log                 /dev/stderr info;

        location / {
            proxy_pass           http://127.0.0.1:8000;
            proxy_set_header     Host $host;
            proxy_set_header     X-Forwarded-For $remote_addr;
        }
    }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We are almost done. Restart the nginx server to use the latest configuration. Run the following command in nginx's docker-compose directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker-compose down
$ docker-compose up -d
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That all. Our request to &lt;a href="http://miniflux.ganesshkumar.com"&gt;http://miniflux.ganesshkumar.com&lt;/a&gt; will be redirected to &lt;a href="https://miniflux.ganesshkumar.com"&gt;https://miniflux.ganesshkumar.com&lt;/a&gt; which will be served from localhost:8000, making sure that all the requests are being served over SSL.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;To add a second application&lt;/strong&gt;, just repeat all the four steps. You will be serving both the applications from the same machine using nginx reverse proxy.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Renewing SSL certificate
&lt;/h3&gt;

&lt;p&gt;After few months your SSL certificate will expire. You can run the following command to renew the certificate.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker run -t --rm \
      -v certs:/etc/letsencrypt \
      -v certs-data:/data/letsencrypt \
      deliverous/certbot \
      renew \
      --webroot --webroot-path=/data/letsencrypt

$ docker-compose kill -s HUP nginx
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This set up has made the process of deploying any new application to the server simple :)&lt;/p&gt;

</description>
      <category>selfhosting</category>
      <category>docker</category>
      <category>nginx</category>
      <category>certbot</category>
    </item>
    <item>
      <title>Adding MSL Shell to Windows Terminal</title>
      <dc:creator>Ganessh Kumar</dc:creator>
      <pubDate>Wed, 14 Aug 2019 20:18:57 +0000</pubDate>
      <link>https://dev.to/ganesshkumar/adding-msl-shell-to-windows-terminal-gil</link>
      <guid>https://dev.to/ganesshkumar/adding-msl-shell-to-windows-terminal-gil</guid>
      <description>&lt;p&gt;After installing any flavors of Linux using Windows Subsystem for Linux, WSL, on Windows 10, you open Microsoft's latest Windows Terminal and do not find your linux shell in it? &lt;/p&gt;

&lt;p&gt;Then this guide is for you.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make sure you have installed your desired version of Linux from the Windows Store.&lt;/li&gt;
&lt;/ul&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F6ysprb0yxpvvgg029976.png" 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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F6ysprb0yxpvvgg029976.png" alt="Ubuntu-18.04"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In Windows Terminal click the dropdown icon and select settings. Alternatively, you can open it with &lt;code&gt;Ctrl + ,&lt;/code&gt; shortcut.
This will open &lt;code&gt;profiles.json&lt;/code&gt; file in your text editor&lt;/li&gt;
&lt;/ul&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fhamezss5fa5k90lceggo.png" 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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fhamezss5fa5k90lceggo.png" alt="Terminal"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the profiles.json file, find the &lt;code&gt;profiles&lt;/code&gt; section. profiles is an array where each element in the array maps to a shell (powershell or cmd or any linux shell)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    "profiles" : 
    [
        {
            "acrylicOpacity" : 0.5,
            "background" : "#012456",
            "closeOnExit" : true,
            "colorScheme" : "Campbell",
            "commandline" : "powershell.exe",
            "cursorColor" : "#FFFFFF",
            "cursorShape" : "bar",
            "fontFace" : "Consolas",
            "fontSize" : 10,
            "guid" : "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
            "historySize" : 9001,
            "icon" : "ms-appx:///ProfileIcons/{61c54bbd-c2c6-5271-96e7-009a87ff44bf}.png",
            "name" : "Windows PowerShell",
            "padding" : "0, 0, 0, 0",
            "snapOnInput" : true,
            "startingDirectory" : "%USERPROFILE%",
            "useAcrylic" : false
        },
        {
            "acrylicOpacity" : 0.75,
            "closeOnExit" : true,
            "colorScheme" : "Campbell",
            "commandline" : "cmd.exe",
            "cursorColor" : "#FFFFFF",
            "cursorShape" : "bar",
            "fontFace" : "Consolas",
            "fontSize" : 10,
            "guid" : "{0caa0dad-35be-5f56-a8ff-afceeeaa6101}",
            "historySize" : 9001,
            "icon" : "ms-appx:///ProfileIcons/{0caa0dad-35be-5f56-a8ff-afceeeaa6101}.png",
            "name" : "cmd",
            "padding" : "0, 0, 0, 0",
            "snapOnInput" : true,
            "startingDirectory" : "%USERPROFILE%",
            "useAcrylic" : true
        }
    ],
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Add an entry in this array for your linux shell. To populate this, you need the following values

&lt;ul&gt;
&lt;li&gt;Command to start your shell

&lt;ul&gt;
&lt;li&gt;To get list of WSL shells run the command &lt;code&gt;wsl.exe --list&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;To start a particular WSL shell run &lt;code&gt;wsl.exe -d &amp;lt;shell_name_from_above&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;To set the home directory as default directory add &lt;code&gt;~&lt;/code&gt; to the wsl.exe command&lt;/li&gt;
&lt;li&gt;Our command to start Ubuntu-18.04 is &lt;code&gt;wsl.exe ~ -d Ubuntu-18.04&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;A new GUID (unique id in this array)

&lt;ul&gt;
&lt;li&gt;A random GUID can be generated from the linux shell by running &lt;code&gt;uuidgen&lt;/code&gt; command&lt;/li&gt;
&lt;li&gt;Replace &lt;code&gt;&amp;lt;guid&amp;gt;&lt;/code&gt; in the below snippet with your new GUID (leave the paranthesis intact)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Name and icon for the entry

&lt;ul&gt;
&lt;li&gt;Give an identifiable name like &lt;code&gt;Ubuntu-18.04&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;For icon, you can give any file system path in the system. I am opting to use the default linux penguine logo that has been packaged along with the Windows Terminal. Hence, I set &lt;code&gt;ms-appx:///ProfileIcons/{9acb9455-ca41-5af7-950f-6bca1bc9722f}.png&lt;/code&gt; as my icon path.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        {
            "acrylicOpacity":0.75,
            "closeOnExit":true,
            "colorScheme":"Campbell",
            "commandline":"wsl.exe ~ -d Ubuntu-18.04",
            "cursorColor":"#FFFFFF",
            "cursorShape":"bar",
            "fontFace":"Consolas",
            "fontSize":12,
            "guid":"{&amp;lt;guid&amp;gt;}",
            "historySize":9001,
            "icon" : "ms-appx:///ProfileIcons/{9acb9455-ca41-5af7-950f-6bca1bc9722f}.png",
            "name":"Ubuntu-18.04",
            "padding":"0, 0, 0, 0",
            "snapOnInput":true,
            "startingDirectory":"%USERPROFILE%",
            "useAcrylic":true
        }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;As soon as you save the &lt;code&gt;profiles.json&lt;/code&gt; file, the changes will be picked up by the Windows Terminal and you can see your WSL shell.&lt;/li&gt;
&lt;/ul&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fzloo3vpsgvhdhxoge317.png" 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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fzloo3vpsgvhdhxoge317.png" alt="Ubuntu in Terminal"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start a shell and start configuring it. I have configure my shell to be &lt;code&gt;zsh&lt;/code&gt; shell with &lt;code&gt;oh-my-zsh&lt;/code&gt; extension.&lt;/li&gt;
&lt;/ul&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Frb9036qyltxyn202a986.png" 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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Frb9036qyltxyn202a986.png" alt="zsh in terminal"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>windowsterminal</category>
      <category>productivity</category>
      <category>wsl</category>
      <category>ubuntu</category>
    </item>
  </channel>
</rss>
