<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Ubuntu - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Ubuntu - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sat, 23 May 2026 22:20:18 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/ubuntu/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Self-Host Your Own Server Monitoring Dashboard Using Uptime Kuma and Docker ]]>
                </title>
                <description>
                    <![CDATA[ As a developer, there's nothing worse than finding out from an angry user that your website is down. Usually, you don't know your server crashed until someone complains. And while many SaaS tools can  ]]>
                </description>
                <link>https://www.freecodecamp.org/news/self-host-uptime-kuma-docker/</link>
                <guid isPermaLink="false">69d4185f40c9cabf44851652</guid>
                
                    <category>
                        <![CDATA[ Docker ]]>
                    </category>
                
                    <category>
                        <![CDATA[ self-hosted ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Devops ]]>
                    </category>
                
                    <category>
                        <![CDATA[ monitoring ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Ubuntu ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Abdul Talha ]]>
                </dc:creator>
                <pubDate>Mon, 06 Apr 2026 20:32:31 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/uploads/covers/5e1e335a7a1d3fcc59028c64/ea068a20-bc19-400a-a42e-1bbb7e492da8.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>As a developer, there's nothing worse than finding out from an angry user that your website is down. Usually, you don't know your server crashed until someone complains.</p>
<p>And while many SaaS tools can monitor your site, they often charge high monthly fees for simple alerts.</p>
<p>My goal with this article is to help you stop paying those expensive fees by showing you a powerful, free, open-source alternative called Uptime Kuma.</p>
<p>In this guide, you'll learn how to use Docker to deploy Uptime Kuma safely on a local Ubuntu machine.</p>
<p>By the end of this tutorial, you'll have set up your own private server monitoring dashboard in less than 10 minutes and created an automated Discord alert to ping your phone if your website goes offline.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a href="#heading-step-1-update-packages-and-prepare-the-firewall">Step 1: Update Packages and Prepare the Firewall</a></p>
</li>
<li><p><a href="#heading-step-2-create-the-docker-compose-file">Step 2: Create the Docker Compose File</a></p>
</li>
<li><p><a href="#heading-step-3-start-the-application">Step 3: Start the Application</a></p>
</li>
<li><p><a href="#heading-step-4-access-the-dashboard">Step 4: Access the Dashboard</a></p>
</li>
<li><p><a href="#heading-step-5-use-case-monitor-a-website-and-send-discord-alerts">Step 5: Use Case – Monitor a Website and Send Discord Alerts</a></p>
</li>
<li><p><a href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before you start, make sure you have:</p>
<ul>
<li><p>An Ubuntu machine (like a local server, VM, or desktop).</p>
</li>
<li><p>Docker and Docker Compose installed.</p>
</li>
<li><p>Basic knowledge of the Linux terminal.</p>
</li>
</ul>
<h2 id="heading-step-1-update-packages-and-prepare-the-firewall">Step 1: Update Packages and Prepare the Firewall</h2>
<p>First, you'll want to make sure your system has the newest updates. Then, you'll install the Uncomplicated Firewall (UFW) and open the network "door" (port) that Uptime Kuma uses for the dashboard. You'll also need to allow SSH so you don't lock yourself out.</p>
<p>Run these commands in your terminal:</p>
<ol>
<li>Update your packages:</li>
</ol>
<pre><code class="language-shell">sudo apt update &amp;&amp; sudo apt upgrade -y
</code></pre>
<ol>
<li>Install the firewall:</li>
</ol>
<pre><code class="language-shell">sudo apt install ufw -y
</code></pre>
<ol>
<li>Allow SSH and open port 3001:</li>
</ol>
<pre><code class="language-shell">sudo ufw allow ssh
sudo ufw allow 3001/tcp
</code></pre>
<ol>
<li>Enable the firewall:</li>
</ol>
<pre><code class="language-shell">sudo ufw enable
sudo ufw reload
</code></pre>
<h2 id="heading-step-2-create-the-docker-compose-file">Step 2: Create the Docker Compose File</h2>
<p>Using a <code>docker-compose.yml</code> file is the professional way to manage Docker containers. It keeps your setup organised in one single place.</p>
<p>To start, create a new folder for your project and enter it:</p>
<pre><code class="language-shell">mkdir uptime-kuma &amp;&amp; cd uptime-kuma
</code></pre>
<p>Then create the configuration file:</p>
<pre><code class="language-shell">nano docker-compose.yml
</code></pre>
<p>Paste the following code into the editor:</p>
<pre><code class="language-yaml">services:
  uptime-kuma:
    image: louislam/uptime-kuma:2
    restart: unless-stopped
    volumes:
      - ./data:/app/data
    ports:
      - "3001:3001"
</code></pre>
<p><strong>Note</strong>: The <code>./data:/app/data</code> line is very important. It saves your database in a normal folder on your machine, making it easy to back up later.</p>
<p>Finally, save and exit: Press <code>CTRL + X</code>, then <code>Y</code>, then <code>Enter</code>.</p>
<h2 id="heading-step-3-start-the-application">Step 3: Start the Application</h2>
<p>Now, tell Docker to read your file and start the monitoring service in the background.</p>
<pre><code class="language-shell">docker compose up -d
</code></pre>
<p><strong>How to verify:</strong> Docker will download the files. When it finishes, your terminal should print <code>Started uptime-kuma</code>.</p>
<h2 id="heading-step-4-access-the-dashboard">Step 4: Access the Dashboard</h2>
<p>To access the dashboard, first open your web browser and go to <code>http://localhost:3001</code> (or your machine's local IP address).</p>
<p>When asked to choose the database, select <strong>SQLite</strong>. It's simple, fast, and requires no extra setup.</p>
<p>Then create an account and choose a secure admin username and password.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6729b04417afd6915f5c2e3e/02913589-020e-4a8a-aa7a-1bf70a9244c6.png" alt="02913589-020e-4a8a-aa7a-1bf70a9244c6" style="display:block;margin:0 auto" width="908" height="851" loading="lazy">

<h2 id="heading-step-5-use-case-monitor-a-website-and-send-discord-alerts">Step 5: Use Case – Monitor a Website and Send Discord Alerts</h2>
<p>Now you'll put Uptime Kuma to work by monitoring a live website and setting up an alert. Just follow these steps:</p>
<ol>
<li><p>Click Add New Monitor.</p>
</li>
<li><p>Set the Monitor Type to <code>HTTP(s)</code>.</p>
</li>
<li><p>Give it a Friendly Name (e.g., "My Blog") and enter your website's URL.</p>
</li>
</ol>
<img src="https://cdn.hashnode.com/uploads/covers/6729b04417afd6915f5c2e3e/74567f1e-acc4-480f-b969-7883e01aa459.png" alt="74567f1e-acc4-480f-b969-7883e01aa459" style="display:block;margin:0 auto" width="1918" height="867" loading="lazy">

<h3 id="heading-pro-tip-how-to-fix-down-errors-bot-protection">Pro-Tip: How to Fix "Down" Errors (Bot Protection)</h3>
<p>If your site uses strict security, it might block Uptime Kuma and say your site is "Down" with a 403 Forbidden error.</p>
<p><strong>The Fix:</strong> Scroll down to Advanced, find the User Agent box, and paste this text to make Uptime Kuma look like a normal Chrome browser:</p>
<p><code>Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36</code></p>
<h3 id="heading-add-a-discord-alert">Add a Discord Alert</h3>
<p>To get a message on your phone when your site goes down:</p>
<ol>
<li><p>On the right side of the monitor screen, click Setup Notification.</p>
</li>
<li><p>Select Discord from the dropdown list.</p>
</li>
<li><p>Paste a Discord Webhook URL (you can create one in your Discord server settings under Integrations).</p>
</li>
<li><p>Click Test to receive a test ping, then click Save.</p>
</li>
</ol>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Congratulations! You just took control of your server health. By deploying Uptime Kuma, you replaced an expensive SaaS subscription with a powerful, free monitoring tool that alerts you the second a project goes offline.</p>
<p><strong>Let’s connect!</strong> I am a developer and technical writer specialising in writing step-by-step guides and workflows. You can find my latest projects on my <a href="https://blog.abdultalha.tech/portfolio"><strong>Technical Writing Portfolio</strong></a> or reach out to me directly on <a href="https://www.linkedin.com/in/abdul-talha/"><strong>LinkedIn</strong></a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build a Simple Secure Chat System Using Netcat ]]>
                </title>
                <description>
                    <![CDATA[ In this hands-on tutorial, you'll learn how to harness the power of Netcat to build practical networking tools. We’ll start with basic message transmission. Then you'll progress to creating a file transfer system, and you’ll ultimately develop a secu... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/build-a-simple-secure-chat-system-with-netcat/</link>
                <guid isPermaLink="false">671a491036e11cfa5033debb</guid>
                
                    <category>
                        <![CDATA[ cybersecurity ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Linux ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Netcat ]]>
                    </category>
                
                    <category>
                        <![CDATA[ shell ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Ubuntu ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Hang Hu ]]>
                </dc:creator>
                <pubDate>Thu, 24 Oct 2024 13:18:08 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1729729356682/acf8ca42-3aaa-4ca1-9ebc-10f0f658c678.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this hands-on tutorial, you'll learn how to harness the power of Netcat to build practical networking tools.</p>
<p>We’ll start with basic message transmission. Then you'll progress to creating a file transfer system, and you’ll ultimately develop a secure chat application with encryption.</p>
<p>Here’s what we’ll cover:</p>
<ul>
<li><p><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-install-netcat">Install Netcat</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-your-first-network-connection">Your First Network Connection</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-build-a-simple-file-transfer-tool">How to Build a Simple File Transfer Tool</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-create-a-secure-chat-system">How to Create a Secure Chat System</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-practice-your-skills">Practice Your Skills</a></p>
</li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before we start, you'll need:</p>
<ul>
<li><p>A Linux-based system: I recommend Ubuntu. Alternatively, you can use the <a target="_blank" href="https://labex.io/tutorials/linux-online-linux-playground-372915">Online Linux Terminal</a> if you don't have Linux installed.</p>
</li>
<li><p>Basic terminal knowledge (how to use <code>cd</code> and <code>ls</code>)</p>
</li>
</ul>
<p>Don't worry if you're new to networking - I’ll explain everything as we go!</p>
<h2 id="heading-install-netcat"><strong>Install Netcat</strong></h2>
<p><a target="_blank" href="https://nc110.sourceforge.io/">Netcat</a> is like a digital "pipe" between computers – anything you put in one end comes out the other. Before we start using it, let's get it installed on your system.</p>
<p>Open your terminal and run these commands:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Update your system's package list</span>
sudo apt update

<span class="hljs-comment"># Install Netcat</span>
sudo apt install netcat -y
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729583277378/d5fb06c5-3163-4885-b163-2cdde4fa434b.png" alt="Update your system's package list" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>To check if the installation worked, run:</p>
<pre><code class="lang-bash">nc -h
</code></pre>
<p>You should see a message starting with "OpenBSD netcat". If you do, great! If not, try running the installation commands again.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729583329155/812f32b9-2ca7-41f6-aead-07ffacbf161c.png" alt="check if the installation worked" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h2 id="heading-your-first-network-connection"><strong>Your First Network Connection</strong></h2>
<p>Before we dive into building tools, let's understand what a network connection actually is. Think of it like a phone call: one person needs to wait for the call (the listener), and another person needs to make the call (the connector).</p>
<p>In networking, we use "ports" to make these connections. You can think of ports like different phone lines – they let multiple conversations happen at the same time.</p>
<p>Let's try making our first connection:</p>
<ol>
<li>Open a terminal window and create a listener:</li>
</ol>
<pre><code class="lang-bash">nc -l 12345
</code></pre>
<p>What did we just do? The <code>-l</code> tells Netcat to "listen" for a connection, and <code>12345</code> is the port number we chose. Your terminal will look like it's frozen – that's normal! It's waiting for someone to connect.</p>
<ol start="2">
<li>Open another terminal window and connect to your listener:</li>
</ol>
<pre><code class="lang-bash">nc localhost 12345
</code></pre>
<p>Here, <code>localhost</code> means "this computer" – we're connecting to ourselves for practice. If you want to connect to another computer, you can replace <code>localhost</code> with its IP address.</p>
<p>Now try typing a message (like "hi") in either window and press Enter. Cool, right? The message appears in the other window! This is exactly how basic network communication works.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729583496294/da70a4bc-5626-493c-8a52-385b708593f4.png" alt="making our first connection" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>To stop the connection, press <code>Ctrl+C</code> in both windows.</p>
<h3 id="heading-what-just-happened"><strong>What Just Happened?</strong></h3>
<p>You just created your first network connection! The first terminal was like someone waiting by a phone, and the second terminal was like someone calling that phone. When they connected, they could send messages back and forth.</p>
<h2 id="heading-how-to-build-a-simple-file-transfer-tool"><strong>How to Build a Simple File Transfer Tool</strong></h2>
<p>Now that we understand basic connections, let's build something more useful: a tool to transfer files between computers.</p>
<p>First, let's create a test file to send:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Create a file with some content</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"This is my secret message"</span> &gt; secret.txt
</code></pre>
<p>To transfer this file, we'll need two terminals again, but this time we'll use them differently:</p>
<ol>
<li>In the first terminal, set up the receiver:</li>
</ol>
<pre><code class="lang-bash">nc -l 12345 &gt; received_file.txt
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729583969994/d3159a2f-37f7-4cab-a23b-3788ed85876f.png" alt="transfer file" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>This tells Netcat to:</p>
<ul>
<li><p>Listen for a connection (<code>-l</code>)</p>
</li>
<li><p>Save whatever it receives to a file called <code>received_file.txt</code> (<code>&gt;</code>)</p>
</li>
</ul>
<ol start="2">
<li>In the second terminal, send the file:</li>
</ol>
<pre><code class="lang-bash">nc localhost 12345 &lt; secret.txt
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729583998676/ab865ded-626a-47aa-9df6-83e56aa5f5d1.png" alt="send the file" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>The <code>&lt;</code> tells Netcat to send the contents of our file.</p>
<ol start="3">
<li>Press Ctrl+C in both terminals to stop the transfer. Then check if it worked:</li>
</ol>
<pre><code class="lang-bash">cat received_file.txt
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729584030360/32fa9916-ffdb-49da-abcf-57569c9b2f79.png" alt="received file" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>You should see your message!</p>
<p>This is similar to our chat system, but instead of typing messages, we're:</p>
<ol>
<li><p>Taking content from a file</p>
</li>
<li><p>Sending it through our network connection</p>
</li>
<li><p>Saving it to a new file on the other end</p>
</li>
</ol>
<p>Think of it like sending a document through a fax machine!</p>
<h2 id="heading-how-to-create-a-secure-chat-system"><strong>How to Create a Secure Chat System</strong></h2>
<p>Our previous examples sent everything as plain text – anyone could read it if they intercepted the connection. Let's make something more secure by adding encryption.</p>
<p>First, let's understand what encryption does:</p>
<ul>
<li><p>It's like putting your message in a locked box</p>
</li>
<li><p>Only someone with the right key can open it</p>
</li>
<li><p>Even if someone sees the box, they can't read your message</p>
</li>
</ul>
<p>We'll create two scripts: one for sending messages and one for receiving them.</p>
<ol>
<li>Create the sender script:</li>
</ol>
<pre><code class="lang-bash">nano secure_sender.sh
</code></pre>
<p>Copy this code into the file:</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>

<span class="hljs-built_in">echo</span> <span class="hljs-string">"Secure Chat - Type your messages below"</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"Press Ctrl+C to exit"</span>

<span class="hljs-keyword">while</span> <span class="hljs-literal">true</span>; <span class="hljs-keyword">do</span>
  <span class="hljs-comment"># Get the message</span>
  <span class="hljs-built_in">read</span> message

  <span class="hljs-comment"># Encrypt and send it</span>
  <span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$message</span>"</span> | openssl enc -aes-256-cbc -salt -base64 \
    -pbkdf2 -pass pass:chatpassword 2&gt;/dev/null | \
    nc -N localhost 12345
<span class="hljs-keyword">done</span>
</code></pre>
<p>This script will:</p>
<ol>
<li><p>Read messages from user input.</p>
</li>
<li><p>Encrypt them using OpenSSL's AES-256-CBC encryption (a strong encryption standard).</p>
</li>
<li><p>Send the encrypted message to the specified port.</p>
</li>
</ol>
<p>Press Ctrl+X, then Y, then Enter to save.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729584825701/bcd3c3fb-5cd5-40f7-8105-14d1fff069ec.png" alt="Create the sender script" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<ol start="2">
<li>Create the receiver script:</li>
</ol>
<pre><code class="lang-bash">nano secure_receiver.sh
</code></pre>
<p>Copy this code:</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>

<span class="hljs-built_in">echo</span> <span class="hljs-string">"Waiting for messages..."</span>

<span class="hljs-keyword">while</span> <span class="hljs-literal">true</span>; <span class="hljs-keyword">do</span>
  <span class="hljs-comment"># Receive and decrypt messages</span>
  nc -l 12345 | openssl enc -aes-256-cbc -d -salt -base64 \
    -pbkdf2 -pass pass:chatpassword 2&gt;/dev/null
<span class="hljs-keyword">done</span>
</code></pre>
<p>This script will:</p>
<ol>
<li><p>Listen for incoming encrypted messages.</p>
</li>
<li><p>Decrypt them using the same encryption key.</p>
</li>
<li><p>Display the decrypted messages.</p>
</li>
</ol>
<p>Save this file too.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729584787785/c1e329ad-cbbe-49e8-918f-25d683884972.png" alt="Create the receiver script" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<ol start="3">
<li>Make both scripts executable:</li>
</ol>
<pre><code class="lang-bash">chmod +x secure_sender.sh secure_receiver.sh
</code></pre>
<ol start="4">
<li>Try it out:</li>
</ol>
<ul>
<li><p>In one terminal: <code>./secure_receiver.sh</code></p>
</li>
<li><p>In another terminal: <code>./secure_sender.sh</code></p>
</li>
</ul>
<p>Type a message in the sender terminal. The receiver will show your decrypted message!</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729584834464/1f902a94-3a79-404b-bc9f-af9d8d2471e0.png" alt="Type a message in the sender terminal" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h3 id="heading-enhancing-our-chat-system"><strong>Enhancing Our Chat System</strong></h3>
<p>Now that we have a working basic chat system, let's make it more user-friendly and informative. We'll add features like timestamps, color-coded messages, and encryption status updates. This enhanced version will help you better understand what's happening during the encryption and transmission process.</p>
<p>If you're comfortable with the basic version, try this improved version:</p>
<ol>
<li>Create an enhanced sender script (save it as <code>secure_sender_v2.sh</code>):</li>
</ol>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>

<span class="hljs-comment"># Set up color codes for better visibility</span>
GREEN=<span class="hljs-string">'\033[0;32m'</span>
BLUE=<span class="hljs-string">'\033[0;34m'</span>
NC=<span class="hljs-string">'\033[0m'</span> <span class="hljs-comment"># No Color</span>

<span class="hljs-built_in">echo</span> -e <span class="hljs-string">"<span class="hljs-variable">${GREEN}</span>Secure Chat Sender - Started at <span class="hljs-subst">$(date)</span><span class="hljs-variable">${NC}</span>"</span>
<span class="hljs-built_in">echo</span> -e <span class="hljs-string">"<span class="hljs-variable">${BLUE}</span>Type your messages below. Press Ctrl+C to exit<span class="hljs-variable">${NC}</span>"</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"----------------------------------------"</span>

<span class="hljs-keyword">while</span> <span class="hljs-literal">true</span>; <span class="hljs-keyword">do</span>
    <span class="hljs-comment"># Show prompt with timestamp</span>
    <span class="hljs-built_in">echo</span> -ne <span class="hljs-string">"<span class="hljs-variable">${GREEN}</span>[<span class="hljs-subst">$(date +%H:%M:%S)</span>]<span class="hljs-variable">${NC}</span> Your message: "</span>

    <span class="hljs-comment"># Get the message</span>
    <span class="hljs-built_in">read</span> message

    <span class="hljs-comment"># Skip if message is empty</span>
    <span class="hljs-keyword">if</span> [ -z <span class="hljs-string">"<span class="hljs-variable">$message</span>"</span> ]; <span class="hljs-keyword">then</span>
        <span class="hljs-built_in">continue</span>
    <span class="hljs-keyword">fi</span>

    <span class="hljs-comment"># Add timestamp to message</span>
    timestamped_message=<span class="hljs-string">"[<span class="hljs-subst">$(date +%H:%M:%S)</span>] <span class="hljs-variable">$message</span>"</span>

    <span class="hljs-comment"># Show encryption status</span>
    <span class="hljs-built_in">echo</span> -e <span class="hljs-string">"<span class="hljs-variable">${BLUE}</span>Encrypting and sending message...<span class="hljs-variable">${NC}</span>"</span>

    <span class="hljs-comment"># Encrypt and send it, showing the encrypted form</span>
    encrypted=$(<span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$timestamped_message</span>"</span> | openssl enc -aes-256-cbc -salt -base64 \
        -pbkdf2 -iter 10000 -pass pass:chatpassword 2&gt;/dev/null)

    <span class="hljs-built_in">echo</span> -e <span class="hljs-string">"<span class="hljs-variable">${BLUE}</span>Encrypted form:<span class="hljs-variable">${NC}</span> <span class="hljs-variable">${encrypted:0:50}</span>..."</span> <span class="hljs-comment"># Show first 50 chars</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$encrypted</span>"</span> | nc -N localhost 12345

    <span class="hljs-built_in">echo</span> -e <span class="hljs-string">"<span class="hljs-variable">${GREEN}</span>Message sent successfully!<span class="hljs-variable">${NC}</span>"</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-string">"----------------------------------------"</span>
<span class="hljs-keyword">done</span>
</code></pre>
<ol start="2">
<li>Create an enhanced receiver script (save as <code>secure_receiver_v2.sh</code>):</li>
</ol>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>

<span class="hljs-comment"># Set up color codes for better visibility</span>
GREEN=<span class="hljs-string">'\033[0;32m'</span>
BLUE=<span class="hljs-string">'\033[0;34m'</span>
YELLOW=<span class="hljs-string">'\033[1;33m'</span>
NC=<span class="hljs-string">'\033[0m'</span> <span class="hljs-comment"># No Color</span>

<span class="hljs-built_in">echo</span> -e <span class="hljs-string">"<span class="hljs-variable">${GREEN}</span>Secure Chat Receiver - Started at <span class="hljs-subst">$(date)</span><span class="hljs-variable">${NC}</span>"</span>
<span class="hljs-built_in">echo</span> -e <span class="hljs-string">"<span class="hljs-variable">${BLUE}</span>Waiting for messages... Press Ctrl+C to exit<span class="hljs-variable">${NC}</span>"</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"----------------------------------------"</span>

<span class="hljs-keyword">while</span> <span class="hljs-literal">true</span>; <span class="hljs-keyword">do</span>
    <span class="hljs-comment"># Receive and show the encrypted message</span>
    <span class="hljs-built_in">echo</span> -e <span class="hljs-string">"<span class="hljs-variable">${BLUE}</span>Waiting for next message...<span class="hljs-variable">${NC}</span>"</span>

    encrypted=$(nc -l 12345)

    <span class="hljs-comment"># Skip if received nothing</span>
    <span class="hljs-keyword">if</span> [ -z <span class="hljs-string">"<span class="hljs-variable">$encrypted</span>"</span> ]; <span class="hljs-keyword">then</span>
        <span class="hljs-built_in">continue</span>
    <span class="hljs-keyword">fi</span>

    <span class="hljs-built_in">echo</span> -e <span class="hljs-string">"<span class="hljs-variable">${YELLOW}</span>Received encrypted message:<span class="hljs-variable">${NC}</span> <span class="hljs-variable">${encrypted:0:50}</span>..."</span> <span class="hljs-comment"># Show first 50 chars</span>
    <span class="hljs-built_in">echo</span> -e <span class="hljs-string">"<span class="hljs-variable">${BLUE}</span>Decrypting...<span class="hljs-variable">${NC}</span>"</span>

    <span class="hljs-comment"># Decrypt and display the message</span>
    decrypted=$(<span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$encrypted</span>"</span> | openssl enc -aes-256-cbc -d -salt -base64 \
        -pbkdf2 -iter 10000 -pass pass:chatpassword 2&gt;/dev/null)

    <span class="hljs-comment"># Check if decryption was successful</span>
    <span class="hljs-keyword">if</span> [ $? -eq 0 ]; <span class="hljs-keyword">then</span>
        <span class="hljs-built_in">echo</span> -e <span class="hljs-string">"<span class="hljs-variable">${GREEN}</span>Decrypted message:<span class="hljs-variable">${NC}</span> <span class="hljs-variable">$decrypted</span>"</span>
    <span class="hljs-keyword">else</span>
        <span class="hljs-built_in">echo</span> -e <span class="hljs-string">"\033[0;31mError: Failed to decrypt message<span class="hljs-variable">${NC}</span>"</span>
    <span class="hljs-keyword">fi</span>

    <span class="hljs-built_in">echo</span> <span class="hljs-string">"----------------------------------------"</span>
<span class="hljs-keyword">done</span>
</code></pre>
<ol start="3">
<li>Make the enhanced scripts executable:</li>
</ol>
<pre><code class="lang-bash">chmod +x secure_sender_v2.sh secure_receiver_v2.sh
</code></pre>
<p>Try running both versions to see how the additional feedback helps you better understand the encryption and communication process.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729585592733/01d25154-37a9-4c14-95ac-410c513956b9.png" alt="Enhancing Our Chat System" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>The enhanced version (v2) adds several improvements:</p>
<ul>
<li><p>Colorized output for better readability.</p>
</li>
<li><p>Timestamps for each message.</p>
</li>
<li><p>Status updates showing the encryption/decryption process.</p>
</li>
<li><p>Error handling for failed decryption attempts.</p>
</li>
<li><p>Preview of encrypted messages before sending/after receiving.</p>
</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>This tutorial taught you how to use Netcat as a versatile networking tool. We started with basic message sending, progressed to building a simple file transfer system, and then created a secure chat system with encryption.</p>
<p>You've gained hands-on experience with:</p>
<ul>
<li><p>Setting up network listeners and connections</p>
</li>
<li><p>Transferring files securely between systems</p>
</li>
<li><p>Implementing basic encryption for secure communication</p>
</li>
<li><p>Adding user-friendly features like timestamps and status updates</p>
</li>
</ul>
<p>The skills you've learned here form a solid foundation for understanding network communication and can be applied to more complex networking projects. To practice the operations from this tutorial, try <a target="_blank" href="https://labex.io/labs/linux-using-netcat-for-simple-network-communication-392039">the interactive hands-on lab</a>.</p>
<h2 id="heading-practice-your-skills"><strong>Practice Your Skills</strong></h2>
<p>Now that you've learned the basics of Netcat and built a secure chat system, let's put your skills to the test with a real-world scenario. Try the "<a target="_blank" href="https://labex.io/labs/linux-receive-messages-using-netcat-392102"><strong>Receive Messages Using Netcat</strong></a>" lab challenge where you'll play the role of a junior interstellar communications analyst. Your mission: intercept and log signals from an alien civilization using your newfound Netcat knowledge.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Install NVIDIA CUDA Toolkit on Ubuntu ]]>
                </title>
                <description>
                    <![CDATA[ The NVIDIA Compute Unified Device Architecture (CUDA) Toolkit is a software platform that allows developers to tap into the computing power of NVIDIA processing and GPU-accelerated applications. CUDA is also a programming model and an API that enable... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-install-nvidia-cuda-toolkit-on-ubuntu/</link>
                <guid isPermaLink="false">66d45d58b3016bf139028cf1</guid>
                
                    <category>
                        <![CDATA[ Linux ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Ubuntu ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Abraham Dahunsi ]]>
                </dc:creator>
                <pubDate>Mon, 29 Jan 2024 21:25:58 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/01/Feature-image.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>The NVIDIA Compute Unified Device Architecture (CUDA) Toolkit is a software platform that allows developers to tap into the computing power of NVIDIA processing and GPU-accelerated applications.</p>
<p>CUDA is also a programming model and an API that enables programmers to write code that can run on both the CPU and GPU while also handling data transfer between them.</p>
<p>By using the CUDA Toolkit, you can improve performance, scalability, and efficiency across a range of applications. These include computing, deep learning, computer vision, gaming, and more.</p>
<p>The toolkit supports programming languages like C, C++, Fortran, Python, and Java. It seamlessly integrates with frameworks and libraries such as TensorFlow, PyTorch OpenCV, and cuDNN.</p>
<p>Also, the use of the CUDA Toolkit extends across different domains, such as healthcare finance, robotics, the automotive industry, and entertainment. If you're looking to speed up image processing or natural language processing, enhance cryptography, or advance ray tracing techniques, the CUDA Toolkit empowers you to solve problems faster and more efficiently.</p>
<p>In terms of compatibility, the CUDA Toolkit offers support for Linux distributions, including Ubuntu, Debian, Fedora, CentOS, and OpenSUSE.</p>
<p>In this article, I will guide you through the process of installing the CUDA Toolkit on Ubuntu 22.04, which happens to be the LTS (Long Term Support) version of Ubuntu.</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>To install the CUDA Toolkit on Ubuntu 22.04, you need the following:</p>
<ul>
<li><p><a target="_blank" href="https://developer.nvidia.com/cuda-gpus">A supported NVIDIA GPU with a minimum compute capability of 3.0</a></p>
</li>
<li><p><a target="_blank" href="https://docs.nvidia.com/deploy/cuda-compatibility/">NVIDIA driver compatible with the CUDA Toolkit version</a></p>
</li>
</ul>
<p>In this guide I will be using a <a target="_blank" href="https://docs.paperspace.com/core/compute/machine-types">Paperspace GPU instance</a> with Ubuntu 22.04 LTS operating system.</p>
<p>Please note that you can use any other Cloud Service provider, like Google Cloud and Vultr, or even your own computer, as long as it meets the requirements listed above.</p>
<p>To get started, you'll need to create a new user, like <code>seconduser</code> and then switch to the new user.</p>
<h2 id="heading-install-cuda-toolkit">Install CUDA Toolkit</h2>
<p>You can install CUDA using the release file or alternatively, by using Conda. In this guide, we will be installing CUDA with the release file from the official Toolkit Archive.</p>
<h3 id="heading-step-1-download-the-cuda-release-file">Step 1: Download the CUDA release file.</h3>
<pre><code class="lang-bash"> $ wget https://developer.download.nvidia.com/compute/cuda/12.0.1/local_installers/cuda_12.0.1_525.85.12_linux.run
</code></pre>
<h3 id="heading-step-2-execute-the-release-file">Step 2: Execute the release file.</h3>
<pre><code class="lang-bash"> $ sudo sh cuda_12.0.1_525.85.12_linux.run
</code></pre>
<p>You will be prompted to accept the End User License Agreement, then press <code>Enter</code> to configure your installation.</p>
<p>Once the installation is complete, you should see an output similar to this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/carbon--6-.png" alt="carbon--6-" width="600" height="400" loading="lazy"></p>
<h2 id="heading-configuration-and-verification">Configuration and Verification</h2>
<h3 id="heading-step-1-configure-the-server">Step 1: Configure the server</h3>
<p>Configure the server to work with the CUDA toolkit. Move the CUDA path to the system’s <code>PATH</code>, then add the CUDA Toolkit library path to the <code>LD_LIBRARY_PATH</code> so that the CUDA toolkit link loader will be updated with the location of shared libraries.</p>
<pre><code class="lang-bash">  $ <span class="hljs-built_in">echo</span> <span class="hljs-string">"export PATH=/usr/local/cuda-12.0/bin<span class="hljs-variable">${PATH:+:${PATH}</span>}"</span> &gt;&gt; /home/seconduser/.bashrc
</code></pre>
<pre><code class="lang-bash">  $ <span class="hljs-built_in">echo</span> <span class="hljs-string">"export LD_LIBRARY_PATH=/usr/local/cuda-12.0/lib64<span class="hljs-variable">${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}</span>}"</span> &gt;&gt; /home/seconduser/.bashrc
</code></pre>
<h3 id="heading-step-2-activate-environment">Step 2: Activate Environment</h3>
<p>After configuring the server to work with the CUDA toolkit, activate the environment variable changes so that the system can find and use CUDA.</p>
<pre><code class="lang-bash">$ <span class="hljs-built_in">source</span> /home/seconduser/.bashrc
</code></pre>
<h3 id="heading-step-3-verify-installation">Step 3: Verify Installation</h3>
<pre><code class="lang-bash"> $ nvidia-smi
</code></pre>
<p>Output:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/carbon--7-.png" alt="carbon--7-" width="600" height="400" loading="lazy"></p>
<h3 id="heading-step-4-check-package-installation">Step 4: Check Package Installation.</h3>
<p>Verify that the package from the CUDA Toolkit is successfully installed on your server.</p>
<pre><code class="lang-bash"> $ nvcc --version
</code></pre>
<p>Output:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/carbon--8-.png" alt="carbon--8-" width="600" height="400" loading="lazy"></p>
<h2 id="heading-testing">Testing</h2>
<p>To test your newly installed CUDA programs, you will use some already-made test scripts by CUDA that will allow you to comprehensively verify the compatibility and functionality of your CUDA-enabled environment.</p>
<h3 id="heading-step-1-clone-the-test-scripts-repository">Step 1: Clone the test scripts repository</h3>
<pre><code class="lang-bash"> $ git <span class="hljs-built_in">clone</span> https://github.com/NVIDIA/cuda-samples.git
</code></pre>
<h3 id="heading-step-2-go-to-the-directory-containing-the-devicequery-sample-script">Step 2: Go to the directory containing the deviceQuery sample script.</h3>
<pre><code class="lang-bash"> $ <span class="hljs-built_in">cd</span> cuda-samples/Samples/1_Utilities/deviceQuery
</code></pre>
<h3 id="heading-step-3-compile-the-script">Step 3: Compile the script.</h3>
<pre><code class="lang-bash"> $ make
</code></pre>
<h3 id="heading-step-4-run-the-script">Step 4: Run the script.</h3>
<pre><code class="lang-bash"> $ ./deviceQuery
</code></pre>
<p>Your output should look similar to the one below if your CUDA program ran the script successfully:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/carbon--9-.png" alt="carbon--9-" width="600" height="400" loading="lazy"></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this article, you learned how to install the CUDA Toolkit on Ubuntu 22.04.</p>
<p>Some of the best practices for using CUDA on Ubuntu are:</p>
<ul>
<li><p>Keep your system and NVIDIA drivers up to date to ensure the compatibility and stability of the CUDA Toolkit.</p>
</li>
<li><p>Use the CUDA APT PPA to install and update the CUDA Toolkit easily and quickly.</p>
</li>
<li><p>Use the nvcc compiler options and flags to optimize and debug your CUDA code.</p>
</li>
<li><p>Use the CUDA libraries and tools to enhance and simplify your CUDA development process.</p>
</li>
<li><p>Follow the CUDA coding standards and best practices to write efficient and maintainable CUDA code.</p>
</li>
</ul>
<p>Here are some resources to learn more about CUDA:</p>
<ul>
<li><p><a target="_blank" href="https://docs.nvidia.com/cuda/">CUDA Official Docs</a></p>
</li>
<li><p><a target="_blank" href="https://riptutorial.com/cuda/example/13338/compiling-and-running-the-sample-programs">CUDA Refresher Tutorial</a></p>
</li>
<li><p><a target="_blank" href="https://cuda-tutorial.readthedocs.io/en/latest/tutorials/tutorial01/">Read The Docs: Say Hello to CUDA</a></p>
</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Install Node.js on Ubuntu – Node Linux Installation Guide ]]>
                </title>
                <description>
                    <![CDATA[ If you are a web developer working on the frontend or the backend, you'll want to have Node.js installed on your system.  But if you use the typical sudo apt install nodejs command, it may install a very old version of Node which can be troublesome f... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-install-node-js-on-ubuntu/</link>
                <guid isPermaLink="false">66b902ede26f442bbe4b2770</guid>
                
                    <category>
                        <![CDATA[ Linux ]]>
                    </category>
                
                    <category>
                        <![CDATA[ node ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Ubuntu ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Md. Fahim Bin Amin ]]>
                </dc:creator>
                <pubDate>Fri, 20 Oct 2023 19:29:06 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/10/programming-development-technology-work-at-night-2022-01-19-00-14-46-utc-1.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>If you are a web developer working on the frontend or the backend, you'll want to have <strong>Node.js</strong> installed on your system. </p>
<p>But if you use the typical <code>sudo apt install nodejs</code> command, it may install a very old version of Node which can be troublesome for you.</p>
<p>So you'll want to install a specific version, which requires a different command. This will install the LTS (Long-Term Support) version of Node which is useful for devs because it has a longer period for support. </p>
<p>Today, I am going to show you how you can install the latest LTS version of Node on your Ubuntu operating system. </p>
<p>This processes will work on any kind of Debian-based Linux operating system (Ubuntu, Mint, Zorin, Debian, Elementary OS, and so on). It'll work whether you are using that as your main operating system, secondary operating system on dual boot, WSL on Windows, or using in a virtual machine (VMware Workstation, VirtualBox, and so on).</p>
<h2 id="heading-video-tutorial">Video Tutorial</h2>
<p>I have also created a complete video to show you the process step-by-step. You can watch it here:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/g4Enhyn1o-4" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p>At the time of writing this article, the latest LTS version for Node is 18.18.2.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/Screenshot-2023-10-20-141242.png" alt="Image" width="600" height="400" loading="lazy">
<em>Node download page showing current LTS version</em></p>
<p>When you install Node following the instructions in this article, it will install the latest LTS version of Nodejs automatically. So you'll be safe without any hassle if you simply follow this article and the accompanying video.</p>
<h2 id="heading-update-your-operating-system">Update Your Operating System</h2>
<p>First, you'll want to ensure that you have installed all the updates beforehand. I like to work in the terminal mostly, so I'll install the updates using the terminal directly. </p>
<p>For updating to the latest versions of all the relevant packages, use <code>sudo apt update</code> in the terminal. Use your password when it asks for that.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/Screenshot-2023-10-20-104647.png" alt="Image" width="600" height="400" loading="lazy">
<em>Updating all relevant packages</em></p>
<p>Now use <code>sudo apt upgrade -y</code> to upgrade all the upgradable packages.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/Screenshot-2023-10-20-120347.png" alt="Image" width="600" height="400" loading="lazy">
<em>Upgrading all relevant packages</em></p>
<h2 id="heading-install-curl">Install CURL</h2>
<p>We're using the <strong>Node Version Manager (NVM)</strong> here to install Node. There are various advantages when we install Node and npm using the NVM as it also allows us to manage multiple versions of Node.js on our system altogether. </p>
<p>First, you'll need to install <code>curl</code> if it's not installed on your system already. You can install curl by using the command below:</p>
<pre><code class="lang-bash">sudo apt install curl -y
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/Screenshot-2023-10-20-122355.png" alt="Image" width="600" height="400" loading="lazy">
<em>Installing CURL</em></p>
<h2 id="heading-how-to-install-nodejs">How to Install Node.js</h2>
<p>Now you'll need to follow these steps in order to ensure that you've installed Node.js successfully on your system.</p>
<h3 id="heading-install-node-version-manager-nvm">Install Node Version Manager (NVM)</h3>
<p>Install the Node Version Manager (NVM) by using the following command:</p>
<pre><code class="lang-bash">curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/Screenshot-2023-10-20-122423.png" alt="Image" width="600" height="400" loading="lazy">
<em>Installing the Node Version Manager (NVM)</em></p>
<p>When you run this specific command, the curl downloads the NVM installation script from that specific URL. Afterward, bash executes the same script for installing NVM.</p>
<h3 id="heading-activate-nvm">Activate NVM</h3>
<p>Activate the NVM using the command below:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">source</span> ~/.bashrc
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/Screenshot-2023-10-20-122517.png" alt="Image" width="600" height="400" loading="lazy">
<em>Activating the Node Version Manager (NVM)</em></p>
<h3 id="heading-install-the-latest-lts-version-of-node">Install the latest LTS version of Node</h3>
<p>Install the latest Long Term Support version of Node by using the command below:</p>
<pre><code class="lang-bash">nvm install --lts
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/Screenshot-2023-10-20-122656.png" alt="Image" width="600" height="400" loading="lazy">
<em>Command for installing the latest LTS version of Node.js</em></p>
<p>It installs the latest version of the LTS release of Node by default. </p>
<h3 id="heading-make-the-default-lts-version-as-nvm">Make the default LTS version as NVM</h3>
<p>We have installed the latest LTS version of Node, but we also need to set the default version of NVM so that it gets used by default whenever we need it. You can use the command below to do that. Make sure to change the version to the exact LTS version you have installed on your system just now. </p>
<pre><code class="lang-bash">nvm <span class="hljs-built_in">alias</span> default 18.18.2
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/Screenshot-2023-10-20-122842.png" alt="Image" width="600" height="400" loading="lazy">
<em>Selecting the appropriate Node version as the default version</em></p>
<p>If your LTS version is something like <code>24.1.2</code> then the command would be like below:</p>
<pre><code class="lang-bash">nvm <span class="hljs-built_in">alias</span> default 24.1.2
</code></pre>
<h3 id="heading-confirm-that-node-was-installed">Confirm that Node was installed</h3>
<p>Use the command below to check whether the default version is the exact version you just installed:</p>
<pre><code class="lang-bash">node -v npm -v
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/Screenshot-2023-10-20-122937.png" alt="Image" width="600" height="400" loading="lazy">
<em>Showing the current version of Node installed</em></p>
<h2 id="heading-how-to-set-up-the-nodejs-environment">How to Set Up the Node.js Environment</h2>
<p>After installing Node and NPM, you need to set up the Node environment by creating a new Node project.</p>
<p>Use the command below to create a new directory/folder where you want to test a simple "Hello World" type Node project.</p>
<pre><code class="lang-bash">mkdir my-node-project
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/Screenshot-2023-10-20-123101.png" alt="Image" width="600" height="400" loading="lazy">
<em>Creating a new directory/folder to test a simple "Hello World" program on Node</em></p>
<p>Navigate to the <code>my-node-project</code> directory by using the command below:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">cd</span> my-node-project
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/Screenshot-2023-10-20-123148.png" alt="Image" width="600" height="400" loading="lazy">
<em>Changing the directory to enter into that newly created directory/folder</em></p>
<p>Initialize the new Node project like this:</p>
<pre><code class="lang-bash">npm init -y
</code></pre>
<p>This command will create a "package.json" file containing your project's metadata and dependencies. Here is the JSON output:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/Screenshot-2023-10-20-123304-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Initializing npm in the folder</em></p>
<p>The JSON output is below:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"name"</span>: <span class="hljs-string">"my-node-project"</span>,
  <span class="hljs-attr">"version"</span>: <span class="hljs-string">"1.0.0"</span>,
  <span class="hljs-attr">"description"</span>: <span class="hljs-string">""</span>,
  <span class="hljs-attr">"main"</span>: <span class="hljs-string">"index.js"</span>,
  <span class="hljs-attr">"scripts"</span>: {
    <span class="hljs-attr">"test"</span>: <span class="hljs-string">"echo \"Error: no test specified\" &amp;&amp; exit 1"</span>
  },
  <span class="hljs-attr">"keywords"</span>: [],
  <span class="hljs-attr">"author"</span>: <span class="hljs-string">""</span>,
  <span class="hljs-attr">"license"</span>: <span class="hljs-string">"ISC"</span>
}
</code></pre>
<p>Now run the setup with the simple command. For this, I am going to create a new file called <code>app.js</code> using the <strong>nano</strong> text editor in the terminal.</p>
<pre><code class="lang-bash">sudo nano app.js
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/Screenshot-2023-10-20-123550.png" alt="Image" width="600" height="400" loading="lazy">
<em>Opening app.js file in nano</em></p>
<p>Once the text editor opens, type the below code:</p>
<pre><code class="lang-bash">console.log(<span class="hljs-string">"Hello, Node.js from Ubuntu!"</span>);
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/Screenshot-2023-10-20-123710.png" alt="Image" width="600" height="400" loading="lazy">
<em>Writing a simple console.log code in the app.js file using nano</em></p>
<p>Use <code>Ctrl</code>+ <code>O</code> to save the file. Use <code>Enter</code> to save the file as <code>app.js</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/Screenshot-2023-10-20-123831.png" alt="Image" width="600" height="400" loading="lazy">
<em>Save the app.js file with the newly added line of code</em></p>
<p>Use <code>Ctrl</code> + <code>X</code> to return to the bash terminal again.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/Screenshot-2023-10-20-123907.png" alt="Image" width="600" height="400" loading="lazy">
<em>Returning to the terminal again</em></p>
<p>Now, it is time to check the output and see whether it's working or not.</p>
<p>Use the command below:</p>
<pre><code class="lang-bash">node app.js
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/10/Screenshot-2023-10-20-124010.png" alt="Image" width="600" height="400" loading="lazy">
<em>Running the app.js file using Node</em></p>
<p>It is working!</p>
<p>We have successfully installed the latest LTS release of Node on our Ubuntu/Debian-based Linux operating system.</p>
<p>Cheers! 🥂</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Thank you so much for reading the entire article till now.</p>
<p>If you have enjoyed the procedures step-by-step, then don't forget to let me know on <a target="_blank" href="https://twitter.com/Fahim_FBA">Twitter/X</a> or <a target="_blank" href="https://www.linkedin.com/in/fahimfba/">LinkedIn</a>.</p>
<p>You can follow me on <a target="_blank" href="https://github.com/FahimFBA">GitHub</a> as well if you are interested in open source. Make sure to check <a target="_blank" href="https://fahimbinamin.com/">my website</a> (<a target="_blank" href="https://fahimbinamin.com/">https://fahimbinamin.com/</a>) as well! </p>
<p>If you like to watch programming and technology-related videos, then you can check my <a target="_blank" href="https://www.youtube.com/@FahimAmin?sub_confirmation=1">YouTube channel</a>, too.</p>
<p>All the best for your programming and development journey. 😊</p>
<p>You can do it! Don't give up, never! ❤️</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Install Java in Ubuntu – JDK Linux Tutorial ]]>
                </title>
                <description>
                    <![CDATA[ Installing software on Linux is usually easier, or at least that's what it seems like. But this is usually not the case as we've come to a realization that installing and configuring some specific tools on Linux might be more time-consuming than on W... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-install-java-in-ubuntu/</link>
                <guid isPermaLink="false">66b902e53639976bd84355b7</guid>
                
                    <category>
                        <![CDATA[ Java ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Linux ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Ubuntu ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Md. Fahim Bin Amin ]]>
                </dc:creator>
                <pubDate>Thu, 07 Sep 2023 19:05:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/09/How-to-Install-Java-in-Ubuntu---JDK-Linux-Tutorial.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Installing software on Linux is usually easier, or at least that's what it seems like. But this is usually not the case as we've come to a realization that installing and configuring some specific tools on Linux might be more time-consuming than on Windows or MacOS.</p>
<p>An example of this can be seen when you want to install the latest version of Java on Ubuntu and make it your default Java version. Yes, I know that you're wondering about other Linux distributions like Fedora or Arch, and so on, but each distribution has some specific advantages and disadvantages over others.</p>
<p>Ubuntu is one of the most commonly used Linux distributions, and most people who would like to try out the Linux operating system for the first time usually start their Linux journey with Ubuntu.</p>
<p>However, if you're a Java developer who is migrating from a Windows machine to an Ubuntu based Linux machine, you might find it tedious to configure the latest version of Java on Ubuntu as opposed to Windows where you simply have to download and install the latest version, and add the directory to the path variable.</p>
<p>In this article, I will cover everything you need to know and do to configure your Ubuntu operating system for Java development. I will explain each of the processes with appropriate screenshots and test runs. </p>
<p>I have also created a full-length video showing all of the procedures. You can find the video at the end of this article. By the way, if you're wondering, "Hey Fahim! Who told you that installing Java on Windows is easier?", then you should probably check out my article on <a target="_blank" href="https://www.freecodecamp.org/news/how-to-install-java-on-windows/">how to install Java on Windows</a>.</p>
<h2 id="heading-how-to-check-java-version-on-ubuntu">How to Check Java Version on Ubuntu</h2>
<p>Before proceeding further, you might want to check whether you already have Java installed on your Ubuntu.</p>
<p>You can do this using the terminal. If it returns any version, then that means a version of Java is already installed on your machine. But if it returns something different, then we can assume that you do not have Java installed or it is not configured correctly.</p>
<p>Simply open your terminal. You can also use the shortcut keys for opening the terminal on Ubuntu: <code>Ctrl</code> + <code>Alt</code> + <code>T</code></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/2023-08-16_01-38.png" alt="Image" width="600" height="400" loading="lazy">
<em>Open the terminal</em></p>
<p>Then run the command: <code>java --version</code></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/2023-08-18_00-00.png" alt="Image" width="600" height="400" loading="lazy">
<em>java --version</em></p>
<p>If it says "java not found" (like you see in the image above), then you can be sure that your system does not have Java installed.</p>
<p>But if it returns any version of Java or JDK (Java Development Kit), then Java is already installed on your machine. Based on the installed version and your need for the other versions, you can remove the older one and install the newer version or you can keep both of them and make one version the default version.</p>
<h2 id="heading-how-to-install-java-on-ubuntu">How to Install Java On Ubuntu</h2>
<p>There are many ways to install Java on Ubuntu. You can use the CLI (Command Line Interface) where you will install via the terminal, or you can download the package and install it using GUI (Graphical User Interface). </p>
<p>In this article, I am going to show you how you can download the latest Java from <a target="_blank" href="https://www.oracle.com/">Oracle</a> and install it on your Ubuntu machine. But that, you have to choose between installing the JRE (Java Runtime Environment) or the JDK (Java Development Kit) version for Java.</p>
<p>If you don't understand the differences between them or which one you need for your tasks, then here is a comparison for you:</p>
<h2 id="heading-jdk-vs-jre-in-java">JDK vs JRE in Java</h2>
<p>Here are some differences between JDK and JRE in Java:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>JDK</td><td>JRE</td></tr>
</thead>
<tbody>
<tr>
<td>It is used to develop Java applications and contains development tools like debuggers.</td><td>It is used only to execute Java programs.</td></tr>
<tr>
<td>As it is a complete package for Java development, it contains almost everything you might need as a Java developer.</td><td>It is mainly used for end users, who do not develop Java applications but only run Java applications as software or tools in their systems.</td></tr>
<tr>
<td>As it is responsible for Java development, you will get all of the development and debugging tools you need as a Java developer.</td><td>If you only want something lightweight, only to run Java applications, then it is the right choice for you. But keep in mind that it doesn't contain any tools like compilers, debuggers, or any other necessary development or debugging features in it. The sole purpose of it is to support the files required for executing them on the end systems.</td></tr>
</tbody>
</table>
</div><p>If you are a developer, then you should install the JDK instead of the JRE. On the other hand, if you are just a normal user who will not program or write code at all, you can install the JRE.</p>
<p>In this article, we'll be installing the JDK version because that covers everything. If you already have a JDK then you do not need to install JRE separately.</p>
<h2 id="heading-how-to-update-ubuntu">How to Update Ubuntu</h2>
<p>Before we install Java, we need to ensure that we've installed all the necessary updates for the Ubuntu operating system. </p>
<p>To update the your Ubuntu OS, simply use the <code>sudo apt update</code> command . Then provide your password and hit the enter key.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/2023-08-18_01-24.png" alt="Image" width="600" height="400" loading="lazy">
<em>Update the system</em></p>
<p>After updating, if you get a message that says something needs to be upgraded then you can upgrade them using <code>sudo apt upgrade</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/2023-08-18_01-25.png" alt="Image" width="600" height="400" loading="lazy">
<em>23 packages can be upgraded on my system right now. In your case, it might be different.</em></p>
<p>Make sure to press "y" or "Y" while upgrading.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/2023-08-18_01-27.png" alt="Image" width="600" height="400" loading="lazy">
<em>Upgrading the system</em></p>
<p>The upgrade might take some time depending on the file sizes that it needs to download and your internet speed.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/2023-08-18_01-31.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Make sure that everything has been upgraded without creating any errors.</p>
<h2 id="heading-how-to-download-oracle-jdk">How to Download Oracle JDK</h2>
<p>You can download the official JDK from <a target="_blank" href="https://www.oracle.com/">Oracle website</a>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/2023-09-05_22-00.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Once the landing page loads, click on <strong>Products</strong> on the top navigation bar:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/image-43.png" alt="Image" width="600" height="400" loading="lazy">
<em>Oracle website navigation options</em></p>
<p>Then click <strong>Java</strong> under the <strong>Hardware and Software</strong> section.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/image-45.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Click <strong>Download Java</strong>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/image-46.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Here, you will get all the latest JDK files. For development purposes, it is recommended to use the LTS (Long Term Support) versions as they receive stable version updates for an extended period.</p>
<p>I am going to install the JDK 20 version (which is the latest version as of the time of writing this article). It is not the LTS version of course, but if you follow through with this article, then you'll be able to install any version you want swiftly!</p>
<p>In your case, I would recommend installing the latest LTS version of JDK. But if you want continuous access to latest JDK features (these features might not be stable), then you can download the latest JDK.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/image-47.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>To download, select <strong>Linux</strong> in the operating system section and download the file for <strong>x64 Debian Package</strong>. Clicking on the download link will start the download for the Debian package file.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/image-48.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Depending on your internet speed, it can take a shorter or longer amount of time. As I am writing this article at night and my internet speed remains slow at night, it is taking longer to download the package file in my system. </p>
<h2 id="heading-how-to-install-the-jdk">How to Install the JDK</h2>
<p>I have downloaded the package file using the Mozilla Firefox browser and by default, it downloads files in the <strong>Downloads</strong> directory. </p>
<p>Simply go to the directory where you downloaded the file and open the terminal there.</p>
<p>Usually, if you go into any directory and right-click, you will see a context menu that says <strong>Open in Terminal</strong>. By using that, you can open your terminal in that directory.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/2023-09-05_23-01.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Alternatively, if you open the terminal elsewhere, you can use the <code>cd</code> command to go into any specific directory. </p>
<p>For example, I have opened my terminal elsewhere. I am using the <code>cd</code> command to go into my <strong>Downloads</strong> directory as can be seen in the image below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/2023-09-05_23-03.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You can use the <code>ls</code> command to see all the files and folders available on a particular directory:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/2023-09-05_23-04.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>After downloading the file, you will see that the file name also contains the version name which is necessary, but if you think that would be troublesome to type later on, you can shorten the filename as well.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/2023-09-05_23-06.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>For this article, we'll use the default filename.</p>
<p>Grab the full directory path where the JDK package file is downloaded. You can use the shortcut <code>Ctrl</code> + <code>L</code> to display the whole directory path.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/2023-09-05_23-07.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>For me, the current directory path where my JDK Debian file is located is <code>/home/fahim/Downloads/</code>. Make sure to copy the address.</p>
<p>Next, open the terminal. You can do that using the shortcut <code>Ctrl</code> + <code>Alt</code> + <code>T</code>.</p>
<p>I like to install the JDK using the terminal, but if you can also install it using the GUI (Graphical User Interface). But I recommend using the terminal as that would also help you debug any issues you face during installation.</p>
<p>Use the <code>sudo apt install /home/fahim/Downloads/jdk_filename.deb</code> command to start the installation. For me, the entire command is <code>sudo apt install /home/fahim/Downloads/jdk-20_linux-x64_bin.deb</code>.</p>
<p>Hit the enter key:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/2023-09-05_23-11.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Input your password and type "y" when it asks for your permission to install the package.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/2023-09-05_23-12.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Make sure that you have successfully installed the package before proceeding to the next step.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/2023-09-05_23-13.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You might get <code>N: Download is performed unsandboxed as root as file '/home/fahim/Downloads/jdk-20_linux-x64_bin.deb' couldn't be accessed by user '_apt'. - pkgAcquire::Run (13: Permission denied)</code>. But don't worry about that because we performed the installation "unsandboxed" intentionally. </p>
<p>You will not face any problems if you use the Debian package downloaded from the right source.</p>
<p>You can clear the terminal using the command <code>clear</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/2023-09-05_23-15.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-configure-java-in-ubuntu">How to Configure Java in Ubuntu</h2>
<p>We need to make sure that if it updates, it does not download any downgraded version of Java.</p>
<p>You can do that using the <code>sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/jdk-version/bin/java 1</code> command.</p>
<p>Since I'm using the "JDK - 20" version, my command would be <code>sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/jdk-20/bin/java 1</code>.</p>
<p>Make sure to change the <code>jdk-version</code> to match your installed JDK version.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/2023-09-05_23-18.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>We need to do the same thing for the <code>javac</code> (Java Compiler) version as well. The command would be <code>sudo update-alternatives --install /usr/bin/javac javac /usr/lib/jvm/jdk-version/bin/javac 1</code>.</p>
<p>My command would look like this: <code>sudo update-alternatives --install /usr/bin/javac javac /usr/lib/jvm/jdk-20/bin/javac 1</code>.</p>
<p>Remember to change the <code>jdk-version</code> to match your installed JDK version.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/2023-09-05_23-20.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>We'll also do the same for <code>jar</code>. JAR is essential for running Java based applications directly in the system.</p>
<p>The command would be <code>sudo update-alternatives --install /usr/bin/jar jar /usr/lib/jvm/jdk-version/bin/jar 1</code>.</p>
<p>My command would look like this: <code>sudo update-alternatives --install /usr/bin/jar jar /usr/lib/jvm/jdk-20/bin/jar 1</code>.</p>
<p>Then change the <code>jdk-version</code> to match your installed JDK version.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/2023-09-05_23-23.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>This is all for most of the cases. You are good to go!</p>
<p>But if you face any kind of problems, then check the complete video provided below. In that video, I talked about a lot of possible issues and how to solve them. If you have multiple Java versions installed on your system, then you need to make one of them the default. This is also covered in the video.</p>
<p>Also, if you want to make more modifications, then the video is going to help you with that as well. But for most of the users, this article is everything that you need to install Java on your Ubuntu operating system.</p>
<h2 id="heading-video-walkthrough">Video Walkthrough</h2>
<p>Check the complete video for troubleshooting any more issues or if you want to make more modifications.</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/amk1hIeDK9c" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>I hope you have enjoyed this article and are able to install Java on your Ubuntu operating system.</p>
<p>If you have any questions then please let me know by reaching out on <a target="_blank" href="https://twitter.com/Fahim_FBA">Twitter</a> or <a target="_blank" href="https://www.linkedin.com/in/fahimfba/">LinkedIn</a>.</p>
<p>You can also follow me on:<br>🎁GitHub: <a target="_blank" href="https://github.com/FahimFBA">FahimFBA</a><br>🎁YouTube: <a target="_blank" href="https://www.youtube.com/@FahimAmin?sub_confirmation=1">@FahimAmin</a></p>
<p>If you are interested then you can also check my website: <a target="_blank" href="https://fahimbinamin.com/">https://fahimbinamin.com/</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Setting a Static IP in Ubuntu – Linux IP Address Tutorial ]]>
                </title>
                <description>
                    <![CDATA[ In most network configurations, the router DHCP server assigns the IP address dynamically by default. If you want to ensure that your system IP stays the same every time, you can force it to use a static IP.  That's what we will learn in this article... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/setting-a-static-ip-in-ubuntu-linux-ip-address-tutorial/</link>
                <guid isPermaLink="false">66adea771ad24d82983fd255</guid>
                
                    <category>
                        <![CDATA[ computer network ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Linux ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Ubuntu ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Zaira Hira ]]>
                </dc:creator>
                <pubDate>Thu, 02 Mar 2023 21:24:59 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/03/setting-static-ip-ubuntu.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In most network configurations, the router DHCP server assigns the IP address dynamically by default. If you want to ensure that your system IP stays the same every time, you can force it to use a static IP. </p>
<p>That's what we will learn in this article. We will explore two ways to set a static IP in Ubuntu.</p>
<p>Static IP addresses find their use in the following situations:</p>
<ul>
<li>Configuring port forwarding.</li>
<li>Configuring your system as a server such as an FTP server, web server, or a media server.</li>
</ul>
<p><strong>Pre-requisites:</strong></p>
<p>To follow this tutorial you will need the following:</p>
<ul>
<li>Ubuntu installation, preferably with a GUI.</li>
<li><code>sudo</code> rights as we will be modifying system configuration files.</li>
</ul>
<h2 id="heading-how-to-set-a-static-ip-using-the-command-line">How to Set a Static IP Using the Command Line</h2>
<p>In this section, we will explore all the steps in detail needed to configure a static IP.</p>
<h3 id="heading-step-1-launch-the-terminal">Step 1: Launch the terminal</h3>
<p>You can launch the terminal using the shortcut <code>Ctrl+ Shift+t</code>. </p>
<h3 id="heading-step-2-note-information-about-the-current-network">Step 2: Note information about the current network</h3>
<p>We will need our current network details such as the current assigned IP, subnet mask, and the network adapter name so that we can apply the necessary changes in the configurations.</p>
<p>Use the command below to find details of the available adapters and the respective IP information.</p>
<pre><code class="lang-bash">ip a
</code></pre>
<p>The output will look something like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/image-14.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>For my network, the current adapter is <code>eth0</code>. It could be different for your system</p>
<ul>
<li><strong>Note the current network adapter name</strong></li>
</ul>
<p>As my current adapter is <code>eth0</code>, the below details are relevant.</p>
<pre><code class="lang-bash">6: eth0: &lt;BROADCAST,MULTICAST,UP,LOWER_UP&gt; mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:15:5d:df:c3:ad brd ff:ff:ff:ff:ff:ff
    inet 172.23.199.129/20 brd 172.23.207.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::215:5dff:fedf:c3ad/64 scope link
       valid_lft forever preferred_lft forever
</code></pre>
<p>It is worth noting that the current IP <code>172.23.199.129</code> is dynamically assigned. It has <code>20</code> bits reserved for the netmask. The broadcast address is <code>172.23.207.255</code>.</p>
<ul>
<li><strong>Note the subnet</strong></li>
</ul>
<p>We can find the subnet mask details using the command below:</p>
<pre><code class="lang-bash">ifconfig -a
</code></pre>
<p>Select the output against your adapter and read it carefully.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/image-15.png" alt="Image" width="600" height="400" loading="lazy">
<em>IP is <code>172.23.199.129</code> and subnet mask is <code>255.255.240.0</code></em></p>
<p>Based on the class and subnet mask, the usable host IP range for my network is: <code>172.23.192.1 - 172.23.207.254</code>.</p>
<p>Subnetting is a vast topic. For more info on subnetting and your usable IP ranges, check out this <a target="_blank" href="https://www.freecodecamp.org/news/subnet-cheat-sheet-24-subnet-mask-30-26-27-29-and-other-ip-address-cidr-network-references/">article</a>.</p>
<h3 id="heading-step-3-make-configuration-changes">Step 3: Make configuration changes</h3>
<p><a target="_blank" href="https://netplan.io/">Netplan</a> is the default network management tool for the latest Ubuntu versions. Configuration files for Netplan are written using YAML and end with the extension <code>.yaml</code>.</p>
<p>Note: Be careful about spaces in the configuration file as they are part of the syntax. Without proper indentation, the file won't be read properly.</p>
<ul>
<li>Go to the <code>netplan</code> directory located at <code>/etc/netplan</code>.</li>
</ul>
<p><code>ls</code> into the <code>/etc/netplan</code> directory.</p>
<p>If you do not see any files, you can create one. The name could be anything, but by convention, it should start with a number like <code>01-</code> and end with <code>.yaml</code>. The number sets the priority if you have more than one configuration file. </p>
<p>I'll create a file named <code>01-network-manager-all.yaml</code>. </p>
<p>Let's add these lines to the file. We'll build the file step by step.</p>
<pre><code class="lang-bash">network:
 version: 2
</code></pre>
<p>The top-level node in a Netplan configuration file is a <code>network:</code> mapping that contains <code>version: 2</code> (means that it is using network definition version 2).</p>
<p>Next, we'll add a renderer, that controls the overall network. The renderer is <code>systemd-networkd</code> by default, but we'll set it to <code>NetworkManager</code>.</p>
<p>Now, our file looks like this:</p>
<pre><code class="lang-bash">network:
 version: 2
 renderer: NetworkManager
</code></pre>
<p>Next, we'll add <code>ethernets</code> and refer to the network adapter name we looked for earlier in step#2. Other device types supported are <code>modems:</code>, <code>wifis:</code>, or <code>bridges:</code>.</p>
<pre><code class="lang-bash">network:
 version: 2
 renderer: NetworkManager
 ethernets:
   eth0:
</code></pre>
<p>As we are setting a static IP and we do not want to dynamically assign an IP to this network adapter, we'll set <code>dhcp4</code> to <code>no</code>.</p>
<pre><code class="lang-bash">network:
 version: 2
 renderer: NetworkManager
 ethernets:
   eth0:
     dhcp4: no
</code></pre>
<p>Now we'll specify the specific static IP we noted in step #2 depending on our subnet and the usable IP range. It was <code>172.23.207.254</code>.</p>
<p>Next, we'll specify the gateway, which is the router or network device that assigns the IP addresses. Mine is on <code>192.168.1.1</code>.</p>
<pre><code class="lang-bash">network:
 version: 2
 renderer: NetworkManager
 ethernets:
   eth0:
     dhcp4: no
     addresses: [172.23.207.254/20]
     gateway4: 192.168.1.1
</code></pre>
<p>Next, we'll define <code>nameservers</code>. This is where you define a DNS server or a second DNS server. Here the first value is  <code>8.8.8.8</code> which is Google's primary DNS server and the second value is <code>8.8.8.4</code> which is Google's secondary DNS server. These values can vary depending on your requirements.</p>
<pre><code class="lang-bash">network:
 version: 2
 renderer: NetworkManager
 ethernets:
   eth0:
     dhcp4: no
     addresses: [172.23.207.254/20]
     gateway4: 192.168.1.1
     nameservers:
         addresses: [8.8.8.8,8.8.8.4]
</code></pre>
<h3 id="heading-step-4-apply-and-test-the-changes">Step 4: Apply and test the changes</h3>
<p>We can test the changes first before permanently applying them using this command:</p>
<pre><code class="lang-bash">sudo netplan try
</code></pre>
<p>If there are no errors, it will ask if you want to apply these settings.</p>
<p>Now, finally, test the changes with the command <code>ip a</code> and you'll see that the static IP has been applied.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/image-17.png" alt="Image" width="600" height="400" loading="lazy">
<em>Static IP applied</em></p>
<h2 id="heading-how-to-set-a-static-ip-using-the-gui">How to Set a Static IP Using the GUI</h2>
<p>It is very easy to set a static IP through the Ubuntu GUI/ Desktop. Here are the steps:</p>
<ul>
<li>Search for <code>settings</code>.</li>
<li>Click on either Network or Wi-Fi tab, depending on the interface you would like to modify.</li>
<li>To open the interface settings, click on the gear icon next to the interface name.</li>
<li>Select “Manual” in the IPV4 tab and enter your static IP address, Netmask and Gateway. </li>
<li>Click on the <code>Apply</code> button.</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/image-16.png" alt="Image" width="600" height="400" loading="lazy">
<em>Manually setting a static IP using Ubuntu Desktop.</em></p>
<ul>
<li>Verify by using the command <code>ip a</code></li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/image-18.png" alt="Image" width="600" height="400" loading="lazy">
<em>Static IP updated via GUI</em></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this article, we covered two methods to set the static IP in Ubuntu. I hope you found the article useful.</p>
<p>What’s your favorite thing you learned from this tutorial? Let me know on <a target="_blank" href="https://twitter.com/hira_zaira">Twitter</a>!</p>
<p>You can read my other posts <a target="_blank" href="https://www.freecodecamp.org/news/author/zaira/">here</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Install Java in Ubuntu – JDK Linux Tutorial ]]>
                </title>
                <description>
                    <![CDATA[ By Sebastian Sigl Java is one of the most popular programming languages in use today. And a clean setup lets you seamlessly install Java and switch between different versions when you're building applications.  In this tutorial you will learn how to:... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-install-java-in-ubuntu-jdk-linux-tutorial/</link>
                <guid isPermaLink="false">66d460f8182810487e0ce1ae</guid>
                
                    <category>
                        <![CDATA[ Java ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Linux ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Ubuntu ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 28 Jun 2022 19:21:28 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/06/how-to-install-java.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Sebastian Sigl</p>
<p>Java is one of the most popular programming languages in use today. And a clean setup lets you seamlessly install Java and switch between different versions when you're building applications. </p>
<p>In this tutorial you will learn how to:</p>
<ul>
<li>Install any Java version,</li>
<li>Switch between Java versions,</li>
<li>Update to the newest Java version.</li>
</ul>
<p>The provided guide should work for most operating systems. I tested it for the following Linux versions:</p>
<ul>
<li>Ubuntu</li>
<li>Debian</li>
<li>MacOS</li>
</ul>
<h2 id="heading-java-development-kit">Java Development Kit</h2>
<blockquote>
<p>The Java Development Kit (JDK) is a development environment for building applications, applets, and components using the Java programming language. (<a target="_blank" href="https://www.oracle.com/java/technologies/javase/jdk-jdk-7-readme.html">Source</a>)</p>
</blockquote>
<p>The JDK contains different applications, including</p>
<blockquote>
<p><code>javac</code>, the <a target="_blank" href="https://en.wikipedia.org/wiki/Java_compiler">Java compiler</a>, which converts source code into <a target="_blank" href="https://en.wikipedia.org/wiki/Java_bytecode">Java bytecode</a>.  </p>
<p><code>java</code>, the <a target="_blank" href="https://en.wikipedia.org/wiki/Loader_(computing)">loader</a> for Java applications. This tool is an interpreter and can interpret the class files generated by the <a target="_blank" href="https://en.wikipedia.org/wiki/Javac">javac</a> compiler.   </p>
<p>Now a single launcher is used for both development and deployment. The old deployment launcher, jre, no longer comes with Sun JDK, and instead it has been replaced by this new java loader. (<a target="_blank" href="https://www.javatpoint.com/jdk">Source</a>)</p>
</blockquote>
<p>Java Build tools (Maven, Gradle, and so on) and your code editors use Java applications behind the scenes to give developers a nice experience running, creating, and maintaining applications.</p>
<p>Let’s see how to install Java in a Linux environment using the terminal. This enables you to use the steps in your own Linux environment and in many remote environments.</p>
<h2 id="heading-how-to-use-sdkman-to-manage-java-versions">How to Use SDKMan to Manage Java Versions</h2>
<blockquote>
<p>SDKMAN! is a tool for managing parallel versions of multiple Software Development Kits on most Unix based systems. It provides a convenient Command Line Interface (CLI) and API for installing, switching, removing and listing Candidates. (<a target="_blank" href="https://sdkman.io/">Source</a>)</p>
</blockquote>
<p>SDKMan comes with its own installer, which supports many operation systems. Make sure you install curl before, and execute the installer script after.</p>
<h3 id="heading-how-to-install-sdkman-on-ubuntu-22">How to Install SDKMan on Ubuntu 22</h3>
<pre><code class="lang-sh"><span class="hljs-comment"># install curl</span>
$ sudo apt install curl

<span class="hljs-comment"># install sdkman</span>
$ curl -s <span class="hljs-string">"https://get.sdkman.io"</span> | bash
</code></pre>
<h3 id="heading-how-to-install-sdkman-on-debian-11">How to Install SDKMan on Debian 11</h3>
<pre><code class="lang-sh"><span class="hljs-comment"># login as root</span>
$ su

<span class="hljs-comment"># install curl</span>
$ apt install curl zip

<span class="hljs-comment"># exit root user session</span>
$ <span class="hljs-built_in">exit</span>

<span class="hljs-comment"># install sdkman</span>
$ curl -s <span class="hljs-string">"https://get.sdkman.io"</span> | bash
</code></pre>
<h3 id="heading-how-to-install-sdkman-on-macos">How to Install SDKMan on MacOS</h3>
<p>In case you don’t have brew and curl yet on Mac, you need to install them to easily install and update sdkman.</p>
<pre><code class="lang-sh"><span class="hljs-comment"># install brew package manager)</span>
$ /bin/bash -c <span class="hljs-string">"<span class="hljs-subst">$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)</span>"</span>

<span class="hljs-comment"># install curl</span>
$ brew install curl

<span class="hljs-comment"># install sdkman</span>
$ curl -s <span class="hljs-string">"https://get.sdkman.io"</span> | bash
</code></pre>
<p>Now, close and reopen your terminal to use sdkman.</p>
<pre><code class="lang-sh"><span class="hljs-comment"># print sdkman version to verify installation</span>
$ sdk versionSDKMAN 5.15.0

<span class="hljs-comment"># install latest java</span>
$ sdk install java

<span class="hljs-comment"># check your java installation and print your java’s version</span>
$ java –version

Openjdk version <span class="hljs-string">"17.0.3"</span> 2022-04-19OpenJDK Runtime Environment Temurin-17.0.3+7 (build 17.0.3+7)OpenJDK 64-Bit Server VM Temurin-17.0.3+7 (build 17.0.3+7, mixed mode, sharing)

<span class="hljs-comment"># Show path to current java version$ which java/home/sesigl/.sdkman/candidates/java/current/bin/java</span>
</code></pre>
<p>Now, you are ready to use Java.</p>
<h2 id="heading-how-to-install-multiple-java-versions">How to Install Multiple Java Versions</h2>
<p>It is very useful to install multiple Java versions. Maybe certain applications require an older version of Java. Or you want to play with a brand new Java version and easily switch back. </p>
<p>Next, you additionally install Java 18:</p>
<pre><code class="lang-sh">$ sdk install java 18.0.1-tem
Done installing!

Do you want java 18.0.1-tem to be <span class="hljs-built_in">set</span> as default? (Y/n): n
</code></pre>
<p>By typing <code>n</code>,  it means that you do not want to use Java 18 as your default version. You can manually enable versions temporarily in your shell by executing <code>sdk use java &lt;version&gt;</code>.</p>
<pre><code class="lang-sh">$ sdk use java 18.0.1-tem
Using java version 18.0.1-tem <span class="hljs-keyword">in</span> this shell.

$ java -version
openjdk version <span class="hljs-string">"18.0.1"</span> 2022-04-19OpenJDK Runtime Environment Temurin-18.0.1+10 (build 18.0.1+10)OpenJDK 64-Bit Server VM Temurin-18.0.1+10 (build 18.0.1+10, mixed mode, sharing)
</code></pre>
<p>If you close the window or type Java <code>sdk use java 17.0.3-tem</code> you can switch back.</p>
<pre><code class="lang-sh">$ sdk use java 17.0.3-tem
Using java version 17.0.3-tem <span class="hljs-keyword">in</span> this shell.

$ java -version
openjdk version <span class="hljs-string">"17.0.3"</span> 2022-04-19OpenJDK Runtime Environment Temurin-17.0.3+7 (build 17.0.3+7)OpenJDK 64-Bit Server VM Temurin-17.0.3+7 (build 17.0.3+7, mixed mode, sharing)
</code></pre>
<h2 id="heading-how-to-automatically-switch-the-java-version">How to Automatically Switch the Java Version</h2>
<p>Let’s say that you have 2 projects, one with Java 17 and one with Java 18. By creating a <code>.sdkmanrc</code> file in a directory, you can automatically switch versions, which will boost your productivity. </p>
<p>Let’s create a file for a Java 17 project:</p>
<pre><code class="lang-sh">$ sdk env init
.sdkmanrc created.

$ tail .sdkmanrc
<span class="hljs-comment"># Enable auto-env through the sdkman_auto_env config</span>
<span class="hljs-comment"># Add key=value pairs of SDKs to use below</span>
java=17.0.3-tem
</code></pre>
<p>Next, create another directory, switch the Java version to Java 18, and create another <code>.sdkmanrc</code> by executing <code>sdk env init</code>.</p>
<pre><code class="lang-sh">$ <span class="hljs-built_in">cd</span> ..

$ mkdir my-java-18-project

$ <span class="hljs-built_in">cd</span> my-java-18-project/

$ sdk use java 18.0.1-tem
Using java version 18.0.1-tem <span class="hljs-keyword">in</span> this shell.

$ sdk env init
.sdkmanrc created.

$ tail .sdkmanrc
<span class="hljs-comment"># Enable auto-env through the sdkman_auto_env config</span>
<span class="hljs-comment"># Add key=value pairs of SDKs to use below</span>
java=18.0.1-tem
</code></pre>
<p>To automatically switch Java versions, you need to edit the file <code>$HOME/.sdkman/etc/config</code> and set <code>sdkman_auto_env=true</code>. There is already a line, so you only need to change <code>false</code> to <code>true</code>.</p>
<p>To enable the configuration change, restart your terminal. Once done, sdkman prints when it changes the Java version automatically for you. </p>
<p>Let’s verify the Java version as well.</p>
<pre><code class="lang-sh">$ <span class="hljs-built_in">cd</span> my-java-17-project/
Using java version 17.0.3-tem <span class="hljs-keyword">in</span> this shell.

$ java -version
openjdk version <span class="hljs-string">"17.0.3"</span> 2022-04-19
OpenJDK Runtime Environment Temurin-17.0.3+7 (build 17.0.3+7)
OpenJDK 64-Bit Server VM Temurin-17.0.3+7 (build 17.0.3+7, mixed mode, sharing)

$ <span class="hljs-built_in">cd</span> ..
Restored java version to 17.0.3-tem (default)

$ <span class="hljs-built_in">cd</span> my-java-18-project/
Using java version 18.0.1-tem <span class="hljs-keyword">in</span> this shell.

$ java -version
openjdk version <span class="hljs-string">"18.0.1"</span> 2022-04-19
OpenJDK Runtime Environment Temurin-18.0.1+10 (build 18.0.1+10)
OpenJDK 64-Bit Server VM Temurin-18.0.1+10 (build 18.0.1+10, mixed mode, sharing)
</code></pre>
<p>If you want to know more about sdkman, check the <a target="_blank" href="https://sdkman.io/usage">sdkman usage documentation</a>.</p>
<h2 id="heading-how-to-update-a-java-version">How to Update a Java Version</h2>
<p>Once a new Java version is available, it should be listed via <code>sdk list java</code>. But, you can also use <code>sdk upgrade java</code> to ask sdkman to check for updates. </p>
<p>Let’s install an older version of Java:</p>
<pre><code class="lang-sh">$ sdk uninstall java 17.0.3-tem

$ sdk install java 17.0.2-tem

$ sdk install java 11.0.12-tem

$ sdk upgrade java
Available defaults:
java (<span class="hljs-built_in">local</span>: 18.0.1-tem, 11.0.12-tem, 17.0.2-tem; default: 17.0.3-tem)

Use prescribed default version(s)? (Y/n): Y

Installing: java 17.0.3-tem
Done installing!
Setting java 17.0.3-tem as default.
</code></pre>
<p>By confirming with <code>y</code>, it downloads the suggested default version <code>17.0.3-tem</code> and sets it as a default on your system. This makes future updates easy by executing <code>sdk upgrade java</code>.</p>
<h2 id="heading-summary">Summary</h2>
<p>In this article, you learned how manage Java SDKs easily using sdkman. It’s a very useful tool, which supports many Linux distributions including Ubuntu, Debian and MacOS. </p>
<p>SDKMan enables you to install and remove Java versions, switch between them, and upgrade your Java versions with a single command. This keeps your system clean and makes managing Java SDKs easy.</p>
<p>I hope you enjoyed the article.</p>
<p>If you liked it and felt the need to give me a round of applause 👏 or just want to get in touch 👋, <a target="_blank" href="https://twitter.com/sesigl">follow me on Twitter</a>. I work at eBay Kleinanzeigen, one of the world’s biggest classified companies. By the way, <a target="_blank" href="https://www.ebay-kleinanzeigen.de/careers">we are hiring</a>!</p>
<h3 id="heading-references">References</h3>
<ul>
<li><a target="_blank" href="https://en.wikipedia.org/wiki/Java_Development_Kit">https://en.wikipedia.org/wiki/Java_Development_Kit</a></li>
<li><a target="_blank" href="https://adoptium.net/">https://adoptium.net/</a></li>
<li><a target="_blank" href="https://phoenixnap.com/kb/create-a-sudo-user-on-debian">https://phoenixnap.com/kb/create-a-sudo-user-on-debian</a></li>
<li><a target="_blank" href="https://stackoverflow.com/questions/63336131/install-sdkman-in-an-alpine-based-docker-image">https://stackoverflow.com/questions/63336131/install-sdkman-in-an-alpine-based-docker-image</a></li>
<li><a target="_blank" href="https://brew.sh/">https://brew.sh/</a></li>
<li><a target="_blank" href="https://reflectoring.io/manage-jdks-with-sdkman/">https://reflectoring.io/manage-jdks-with-sdkman/</a></li>
<li><a target="_blank" href="https://blog.jdriven.com/2020/10/automatic-switching-of-java-versions-with-sdkman/">https://blog.jdriven.com/2020/10/automatic-switching-of-java-versions-with-sdkman/</a></li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Dual Boot Any Linux Distribution With Windows – and Get Rid of It When You Need To ]]>
                </title>
                <description>
                    <![CDATA[ Gone are the days when Linux and Windows were like two opposing forces. Microsoft has embraced the open-source community quite cordially in recent years, and as a result we have things like Windows Subsystem for Linux baked right into our Windows ins... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-dual-boot-any-linux-distribution-with-windows/</link>
                <guid isPermaLink="false">66b0ab376a48f420e310e613</guid>
                
                    <category>
                        <![CDATA[ Linux ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Ubuntu ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Windows ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Farhan Hasin Chowdhury ]]>
                </dc:creator>
                <pubDate>Thu, 23 Dec 2021 16:32:46 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/04/How-to-Dual-Boot-Any-Linux-Distribution-With-Windows.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Gone are the days when Linux and Windows were like two opposing forces. Microsoft has embraced the open-source community quite cordially in recent years, and as a result we have things like <a target="_blank" href="https://docs.microsoft.com/en-us/windows/wsl/">Windows Subsystem for Linux</a> baked right into our Windows installations.</p>
<p>That doesn't mean that we no longer need a full blown Linux installation. In fact, machines with both Windows and Linux running side by side are quite common.</p>
<p>But do you know what's more common than machines running both operating systems? Machine owners who have tried to dual boot their machines and ended up losing a lot of data in the process.</p>
<p>So if you're one of the victims or one of those who are trying to avoid possible disasters in their upcoming dual booting adventure, this article is for you. Here you'll learn about:</p>
<ul>
<li>How to install any Linux distribution alongside Windows</li>
<li>How to get rid of Linux without messing up Windows if necessary</li>
<li>Common problems, misconceptions, and their solutions, and</li>
<li>Some generally geeky stuff to impress you peers</li>
</ul>
<p>Without any further ado, let's grab a mug of coffee or tea or at least water and jump right into the process.</p>
<h2 id="heading-some-assumptions-im-making">Some Assumptions I’m Making</h2>
<p>Before I jump into the core of the tutorial, I want to clarify a few things. To make this entire article approachable, I'm making following assumptions about your system:</p>
<ul>
<li>Your computer is using UEFI and not BIOS</li>
<li>You already have Windows installed on your machine</li>
<li>You have a USB drive large enough (4GB) to boot Linux from</li>
<li>You have enough space (25GB) to install Linux on your HDD or SSD</li>
</ul>
<p>That's pretty much it. If you have all of the above ready, you're good to go.</p>
<h2 id="heading-how-to-create-a-bootable-linux-usb-drive">How to Create a Bootable Linux USB Drive</h2>
<p>There are multiple tools that can help you to create a bootable Linux USB drive. Among all these tools, my favorites are:</p>
<ul>
<li><a target="_blank" href="https://www.balena.io/etcher/">balenaEtcher</a></li>
<li><a target="_blank" href="https://getfedora.org/en/workstation/download/">Fedora Media Writer</a></li>
</ul>
<p>Both of these tools are open-source, free to use, and available on pretty much all major platforms. For this article, I'll go with Fedora Media Writer simply because there are not a lot of tutorials talking about it and because I use it personally.</p>
<p>Like the name suggests, Fedora Media Writer is a tool created by Red Hat for making bootable Linux USBs. Once you've downloaded the program, install it on your system and fire it up.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/fedora-media-writer.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>This is how it looks. As you can see, you've got the option to download the latest Fedora ISOs as well as an option to pick a custom image file from your drives.</p>
<p>Unless you're planning on installing Fedora (spoiler! it's my favorite) on your machine, you'll have to go ahead and download your desired ISO file. </p>
<p>In this article, I'll use <a target="_blank" href="https://ubuntu.com/">Ubuntu</a> because it's more popular among newcomers. But the things you'll learn here can be applied to any other Linux distribution.</p>
<p>Go ahead and download the ISO for Ubuntu from their <a target="_blank" href="https://ubuntu.com/download/desktop">download</a> page. Ubuntu 20.04 LTS (the latest long term release at the time of writing) is around 2.67GB in size. Once you've finished downloading the file, go back to Fedora Media Writer, click on "Custom Image", and select the ISO file you've just downloaded.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/fmw-ready-to-write.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>The "Write to Disk" button is grayed out because there are no USB drives attached to the computer. Connect your USB drive and the button should turn bright red.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/fmw-ready-to-write-with-usb-drive.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Recheck that the correct USB drive is selected in the dropdown and hit the "Write to Disk" button. Depending on your machine's transfer rate, this process may take a few minutes. Once it's done, disconnect the USB drive and set it aside. You'll need it soon.</p>
<h2 id="heading-how-to-prepare-your-computer-for-installing-linux">How to Prepare Your Computer for Installing Linux</h2>
<p>Again, it's not uncommon to find people who have failed to boot from a Linux USB drive. This can happen if you haven't configured your computer properly. </p>
<p>To do so, go to your Control Panel. Not the new Settings application, but the OG Control Panel.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/control-panel-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Make sure Control Panel is either on "Small icons" or "Large icons" mode and not on the "Category mode". Now go to "Power Options" and from the left side-bar, click on "Choose what the power buttons do".</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/turn-off-fast-startup.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Click on the Change settings that are currently unavailable link and uncheck the "Turn on fast startup (recommended)" option and hit "Save changes". </p>
<p>According to Walter Glenn's <a target="_blank" href="https://www.howtogeek.com/243901/the-pros-and-cons-of-windows-10s-fast-startup-mode/">article</a>,</p>
<blockquote>
<p>Fast Startup combines elements of a cold shutdown and the hibernate feature. When you shut down your computer with Fast Startup enabled, Windows closes all applications and logs off all users, just as in a normal cold shutdown.   </p>
<p>At this point, Windows is in a state very similar to when it’s freshly booted up: No users have logged in and started programs, but the Windows kernel is loaded and the system session is running.   </p>
<p>Windows then alerts device drivers that support it to prepare for hibernation, saves the current system state to the hibernation file, and turns off the computer.  </p>
<p>When you start the computer again, Windows does not have to reload the kernel, drivers, and system state individually. Instead, it just refreshes your RAM with the loaded image from the hibernation file and delivers you to the login screen. This technique can shave considerable time off your start up.</p>
</blockquote>
<p>I know this sounds like a nice to have feature, but the problem is, if you keep fast startup enabled in a dual boot system, Linux will be unable to use any of the drives shared between the two operating systems because they're hibernated and held by Windows.</p>
<p>Next, boot into your motherboard's UEFI configuration screen. Depending on your motherboard or laptop brand, the key can change but in most cases pressing the "Del" key should get you in.</p>
<p>Once you're there, you'll have to change one setting in particular:</p>
<ul>
<li><strong>Turn off secure boot</strong> – this is one of the features of UEFI that helps prevent attacks and malware during boot. Disabling it is not strictly necessary but depending on the distribution you've chosen you may or may not face issues during installation. Disable it to be safe.</li>
</ul>
<p>Save the updated settings and boot back to Windows. Now it's time to prepare some disk space for Linux to fit into.</p>
<h2 id="heading-how-to-create-additional-partitions-for-installing-linux">How to Create Additional Partitions for Installing Linux</h2>
<p>Now it's time to make some room for the new OS. Based on the state of your HDD or SSD, it can either be very straightforward or quite tricky. </p>
<p>Let me explain what we're going to do. There is a utility built into Windows called "Disk Management" that's useful when you want to mess around with your partitions.</p>
<p>You can use this to squeeze out some space out of your existing partitions. To do so, open Disk Management by searching for it in the start menu.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/disk-management-in-start-menu.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Keep in mind that it may pop up as "Create and format hard disk partitions" instead of Disk Management. Fire it up and have a good look at its user interface:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/disk-management.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>This screenshot is from one of my machines that doesn't have Linux installed. I'll use this device as the guinea pig for this article. It has a 512GB NVME SSD and 8GB of RAM. </p>
<p>The user interface is divided into two parts. The top one is a list of all your partitions and the bottom part has all the physical disks connected to your computer listed vertically.</p>
<p>The below screenshot is from my desktop workstation that has a 250GB NVME SSD and a 1TB HDD. I have both Windows and Linux installed on the second disk. So if you have multiple disks on your machine as well, I would suggest you install the OS on the disk that contains the EFI partition. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/disk-management-desktop.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>If you look at the beginning of Disk 1, that 550MB FAT32 partition is the EFI. On your machine, it may be much smaller.</p>
<p>Let's get back to our guinea pig device. As you can see from the screenshot, the Windows (C:) partition is almost 250GB. I'll cut off 108GB from this partition.</p>
<ul>
<li>100GB for root</li>
<li>8GB for swap</li>
</ul>
<p>In Linux, the root directory contains all other directories and files on the system. When your RAM gets full, Linux moves the inactive pages from memory to the swap space. Having a swap space is not mandatory but it's good to have.</p>
<p>There is no hard and fast rule for determining the swap space. The recommended size for swap when you have a 4GB-8GB RAM is 2 times that size, and for 8GB-16GB is 1.5 times that size. Considering I don't do any memory intensive tasks on this laptop, I will break the rule here.</p>
<p>To cut off some space from your desired partition, right click on it from the bottom part and click on "Shrink". Once you do that, Disk Management will start calculating the amount available for shrinking.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/querying-for-available-space.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You may think that the entire free space of a partition should be shrinkable, but that's not true. Sometimes there are unmovable files scattered around your partition that may prevent you from using the full free space. In those cases, use a tool like <a target="_blank" href="https://www.ccleaner.com/defraggler">Defraggler</a> to optimize your drive.</p>
<p>After Disk Management has finished querying the partition, you'll see the following window:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/shrink-window.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>As you can see, I have 160311MB of space available to shrink. Dividing the value by 1024 will give you the size in gigabytes which in my case is around 156GB.</p>
<p>But I want to shrink my partition by 108GB. Multiplying this value by 1024 gives the value in megabytes of 110592MB.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/calculate-shrink-amount.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Once you have your desired size calculated, hit the "Shrink" button. The shrinking process doesn't take that long. Once the process is done the bottom part of the user interface will update.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/disk-management-after-shrink.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>As you can see, I now have 108GB of unallocated space. To be honest, this is enough for proceeding to the next step. But to make your life easier, I would suggest that you create two RAW partitions before going forward.</p>
<p>To do so, right click on the unallocated space and click on the "New Simple Volume" option. A new wizard window will show up. Press the "Next" button and on the next step, the wizard will ask about the new partition's size:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/partition-creation-size.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>I want to create the 100GB root partition. Multiplying that value by 1024 gives the value in megabytes which is 102400MB. Once you have the size calculated, hit "Next".</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/partition-creation-drive-letter.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>In the next step, the wizard will ask you about the drive letter. Choose "Do not assign a drive letter or drive path" and hit "Next".</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/partition-creation-format.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>In this step, select the "Do not format this volume" option and hit "Next". Finally hit finish on the last step. Follow the same process for creating your swap partition.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/disk-management-after-creating-partitions.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>I now have a 100GB RAW partition for the Linux root and a 8GB RAW partition for swap. Close the disk management tool and grab another mug of coffee or tea or at least water because we're going deeper into the rabbit hole.</p>
<h2 id="heading-how-to-install-linux-alongside-windows">How to Install Linux Alongside Windows</h2>
<p>Okay everyone, it's getting real now. We're going to do it. But first, you'll have to figure out which key to use to get into your boot menu.</p>
<p>On the device I'm using, pressing the F2 button takes me to the UEFI configuration screen. From there, pressing F8 takes me to the boot menu. So make sure you've done the research for your device.</p>
<p>Some tutorials may instruct you to change the boot order from your UEFI configuration screen, but I don't recommend doing that. The SSD or HDD that contains your bootloader should always be on the top.</p>
<p>Now connect the bootable USB device that you set aside on the first section and reboot your computer into the boot menu. From the boot menu, select the bootable USB drive and hit enter.</p>
<p>The GNU GRUB menu will appear. Pick the first one that says "Ubuntu". Wait until the file integrity check finishes or you can just skip it by hitting "Ctrl + C" on your keyboard.</p>
<p>You'll hear a beautiful chime and with that, the majestic Ubuntu installer will show up:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/ubuntu-installer-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Before you hit the "Continue" button, I would suggest that you get connected to the internet. If you're using an ethernet cable then you should be connected already. But if you're using wireless, then check the top right corner of your screen for the Wifi icon:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/wifi.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Once you're connected, hit the "Continue" button on the installer:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/keyboard-layout.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Pick the correct keyboard layout for yourself and hit "Continue".</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/updates-and-other-software.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>The "Normal installation" will give you a bunch of useful software and games from the get go, whereas the "Minimal installation" will give you the essentials only.</p>
<p>Keep the "Download updates while installing Ubuntu" option checked. This will download updated package files from the internet during installation.</p>
<p>The third option needs some explanation. Assume that you're using an NVIDIA GPU. When Ubuntu detects that GPU, Ubuntu will load the open-source drivers for NVIDIA GPUs known as "nouveau". </p>
<p>If you check the "Install third-party software for graphics and Wi-Fi hardware and additional media formats" option, NVIDIA will attempt to install proprietary drivers provided by NVIDIA itself. It'll also install codecs for proprietary media formats such as MPEG. </p>
<p>This device I'm using has an AMD GPU and uses the open-source "amdgpu" driver. I'll leave this unchecked considering I can install the codecs as necessary by myself. Do what you prefer and hit the "Continue" button.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/installation-type.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Okay this step needs attention. The Ubuntu installer is smart enough to detect whether you have other OSes installed on your machine or not. If yes, the installer will offer you the option to install Ubuntu alongside them. Don't pick that option. I repeat, <strong>don't pick that option</strong>.</p>
<p>Choose "Something else" and hit the "Continue" button.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/partition-map.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>This part can be a bit tricky. This is why I instructed you to create the partition from Windows instead of leaving the space unallocated. If you had left it unallocated, figuring out which part of the disk you should use would have become much more difficult.</p>
<p>At the top you can see a multi-colored line along with legends for which color represents which partition. Find out the two partitions you created from Windows.</p>
<p>In my machine, "nvme0n1p4" and "nvme0n1p5" are the ones. Now from the list, find the one you created for the root (nvme0n1p4 in my case) and double click on it:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/edit-partition.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Choose "Ext4 journaling file system" from the "Use as" dropdown and "/" as the "Mount point" dropdown. According to the <a target="_blank" href="http://www.linfo.org/mount_point.html">The Linux Information Project</a>:</p>
<blockquote>
<p>A mount point is a directory (typically an empty one) in the currently accessible <a target="_blank" href="http://www.linfo.org/filesystem.html">filesystem</a> on which an additional filesystem is mounted (i.e., logically attached).</p>
</blockquote>
<p>Hit the "OK" button. Next double click on the partition you created for the swap space:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/swap-partition.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Choose "swap area" from the "Use as" dropdown menu and hit the "OK" button. There is one more partition to configure. That is the EFI partition. Scroll through the list and find the FAT32 partition.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/efi-partition.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>On my machine, the "nvme0n1p1" is the EFI partition. Double click on it:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/use-as-efi.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Make sure "EFI System Partition" is selected from the "Use as" dropdown menu. This is the partition that'll contain your bootloader. Make sure you're not formatting this partition. Hit the "OK" button.</p>
<p>Also, the default mount point for the EFI partition is "/boot/efi". Some distributions like Fedora will require you to write this mount point manually. So make sure you're putting the correct mount point.</p>
<p>Recheck the partition configuration once again and if everything looks fine, hit the "Install Now" button.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/where-are-you.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>The installer will ask you about your time zone. I live in Dhaka, Bangladesh so that's what I've chosen. Hit the "Continue" button.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/who-are-you-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Fill out all the information as you see fit and hit the "Continue" button.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/welcome-to-ubuntu.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>The installation process shouldn't take long. Back when I was a kid, I loved looking at this slideshow.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/restart-now.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Once the installation is done you can either continue testing or restart. If you choose to restart, Ubuntu will instruct you to disconnect the USB drive and hit Enter.</p>
<p>The machine will reboot and the GRUB menu will show up again. Take a look at the list, and you'll see both Ubuntu and Windows Boot Manager on the menu. Boot into Ubuntu because you have one last thing to do.</p>
<h2 id="heading-how-to-sync-the-time-between-windows-and-linux">How to Sync the Time Between Windows and Linux</h2>
<p>This is one of the common problems that people with a dual boot system face. When you boot into Windows and then boot into Linux, you'll find Linux's clock all messed up. The same thing will happen if you first boot into Linux and then boot into Windows.</p>
<p>Let me explain why this happens. Your computer (or rather every computer in the world) has two clocks. One is the system clock that lives within the OS, and the other is the hardware clock that lives in your motherboard and keeps track of time even when your computer is not running.</p>
<p>The problem is that Windows assumes that your hardware clock is running in your local time and Linux assumes that your hardware clock is running in UTC time and applies an offset according to your location.</p>
<p>The easiest way to fix this issue is to make your Linux distribution use local time like Windows does. To do so, execute the following command in the Linux terminal:</p>
<pre><code class="lang-bash">timedatectl set-local-rtc 1 --adjust-system-clock
</code></pre>
<p>Now restart your computer into Windows, sync the system clock and go back to Linux. The time should not be messed up now.</p>
<h2 id="heading-how-to-remove-linux-from-a-dual-boot-system">How to Remove Linux From a Dual Boot System</h2>
<p>Say for some reason you didn't like your time with Linux and want to get rid of it. This would be sad, but life is hard, ain't it?</p>
<p>Removing Linux from a dual boot system is a two step process:</p>
<ol>
<li>Getting rid of the GRUB bootloader</li>
<li>Getting rid of the Linux partitions</li>
</ol>
<p>To get rid of the GRUB bootloader you'll have to remove the corresponding files from the EFI partition. The problem is that the partition is hidden by default. </p>
<p>To make if accessible you'll have to use the <code>diskpart</code> program. It's a disk management utility like the Disk Management tool but it's a command line interface.</p>
<p>Boot into Windows. From the start menu, open Command Prompt as an administrator. To do so, just search for "cmd" in your start menu and when the Command Prompt shows up, press the "Ctrl + Shift + Enter" key combination.</p>
<p>Now write <code>diskpart</code> in the command prompt window and hit enter to start the program.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/diskpart.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Next, write <code>list disk</code> and hit enter to get a list of all the connected disks:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/list-disk.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>This device has only one physical disk but you may have multiple. Write <code>sel disk &lt;disk number&gt;</code> to select the desired disk.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/sel-disk-0.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Then write <code>list vol</code> and press enter to list out all the partitions in this disk.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/list-vol.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Judging by the size and format, I can say that Volume 4 is the EFI partition. Keep in mind this can be much smaller on your system but it will be always a FAT32 partition. Write <code>sel vol &lt;volume number&gt;</code> to select the desired volume.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/sel-vol-4.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Finally write <code>assign letter x</code> and hit enter to assign the letter <code>x</code> to this partition.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/assign-letter-x.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Exit <code>diskpart</code> by writing <code>exit</code> and hitting enter:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/exit.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Now the partition has become accessible. From the same command prompt window, go inside the EFI partition by writing <code>x:</code> and hitting enter.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/x.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>To get a list of all the folders in there, write <code>dir</code> and hit enter.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/dir.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Now write <code>cd EFI</code> to go inside that EFI folder and write <code>dir</code> once again to list out the contents.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/cd-efi.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You'll have to get rid of that <code>ubuntu</code> folder. To do so, write <code>rmdir /s ubuntu</code> and hit enter. Command prompt will ask you whether you're sure or not. Write <code>Y</code> and hit enter to confirm. Then use <code>dir</code> one last time to make sure it's gone.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/rmdir-dir.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<p>That's it. Next, open Disk Management once again like you did before and from the bottom part, right click on the Linux oriented partitions and choose "Delete Volume" from the list.</p>
<p>After deleting the partitions, you can either create a new one using the unallocated space or extend the partition on the left of it to dissolve the unallocated space.</p>
<p>Finally reboot your computer and check whether the Ubuntu has gone away from your machine or not.</p>
<h2 id="heading-what-about-other-linux-distributions">What About Other Linux Distributions?</h2>
<p>The techniques learned in this article is relevant for any Linux distributions out there.</p>
<p>So, whenever you're dual booting a system, make sure that</p>
<ul>
<li>Secure Boot is disabled</li>
<li>Fast Startup is disabled</li>
</ul>
<p>And during the installation</p>
<ul>
<li>Do not choose any guided/automatic installation type</li>
<li>Make sure to not format the EFI/ESP partition</li>
<li>Make sure to mount your partitions properly</li>
</ul>
<p>As long as you're sticking to these few rules, you should be good to go. </p>
<p>Just keep in mind that there are some rare cases when a distribution may not use GRUB as a bootloader.</p>
<p>Take the very popular "<a target="_blank" href="https://pop.system76.com/">Pop!_OS</a>" for example. It uses "systemd-boot" as its default bootloader. As a result you'll have to keep pressing the Space button (or maybe any button on the keyboard) during startup, otherwise the boot menu won't show up and you'll boot into Pop!_OS directly.</p>
<p>Another thing that I've seen: some motherboards such as my MSI B450 Tomahawk Max, chooses the Windows Boot Manager by default even though I have a working Linux installation. If you see something like this, go into your UEFI configuration screen and look for relevant options.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>I would like to thank you from the bottom of my heart for the time you've spent reading this article. </p>
<p>I also have a personal blog where I write about random tech stuff, so if you're interested in something like that, checkout <a target="_blank" href="https://farhan.dev">https://farhan.dev</a>. If you have any questions or are confused about anything – or just want to get in touch – I'm available on <a target="_blank" href="https://twitter.com/frhnhsin">Twitter</a> and <a target="_blank" href="https://www.linkedin.com/in/farhanhasin/">LinkedIn</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Install and Set Up Flutter on Ubuntu 16.04+ ]]>
                </title>
                <description>
                    <![CDATA[ By Otavio Ehrenberger Flutter is a Dart-based toolkit that helps you build the front end of your apps. It really shines in cross-platform mobile app development and aims to be a viable option for web and desktop as well.  In its mobile app flavor, Fl... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-install-and-setup-flutter-on-ubuntu/</link>
                <guid isPermaLink="false">66d851f1afbaabf7a144af00</guid>
                
                    <category>
                        <![CDATA[ Flutter ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Ubuntu ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 12 Aug 2021 15:43:09 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/08/Flutter-logo.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Otavio Ehrenberger</p>
<p>Flutter is a Dart-based toolkit that helps you build the front end of your apps. It really shines in cross-platform mobile app development and aims to be a viable option for web and desktop as well. </p>
<p>In its mobile app flavor, Flutter provides many UI abstractions to build interfaces. You can implement logic in Dart, or directly with Kotlin or Swift if you need more specific interactions with your OS of choice. </p>
<p>While cross-platform app development is nothing new, earlier strategies such as PhoneGap and Ionic used the available WebView implementation instead of interfacing directly with the system. This is not only very limiting but also has a lot of performance costs. </p>
<p>The gold standard for <em>native</em> cross-platform app development is yet to be established. But Flutter both offers a a lot on its own and elegantly steps out of the way when you need to interact directly with the OS using whatever official language you need to use. </p>
<p>This makes Flutter a game changer even before it has fulfilled its potential of sharing the same codebase with the web and desktop versions of an app.</p>
<p>In this tutorial we'll get to setup an Ubuntu 16.04+ machine for Android app development with Flutter. You can also edit Swift code directly from Android Studio, but unfortunately you won't have official support to test the app in iOS devices or emulators due to Apple's policies. </p>
<p>For this we'll need to install and configure Java as an Android Studio dependency, setup Android Studio to use hardware-acceleration and run Flutter apps and, of course, install and configure Flutter itself. So, let's get started.</p>
<h2 id="heading-how-to-install-and-configure-flutter">How to Install and Configure Flutter</h2>
<p>First things first: let's install Flutter through the snap store. If you are using Ubuntu 16.04 onwards, you likely already have the <code>snap</code> command installed. </p>
<p>If you are not, you can follow the instructions available for your distro at the "Install Snap Store on your Linux distribution" section on <a target="_blank" href="https://snapcraft.io/snap-store">this</a> page.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5wgxz7mtwcps32vuq3fp.png" alt="Some of the linux distros snap store is available for." width="600" height="400" loading="lazy"></p>
<p>With the <code>snap</code> command available, install Flutter like this:</p>
<pre><code class="lang-bash">sudo snap install flutter --classic
</code></pre>
<p>After Flutter has finished installing, run a basic checkup which will also do some automatic configuring:</p>
<pre><code class="lang-bash">flutter doctor -v
</code></pre>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/12plekbnhxgfqz6u4efn.png" alt="flutter doctor output" width="600" height="400" loading="lazy"></p>
<p>Flutter has been installed, nice!</p>
<h2 id="heading-how-to-install-and-configure-java">How to Install and Configure Java</h2>
<p>First of all, we need to get the (community-backed) Open Java Development Kit before being able to use Android Studio. </p>
<p>To get the latest stable version of Java 8, open your terminal and run: </p>
<pre><code class="lang-bash">sudo apt-get update &amp;&amp; sudo apt-get install openjdk-8-jdk
</code></pre>
<p>Other versions can sometimes show some unpredictable problems while working alongside Flutter as of May 2021, so I recommend installing OpenJDK 8. Don't worry, OpenJDK 8 is set to receive support at least until 2024.</p>
<p>After a successful installation, it is time to set the <code>$JAVA_HOME</code> environment variable. It's used by default by many applications which interact with your local Java installation, Android Studio among them. </p>
<p>Get a list of the currently installed JDKs in your system with this command:</p>
<pre><code class="lang-bash">sudo update-alternatives --config java
</code></pre>
<p>Choose from the list of locally installed versions (remember that Java 8 is the easiest to use with Flutter) and set the one which you would like to be the system's default. </p>
<p>Set <code>$JAVA_HOME</code> to its path, <strong>without including the <code>/bin</code> portion onwards of the path</strong> (in my case, for instance, the correct path was <code>/usr/lib/jvm/java-8-openjdk-amd64</code>):</p>
<pre><code class="lang-bash"><span class="hljs-comment">#JAVA_HOME=&lt;your_java_installation_path&gt;, same as below if you followed instructions</span>
JAVA_HOME=<span class="hljs-string">"/usr/lib/jvm/java-8-openjdk-amd64"</span> <span class="hljs-comment"># my local path after installing openjdk-8</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"JAVA_HOME=\"<span class="hljs-variable">$JAVA_HOME</span>\""</span> &gt;&gt; ~/.bashrc <span class="hljs-comment"># sets JAVA_HOME env var for current user</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">'export PATH=$PATH:$JAVA_HOME/bin'</span> &gt;&gt; .zshrc <span class="hljs-comment"># adds java's binaries to your path</span>
<span class="hljs-built_in">source</span> ~/.bashrc &amp;&amp; <span class="hljs-built_in">echo</span> <span class="hljs-variable">$JAVA_HOME</span> <span class="hljs-comment"># verifies that the variable was perenially set</span>
</code></pre>
<h2 id="heading-how-to-install-and-configure-android-studio-to-run-with-flutter">How to Install and Configure Android Studio to Run with Flutter</h2>
<p>You can download Android Studio <a target="_blank" href="https://developer.android.com/studio">here</a>.</p>
<p>After your download finishes, extract the Android Studio package into the <code>/usr/local/</code> directory:</p>
<pre><code class="lang-bash">sudo tar -C /usr/<span class="hljs-built_in">local</span> -zxvf ~/Downloads/&lt;android_studio_package&gt;.tar.gz
</code></pre>
<p>After it's successfully extracted, run Android Studio's installation script:</p>
<pre><code class="lang-bash">bash /usr/<span class="hljs-built_in">local</span>/android-studio/bin/studio.sh
</code></pre>
<p>This should pop up the install wizard. Follow the wizard's instructions for the standard installation and you should eventually arrive at the starter screen. </p>
<p>Select Configurations at the lower right corner and click on "Plugins":</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9xaxzsat1b2kcksqkypy.png" alt="Android Studio starter screen" width="600" height="400" loading="lazy"></p>
<p>Install the "Flutter" official plugin, published by <strong>flutter.dev</strong>:</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o6t1w69ero8xe234idnl.png" alt="Flutter Plugin" width="600" height="400" loading="lazy"></p>
<p>You will be prompted to install the Dart plugin (Flutter's base programming language) before you proceed. Click 'Ok' and restart the Android Studio IDE. </p>
<p>The option to start a Flutter project should be visible now. Click on it, then select 'Flutter Application' and click on 'Next'.</p>
<p>You should be greeted by the project configuration screen. Configure your project's name, location, and description as you wish, and point the field "Flutter SDK" to <code>/home/&lt;your_user_name&gt;/snap/flutter/common/flutter</code>:</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w4j43px47sc5o9t04jtl.png" alt="Flutter Project Config" width="600" height="400" loading="lazy"></p>
<p>In case the above path is not available, open a terminal and run:</p>
<pre><code class="lang-bash">flutter doctor -v
</code></pre>
<p>You should then be greeted with the starter project screen:</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ve413tpxbsn674bqlowx.png" alt="Flutter Project Starter" width="600" height="400" loading="lazy"></p>
<p>Almost done. Now you need to accept the Android licenses and double check your Flutter installation's ownership in order to avoid future surprise build errors due to resources denied for Android Studio. </p>
<p>Open up your terminal and run:</p>
<pre><code class="lang-bash">flutter doctor --android-licenses <span class="hljs-comment"># accept Google's licenses, necessary to build the app</span>
sudo chown -R <span class="hljs-variable">$USER</span>:<span class="hljs-variable">$USER</span> /home/<span class="hljs-variable">$USER</span>/snap/flutter <span class="hljs-comment"># confirm you are the owner of local flutter</span>
</code></pre>
<p>Now Android Studio is finally setup to run Flutter projects. Nice!</p>
<p>You should also enable the Desktop Entry for Android Studio. In your project screen, click on "Tools" then "Create Desktop Entry":</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qmw2u417r7v8x6ry2n7t.png" alt="AS Desktop Entry" width="600" height="400" loading="lazy"></p>
<p>The Android Studio shortcut should be available from the "Activities" menu now.</p>
<h2 id="heading-how-to-enable-hardware-virtualization-for-the-android-emulator">How to Enable Hardware Virtualization for the Android Emulator</h2>
<p>In order to run the emulator, we must first set up your CPU's hardware virtualization capabilities.</p>
<p>Run <code>kvm-ok</code> in your terminal and your output should indicate whether you can use KVM acceleration or not. If you have an AMD or Intel CPU, most likely it can.</p>
<p>The Kernel Virtual Machine, in a nutshell, is a bridge between the kernel with virtual devices which allows a virtual device to emulate its own hardware directly from the host computer's hardware. You can take a look <a target="_blank" href="https://www.linux-kvm.org/page/FAQ#Preparing_to_use_KVM">here</a> for more detailed information.</p>
<p>Provided you are indeed able to use KVM acceleration, it is time to setup KVM and authorize the current user for it:</p>
<pre><code class="lang-bash">sudo apt update <span class="hljs-comment"># update repositories</span>
sudo apt install qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils <span class="hljs-comment"># base packages</span>
sudo addgroup kvm &amp;&amp; sudo addgroup libvirtd <span class="hljs-comment"># create user authorization groups</span>
sudo adduser <span class="hljs-variable">$USER</span> kvm &amp;&amp; sudo adduser <span class="hljs-variable">$USER</span> libvirtd <span class="hljs-comment"># add current user to auth groups</span>
sudo virsh -c qemu:///system list <span class="hljs-comment"># checks if virtualization is ok</span>
<span class="hljs-comment"># if everything went fine, your output will be something like:</span>
<span class="hljs-comment">#</span>
<span class="hljs-comment">#  Id    Name                           State</span>
<span class="hljs-comment">#----------------------------------------------------</span>
</code></pre>
<p>And restart your user session. In the computer, not only the terminal. Log off the system and then login or reboot the PC, I'll be waiting.</p>
<h2 id="heading-how-to-use-the-android-emulator-to-test-apps">How to Use the Android Emulator to Test Apps</h2>
<p>Now, open an Android Studio project and click on the 'AVD Manager' (Android Virtual Device) option located in the window's upper right corner:</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a3hnfp08d78fu8s81qad.png" alt="AVD Manager" width="600" height="400" loading="lazy"></p>
<p>Click on the "Create Virtual Device" button and a window with a list of devices should pop up with the 'Phone' category preselected. I recommend that you pick a device with Play Store enabled just in case you might want to use it later inside your emulated device. Mine was the Nexus 5.</p>
<p>Click on the 'Next' button and a list of system images (Android OS Versions) should appear:</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lsncydy90yb8wh6yiq1p.png" alt="System Images" width="600" height="400" loading="lazy"></p>
<p>First, download your target image (by simply clicking on 'Download' right beside the Release Name), select a locally downloaded image, and click on 'Next'. It should only be highlighted after the image was successfully downloaded.</p>
<p>A window will then show up, offering you to customize your virtual device's properties such as screen orientation on startup, RAM usage, and so on. Tweak the device to your liking if you want, otherwise you can safely click on 'Finish'.</p>
<p>If everything goes well, you should now see your device listed at the Android Virtual Device Manager window:</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qsyjl24niolby6uh2np7.png" alt="AVD Manager List" width="600" height="400" loading="lazy"></p>
<p>Go back to your Android Studio project view. At the same line where the 'AVD Manager' button is located, there is a dropdown list of available devices just to the left of 'main.dart'. Select the emulator you have just set up and click the green 'play' button just to the right of 'main.dart'. </p>
<p>In case the emulator is not listed there yet, open the AVD Manager window again and click the green 'play' button under the 'actions' label listed for your virtual device. This will load and open the emulator before running your Flutter code.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hli5nfnywjr2i5mcf289.png" alt="Android Virtual Device" width="600" height="400" loading="lazy"></p>
<p>Notice that 'debug' ribbon in the upper right corner? In case you wanna get rid of it, add <code>debugShowCheckedModeBanner: false</code> as a field of <code>MaterialApp</code>.</p>
<h2 id="heading-how-to-use-a-physical-android-device-to-test-apps">How to Use a Physical Android Device to Test Apps</h2>
<p>You'll need to have a local installation of the Android Debug Bridge in order to enable your computer to trade information (such as APK builds) with any connected Android devices, virtual or otherwise.</p>
<p>The ADB consists of a client (the interface from which you run commands, which will be the ADB binary installed in your computer for all purposes of this tutorial), a daemon (which executes in the Android device the commands initially sent from the client) and a server (which runs locally in the PC, which has a default listening location at tcp://localhost:5037, and intermediates the communication between the client and the daemon).</p>
<p>Very conveniently, Android Studio currently ships with an ADB, so if you followed the instructions above to install Android Studio, you already have one at your computer. </p>
<p>It is possible to install ADB from the Ubuntu repositories alongside the one in Android Studio, but this invites headaches if your computer eventually confuses the locally installed versions. So instead let's setup our Linux user to access Android Studio's ADB and then run ADB:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">echo</span> <span class="hljs-string">'export PATH=$PATH:$HOME"/Android/Sdk/platform-tools"'</span> &gt;&gt; .bashrc <span class="hljs-comment"># adds adb to path</span>
adb start-server <span class="hljs-comment"># launches adb server</span>
adb devices <span class="hljs-comment"># lists connected devices</span>
</code></pre>
<p>After running <code>adb devices</code>, you most likely got an error. This error has registered the <code>$LOGNAME</code> variable which contains the current user name. You will use it to insert your user into the <code>plugdev</code> group, in case you are not there already. </p>
<p>You also most likely do not have a set of <code>udev</code> rules for Android devices. UDEV rule files specify Ubuntu interactions with plugged in devices, and Ubuntu will refuse to perform certain interactions with your Android device unless it is previously authorized in an UDEV rules file. </p>
<p>So, let's correct those errors:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># add user to plugdev group</span>
sudo usermod -aG plugdev <span class="hljs-variable">$LOGNAME</span>
<span class="hljs-comment"># downloads a very thorough UDEV rules file into the appropriate directory</span>
sudo wget -O /etc/udev/rules.d/51-android.rules https://raw.githubusercontent.com/NicolasBernaerts/ubuntu-scripts/master/android/51-android.rules
<span class="hljs-comment"># gives reading permission to the UDEV android file</span>
sudo chmod a+r /etc/udev/rules.d/51-android.rules
</code></pre>
<p>Reboot your current Linux user session to apply these changes, then open a terminal and run <code>adb devices</code> again. </p>
<p>In case you still have a UDEV-related error, your device's manufacturer ID probably is not listed in <code>/etc/udev/rules.d/51-android.rules</code>. In this case, search the internet for your device's manufacturer UDEV id and manually add it to the rule list in the same format as the others. </p>
<p>Notice how the only field with a unique value amongst the rows is <code>ATTR{idVendor}</code>. If you do not receive any error, you'll notice that your device is listed as 'unauthorized'. Let's unlock the device for USB debugging.</p>
<h2 id="heading-how-to-unlock-developer-mode-and-usb-debugging">How to Unlock Developer Mode and USB Debugging</h2>
<p>In your Android device, open up 'Settings', then 'About Phone'. Tap your 'Build number' 5-6 times until a toast telling that 'You are now a developer!' pops up.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/skib1pnotczz49wo5s4k.png" alt="You Are Now a Developer" width="600" height="400" loading="lazy"></p>
<p>Back to 'Settings', open System', you should see that 'Developer Options' were unlocked.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lovbrm5eg1yg8twi3dft.png" alt="Developer Options" width="600" height="400" loading="lazy"></p>
<p>Tap this new entry and check 'USB debugging' just under the 'Debug' section.</p>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0vp2kw9urr2dalqfvorb.png" alt="USB Debugging" width="600" height="400" loading="lazy"></p>
<p>Plug your Android device in your PC via USB, then run <code>adb devices</code> on your terminal. The output should list your device and also point that it is unlocked for debugging. </p>
<p>Now, go back to Android Studio, click on the device dropdown list (the one in which you selected your Virtual Device before) and your physical device should now be listed. Select it. </p>
<p>Finally, click on the 'run' button and you should see the app in your device, ready to be interacted with.</p>
<p>Congratulations! You are now a Flutter developer. Good luck in your development journey!</p>
<p><em>Cover image from flutter.dev.</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Install Docker on Ubuntu 18.04 [Guide for both CE and EE] ]]>
                </title>
                <description>
                    <![CDATA[ By Marcelo Costa Back in 2017, Docker introduced two different versions of its platform: Docker-CE and Docker-EE. But do you know their differences? Docker CE (Community Edition) is the classical OSS (Open Source Software) Docker Engine. Includes... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-install-docker-on-ubuntu-18-04-guide-for-both-ce-and-ee/</link>
                <guid isPermaLink="false">66d851c029e30bc0ad47759f</guid>
                
                    <category>
                        <![CDATA[ Docker ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Ubuntu ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 07 Jul 2020 18:06:10 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/06/Docker-CE--1-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Marcelo Costa</p>
<p><a target="_blank" href="https://www.docker.com/blog/docker-enterprise-edition/">Back in 2017</a>, Docker introduced two different versions of its platform: Docker-CE and Docker-EE. But do you know their differences?</p>
<div>
<img src="https://www.freecodecamp.org/news/content/images/2020/06/DockerCE_1.png" alt="drawing" width="600" height="400" loading="lazy">
</div>

<p>Docker CE (Community Edition) is the classical OSS (Open Source Software) Docker Engine. Includes the full Docker platform and is great for developers and DIY ops teams starting to build container apps.</p>
<p>If you are an avid developer like I am, you've probably been using Docker for a while. And I would say that most likely this is the version you've worked with, simply because it's free!</p>
<div>
<img src="https://www.freecodecamp.org/news/content/images/2020/06/DockerEE.png" alt="drawing" width="600" height="400" loading="lazy">
</div>

<p>Docker EE, on the other hand, is a premium version of CE. It comes with all CE capabilities plus many <a target="_blank" href="https://docs.mirantis.com/docker-enterprise/v3.0/dockeree-products/dee-intro.html">enterprise level features</a>.</p>
<p>Anything that comes with premium is <a target="_blank" href="https://hub.docker.com/editions/enterprise/docker-ee-server-ubuntu/purchase">not free right</a>? So it goes from $750/month basic plan to $2000/month advanced plan. Anyway the prices are on par with what you would expect from enterprise products.</p>
<blockquote>
<p>Please get in touch with their sales team to check the most up-to-date prices.</p>
</blockquote>
<h2 id="heading-docker-ce-vs-ee-the-details">Docker CE vs EE - the Details</h2>
<p>Let's do a quick comparison between Docker EE and Docker CE interest over time:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/Screen-Shot-2020-07-04-at-6.01.50-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Now Docker EE vs Docker CE vs Docker:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/Screen-Shot-2020-07-04-at-6.27.17-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>From my experience, users who are searching for just Docker are looking for the CE edition. This shows us that Docker EE is used much less. But I'm certain that there are robust use cases where it makes sense to use it.</p>
<p>Since I'm an open source enthusiast all my experience comes from using the Docker CE edition, so writing this article was a wonderful experience getting to play with Docker EE.</p>
<p>After that quick introduction, let's get our hands dirty.</p>
<div>
<img src="https://www.freecodecamp.org/news/content/images/2020/06/flamenco-285.png" alt="drawing" width="600" height="400" loading="lazy">
</div>

<h2 id="heading-prepare-the-ubuntu-1804-machine">Prepare the Ubuntu 18.04 machine</h2>
<p>As the first step, we will get the soil ready by running some common commands. </p>
<p>All the commands will be executed on a fresh Ubuntu 18.04 machine, and this time I've chosen Google Cloud Platform as the demonstrating environment.</p>
<h3 id="heading-create-the-virtual-machine">Create the Virtual Machine</h3>
<p>Let's start by creating a fresh VM using Ubuntu 18.04 image:</p>
<pre><code class="lang-bash">gcloud compute instances create ubuntu-fcc-demo \
--zone=us-central1-c \
--machine-type=n1-standard-1 \
--image=ubuntu-minimal-1804-bionic-v20200703a \
--image-project=ubuntu-os-cloud \
--boot-disk-size=10GB \
--boot-disk-type=pd-standard
</code></pre>
<p>Now connect to it using ssh:</p>
<pre><code class="lang-bash">gcloud compute ssh ubuntu-fcc-demo --zone=us-central1-c
</code></pre>
<p>Set up commons dependencies:</p>
<pre><code class="lang-bash">sudo apt-get update

sudo apt-get install \
   apt-transport-https \
   ca-certificates \
   curl \
   gnupg-agent \
   software-properties-common
</code></pre>
<h2 id="heading-install-docker-ce-on-ubuntu-1804">Install Docker CE on Ubuntu 18.04</h2>
<h3 id="heading-install-from-httpsgetdockercom">Install from https://get.docker.com</h3>
<p>The install script lets you quickly install the latest Docker-CE releases on the supported linux distros. I don't recommend depending on this script for deployment to production systems. From <a target="_blank" href="https://github.com/docker/docker-install">docker-install</a>:</p>
<pre><code class="lang-bash">curl -sSL https://get.docker.com/ | sh
</code></pre>
<p>The beauty of this command is that it will check your linux distro and run the right instructions to get Docker CE running for you.</p>
<p>You can test that everything is OK by running:</p>
<pre><code class="lang-bash">sudo docker run hello-world

<span class="hljs-comment"># output</span>
Hello from Docker!
This message shows that your installation appears to be working correctly.
</code></pre>
<div>
<img src="https://www.freecodecamp.org/news/content/images/2020/06/flamenco-done.png" alt="drawing" width="600" height="400" loading="lazy">
</div>

<h3 id="heading-install-from-docker-repository">Install from Docker repository</h3>
<p>This one has more step, but is the recommended approach from Docker's official docs (we even check their <a target="_blank" href="https://en.wikipedia.org/wiki/Public_key_fingerprint">GPG key fingerprin</a>t).</p>
<p>First, add Docker’s official GPG key:</p>
<pre><code class="lang-bash">curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
| sudo apt-key add -
</code></pre>
<p>Then verify the key's fingerprint:</p>
<pre><code class="lang-bash">sudo apt-key fingerprint 0EBFCD88
</code></pre>
<p>Look for the fingerprint <code>9DC8 5822 9FC7 DD38 854A  E2D8 8D81 803C 0EBF CD88</code>. This makes sure the key has not been tempered with.</p>
<p>Next, set up a docker <strong>stable</strong> repository:</p>
<pre><code class="lang-bash">sudo add-apt-repository \
   <span class="hljs-string">"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   <span class="hljs-subst">$(lsb_release -cs)</span> \
   stable"</span>
</code></pre>
<p>The  <code>$(lsb_release -cs)</code> command returns the Ubuntu distribution. In our case we used <code>bionic</code>.</p>
<p>Now install Docker Engine:</p>
<pre><code class="lang-bash"> sudo apt-get update
 sudo apt-get install docker-ce docker-ce-cli containerd.io
</code></pre>
<p>And test that everything is OK by running:</p>
<pre><code class="lang-bash">sudo docker run hello-world

<span class="hljs-comment"># output</span>
Hello from Docker!
This message shows that your installation appears to be working correctly.
</code></pre>
<div>
<img src="https://www.freecodecamp.org/news/content/images/2020/06/cherry-success.png" alt="drawing" width="600" height="400" loading="lazy">
</div>

<p>Instructions based on <a target="_blank" href="https://docs.docker.com/engine/install/ubuntu/">docs.docker.com</a>. </p>
<h2 id="heading-install-docker-ee-on-ubuntu-1804">Install Docker EE on Ubuntu 18.04</h2>
<h3 id="heading-install-using-mirantis-launchpad-cli">Install using Mirantis Launchpad CLI</h3>
<p>To work with Docker EE you need a trial/purchased version. Docker disabled the option to get a trial subscription on their website, and now you need to contact their sales team <a target="_blank" href="https://hub.docker.com/editions/enterprise/docker-ee-server-ubuntu">to get a trial account</a>. </p>
<p>Looking around I found out that, since <a target="_blank" href="https://techcrunch.com/2019/11/13/mirantis-acquires-docker-enterprise/">Mirantis acquired Docker Enterprise</a>, the way to get a Docker EE trial account has changed. You need to go to the <a target="_blank" href="https://www.mirantis.com/software/docker/download/">Mirantis website</a> and, after applying, you can download it right away.</p>
<p>At the time of this writing the installer is currently beta software. If there's a different way to install Docker EE, please get in touch. I would love to improve this article!</p>
<p>The Mirantis Launchpad CLI tool ("<strong>launchpad</strong>") is the new, better way to evaluate and experience <a target="_blank" href="https://www.mirantis.com/software/docker/docker-enterprise/">Docker Enterprise</a> (check out <a target="_blank" href="https://github.com/Mirantis/launchpad">launchpad GitHub</a>).</p>
<h3 id="heading-download-launchpad-cli">Download Launchpad CLI</h3>
<p>Start by <a target="_blank" href="https://github.com/Mirantis/launchpad/releases/latest">Downloading Launchpad</a>. For Ubuntu 18.04 I used the <a target="_blank" href="https://github.com/Mirantis/launchpad/releases/download/0.12.0/launchpad-darwin-x64">launchpad-darwin-x64</a> version.</p>
<p>If you didn't download it from the Virtual Machine, here's a command to upload it to it:</p>
<pre><code class="lang-bash">gcloud compute scp launchpad-linux-x64 ubuntu-fcc-demo:~/launchpad \
  --zone=us-central1-c
</code></pre>
<p>Next, verify the installation:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Give it writting permission</span>
chmod +x launchpad

<span class="hljs-comment"># Verify the installation</span>
./launchpad version

<span class="hljs-comment"># output</span>
version: 0.12.0
commit: 4492884
</code></pre>
<p>Then register your user: </p>
<pre><code class="lang-bash">launchpad register
</code></pre>
<p>The information provided via registration is used to assign evaluation licenses and for providing assistance for the usage of the product.</p>
<p>Next, set up your  <code>cluster.yaml</code> config.</p>
<p>This step was the one that took the most time for me. You need to set up 3 machines:</p>
<ul>
<li>Admin machine: The one where you are executing the launchpad command.</li>
<li>Worker machine: Will be running your workloads.</li>
<li>Manager machine: Contains the admin dashboard, where you have access to many configs and metrics.</li>
</ul>
<p>They did a great job with the Go <code>launchpad</code> binary. The tricky parts are within the infrastructure setup. Fortunately they already have some <a target="_blank" href="https://github.com/Mirantis/launchpad/tree/master/examples/terraform">terraform scripts</a> to help with it. </p>
<p>Since at the time of this writing there was no option for GCP, I had to setup the infrastructure manually. The Admin machine connects to the Worker and Manager nodes to setup many steps, so make sure you have the ssh keys correctly set up. </p>
<p>The ssh keys step took me some time to figure out, and I even <a target="_blank" href="https://github.com/Mirantis/launchpad/issues/30">opened an issue</a> in their repo, but then I quickly solved it. So if you have a similar issue, make sure you check it out.</p>
<p>There's a really <a target="_blank" href="https://github.com/Mirantis/launchpad/blob/master/docs/configuration-file.md">detailed documentation</a> about each attribute you can use in the config file.</p>
<p>Now it's time to bootstrap your cluster.</p>
<p>Once you have the <code>cluster.yaml</code> config set up, you can run the apply command:</p>
<pre><code class="lang-bash">launchpad --debug apply
</code></pre>
<p>You should see something like this:</p>
<p><strong>Running phase: Install Docker EE Engine on the hosts</strong></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/Screen-Shot-2020-07-07-at-12.06.45-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>This is where I can say that they did a really good job abstracting all the setup steps.</p>
<p>There are 37 steps that the Go <code>launchpad</code> binary executes.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/Screen-Shot-2020-07-07-at-12.22.30-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>At the end you should see a message like this:</p>
<pre><code class="lang-bash">INFO[0021] ==&gt; Running phase: UCP cluster info
INFO[0021] Cluster is now configured. You can access your cluster admin UI at: https://34.71.157.231 \
INFO[0021] You can also download the admin client bundle with the following <span class="hljs-built_in">command</span>: launchpad download-bundle --username &lt;username&gt; --password &lt;password&gt;
</code></pre>
<p>Now, to test that everything is OK, go into the cluster admin UI:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/Screen-Shot-2020-07-07-at-12.25.50-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Admin login UI</em></p>
<p>After logging in, you are presented the cluster admin UI:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/Screen-Shot-2020-07-07-at-12.27.30-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Admin dashboard</em></p>
<div>
<img src="https://www.freecodecamp.org/news/content/images/2020/06/cherry-success.png" alt="drawing" width="600" height="400" loading="lazy">
</div>

<p>I played a little with some of its features, and overall they are great. They provide easy to usage Access Controls and Certified Docker images.</p>
<p>These instructions are based on this <a target="_blank" href="https://github.com/Mirantis/launchpad/blob/master/docs/getting-started.md">getting-started guide</a>. </p>
<h2 id="heading-wrapping-up"><strong>Wrapping </strong>up<em>**</em></h2>
<p>In this article we saw how to set up Docker on Ubuntu 18.04 for both CE and EE versions.</p>
<p>And since <a target="_blank" href="https://techcrunch.com/2019/11/13/mirantis-acquires-docker-enterprise/">Mirantis has acquired Docker Enterprise</a>, we found out that Launchpad is the latest way for customers looking to try out Docker Enterprise licenses. </p>
<p>Overall the developer/deployment experience is really good, since almost all steps to get an environment ready for Docker EE are automated. And Docker seems to be looking to increasingly automate this process, so that is really nice!  </p>
<ul>
<li>Illustrations from <a target="_blank" href="https://icons8.com/">Icons8</a></li>
</ul>
<p>If you found this helpful, or wish to challenge or extend anything raised here, feel free to contact me on <a target="_blank" href="https://twitter.com/mesmacosta">Twitter</a> or <a target="_blank" href="https://www.linkedin.com/in/mesmacosta">Linkedin</a>. Let's connect!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Install Rails on Ubuntu and Update Ruby to the Latest Version ]]>
                </title>
                <description>
                    <![CDATA[ By Adebola Adeniran A couple of months ago, when I learned Ruby-on-Rails for the first time, I had to work on a collaborative project with a coding partner. We kept running into issues, as he had a different version of Rails and Buby setup for the pr... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-install-rails-on-ubuntu-and-update-ruby-to-the-latest-version/</link>
                <guid isPermaLink="false">66d45d5d51f567b42d9f840f</guid>
                
                    <category>
                        <![CDATA[ Rails ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Ruby ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Ubuntu ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 01 Jul 2020 12:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/06/Slice-3-1-.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Adebola Adeniran</p>
<p>A couple of months ago, when I learned Ruby-on-Rails for the first time, I had to work on a collaborative project with a coding partner. We kept running into issues, as he had a different version of Rails and Buby setup for the project. I couldn't wrap my head around how to install the versions the project needed. </p>
<p>Here's the guide I wish I had. It also shows you how to switch the version of Ruby or Rails you're using, depending on the projects you're working on.</p>
<p>First, let's get the latest version of Ruby installed. To do this, we need to install a package called <strong>RVM - Ruby version manager.</strong> This package lets us install ANY version of Ruby on our Ubuntu machine and allows us to switch between versions.</p>
<p>All the code here will be run using the Ubuntu CLI/terminal.</p>
<h2 id="heading-installing-rvm">Installing RVM</h2>
<ol>
<li>First, we need to install a pre-requisite. Open up your Ubuntu terminal and type the command:</li>
</ol>
<pre><code>sudo apt-get install software-properties-common
</code></pre><p>Next, we need to add the <strong>PPA (Personal Package archive)</strong>. A PPA is how we get files distributed by developers that are yet to make it to the official Ubuntu package/app store. </p>
<p>It's also a way for developers to distribute the latest versions of their software while waiting for Ubuntu to test and publish that software in the official store.</p>
<pre><code>sudo apt-add-repository -y ppa:rael-gc/rvm
</code></pre><p>The command above adds the PPA to the list of locations we can download packages from on our Ubuntu machine.</p>
<p>Next, let's refresh our list of packages by running:</p>
<p><code>sudo apt-get update</code></p>
<p>Finally, let's install RVM itself.</p>
<pre><code>sudo apt-get install rvm
</code></pre><p>Now restart your terminal for your changes to take effect. Then, type <code>rvm version</code> and hit <code>enter</code> to check that rvm is installed. You should get a response like this:</p>
<p><code>rvm 1.29.10 (manual) by Michal Papis, Piotr Kuczynski, Wayne E. Seguin [[https://rvm.io](https://rvm.io)]</code></p>
<h2 id="heading-installing-ruby">Installing Ruby</h2>
<p>Now we can install the latest Ruby version which is 2.7.1. Run the command <code>rvm install 2.7.1</code>. Alternatively, you can run <code>rvm install ruby</code> which will install the latest stable version (this will install v2.7.0).  </p>
<p>To see what Ruby versions you have installed, run <code>rvm ls</code>. To switch between Ruby versions, run <code>rvm use &lt;version_number&gt;</code> (for example, <code>rvm use 2.7.1</code>).</p>
<h2 id="heading-installing-ruby-on-rails">Installing Ruby-on-Rails</h2>
<p>The latest version of Rails is at 6.03. Rails is simply a Ruby gem, and with Ruby installed we can install Rails! Run <code>gem install rails</code> to install the latest version of Rails.  </p>
<p>Finally, to check that all went well, run <code>rails -v</code>. You should get <code>Rails 6.0.3.2</code> back, as this is the latest version at the time of publishing this article.   </p>
<p>You can now start your first Rails project by typing <code>rails new myapp</code>.</p>
<p>Hey, you're now on Rails!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Install Node.js on Ubuntu and Update npm to the Latest Version ]]>
                </title>
                <description>
                    <![CDATA[ By Adebola Adeniran If you try installing the latest version of node using the apt-package manager, you'll end up with v10.19.0. This is the latest version in the ubuntu app store, but it's not the latest released version of NodeJS.  This is because ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-install-node-js-on-ubuntu-and-update-npm-to-the-latest-version/</link>
                <guid isPermaLink="false">66d45d5b55db48792eed3efd</guid>
                
                    <category>
                        <![CDATA[ node js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ npm ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Ubuntu ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 30 Jun 2020 18:18:41 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/06/Slice-3-2-.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Adebola Adeniran</p>
<p>If you try installing the latest version of node using the apt-package manager, you'll end up with <strong>v10.19.0</strong>. This is the latest version in the ubuntu app store, but it's not the latest released version of NodeJS. </p>
<p>This is because when new versions of a software are released, it can take months for the Ubuntu team to test and release in the official Ubuntu store. As a result, to get the latest versions of any software, we may have to use private packages published by developers.</p>
<p>In this tutorial, what we want to do is get either <strong>v12.18.1</strong> (LTS - with Long term support) or <strong>v14.4</strong> of Node. To get the latest versions, we can use either <strong>nodesource</strong> or <strong>nvm</strong> (node version manager). I'll show you how to use both.</p>
<p>All commands here will be run using the Ubuntu CLI/terminal.</p>
<h2 id="heading-using-nvm-my-preferred-method">Using NVM - my preferred method</h2>
<p>I like nvm because it allows me use different node versions for different projects.<br>Sometimes, you may be collaborating on a project with someone using a different version of node and you need to switch node versions to what the project requires. For this, nvm is the best tool.</p>
<h2 id="heading-install-nvm">Install NVM</h2>
<p><code>curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash</code></p>
<p>To check that nvm is installed, type <code>nvm --version</code>. If you get a version number back like <code>0.35.3</code>, then you know nvm was successfully installed.</p>
<p><strong>Restart your terminal for your changes to take effect.</strong></p>
<h2 id="heading-install-nodejs">Install NodeJS</h2>
<p>Next, let's install Nodejs version 14.4. </p>
<p>Simply run <code>nvm install 14.4.0</code> .</p>
<p>You can use a similar command to install any version of node you want, for example <code>nvm install 12.18.1</code>.</p>
<p>This command automatically installs <strong>nodejs</strong> as well as the latest <strong>npm</strong> version which is at  <code>v6.14.5</code>.</p>
<p>If you ever need to switch node versions, you can simply run <code>nvm use &lt;version-number&gt;</code> , for example <code>nvm use v12.18.1</code>.</p>
<p>To list the different node versions you have installed with nvm, run <code>nvm ls</code>.</p>
<h2 id="heading-install-nodesource">Install Nodesource</h2>
<p>Run the command below to tell Ubuntu that we want to install the Nodejs<br>package from nodesource.</p>
<p><code>curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash -</code></p>
<p><strong>NB</strong> that v14.4.0 is the latest version of Node but doesn't currently have LTS - long term support provided for it. To install the latest version of Node with LTS, change <code>14</code> in the command above to <code>12</code>.</p>
<p>You may be prompted to enter the password for your root user. Enter that and hit enter/return.</p>
<h2 id="heading-install-nodejs-1">Install NodeJS</h2>
<p>Once we're done setting up Nodesource, we can now install Nodejs v14.4.<br>Run <code>sudo apt-get install -y nodejs</code>.</p>
<p>Once we're done, we can check that we have the latest version of Node installed.<br>Simply type <code>nodejs -v</code> into your terminal and it should return <code>v14.4.0</code>.</p>
<p>You should have npm automatically installed at this point. To check what npm version you have, run <code>npm version</code>. If you do not get an object that includes the latest version of npm at 6.14.5, <code>{ npm: '6.14.5' }</code>, then you can update npm manually by running the following command:</p>
<p> <code>npm install -g npm@latest</code>.</p>
<p>If you run into any issues with npm being unable to update because it's not installed, you can install npm first by using <code>sudo apt-get install -y npm</code>, then run the command above to update it.</p>
<p>For certain npm packages to run, we also need to run the command below<br><code>sudo apt install build-essential</code>.</p>
<p>And that's it!</p>
<p>You've got the latest versions of NodeJS and NPM on your Ubuntu machine.</p>
<p>Go build great products :)</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Set Up Ubuntu MATE on a Raspberry PI ]]>
                </title>
                <description>
                    <![CDATA[ By Goran Aviani A few days ago a Raspberry Pi I use for CI on my personal projects stopped working. The error was easily fixable, but since running anything on that PI was slow from day one, I decided not to proceed in that direction.  Also, because ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-set-up-ubuntu-mate-on-raspberry-pi/</link>
                <guid isPermaLink="false">66d45ee6680e33282da25e6d</guid>
                
                    <category>
                        <![CDATA[ Computers ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Linux ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Raspberry Pi ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Ubuntu ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 30 Jun 2020 15:46:18 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/06/1593285574373_plus-1.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Goran Aviani</p>
<p>A few days ago a Raspberry Pi I use for CI on my personal projects stopped working. The error was easily fixable, but since running anything on that PI was slow from day one, I decided not to proceed in that direction. </p>
<p>Also, because of the same issue I always wanted to switch to another OS – but I never had the proper motivation since everything worked on that Raspberry PI, right? Well the motivation came along with this article :)</p>
<p><strong>Note</strong>: The original setup on the Raspberry PI was quite simple: Raspibian OS, VNC Server, and Jenkins.</p>
<p>For you that are new to Raspberries here is a little background at what they are, and what they can be used for. </p>
<p>Raspberry Pi's are basically small computers used most often used to learn programming skills, build hardware projects, do home automation, and some have even found usage in industrial applications. </p>
<p>There are a few different types of PI's on the market today. To learn more about them please visit the their Wikipedia page: <a target="_blank" href="https://en.wikipedia.org/wiki/Raspberry_Pi#Generations">https://en.wikipedia.org/wiki/Raspberry_Pi#Generations</a></p>
<p>Tools you'll needed to complete this tutorial:</p>
<ul>
<li>Raspberry PI</li>
<li>Micro SD card</li>
<li>Micro SD card adapter for your laptop</li>
<li>Windows</li>
<li>Mouse for Raspberry PI</li>
<li>HDMI cable to connect  your Raspberry PI to at TV or any other kind of screen</li>
<li>Keyboard for Raspberry PI is good to have but not necessary as Ubuntu MATE offers on screen keyboard</li>
</ul>
<p>Once we complete all the steps, this article will show you how to:</p>
<ul>
<li>Set up Ubuntu MATE on an SD card using Windows</li>
<li>Install Ubuntu MATE to Raspberry PI</li>
<li>Things to do after installing Ubuntu MATE</li>
</ul>
<p>There are several OS options for Raspberry PI available, and Ubuntu Mate is just one option. For more info on other options you can check out this article: </p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://www.ubuntupit.com/best-raspberry-pi-os-available/">https://www.ubuntupit.com/best-raspberry-pi-os-available/</a></div>
<h2 id="heading-flashing-ubuntu-mate-to-micro-sd-card">Flashing Ubuntu MATE to Micro SD card</h2>
<p>The SD card and USB sticks are called a Flash drives because they have a flash type memory in them. So flashing means creating a bootable drive with a specific operating system (OS) on it. </p>
<p>Navigate to the download page of Ubuntu MATE and download the recommended architecture image for Raspberry PI: </p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://ubuntu-mate.org/">https://ubuntu-mate.org/</a></div>
<p><img src="https://lh6.googleusercontent.com/HJ1b4UY1H8tqnWldXMWh1inaYVTuMQEvFyY6ia-MvNw-pKmx0B42YQ96i2x4UmB3gBfAmtkrOeeoAHr4H4DNU_I025ionZRQY0ZKXDaDLrBBWCP3R_vZrzUR3SC2f0O7-TNYLzne" alt="Image" width="1397" height="731" loading="lazy">
<em>Download the Raspberry PI 32 bit version (recommended)</em></p>
<h3 id="heading-setting-up-the-sd-card">Setting Up the SD Card</h3>
<p>After downloading the Ubuntu MATE image we need to write it to the SD card. To do that we will use the Balena Etcher tool. Etcher is a tool we will download from here:</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://www.balena.io/etcher/">https://www.balena.io/etcher/</a></div>
<p><img src="https://lh6.googleusercontent.com/1vYIoox0YKBcjUKbaZeGySgpiBgGl5VvcibE_vHRG15r1lq8geFO44TBdszTA-qRU2eUYqX2rkUoTiregfWz78BZ5IjQKIOwMAfoZc5ltVtgsVNxwrJ0EswWNXrM-DNOLVdDwsfC" alt="Image" width="1512" height="815" loading="lazy">
<em>Balena Ether download page</em></p>
<p>Install Etcher and launch it. Then select the Ubuntu MATE image file you previously downloaded, along with your SD card, and start the flashing process.</p>
<p><strong>Note</strong>: Flashing Ubuntu MATE to the SD card takes some time, so feel free to get yourself a cup of coffee.</p>
<p><img src="https://lh3.googleusercontent.com/BAvIy-shTq645HjARX0MI0DqE5eZvfNqd2A8srKGtB8sVsDfxPOfhz-v6B7qSUl6JddF7O8dP7C9U_hJmgmhrGB02gZ2Ub0tgsOJfQOaocBdoHgUDQ1tYODhSARSLd2STl_G43Id" alt="Image" width="988" height="596" loading="lazy">
<em>Balena Etcher decompressing Ubuntu MATE image</em></p>
<p><img src="https://lh4.googleusercontent.com/iL3a8osNs-fgqcoqbiWljsfpQItxMB2lsY6ibHOAValUdYoNetN0DoqwV4K2a0enatDXAvulVmuuOckdtcQn3QcyXr-OfZRBgg02_2jSG2Ms7bTzYL5LGVXu5irD6-cL6T03NLo7" alt="Image" width="982" height="582" loading="lazy">
<em>Balena Etcher validating Ubuntu MATE image</em></p>
<p>Once you are done with flashing, take out the SD card from the adapter and put it in the Raspberry PI. Also, this is the step where you will need to connect the PI with the mouse and a screen.</p>
<h2 id="heading-installing-ubuntu-mate-on-raspberry-pi">Installing Ubuntu MATE on Raspberry PI</h2>
<p>Once you are done connecting all peripherals of the Raspberry PI, connect it to the power source and let it startup.</p>
<p>The Ubuntu MATE installation process is exactly the same as for ordinary Ubuntu. During this process you will be asked to to select your keyboard layout, timezone, username and password. Here is the step by step instalation guide for Ubuntu 18.04:  <a target="_blank" href="https://phoenixnap.com/kb/how-to-install-ubuntu-18-04-bionic-beaver">Ubuntu installation</a>. </p>
<p>After the installation is done you will be greeted by the desktop screen.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/ubuntu-mate-home.png" alt="Image" width="600" height="400" loading="lazy">
<em>Ubuntu Mate desktop greeting screen</em></p>
<h2 id="heading-things-to-do-after-installing-ubuntu-mate">Things to do after installing Ubuntu MATE</h2>
<h3 id="heading-update-the-local-database">Update the local database</h3>
<p>This command updates/maps the local database of your local packages with updates, later allowing your system to fetch new versions of the packages.</p>
<p>sudo apt update</p>
<h3 id="heading-upgrading-the-installed-packages">Upgrading the installed packages</h3>
<p>This command fetches new versions of packages existing on the machine you previously mapped with <em>sudo apt update</em> command.</p>
<p>sudo apt upgrade</p>
<p>Note: Updating Ubuntu MATE takes a lot of time so feel free to get yourself another cup of coffee, and a pastry to go along with it. If you don't have any pastry around feel free to go to the nearest bakery, because by the time you get back you system will probably be 50% upgraded.</p>
<h3 id="heading-installing-the-ubuntu-software-application">Installing the Ubuntu Software application</h3>
<p>Software Boutique is the default software center on Ubuntu MATE. However, it has a very limited selection of applications, and one of the more interesting apps needed for my project is missing. </p>
<p>Luckily, since this is an Ubuntu distribution, there is a way to install the standard Ubuntu Software center which has more app choices.  </p>
<p>Apparently there is a way of installing Ubuntu Software center via Software Bundle. But when selecting the option to doing that I was stuck and nothing seemed to happen for me so I just used the terminal command:</p>
<p>sudo apt install ubuntu-software</p>
<p>Bra gjort! You have just finished setting up the Ubuntu Mate OS on your Raspberry PI device!</p>
<p>Check out more articles like this on my <a target="_blank" href="https://www.freecodecamp.org/news/author/goran/">freeCodeCamp profile</a>, <a target="_blank" href="https://medium.com/@goranaviani">Medium profile</a>, and other fun stuff I build on my <a target="_blank" href="https://github.com/GoranAviani">GitHub page</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Set Up a Python Virtual Environment on Ubuntu 20.04 ]]>
                </title>
                <description>
                    <![CDATA[ By Goran Aviani I recently got myself a “new” laptop – a Lenovo x270 (yay)! And once again I needed to set up a Python virtual environment. So of course I Googled for a solution, just to find my previously written article on the same topic! So in thi... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-set-up-python-virtual-environment-on-ubuntu-20-04/</link>
                <guid isPermaLink="false">66d45ee1b3016bf139028d3b</guid>
                
                    <category>
                        <![CDATA[ Integrated Development Environment   ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Ubuntu ]]>
                    </category>
                
                    <category>
                        <![CDATA[ virtualenv ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 12 Jun 2020 14:36:40 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/06/prateek-katyal-6jYnKXVxOjc-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Goran Aviani</p>
<p>I recently got myself a “new” laptop – a Lenovo x270 (yay)! And once again I needed to set up a Python virtual environment. So of course I Googled for a solution, just to find my <a target="_blank" href="https://www.freecodecamp.org/news/virtualenv-with-virtualenvwrapper-on-ubuntu-18-04/">previously written article on the same topic</a>!</p>
<p>So in this article, I'll update the instructions based on my newly acquired knowledge.</p>
<p>And let me tell you, it’s easier than before because we are going to do only two things:</p>
<ul>
<li>Install virtualenvwrapper</li>
<li>Edit the .bashrc file</li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>In this article I will show you how to set up virtualenvwrapper with pip3 (pip for Python 3). We are not going to use Python 2 because <a target="_blank" href="https://www.python.org/doc/sunset-python-2/">it's no longer supported</a>.</p>
<p>To complete this tutorial, you will need a computer with Ubuntu 20.04 installed and an internet connection. Also, some knowledge of the terminal and Vim editor would be useful.</p>
<h2 id="heading-setting-up-a-virtual-environment">Setting up a Virtual Environment</h2>
<p>Now open your terminal in the home directory by right clicking and choosing the option “Open in Terminal”. You can also press the CTRL, ALT, and T keys on your keyboard at the same time to open the Terminal application automatically.</p>
<p>You first need to create a special directory that will hold all of your virtual environments. So go ahead and create a new hidden directory called virtualenv:</p>
<pre><code class="lang-bash">mkdir .virtualenv
</code></pre>
<h2 id="heading-pip3">pip3</h2>
<p>Now you should install pip for Python3:</p>
<pre><code class="lang-bash">sudo apt install python3-pip
</code></pre>
<p>Confirm the pip3 installation:</p>
<pre><code class="lang-bash">pip3 -V
</code></pre>
<h2 id="heading-virtualenvwrapper">virtualenvwrapper</h2>
<p>virtualenvwrapper is a set of extensions for virtualenv. It provides commands like mkvirtualenv, lssitepackages, and especially workon for switching between different virtualenv environments.</p>
<p>Install virtualenvwrapper via pip3:</p>
<pre><code class="lang-bash">pip3 install virtualenvwrapper
</code></pre>
<h2 id="heading-bashrc-file">bashrc file</h2>
<p>We are going to modify your .bashrc file by adding a row that will adjust every new virtual environment to use Python 3. We will point virtual environments to the directory we created above (.virtualenv) and we will also point to the locations of the virtualenv and virtualenvwrapper.</p>
<p>Now open the .bashrc file using the Vim editor:</p>
<pre><code class="lang-bash">vim .bashrc
</code></pre>
<p>If you still haven’t used Vim before or you don’t have it installed on your computer, you should install it now. It is one of the most widely used Linux editors and for good reason.</p>
<pre><code class="lang-bash">sudo apt install vim
</code></pre>
<p>After you've installed Vim open the .bashrc file by typing in the <code>vim .bashrc</code> command in your terminal. Navigate to the bottom of the .bashrc file, press the letter <strong><em>i</em></strong> to enter insert mode in Vim, and add these rows:</p>
<pre><code class="lang-bash"><span class="hljs-comment">#Virtualenvwrapper settings:</span>
<span class="hljs-built_in">export</span> WORKON_HOME=<span class="hljs-variable">$HOME</span>/.virtualenvs
VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3
. /usr/<span class="hljs-built_in">local</span>/bin/virtualenvwrapper.sh
</code></pre>
<p>After you are done, press the <em><strong>esc</strong></em> key, then type <strong>:<em>wq</em></strong> and press enter. This command will save the file and exit Vim.</p>
<p>Now you need to reload the bashrc script. There are two ways to do it – close and reopen your terminal, or execute this command in the terminal:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">source</span> ~/.bashrc
</code></pre>
<p>To create a virtual environment in Python3 and activate it immediately use this command in your terminal:</p>
<pre><code class="lang-bash">mkvirtualenv name_of_your_env
</code></pre>
<p>To deactivate the environment use the deactivate command.</p>
<p>To list all available virtual environments use the command <em>workon</em> or <em>lsvirtualenv</em> (lsvirtualenv will show the same result as workon but in a fancier way) in your terminal:</p>
<pre><code class="lang-bash">workon
</code></pre>
<pre><code class="lang-bash">lsvirtualenv
</code></pre>
<p>To activate one specific environment use workon + name of your environment:</p>
<pre><code class="lang-bash">workon name_of_your_env
</code></pre>
<p>There are several useful command you might need to use someday:</p>
<p><em>Rmvirtualenv</em> will remove a specific virtual environment located in your .virtualenv directory.</p>
<pre><code class="lang-bash">rmvirtualenv name_of_your_env
</code></pre>
<p><em>Cpvirtualenv</em> will copy the existing virtual environment to a new virtual environment and activate it.</p>
<pre><code class="lang-bash">cpvirtualenv old_virtual_env new_virtual_env
</code></pre>
<p>Well done! You have now created your first isolated Python 3 environment.</p>
<p>Thank you for reading! </p>
<p>Check out more articles like this on my <a target="_blank" href="https://www.freecodecamp.org/news/author/goran/">freeCodeCamp profile</a>, <a target="_blank" href="https://medium.com/@goranaviani">Medium profile</a>, and other fun stuff I build on my <a target="_blank" href="https://github.com/GoranAviani">GitHub page</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Set Up Virtualenv with Virtualenvwrapper on Ubuntu 18.04 ]]>
                </title>
                <description>
                    <![CDATA[ By Goran Aviani Let me tell you a story. Recently, I realized that I needed to review how to set up virtualenvwrapper on top of virtualenv in Ubuntu 18.04. I have completed this process several of times on different computers, and every time it seems... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/virtualenv-with-virtualenvwrapper-on-ubuntu-18-04/</link>
                <guid isPermaLink="false">66d45eff4a7504b7409c33e7</guid>
                
                    <category>
                        <![CDATA[ Developer ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Integrated Development Environment   ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Ubuntu ]]>
                    </category>
                
                    <category>
                        <![CDATA[ virtualenv ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 01 Apr 2020 10:34:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/06/1-aMYnl2Ctt9Y-RZ5bodNF2g.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Goran Aviani</p>
<p>Let me tell you a story. Recently, I realized that I needed to review how to set up virtualenvwrapper on top of virtualenv in Ubuntu 18.04. I have completed this process several of times on different computers, and every time it seems to be just a little bit different than before.</p>
<p>I just got a new laptop and on the way home I read several tutorials on “How to set up virtualenvwrapper on Ubuntu 18.04”. And let me tell you – it seemed really easy because all of those tutorials were pretty straight forward and basically explained how to do these three 3 things:</p>
<ul>
<li>Install virtualenv</li>
<li>Install virtualenvwrapper</li>
<li>Edit .bashrc/.bash_profile or both</li>
</ul>
<p>But even though I read all those tutorials none of them really worked for me.</p>
<p>I had several errors while trying to figure out what went wrong while following the tutorials. </p>
<p>First I got some of “<em>mkvirtualenv: command not found</em>”, then a little of “<em>-bash: /usr/bin/virtualenvwrapper.sh: No such file or directory</em>”, and then a touch of “<em>ERROR: virtualenvwrapper could not find virtualenv in your path</em>”.</p>
<p>After some research I realized that all virtualenvwrapper Ubuntu 18.04 tutorials are copies an old text written before April 2016 (the release date of Ubuntu 16.04).  </p>
<p>I know this because from Ubuntu 16.04 and onward the location of vritualenvwrapper’s pip installation changed from <code>/usr/local/bin/virtualenvwrapper.sh</code> to <code>~/.local/bin/virtualenvwrapper.sh.</code> Note that the local directory is hidden.</p>
<p>So I'll start by writing a tutorial that will show you how to avoid all those issues mentioned above.</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>In this article I will show you how to set up virtualenvwrapper with pip3 (pip for Python 3). I chosen this version of pip instead of a Python 2 because Pythons 2's end of life was January 1. 2020.</p>
<blockquote>
<p>Python 2 will retire in… <a target="_blank" href="https://pythonclock.org/">https://pythonclock.org/</a></p>
</blockquote>
<p>To complete this tutorial you will need a computer with Ubuntu 18.04 installed and an internet connection :). Also some knowledge about terminals and the Vim editor would be useful. I will assume you already updated and upgraded your system.</p>
<h2 id="heading-setting-up-a-virtual-environment">Setting up a Virtual Environment</h2>
<p>Now open your terminal in the home directory by right clicking and choosing the option “Open in Terminal”. You can also press the <code>CTRL</code>, <code>ALT</code>, and <code>T</code> keys on your keyboard at the same time to open the Terminal application automatically.</p>
<p>You first need to create a special directory that will hold all of your virtual environments. So proceed with creating a new hidden directory called virtualenv.</p>
<pre><code>mkdir .virtualenv
</code></pre><p>Now you should install pip for Python3.</p>
<pre><code>sudo apt install python3-pip
</code></pre><p>Confirm the pip3 installation.</p>
<pre><code>pip3 --version
</code></pre><p>Now install virtualenv via pip3.</p>
<pre><code>pip3 install virtualenv
</code></pre><p>To find where your virtualenv was installed, type:</p>
<pre><code>which virtualenv
</code></pre><p>Install virtualenvwrapper via pip3:</p>
<pre><code>pip3 install virtualenvwrapper
</code></pre><p>We are going to modify your .bashrc file by adding a row that will adjust every new virtual environment to use Python 3. We will point virtual environments to the directory we created above (.virtualenv) and we will also point to the locations of the virtualenv and virtualenvwrapper.</p>
<p>Now open the .bashrc file using Vim editor.</p>
<pre><code>vim .bashrc
</code></pre><p>If you still haven’t used the Vim editor or you don’t have it installed on your computer you should install it now. It is a widely used Linux editor, and for good reason.</p>
<pre><code>sudo apt install vim
</code></pre><p>After you've installed Vim open the file .bashrc file by typing the <em>vim .bashrc</em> command in your terminal. Navigate to the bottom of the .bashrc file, press the letter <em>i</em> to enter the insert mode of Vim, and add these rows:</p>
<pre><code>#Virtualenvwrapper settings:
<span class="hljs-keyword">export</span> VIRTUALENVWRAPPER_PYTHON=<span class="hljs-regexp">/usr/</span>bin/python3
<span class="hljs-keyword">export</span> WORKON_HOME=$HOME/.virtualenvs
<span class="hljs-keyword">export</span> VIRTUALENVWRAPPER_VIRTUALENV=<span class="hljs-regexp">/home/g</span>oran/.local/bin/virtualenv
source ~<span class="hljs-regexp">/.local/</span>bin/virtualenvwrapper.sh
</code></pre><p>After you are done, press the <em>esc</em> key. Then type <code>:wq</code> and press enter. This command will save and exit the Vim editor. Close and reopen your terminal when you’re done.</p>
<p>To create a virtual environment in Python3 and activate it immediately, use this command in your terminal:</p>
<pre><code>mkvirtualenv name_of_your_env
</code></pre><p>You should confirm that this environment is set up for Python3:</p>
<pre><code>Python -V
</code></pre><p>To deactivate the environment use the deactivate command.</p>
<pre><code>deactivate
</code></pre><p>To list all available virtual environments use the command <em>workon</em> or <em>lsvirtualenv</em> (same result as workon but shown in a fancy way) in your terminal:</p>
<pre><code>workon

lsvirtualenv
</code></pre><p>To activate one specific environment use workon + name of your environment:</p>
<pre><code>workon name_of_your_env
</code></pre><p>There are several useful command you might need to use someday:</p>
<p><em>Rmvirtualenv</em> will remove a specific virtual environment located in your .virtualenv directory.</p>
<pre><code>rmvirtualenv name_of_your_env
</code></pre><p><em>Cpvirtualenv</em> will copy the existing virtual environment to a new virtual environment and activate it.</p>
<pre><code>cpvirtualenv old_virtual_env new_virtual_env
</code></pre><p>Well done! You have now created your first isolated Python 3 environment.</p>
<p>Thank you for reading! Check out more articles like this on <a target="_blank" href="https://www.freecodecamp.org/news/author/goran/">my freeCodeCamp profile</a> and other fun stuff I build on <a target="_blank" href="https://github.com/GoranAviani">my GitHub page</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
