<?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[ WSL - 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[ WSL - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sat, 30 May 2026 19:49:41 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/wsl/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Troubleshoot Ghost CMS: Fixing WSL, Docker, and ActivityPub Errors ]]>
                </title>
                <description>
                    <![CDATA[ Setting up Ghost CMS (Content Management System) on your local machine is a great way to develop themes and test new features. But if you're using Windows or Docker, you might run into errors that sto ]]>
                </description>
                <link>https://www.freecodecamp.org/news/fix-ghost-cms-errors/</link>
                <guid isPermaLink="false">69bc3254b238fd45a31f6959</guid>
                
                    <category>
                        <![CDATA[ ghost ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Docker ]]>
                    </category>
                
                    <category>
                        <![CDATA[ WSL ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Node.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ troubleshooting ]]>
                    </category>
                
                    <category>
                        <![CDATA[ debugging ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Abdul Talha ]]>
                </dc:creator>
                <pubDate>Thu, 19 Mar 2026 17:28:52 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/uploads/covers/5e1e335a7a1d3fcc59028c64/85f5e0bb-26ff-42ce-ba66-afec6df4bb5d.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Setting up Ghost CMS (Content Management System) on your local machine is a great way to develop themes and test new features. But if you're using Windows or Docker, you might run into errors that stop your progress. And debugging takes time away from your actual development work.</p>
<p>In this guide, you'll learn the root causes and exact fixes for three common Ghost CMS deployment errors:</p>
<ul>
<li><p><strong>Error 1:</strong> SQLite installation failures on Windows.</p>
</li>
<li><p><strong>Error 2:</strong> Docker containers crashing with Code 137 (memory limits).</p>
</li>
<li><p><strong>Error 3:</strong> "Loading Interrupted" errors in the ActivityPub Network tab.</p>
</li>
</ul>
<p>By the end of this article, you'll have a stable, working local Ghost setup. You'll know how to properly use WSL for Node.js apps, manage Docker resources, and successfully configure Ghost's new social web features.</p>
<h2 id="heading-error-1-sqlite-installation-failures-on-windows">Error 1: SQLite Installation Failures on Windows</h2>
<h3 id="heading-the-symptom"><strong>The Symptom</strong></h3>
<p>When you run the command <code>ghost install local</code> on a Windows machine, the setup fails. You will see a long list of red text in your terminal that looks like this:</p>
<pre><code class="language-plaintext">Error: Cannot find module 'sqlite3'
...
node-pre-gyp ERR! stack Error: Failed to execute...
...
MSB4019: The imported project "C:\Microsoft.Cpp.Default.props" was not found.
</code></pre>
<p>The error usually mentions "sqlite3" and says it "failed to execute" or is "missing."</p>
<h3 id="heading-the-cause"><strong>The Cause</strong></h3>
<p>Ghost uses SQLite to store your blog's data. SQLite is a "native module." This means it needs a small piece of code that must be built to fit your computer's system perfectly.</p>
<p>Because Ghost was created to run on Linux servers, it expects to find Linux build tools to make these files. Windows uses different tools and a different way of organising files. When the Ghost CLI tries to build the SQLite files on Windows, it can't find the tools it needs, so the installation stops. Using WSL gives Ghost the Linux environment it expects.</p>
<h3 id="heading-how-to-fix-it">How to Fix it:</h3>
<p>You can use Windows Subsystem for Linux (WSL) to create a working setup.</p>
<ol>
<li><p>Open your WSL terminal (like Ubuntu).</p>
</li>
<li><p>Check your tools by running <code>node --version</code>, <code>npm --version</code>, and <code>python3 --version</code>.</p>
</li>
<li><p>Install the Ghost CLI globally inside WSL:</p>
<pre><code class="language-plaintext">npm install -g ghost-cli@latest
</code></pre>
</li>
<li><p>Run the local setup command:</p>
<pre><code class="language-plaintext">ghost install local
</code></pre>
</li>
<li><p>Start the server:</p>
<pre><code class="language-plaintext">ghost start
</code></pre>
</li>
</ol>
<h3 id="heading-how-to-verify">How to Verify:</h3>
<p>Open your web browser and go to <code>http://localhost:2368</code>. You should see the default Ghost welcome page load without errors.</p>
<h2 id="heading-error-2-docker-container-exiting-with-code-137">Error 2: Docker Container Exiting with Code 137</h2>
<h3 id="heading-the-symptom">The Symptom:</h3>
<p>When you're running Ghost using Docker Compose, the containers crash. The terminal logs show <code>Ghost admin container exiting with code 137</code> or <code>Admin service killed due to memory constraints</code>.</p>
<h3 id="heading-the-cause">The Cause:</h3>
<p>So why does this happen? Well, error code 137 means your computer ran out of memory (RAM) and stopped the container. This usually happens if you try to run the full Ghost developer setup (which includes 15+ extra tools) on a standard computer.</p>
<h3 id="heading-how-to-fix-it">How to Fix it:</h3>
<p>To fix this error, you can switch from the complex setup to a simple setup using the official Ghost Docker image.</p>
<p>To do this, first stop and remove the broken containers:</p>
<pre><code class="language-plaintext">docker-compose down -v
docker system prune -a
</code></pre>
<p>Then create a new <code>docker-compose.yml</code> file with only the basic tools (Ghost and a database):</p>
<pre><code class="language-plaintext">services:
  ghost:
    image: ghost:latest
    restart: always
    ports:
      - "2368:2368"
    environment:
      database__client: mysql
      database__connection__host: mysql
      database__connection__user: root
      database__connection__password: yourpassword
      database__connection__database: ghost
      url: http://localhost:2368
    volumes:
      - ghost_content:/var/lib/ghost/content

  mysql:
    image: mysql:8.0
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: yourpassword
      MYSQL_DATABASE: ghost
    volumes:
      - mysql_data:/var/lib/mysql

volumes:
  ghost_content:
  mysql_data:
</code></pre>
<p>Then start the simple setup:</p>
<pre><code class="language-plaintext">docker-compose up -d
</code></pre>
<h3 id="heading-how-to-verify">How to Verify:</h3>
<p>Type <code>docker-compose ps</code> in your terminal. You should see both the <code>ghost</code> and <code>mysql</code> containers listed with a status of "Up".</p>
<h2 id="heading-error-3-loading-interrupted-in-network-analytics">Error 3: "Loading Interrupted" in Network Analytics</h2>
<h3 id="heading-the-symptom">The Symptom:</h3>
<p>When you click the <strong>Analytics → Network</strong> tab in your local Ghost admin panel, the page shows a "Loading Interrupted" error. Your terminal logs show 404 errors and webhook failures:</p>
<pre><code class="language-plaintext">INFO "GET /.ghost/activitypub/v1/feed/reader/" 404 52ms
ERROR No webhook secret found - cannot initialise
</code></pre>
<h3 id="heading-the-cause">The Cause:</h3>
<p>The Network tab acts as an ActivityPub reader, not a normal analytics dashboard. This error happens because ActivityPub is not set up for local use. It needs extra tools (Caddy, Redis) and a clean web address without port numbers to work.</p>
<h3 id="heading-how-to-fix-it">How to Fix it:</h3>
<p>To fix this error, just run Ghost with its required Docker tools and update your local config file to turn on the social web features.</p>
<p>First, start the required tools (Caddy, MySQL, Redis) from your Ghost folder:</p>
<pre><code class="language-plaintext">SSH_AUTH_SOCK=/dev/null docker compose up -d caddy mysql redis
</code></pre>
<p>Then open your <code>config.local.json</code> file. Set the URL to a clean localhost address (remove the <code>:2368</code> port) and turn on the developer features:</p>
<pre><code class="language-plaintext">{
    "url": "http://localhost",
    "social_web_enabled": true,
    "enableDeveloperExperiments": true
}
</code></pre>
<p>Stop your current Ghost process:</p>
<pre><code class="language-plaintext">pkill -f "yarn dev:ghost"
</code></pre>
<p>And restart Ghost with the new settings:</p>
<pre><code class="language-plaintext">yarn dev:ghost
</code></pre>
<h3 id="heading-how-to-verify">How to Verify:</h3>
<p>Log back into your Ghost admin panel and click <strong>Analytics → Network</strong>. The error message will be gone, and you will see the ActivityPub feed instead.</p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>Local setups can be hard, especially when mixing Windows, Docker, and new features like ActivityPub.</p>
<p>By fixing these three errors, you did more than just get Ghost running. You learned how to bypass Windows limits using WSL, how to manage Docker memory, and how Ghost routes social web traffic.</p>
<p>You now have a stable, fast, and fully working Ghost CMS workspace ready for your content.</p>
<p><strong>Let’s connect!</strong> You can find my latest work on my <a href="https://blog.abdultalha.tech/portfolio"><strong>Technical Writing Portfolio</strong></a> or reach out to me on <a href="https://www.linkedin.com/in/abdul-talha/"><strong>LinkedIn</strong></a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Self-Host AFFiNE on Windows with WSL and Docker ]]>
                </title>
                <description>
                    <![CDATA[ Depending on cloud apps means that you don't truly own your notes. If your internet goes down or if the company changes its rules, you could lose access. In this article, you'll learn how to build you ]]>
                </description>
                <link>https://www.freecodecamp.org/news/self-host-affine-windows/</link>
                <guid isPermaLink="false">69b2e3051be92d8f177bf807</guid>
                
                    <category>
                        <![CDATA[ self-hosted ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Open Source ]]>
                    </category>
                
                    <category>
                        <![CDATA[ deployment ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Docker ]]>
                    </category>
                
                    <category>
                        <![CDATA[ WSL ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Abdul Talha ]]>
                </dc:creator>
                <pubDate>Thu, 12 Mar 2026 16:00:05 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/uploads/covers/5e1e335a7a1d3fcc59028c64/950eee10-aa2c-4071-9c40-abaf759f6d10.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Depending on cloud apps means that you don't truly own your notes. If your internet goes down or if the company changes its rules, you could lose access.</p>
<p>In this article, you'll learn how to build your own private workspace using AFFiNE. You'll use Docker Compose to link three separate pieces of software together:</p>
<ul>
<li><p>The AFFiNE Core application.</p>
</li>
<li><p>A PostgreSQL database to store your notes and pages.</p>
</li>
<li><p>A Redis cache to make the app run fast and smooth.</p>
</li>
</ul>
<p>By the end of this article, you'll have a fully functional web app running on your own computer that works just like the cloud version of Notion.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a href="#heading-what-is-affine">What is AFFiNE?</a></p>
</li>
<li><p><a href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a href="#heading-step-1-preparing-your-workspace">Step 1: Preparing Your Workspace</a></p>
</li>
<li><p><a href="#heading-step-2-getting-the-official-setup-files">Step 2: Getting the Official Setup Files</a></p>
</li>
<li><p><a href="#heading-step-3-configuring-your-environment-env">Step 3: Configuring Your Environment (.env)</a></p>
</li>
<li><p><a href="#heading-step-4-launching-the-system">Step 4: Launching the System</a></p>
</li>
<li><p><a href="#heading-step-5-accessing-the-admin-panel">Step 5: Accessing the Admin Panel</a></p>
</li>
<li><p><a href="#heading-step-6-configuration-making-it-yours">Step 6: Configuration (Making It Yours)</a></p>
</li>
<li><p><a href="#heading-step-7-connecting-the-desktop-app-optional">Step 7: Connecting the Desktop App (Optional)</a></p>
</li>
<li><p><a href="#heading-step-8-stopping-the-server-and-safe-backups">Step 8: Stopping the Server and Safe Backups</a></p>
</li>
<li><p><a href="#heading-step-9-how-to-upgrade-later">Step 9: How to Upgrade Later</a></p>
</li>
<li><p><a href="#heading-common-installation-errors-and-troubleshooting">Common Installation Errors and Troubleshooting</a></p>
</li>
<li><p><a href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-what-is-affine">What is AFFiNE?</h2>
<p>AFFiNE is an "all-in-one" workspace that combines the powers of writing, drawing, and planning.</p>
<p>While tools like Notion focus on documents and Miro focus on whiteboards, AFFiNE lets you do both in a single space. You can turn your written notes into a visual canvas with one click. This makes it perfect for brainstorming, tracking tasks, and managing your personal knowledge.</p>
<h3 id="heading-the-power-of-self-hosting">The Power of Self-Hosting</h3>
<p>While AFFiNE offers a cloud version, hosting it yourself gives you three major benefits:</p>
<ul>
<li><p><strong>Total data ownership:</strong> Your notes never leave your machine. You own the database.</p>
</li>
<li><p><strong>Privacy in the AI age:</strong> No big tech company can scan your private ideas or use them for AI training.</p>
</li>
<li><p><strong>Real DevOps skills:</strong> Learning how to manage Docker inside WSL is a high-value skill for any modern developer.</p>
</li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>To follow this article, make sure you have these tools ready on your machine:</p>
<ul>
<li><p><strong>WSL 2 Installation:</strong> You must have WSL installed if you are using Windows (I am using Ubuntu for this guide).</p>
</li>
<li><p><strong>Docker and Docker Compose:</strong> These must be installed and running on your machine.</p>
</li>
<li><p><strong>Linux Terminal Commands:</strong> You should be familiar with basic commands like <code>mkdir</code>, <code>cd</code>, and <code>wget</code>.</p>
</li>
</ul>
<h2 id="heading-step-1-preparing-your-workspace">Step 1: Preparing Your Workspace</h2>
<p>To start, create a folder for your AFFiNE files. This keeps your data in one organised place.</p>
<p>Then open your WSL terminal and run these commands:</p>
<pre><code class="language-shell">mkdir affine
cd affine
</code></pre>
<img src="https://cdn.hashnode.com/uploads/covers/6729b04417afd6915f5c2e3e/021e4aef-ede1-4bec-b96e-2acaea9d8f40.png" alt="A terminal Showing the commands mkdir and cd" style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<h2 id="heading-step-2-getting-the-official-setup-files">Step 2: Getting the Official Setup Files</h2>
<p>You will download the official configuration files directly from the AFFiNE. In your WSL terminal, run these two commands:</p>
<ol>
<li>Download the Docker Compose file:</li>
</ol>
<pre><code class="language-shell">wget -O docker-compose.yml https://github.com/toeverything/affine/releases/latest/download/docker-compose.yml
</code></pre>
<ol>
<li>Download the Environment template:</li>
</ol>
<pre><code class="language-shell">wget -O .env https://github.com/toeverything/affine/releases/latest/download/default.env.example
</code></pre>
<img src="https://cdn.hashnode.com/uploads/covers/6729b04417afd6915f5c2e3e/5b366a5f-b426-4e70-95c0-b469f40d6af5.png" alt="A terminal Showing the commands to download affine" style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<h2 id="heading-step-3-configuring-your-environment-env">Step 3: Configuring Your Environment (.env)</h2>
<p>The <code>.env</code> file is like a hidden settings sheet. It keeps your passwords and setup details private.</p>
<p>To edit this file, you can use Nano, which is a simple text editor built into your Linux terminal. Follow these steps to update your settings:</p>
<ol>
<li><p><strong>Open the file with Nano:</strong></p>
<pre><code class="language-shell">nano .env
</code></pre>
</li>
<li><p><strong>Update the settings:</strong> Use your arrow keys to move around the file. Update these specific lines to match the locations below. This keeps your data safely inside your new <code>affine</code> folder:</p>
<pre><code class="language-plaintext">DB_DATA_LOCATION=./postgres
UPLOAD_LOCATION=./storage
CONFIG_LOCATION=./config

DB_USERNAME=affine
DB_PASSWORD=
DB_DATABASE=affine
</code></pre>
<img src="https://cdn.hashnode.com/uploads/covers/6729b04417afd6915f5c2e3e/d0f4a358-e221-45d3-94df-d97b606b4afc.png" alt="A terminal to change the values in env file" style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p><strong>Save and Exit:</strong> Press Ctrl + O to save.</p>
<ul>
<li><p>Press <strong>Enter</strong> to confirm the filename.</p>
</li>
<li><p>Press <strong>Ctrl + X</strong> to exit the editor.</p>
</li>
</ul>
</li>
</ol>
<h2 id="heading-step-4-launching-the-system">Step 4: Launching the System</h2>
<p>Run this Docker command to build your workspace:</p>
<pre><code class="language-shell">docker compose up -d
</code></pre>
<p>Docker will download the AFFiNE app and a Postgres database. The <code>-d</code> flag means it will run quietly in the background.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6729b04417afd6915f5c2e3e/407237bd-f805-4fca-b15c-6bf001f467e7.png" alt="A terminal Showing the commands for docker compose" style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<h2 id="heading-step-5-accessing-the-admin-panel">Step 5: Accessing the Admin Panel</h2>
<p>Once the terminal says "Started," your private server is live!</p>
<p>Open your web browser and go to:</p>
<pre><code class="language-plaintext">http://localhost:3010/
</code></pre>
<p>The first time you visit this page, you must create an admin account. This is the master key to your server.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6729b04417afd6915f5c2e3e/780fafda-0afd-4b67-a2fa-6248b4d5d4f3.png" alt="creating an Admin account" style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<h2 id="heading-step-6-configuration-making-it-yours">Step 6: Configuration (Making It Yours)</h2>
<p>There are two ways to configure your server.</p>
<h3 id="heading-the-easy-way-admin-panel"><strong>The Easy Way: Admin Panel</strong></h3>
<p>In your browser, go to <code>http://localhost:3010/admin/settings</code>. You can change your server name or set up emails here.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6729b04417afd6915f5c2e3e/0f8d4e97-7a47-4328-8e91-a36582d47143.png" alt="Overview of the settings page" style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<h3 id="heading-the-developer-way-config-file"><strong>The Developer Way: Config File</strong></h3>
<p>You can also create a <code>config.json</code> file inside your <code>./config</code> folder.</p>
<pre><code class="language-json">{
  "$schema": "https://github.com/toeverything/affine/releases/latest/download/config.schema.json",
  "server": {
    "name": "My Private Workspace"
  }
}
</code></pre>
<h2 id="heading-step-7-connecting-the-desktop-app-optional">Step 7: Connecting the Desktop App (Optional)</h2>
<p>You don't have to use the browser. You can connect the official AFFiNE desktop app.</p>
<ol>
<li><p>Download the AFFiNE desktop app.</p>
</li>
<li><p>Click the workspace list panel in the top left corner.</p>
</li>
<li><p>Click "Add Server" and enter <code>http://localhost:3010</code>.</p>
</li>
<li><p>Log in with your account.</p>
</li>
</ol>
<img src="https://cdn.hashnode.com/uploads/covers/6729b04417afd6915f5c2e3e/2c668ed4-3552-420f-9217-e5f8d09f311c.png" alt="Connecting your local server to Affine Server" style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<img src="https://cdn.hashnode.com/uploads/covers/6729b04417afd6915f5c2e3e/3a12b7f6-33b9-497e-8684-7fd7a09d8c42.png" alt="Overview of Workspace" style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<h2 id="heading-step-8-stopping-the-server-and-safe-backups">Step 8: Stopping the Server and Safe Backups</h2>
<p>You must turn your server off safely before you back up your notes.</p>
<p>To do that, run this command:</p>
<pre><code class="language-shell">docker compose down
</code></pre>
<p>Once it stops, you can safely copy your entire <code>affine</code> folder to a safe place.</p>
<h2 id="heading-step-9-how-to-upgrade-later">Step 9: How to Upgrade Later</h2>
<p>When AFFiNE releases a new version, run these commands inside your <code>affine</code> folder:</p>
<ol>
<li>Download the newest blueprint:</li>
</ol>
<pre><code class="language-shell">wget -O docker-compose.yml https://github.com/toeverything/affine/releases/latest/download/docker-compose.yml
</code></pre>
<ol>
<li>Pull the new images and restart:</li>
</ol>
<pre><code class="language-shell">docker compose pull
docker compose up -d
</code></pre>
<h2 id="heading-common-installation-errors-and-troubleshooting">Common Installation Errors and Troubleshooting</h2>
<h3 id="heading-1-docker-is-not-running">1. Docker is Not Running</h3>
<ul>
<li><p><strong>The Error:</strong> Terminal says <code>docker: command not found</code>.</p>
</li>
<li><p><strong>The Fix:</strong> Open the Docker Desktop app on Windows and wait for it to start.</p>
</li>
</ul>
<h3 id="heading-2-docker-is-not-connected-to-wsl">2. Docker is Not Connected to WSL</h3>
<ul>
<li><strong>The Fix:</strong> In Docker Desktop, go to <strong>Settings &gt; Resources &gt; WSL Integration</strong> and turn it ON for your distro.</li>
</ul>
<h3 id="heading-3-the-port-is-already-in-use">3. The Port is Already in Use</h3>
<ul>
<li><strong>The Fix:</strong> Open <code>docker-compose.yml</code>. Change <code>"3010:3010"</code> to <code>"4000:3010"</code>. You will now visit <code>localhost:4000</code>.</li>
</ul>
<h3 id="heading-4-permission-denied">4. Permission Denied</h3>
<ul>
<li><strong>The Fix:</strong> If you cannot delete a folder, use the sudo command: <code>sudo rm -rf affine/</code>.</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this tutorial, you've successfully built a self-hosted, private workspace. You practised using WSL, Docker Compose, and Postgres. These are valuable skills for any developer.</p>
<p><strong>Your next steps:</strong></p>
<ol>
<li><p>Create a note in AFFiNE documenting what you learned.</p>
</li>
<li><p>Turn off your server (<code>docker compose down</code>) and copy your folder to a backup drive.</p>
</li>
<li><p>Explore Cloudflare Tunnels if you want to access your server from your phone!</p>
</li>
</ol>
<p>Self-hosting takes a little work, but the privacy is worth it.</p>
<p><strong>Let’s connect!</strong> You can find my latest work on my <a href="https://blog.abdultalha.tech/portfolio"><strong>Technical Writing Portfolio</strong></a> or reach out to me on <a href="https://www.linkedin.com/in/abdul-talha/"><strong>LinkedIn</strong></a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Run Rust on Jupyter Notebooks ]]>
                </title>
                <description>
                    <![CDATA[ If you've ever wanted to combine the power of Rust with the interactive goodness of Jupyter notebooks, you're in the right place. Maybe you're tired of compiling every single time you want to test a s ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-run-rust-on-jupyter-notebooks/</link>
                <guid isPermaLink="false">699879483dc17c4862f498f9</guid>
                
                    <category>
                        <![CDATA[ Rust ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Jupyter Notebook  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Linux ]]>
                    </category>
                
                    <category>
                        <![CDATA[ WSL ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Tutorial ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Daniel Iwugo ]]>
                </dc:creator>
                <pubDate>Fri, 20 Feb 2026 15:10:00 +0000</pubDate>
                <media:content url="https://cloudmate-test.s3.us-east-1.amazonaws.com/uploads/covers/5e1e335a7a1d3fcc59028c64/6e411f5d-65a1-407d-a4f0-0beceb1e784b.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>If you've ever wanted to combine the power of Rust with the interactive goodness of Jupyter notebooks, you're in the right place. Maybe you're tired of compiling every single time you want to test a snippet, learn Rust in a more interactive way, or just have a crazy idea pop into your head like I do.</p>
<p>Most people think Jupyter is just for Python and data science stuff, but apparently you can run Rust in one, too.</p>
<p>In this tutorial, we’ll be taking a look at:</p>
<ol>
<li><p><a href="#heading-what-is-evcxr">What is EvCxR?</a></p>
</li>
<li><p><a href="#heading-how-to-install-the-rust-jupyter-kernel">How to Install the Rust Jupyter kernel</a></p>
</li>
<li><p><a href="#heading-step-4-write-your-first-rust-code">How to run your first Rust code in a notebook</a></p>
</li>
<li><p><a href="#heading-handy-tips-and-tricks">Handy Tips and Tricks</a></p>
</li>
<li><p><a href="#heading-common-issues-and-solutions">Common Issues and Solutions</a></p>
</li>
<li><p><a href="#heading-when-not-to-use-jupyter-for-rust">When NOT to Use Jupyter for Rust</a></p>
</li>
</ol>
<p><strong>Friendly Disclaimer</strong>: This tutorial assumes you know the basics of both Rust and Jupyter. If you break something, that's on you, mate 🙂.</p>
<p>So without further ado, let's jump in.</p>
<h2 id="heading-what-is-evcxr"><strong>What is EvCxR?</strong></h2>
<p>EvCxR (pronounced "Evaluator" to my fellow linguists’ horror) is a Rust REPL and Jupyter kernel. It's basically the magic that lets you run Rust code interactively in Jupyter notebooks instead of the traditional compile-run-debug cycle.</p>
<p>The name stands for "Evaluation Context for Rust", and it’s an open source project actively maintained on GitHub. Here are a few things that make this terribly named tool absolutely brilliant:</p>
<ol>
<li><p><strong>Interactive development:</strong> It lets you test Rust snippets without creating a whole project 🧪</p>
</li>
<li><p><strong>Prototyping:</strong> You can quickly try out ideas before committing to a full implementation 💡</p>
</li>
<li><p><strong>Data visualisation:</strong> And yes, you can even plot charts with Rust (more on that later) 📊</p>
</li>
</ol>
<h2 id="heading-how-to-install-the-rust-jupyter-kernel">How to Install the Rust Jupyter kernel</h2>
<h3 id="heading-prerequisites"><strong>Prerequisites</strong></h3>
<p>Before we dive into the installation, make sure you have these sorted:</p>
<ol>
<li><p><strong>A Linux System:</strong> Or at least, Windows Subsystem for Linux (There’s a little note below for Windows users.)</p>
</li>
<li><p><strong>The Rust toolchain:</strong> You can get it from <a href="https://rustup.rs/">rustup.rs</a> if you haven't already</p>
</li>
<li><p><strong>Jupyter:</strong> Install via pip – <code>pip install jupyter</code></p>
</li>
<li><p><strong>Patience:</strong> This might take a minute or two ⏱️</p>
</li>
</ol>
<p>Once you’ve got all that, we can get rusty (pun intended).</p>
<p><strong>Note:</strong> If you’re using Windows, you’ll need to do a little extra to get started. Here’s the quick rundown:</p>
<ol>
<li><p>Go to <a href="https://visualstudio.microsoft.com/visual-cpp-build-tools/">https://visualstudio.microsoft.com/visual-cpp-build-tools/</a></p>
</li>
<li><p>Download and run the installer</p>
</li>
<li><p>Select <strong>"Desktop development with C++"</strong></p>
</li>
<li><p>Install it (it's large, ~5GB)</p>
</li>
</ol>
<h3 id="heading-step-1-install-evcxr"><strong>Step 1: Install EvCxR</strong></h3>
<p>Open your terminal and run this command:</p>
<pre><code class="language-rust">cargo install evcxr_jupyter
</code></pre>
<p>Now go grab a cup of joe ☕. This will take a few minutes as Cargo downloads and compiles everything. And don't panic if it seems stuck. Rust compilation is thorough but not particularly fast.</p>
<p>If you get any errors about missing system libraries, you might need to install some dependencies. On Ubuntu/Debian, try:</p>
<pre><code class="language-bash">sudo apt install jupyter-notebook jupyter-core python-ipykernel
sudo apt install cmake
</code></pre>
<p>On macOS with Homebrew:</p>
<pre><code class="language-bash">brew install cmake jupyter
</code></pre>
<h3 id="heading-step-2-install-the-jupyter-kernel"><strong>Step 2: Install the Jupyter Kernel</strong></h3>
<p>Once the installation finishes, you’ll need to register the EvCxR kernel with Jupyter:</p>
<pre><code class="language-bash">evcxr_jupyter --install
</code></pre>
<p>You should see output that looks something like this at the end:</p>
<pre><code class="language-plaintext">Installation complete
</code></pre>
<h3 id="heading-step-3-launch-jupyter-and-create-a-rust-notebook"><strong>Step 3: Launch Jupyter and Create a Rust Notebook</strong></h3>
<p>Let’s test out our baby. Fire up Jupyter:</p>
<pre><code class="language-bash">jupyter notebook
</code></pre>
<p>Your browser should open automatically (if it doesn't, copy the URL from the terminal).</p>
<p>In the Jupyter interface:</p>
<ol>
<li><p>Click <strong>New</strong> in the top right</p>
</li>
<li><p>Select <strong>Rust</strong> from the dropdown (or "evcxr" depending on your version)</p>
</li>
<li><p>A new notebook opens</p>
</li>
</ol>
<p>Welcome to interactive Rust! 🦀</p>
<h3 id="heading-step-4-write-your-first-rust-code"><strong>Step 4: Write Your First Rust Code</strong></h3>
<p>Let's start with a classic:</p>
<pre><code class="language-rust">println!("Hello my fellow Rustaceans! 🦀");
</code></pre>
<p>Hit <code>Shift + Enter</code> to run the cell. You should see the output appear below the cell. Simple as that.</p>
<p>Note that notebooks execute code at the top level, so you don’t have to wrap it around the <code>main()</code> function. If you still want to do that, you’re going to have to call it like this:</p>
<pre><code class="language-rust">fn main(){
    println!("Hello my fellow Rustaceans! 🦀");
}
//Calling the function
main()
</code></pre>
<p>Now let's try something more interesting:</p>
<pre><code class="language-rust">fn fibonacci(n: u32) -&gt; u32 {
    match n {
        0 =&gt; 0,
        1 =&gt; 1,
        _ =&gt; fibonacci(n - 1) + fibonacci(n - 2)
    }
}

for i in 0..10 {
    println!("fibonacci({}) = {}", i, fibonacci(i));
}
</code></pre>
<p>Run it and watch the Fibonacci sequence appear.</p>
<pre><code class="language-plaintext">fibonacci(0) = 0
fibonacci(1) = 1
fibonacci(2) = 1
fibonacci(3) = 2
fibonacci(4) = 3
fibonacci(5) = 5
fibonacci(6) = 8
fibonacci(7) = 13
fibonacci(8) = 21
fibonacci(9) = 34
</code></pre>
<h2 id="heading-handy-tips-and-tricks"><strong>Handy Tips and Tricks</strong></h2>
<p>Functions aren’t the only things that behave differently when using Rust in notebooks. Here are a few other things you might want to keep in mind:</p>
<h3 id="heading-variables-persist-between-cells">Variables Persist Between Cells</h3>
<p>Unlike traditional Rust compilation, variables you define in one cell stick around for the next cells:</p>
<pre><code class="language-rust">let mut counter = 0;
</code></pre>
<p>Then in the next cell:</p>
<pre><code class="language-rust">counter += 1;
println!("Counter: {}", counter);
</code></pre>
<p>The output would be:</p>
<pre><code class="language-plaintext">Counter: 1
</code></pre>
<p>This is great for building up complex examples step by step.</p>
<h3 id="heading-you-can-use-external-crates">You Can Use External Crates</h3>
<p>Add dependencies with the <code>:dep</code> command in one cell:</p>
<pre><code class="language-rust">:dep serde = { version = "1.0", features = ["derive"] }
:dep serde_json = "1.0"
</code></pre>
<p>Then use them normally in the next:</p>
<pre><code class="language-rust">use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize, Debug)]
struct Person {
    name: String,
    age: u32,
}

let person = Person {
    name: "Amina".to_string(),
    age: 24,
};

let json = serde_json::to_string(&amp;person).unwrap();
println!("{}", json);
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">{"name":"Amina","age":24}
</code></pre>
<p>Pretty neat, huh?</p>
<h3 id="heading-visualisation-support">Visualisation Support</h3>
<p>You can even create graphs. To get started, install the <code>plotters</code> crate:</p>
<pre><code class="language-rust">:dep plotters = { version = "0.3", default-features = false, features = ["evcxr", "all_series", "bitmap_backend", "bitmap_encoder"] }
</code></pre>
<p>Then create a simple sine graph:</p>
<pre><code class="language-rust">use plotters::prelude::*;

let root = SVGBackend::new("sine_wave.svg", (640, 480)).into_drawing_area();
root.fill(&amp;WHITE).unwrap();

let mut chart = ChartBuilder::on(&amp;root)
    .caption("Sine Wave", ("Arial", 20))
    .margin(5)
    .x_label_area_size(30)
    .y_label_area_size(30)
    .build_cartesian_2d(-3.14..3.14, -1.2..1.2)
    .unwrap();

chart.configure_mesh().draw().unwrap();

chart.draw_series(LineSeries::new(
    (-314..314).map(|x| {
        let x = x as f64 / 100.0;
        (x, x.sin())
    }),
    &amp;RED,
)).unwrap();

root.present().unwrap();
println!("Plot saved to sine_wave.svg");
</code></pre>
<p>Output:</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1771272251271/c07b1c22-4ea1-408c-984a-4179a47058d9.png" alt="Sine wave graph showing output of the code" style="display:block;margin:0 auto" width="640" height="480" loading="lazy">

<p><strong>A word on plotting:</strong> You can actually display plots directly inline in your notebook. But if you're using WSL with VSCode (like I do), inline plotting may not work properly due to rendering issues on the notebook interface. That’s why I used it as an svg file that I can easily view in my text editor.</p>
<h3 id="heading-checking-types">Checking Types</h3>
<p>Not sure what type something is? Use <code>:vars</code>. This shows all variables and their types:</p>
<pre><code class="language-rust">let x = vec![1, 2, 3];
</code></pre>
<pre><code class="language-rust">:vars
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">Variable	    Type
       x	Vec&lt;i32&gt;
</code></pre>
<h2 id="heading-common-issues-and-solutions">Common Issues and Solutions</h2>
<h3 id="heading-compilation-errors-everywhere">Compilation Errors Everywhere</h3>
<p>If you're getting weird compilation errors, remember:</p>
<ul>
<li><p>Each cell is compiled separately</p>
</li>
<li><p>You might need to reimport things in each cell</p>
</li>
</ul>
<h3 id="heading-slow-execution">Slow Execution</h3>
<p>The first time you run code in a session, it's slow due to the compilation overhead. Subsequent runs are faster. If it's really slow, you might want to:</p>
<ul>
<li><p>Use release mode: <code>:opt 2</code></p>
</li>
<li><p>Reduce dependency features to only what you need</p>
</li>
<li><p>Consider if Jupyter is the right tool for your use case</p>
</li>
</ul>
<h3 id="heading-dependencies-not-loading">Dependencies Not Loading</h3>
<p>If a crate won't load:</p>
<ul>
<li><p>Make sure the version exists on <a href="http://crates.io">crates.io</a></p>
</li>
<li><p>Check your internet connection (it needs to download)</p>
</li>
<li><p>Try specifying features explicitly</p>
</li>
<li><p>Clear the cargo cache if things get really wonky: <code>rm -rf ~/.evcxr</code></p>
</li>
</ul>
<h2 id="heading-when-not-to-use-jupyter-for-rust"><strong>When NOT to Use Jupyter for Rust</strong></h2>
<p>Jupyter notebooks are great for learning and experimenting, but they're not always the best choice in:</p>
<ul>
<li><p><strong>Production code:</strong> Use proper projects with cargo</p>
</li>
<li><p><strong>Performance-critical code:</strong> The overhead isn't worth it</p>
</li>
<li><p><strong>Large applications:</strong> Notebooks get very messy, very fast</p>
</li>
<li><p><strong>Team collaboration:</strong> Version control with notebooks is quite the nightmare</p>
</li>
</ul>
<p>Stick to notebooks for prototyping and quick experiments. For anything serious, fire up your favourite editor and create a proper Rust project.</p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>Let's summarise what you've learned:</p>
<ol>
<li><p>How to install the EvCxR Jupyter kernel</p>
</li>
<li><p>How to create and run Rust notebooks</p>
</li>
<li><p>How to use external crates in notebooks</p>
</li>
<li><p>Tips and tricks for interactive Rust development</p>
</li>
</ol>
<p>Jupyter notebooks make Rust more accessible for learning and experimentation. Give it a go next time you want to try out a quick Rust snippet without the ceremony of creating a full project. And with that, we've come to the end of this tutorial.</p>
<p>Cheers.</p>
<h2 id="heading-resources">Resources</h2>
<ol>
<li><p><a href="https://github.com/evcxr/evcxr">EvCxR GitHub Repository</a></p>
</li>
<li><p><a href="https://doc.rust-lang.org/book/">Rust Book</a></p>
</li>
<li><p><a href="https://jupyter.org/documentation">Jupyter Documentation</a></p>
</li>
</ol>
<h2 id="heading-acknowledgements">Acknowledgements</h2>
<p>Thanks to <a href="https://www.linkedin.com/in/a-n-u-o/">Anuoluwapo Victor</a>, <a href="https://www.linkedin.com/in/a-n-u-o/">Chinaza Nwukwa,</a> <a href="https://www.linkedin.com/in/chinaza-nwukwa-22a256230/">Holumidey Mer</a><a href="https://www.linkedin.com/in/mercy-holumidey-88a542232/">cy</a>, <a href="https://www.linkedin.com/in/mercy-holumidey-88a542232/">Favour Ojo,</a> <a href="https://www.linkedin.com/in/favour-ojo-906883199/">Georgina</a> <a href="https://www.linkedin.com/in/georgina-awani-254974233/">Awani</a>, <a href="https://www.linkedin.com/in/georgina-awani-254974233/">and my family</a> for the inspiration, support and knowledge used to put this post together.</p>
<p>And thanks to the EvCxR project maintainers for making this possible, the Rust community for being awesome, and to anyone reading this for wanting to learn. You inspire me daily.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Set Up CUDA and WSL2 for Windows 11 (including PyTorch and TensorFlow GPU) ]]>
                </title>
                <description>
                    <![CDATA[ If you’re working on complex Machine Learning projects, you’ll need a good Graphics Processing Unit (or GPU) to power everything. And Nvidia is a popular option these days, as it has great compatibility and widespread support. If you’re new to Machin... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-set-up-cuda-and-wsl2-for-windows-11-including-pytorch-and-tensorflow-gpu/</link>
                <guid isPermaLink="false">69309b9e8c594b8177306456</guid>
                
                    <category>
                        <![CDATA[ Machine Learning ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Windows ]]>
                    </category>
                
                    <category>
                        <![CDATA[ WSL ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GPU ]]>
                    </category>
                
                    <category>
                        <![CDATA[ cuda ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Deep Learning ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Md. Fahim Bin Amin ]]>
                </dc:creator>
                <pubDate>Wed, 03 Dec 2025 20:20:46 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1764786287487/f0c28401-ce77-4873-b238-59fc6b737ce7.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>If you’re working on complex Machine Learning projects, you’ll need a good Graphics Processing Unit (or GPU) to power everything. And Nvidia is a popular option these days, as it has great compatibility and widespread support.</p>
<p>If you’re new to Machine Learning and are just getting started, then a free <a target="_blank" href="https://www.kaggle.com/">Kaggle</a> or <a target="_blank" href="https://colab.research.google.com/">Colab</a> might be enough for you. But that won’t be the case when you want to go deeper. You’ll need a GPU, which can get costly if you’re continuously using it on the cloud.</p>
<p>But there’s some good news: you can utilize your computer’s Nvidia GPU (GTX/RTX) quite easily and perform machine learning-related tasks right on your local machine. The cool thing is, it won’t cost you anything other than the electricity it uses!</p>
<p>When you’re running Machine Learning models on your local machines, the most suitable operating system is a Linux-based one, like Ubuntu. But Windows has improved a lot for this purpose. If you’re using the latest Windows 11, you can leverage Windows Subsystem for Linux (WSL) and use your GPU directly for Machine Learning-related workflows.</p>
<p>This process can be quite tricky, though, as can making two popular Machine Learning frameworks, TensorFlow and PyTorch, compatible with your system GPU in Windows 11. That’s why I have written this comprehensive guide to ease your pain.</p>
<p>In it, I’ll help you set up CUDA on Windows Subsystem for Linux 2 (WSL2) so you can leverage your Nvidia GPU for machine learning tasks.</p>
<p>By following these steps, you’ll be able to run ML frameworks like TensorFlow and PyTorch with GPU acceleration on Windows 11.</p>
<p>Keep in mind that this guide assumes you have a compatible Nvidia GPU. Make sure to check <a target="_blank" href="https://developer.nvidia.com/cuda-gpus">Nvidia's official compatibility list</a> before proceeding.</p>
<p>I have also prepared a video for you that’ll help you follow proper guidelines throughout this article.</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/qOJ49nkU4rY" 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> </p>
<p>Also, if this tutorial helps you, then don’t forget to add a star to the GitHub repository <a target="_blank" href="https://github.com/FahimFBA/CUDA-WSL2-Ubuntu-v2">CUDA-WSL2-Ubuntu-v2</a>. If you face any issues or have any suggestions/improvements, then please raise an issue in the GitHub repository. Currently, the live website is available at <a target="_blank" href="https://ml-win11-v2.fahimbinamin.com/">ml-win11-v2.fahimbinamin.com</a>.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ol>
<li><p><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-windows-terminal">Windows Terminal</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-windows-powershell-latest-amp-greatest">Windows PowerShell (Latest &amp; Greatest)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-configure-windows-terminal">Configure Windows Terminal</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-configuration-of-my-computer">Configuration of my computer</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-cpu-virtualization">CPU Virtualization</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-install-wsl2">Install WSL2</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-install-latest-lts-ubuntu-via-wsl2">Install Latest LTS Ubuntu via WSL2</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-update-amp-upgrade-ubuntu-packages">Update &amp; Upgrade Ubuntu Packages</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-install-and-configure-miniconda">Install and Configure Miniconda</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-install-jupyter-amp-ipykernel">Install Jupyter &amp; Ipykernel</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-nvidia-driver">Nvidia Driver</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-install-cuda-dependencies">Install CUDA dependencies</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-cuda-toolkit">CUDA Toolkit</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-add-path-to-shell-profile-for-cuda">Add Path to Shell Profile for CUDA</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-nvcc-version">nvcc Version</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-cudnn-sdk">cuDNN SDK</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-tensorflow-gpu">TensorFlow GPU</a></p>
<ul>
<li><a class="post-section-overview" href="#heading-check-tensorflow-gpu">Check TensorFlow GPU</a></li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-pytorch-gpu">PyTorch GPU</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-check-pytorch-gpu">Check PyTorch GPU</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-check-pytorch-amp-tensorflow-gpu-inside-jupyter-notebook">Check PyTorch &amp; TensorFlow GPU inside Jupyter Notebook</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ol>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before you begin, make sure you have the following requirements met:</p>
<ul>
<li><p>Windows 11 operating system</p>
</li>
<li><p>Nvidia GPU (GTX/RTX series)</p>
</li>
<li><p>Administrator access to your PC</p>
</li>
<li><p>At least 30 GB of free disk space</p>
</li>
<li><p>Internet connection for downloads</p>
</li>
<li><p>Latest Nvidia drivers installed</p>
</li>
</ul>
<h2 id="heading-windows-terminal">Windows Terminal</h2>
<p>First, you’ll need to ensure that you have Windows Terminal installed properly in your operating system. It is the newest terminal application for users of command-line tools and shells like Command Prompt, PowerShell, and WSL. You can download it from the <a target="_blank" href="https://apps.microsoft.com/detail/9N0DX20HK701?hl=en-us&amp;gl=BD&amp;ocid=pdpshare">Microsoft Store</a>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764094104150/c73ae561-6888-4eea-9419-186c6659a62f.png" alt="Preview of Windows Terminal on Windows 11" class="image--center mx-auto" width="1133" height="641" loading="lazy"></p>
<p>After ensuring that it’s installed properly, you can proceed to the next steps.</p>
<h2 id="heading-windows-powershell-latest-amp-greatest">Windows PowerShell (Latest &amp; Greatest)</h2>
<p>Windows PowerShell is a modern and updated command-line shell from Microsoft. You can use some Linux specific commands directly on it. It comes with built-in command suggestions. You can download it from the <a target="_blank" href="https://github.com/PowerShell/PowerShell/releases/">official GitHub page</a>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764094138179/78315197-f4f2-4df4-b022-37cb9e74cda2.png" alt="Preview of Windows PowerShell on GitHub" class="image--center mx-auto" width="1519" height="904" loading="lazy"></p>
<p>Download the latest x64 installer and install it. After ensuring that it is installed properly, you can proceed to the next steps.</p>
<h2 id="heading-configure-windows-terminal">Configure Windows Terminal</h2>
<p>Now you’ll need to configure your Windows Terminal to use PowerShell as the default shell. It’s optional and you might skip this step. But I recommend doing it for a better experience.</p>
<p>Open Windows Terminal. Click on the down arrow icon in the title bar and select "Settings".</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764094162440/6ea767c8-da3b-4280-84f8-0eb2b0647a46.png" alt="Preview of Windows PowerShell settings window" class="image--center mx-auto" width="1166" height="660" loading="lazy"></p>
<p>In the Settings tab, under "Startup", find the "Default profile" dropdown menu. Select "PowerShell" from the list.</p>
<p>Now for the "Default terminal application", select "Windows Terminal".</p>
<p>By default, Windows PowerShell always shows the version number in the title bar. If you want to disable it, select the "PowerShell" profile from the left sidebar. Click on the "Command Line" field and add an <code>--nologo</code> argument at the end of the command. After this, the line becomes <code>"C:\Program Files\PowerShell\7\pwsh.exe" --nologo</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764094185648/3641d5f0-ba34-44b9-8a63-86b53068d02e.png" alt="Preview of Windows PowerShell --nologo setting" class="image--center mx-auto" width="1170" height="654" loading="lazy"></p>
<p>If you don’t use other shells frequently and want to hide them in the dropdown, then you’ll need to select those profiles one by one from the left sidebar. Scroll down to the bottom and find the "Hide profile from dropdown" toggle and enable it. It will hide that specific shell from the dropdown menu.</p>
<p>For example, I am hiding the <strong>Azure Cloud Shell</strong> profile as I don't use it frequently:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764094214632/73add1b7-bcdd-4368-86a6-975fa2f72b54.png" alt="Preview of hiding profiles in Windows Terminal" class="image--center mx-auto" width="1151" height="657" loading="lazy"></p>
<p>Now click on the "Save" button at the bottom right corner to apply the changes. Close the Windows Terminal for now.</p>
<h2 id="heading-configuration-of-my-computer">Configuration of My Computer</h2>
<p>I figured it’d be helpful to share my current computer’s configuration so you can have a clear idea of which setup I’m using in this guide. Here are the details:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Component</strong></td><td><strong>Specification</strong></td></tr>
</thead>
<tbody>
<tr>
<td><strong>Processor</strong></td><td>AMD Ryzen 7 7700 8-Core Processor (8 Core 16 Threads)</td></tr>
<tr>
<td><strong>RAM</strong></td><td>64GB DDR5 6000MHz</td></tr>
<tr>
<td><strong>Storage</strong></td><td>1 TB Samsung 980 NVMe SSD, 4 TB HDD, 2 TB SATA SSD</td></tr>
<tr>
<td><strong>GPU</strong></td><td>NVIDIA GeForce RTX 3060 12GB GDDR6</td></tr>
<tr>
<td><strong>Operating System</strong></td><td>Windows 11 Pro Version 25H2</td></tr>
</tbody>
</table>
</div><p>Now that you have an idea about my computer’s configuration, we can proceed to the next steps.</p>
<h2 id="heading-cpu-virtualization">CPU Virtualization</h2>
<p>As we are going to use WSL2, we’ll need to make sure that the CPU virtualization is enabled. To check whether virtualization is enabled or not from Windows, simply open the Windows Task Manager. Go to the Performance tab and select CPU from the left sidebar. In the bottom right corner, you will see the Virtualization status. If it shows "Enabled", then you are good to go. If it shows "Disabled", then you need to enable it from the BIOS.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764094252181/29efa40c-ec0a-4d99-adb7-50596348a1aa.png" alt="Preview of Virtualization enabled status in Windows Task Manager" class="image--center mx-auto" width="824" height="760" loading="lazy"></p>
<p>⚠️ You have to ensure that CPU Virtualization is enabled in your BIOS settings. Different manufacturers have different ways to access the BIOS. Usually, you can access the BIOS by pressing the Delete or F2 key during the boot process. Once in BIOS, look for settings related to "Virtualization Technology" or "Intel VT-x"/"AMD-V" and make sure it is enabled. Save the changes and exit the BIOS.</p>
<h2 id="heading-install-wsl2">Install WSL2</h2>
<p>Open the Windows Terminal or Windows PowerShell as an administrator. Run the following command to install WSL2 along with the latest Ubuntu LTS distribution:</p>
<pre><code class="lang-powershell">wsl.exe -<span class="hljs-literal">-install</span>
</code></pre>
<p>It will install Windows Subsystem for Linux 2 (WSL2). After the installation is complete, you will be prompted to restart your computer. Do so to finalize the installation.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764094306994/41db30c0-ecb9-4436-a425-8a059b199c42.png" alt="Preview of WSL installation in Windows PowerShell" class="image--center mx-auto" width="1295" height="656" loading="lazy"></p>
<p>⚠️ If you encounter any issues during installation, refer to the <a target="_blank" href="https://learn.microsoft.com/en-us/windows/wsl/troubleshooting">official Microsoft documentation</a> for troubleshooting WSL installation problems.</p>
<h2 id="heading-install-latest-lts-ubuntu-via-wsl2">Install Latest LTS Ubuntu via WSL2</h2>
<p>Open the Windows Terminal or Windows PowerShell again with the administrator privileges. If you want to check the available Linux distributions to install via WSL, run the following command:</p>
<pre><code class="lang-powershell">wsl.exe -<span class="hljs-literal">-list</span> -<span class="hljs-literal">-online</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764094455888/8f1f2382-41cc-410f-a7b9-a47d3bb634b6.png" alt="Preview of available WSL distributions in Windows PowerShell" class="image--center mx-auto" width="1291" height="660" loading="lazy"></p>
<p>For installing any specific distribution, run the following command:</p>
<pre><code class="lang-powershell">wsl.exe -<span class="hljs-literal">-install</span> &lt;DistroName&gt;
</code></pre>
<p>We are going to install the latest LTS Ubuntu distribution. As of now, the latest LTS version is Ubuntu 24.04. But I prefer to install the <code>Ubuntu</code> directly as it always points to the latest LTS version. So, run the following command:</p>
<pre><code class="lang-powershell">wsl.exe -<span class="hljs-literal">-install</span> Ubuntu
</code></pre>
<p>You need to give it a default user account name. For me, I am going with <code>fahim</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764094505280/9beb24de-54da-4e0c-993d-b15f985867e3.png" alt="Preview of Ubuntu installation in Windows PowerShell" class="image--center mx-auto" width="1666" height="858" loading="lazy"></p>
<p>It also comes with a nice GUI management tool for WSL.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764094530944/89073fb9-881f-48bd-b5ef-a0b08f74e4c5.png" alt="Preview of WSL GUI management tool" class="image--center mx-auto" width="1114" height="724" loading="lazy"></p>
<p>You can configure a lot of stuff in it including restricting core, RAM, disk space and a lot of specifications from the settings GUI window.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764094551095/66aea1e1-e204-4115-80e0-b3dea2d7a2ac.png" alt="Preview of WSL GUI settings window (Memory &amp; Processor)" class="image--center mx-auto" width="1919" height="1024" loading="lazy"></p>
<h2 id="heading-update-amp-upgrade-ubuntu-packages">Update &amp; Upgrade Ubuntu Packages</h2>
<p>Open your Ubuntu terminal from Windows Terminal. First, we need to update and upgrade the existing packages to their latest versions.</p>
<p>To update the Ubuntu system, simply use the following command:</p>
<pre><code class="lang-bash">sudo apt update -y
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764094594281/be41e056-7e55-4139-b84b-6b7921a2d435.png" alt="Preview of apt update command in Ubuntu terminal" class="image--center mx-auto" width="1649" height="888" loading="lazy"></p>
<p>To upgrade all the packages at once, simply use the following command:</p>
<pre><code class="lang-bash">sudo apt upgrade -y
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764094627958/b1c17b1c-5290-470b-aafe-5b89bb03bd01.png" alt="Preview of apt upgrade command in Ubuntu terminal" class="image--center mx-auto" width="1659" height="934" loading="lazy"></p>
<p>⚠️ Make sure that you have a stable internet connection during the update and upgrade process to avoid any interruptions.</p>
<h2 id="heading-install-and-configure-miniconda">Install and Configure Miniconda</h2>
<p>In Machine Learning, we need to manage multiple environments with different package versions. Conda is a popular package and environment management system that makes it easy to create and manage isolated environments for different projects. We will install Miniconda, a minimal installer for Conda, to manage our Python environments. But if you prefer Anaconda, you can install it instead.</p>
<p>Go to the official website of Miniconda. Currently the Miniconda installer is inside Anaconda <a target="_blank" href="https://www.anaconda.com/docs/getting-started/miniconda/install">here</a>. If the official website gets updated, you can always search for "Miniconda installer" on Google to find the latest version. Also, you can create an issue in the <a target="_blank" href="https://github.com/FahimFBA/CUDA-WSL2-Ubuntu-v2/issues">official GitHub repository of this project</a> to notify me about it.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764094667031/7ee2c854-88b6-49ce-8c04-41bf0a052c90.png" alt="Preview of Miniconda official website" class="image--center mx-auto" width="1895" height="935" loading="lazy"></p>
<p>As we are installing it inside WSL, we have to select the macOS/Linux Installation. Then select Linux Terminal Installer and choose Linux x86 for downloading the installer.</p>
<pre><code class="lang-bash">wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
</code></pre>
<p>It will download the installer to your WSL directory. Then use the following command to install it properly:</p>
<pre><code class="lang-bash">bash ~/Miniconda3-latest-Linux-x86_64.sh
</code></pre>
<p>⚠️ Make sure that you are in the correct directory where the installer is downloaded. If you downloaded it to a different location, adjust the path accordingly. Also, replace bash with zsh or sh if you are using a different shell.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764094706995/3a317eb9-0340-4a84-8826-45324c93dd2f.png" alt="Preview of Miniconda installation in WSL Ubuntu terminal" class="image--center mx-auto" width="1794" height="922" loading="lazy"></p>
<p>Make sure to choose the initialization option properly. I prefer to keep the conda env active whenever I open a new shell. Therefore, I chose "Yes".</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764094727839/f3fc8902-0c37-432c-a912-a92810e89fd1.png" alt="Preview of Miniconda initialization option during installation" class="image--center mx-auto" width="1656" height="924" loading="lazy"></p>
<p>Make sure that the installation succeeds without any errors.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764094754454/53dfd998-62c9-4c2a-a71e-0d33e123e027.png" alt="Preview of successful Miniconda installation in WSL Ubuntu terminal" class="image--center mx-auto" width="1652" height="914" loading="lazy"></p>
<p>For the changes to take effect, you can close and reopen the current shell. But you can also do that without closing and reopening the shell by applying the command below.</p>
<pre><code class="lang-bash"><span class="hljs-built_in">source</span> ~/.bashrc
</code></pre>
<p>⚠️ If you’re using a different shell like zsh or fish, make sure to source the appropriate configuration file (e.g., ~/.zshrc for zsh).</p>
<h2 id="heading-install-jupyter-amp-ipykernel">Install Jupyter &amp; Ipykernel</h2>
<p>I prefer to use Jupyter Notebook for running my machine learning experiments. It provides an interactive environment for coding and data analysis. We’ll install Jupyter Notebook and Ipykernel to run Jupyter notebooks in our conda environment. We will do that in all conda environments starting with the <strong>base</strong> environment. It also helps us to keep the conda environment kernel inside Jupyter Notebook.</p>
<p>First, make sure that you are in the base conda environment. You will see (base) on the left side of the terminal.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764094812122/66ad5de8-7553-42da-b920-78d20c3bdc9a.png" alt="Preview of conda base environment in WSL Ubuntu terminal" class="image--center mx-auto" width="1917" height="1027" loading="lazy"></p>
<p>Now install Jupyter and Ipykernel both by applying the following command:</p>
<pre><code class="lang-bash">conda install jupyter ipykernel -y
</code></pre>
<p>Make sure that you accept the terms of service of Conda.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764094839808/90fe3dcf-053d-4bc7-a031-22f81eb706ca.png" alt="Preview of Jupyter and Ipykernel installation in WSL Ubuntu terminal" class="image--center mx-auto" width="1659" height="927" loading="lazy"></p>
<p>Now, I will create a separate conda environment for both TensorFlow and the PyTorch GPU. You can directly install them in the base environment or in any other environment as per your preference. I am not specifying any specific Python version while creating the environment. It will automatically install the latest stable version of Python.</p>
<pre><code class="lang-bash">conda create -name ml -y
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764094865498/ac9ef1f1-4494-4221-8376-5e257c4f9243.png" alt="Preview of creating a new conda environment named 'ml' in WSL Ubuntu terminal" class="image--center mx-auto" width="1659" height="925" loading="lazy"></p>
<p>To activate any specific conda environment, you have to use the following command:</p>
<pre><code class="lang-bash">conda activate &lt;conda-env-name&gt;
</code></pre>
<p>For example, if I want to activate my newly created <strong>ml</strong> environment, I will use this command:</p>
<pre><code class="lang-bash">conda activate ml
</code></pre>
<p>If you’re not sure which conda environments are installed in your system, you can check all available and installed conda environments in your system by running the following command:</p>
<pre><code class="lang-bash">conda env list
</code></pre>
<h2 id="heading-nvidia-driver">Nvidia Driver</h2>
<p>Ensure that you have the latest Nvidia drivers installed on Windows. WSL2 uses the Windows driver, so no separate driver installation is needed in Ubuntu. You can download the latest drivers from the <a target="_blank" href="https://www.nvidia.com/Download/index.aspx">official Nvidia website</a>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764094915617/cd9b0bfc-77a1-45f1-9dab-4349c8f489ef.png" alt="Preview of Nvidia driver download page" class="image--center mx-auto" width="1750" height="916" loading="lazy"></p>
<p>If you are just installing the latest GPU driver, then after installing the drivers, restart your computer to ensure the changes take effect. You can either use the GeForce Game Ready Driver or the NVIDIA Studio Driver. But I recommend using the Studio Driver for better stability with creative and ML applications.</p>
<h2 id="heading-install-cuda-dependencies">Install CUDA Dependencies</h2>
<p>You might face some issues if you do not have the CUDA dependencies installed properly. I recommend that you install the required dependencies before proceeding further:</p>
<pre><code class="lang-bash">sudo apt install gcc g++ build-essential
</code></pre>
<p>After installing the dependencies, you can then verify the CUDA installation if you had any issues earlier.</p>
<h2 id="heading-cuda-toolkit">CUDA Toolkit</h2>
<p>TensorFlow GPU is very picky about the CUDA version. So we need to install a specific version of CUDA Toolkit that is compatible with the TensorFlow version we are going to install.</p>
<p>To understand exactly which CUDA version is compatible with which TensorFlow version, you can check the official TensorFlow GPU support matrix <a target="_blank" href="https://www.tensorflow.org/install/pip">here</a>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764095089103/87a44961-9426-4d20-95ac-cde06961b41a.png" alt="Preview of TensorFlow GPU support in official docs" class="image--center mx-auto" width="1879" height="931" loading="lazy"></p>
<p>At the time I’m writing this article, the TensorFlow GPU documentation says that we should have CUDA Toolkit 12.3. So I will ensure that I install exactly that version. You can simply click on that version link in the official docs and it will redirect you to the official Nvidia CUDA Toolkit download page. But if the link gets updated in the future, you can always search for "Nvidia CUDA Toolkit" on Google to find the latest version.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764095106589/19689d63-5ebd-4783-8da4-e3dedd277efb.png" alt="Preview of Nvidia CUDA Toolkit official website" class="image--center mx-auto" width="1620" height="925" loading="lazy"></p>
<p>As TensorFlow GPU is asking for exact Version 12.3, I will select version 12.3.0 exactly.</p>
<p>In the CUDA Toolkit download page, make sure to choose the operating system as Linux, Architecture as x86_64, Distribution as WSL-Ubuntu, Version as 2.0 and the Installer type as runfile(local).</p>
<p>⚠️ As we are using Ubuntu in our WSL2, you can also choose Ubuntu as your operating system. But I prefer to choose WSL-Ubuntu for better compatibility.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764095151533/b6996611-d4ce-4e07-9c73-30bdc93dbf19.png" alt="Preview of CUDA Toolkit 12.3 download page for WSL-Ubuntu" class="image--center mx-auto" width="1311" height="898" loading="lazy"></p>
<p>After selecting those, it will give you the download commands. You have to apply them sequentially. Make sure that you <strong>don't keep the checkmark in "Kernel Objects" during installing CUDA</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764095169368/c2f81594-536f-4788-b765-1aab3b040fa7.png" alt="Preview of CUDA Toolkit 12.3 download commands for WSL-Ubuntu" class="image--center mx-auto" width="1895" height="1001" loading="lazy"></p>
<p>⚠️ Make sure to copy and paste the commands one by one in your WSL Ubuntu terminal to download and install the CUDA Toolkit properly. If you face any issues related to CUDA dependency, then quickly go through the <a class="post-section-overview" href="#heading-install-cuda-dependencies">Install CUDA dependencies</a> section, where I have explained how to install the CUDA dependencies properly.</p>
<h2 id="heading-add-path-to-shell-profile-for-cuda">Add Path to Shell Profile for CUDA</h2>
<p>After installing CUDA Toolkit, we need to add the CUDA binaries to our shell profile for easy access. This will allow us to run CUDA commands from any directory in the terminal.</p>
<p>Note that, depending on the shell you are using (bash, zsh, and so on), you need to add the CUDA path to the appropriate configuration file. Make sure to replace <strong>.bashrc</strong> with <strong>.zshrc</strong> or other configuration files if you are using a different shell.</p>
<p>To add the CUDA binary path, follow the command below:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">echo</span> <span class="hljs-string">'export PATH=/usr/local/cuda-12.3/bin:$PATH'</span> &gt;&gt; ~/.bashrc
</code></pre>
<p>You have to use the updated path where you installed it. Your terminal will show it after installing the CUDA:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764095215437/15768563-c956-472e-9633-95b3dd1cb7a3.png" alt="Preview of CUDA installation path in WSL Ubuntu terminal" class="image--center mx-auto" width="1912" height="1011" loading="lazy"></p>
<p>Now, you need to add the path inside the Library path. Just use the exact path where you installed CUDA. Your terminal will list the path properly.</p>
<pre><code class="lang-bash"><span class="hljs-built_in">echo</span> <span class="hljs-string">'export LD_LIBRARY_PATH=/usr/local/cuda-12.3/lib64:$LD_LIBRARY_PATH'</span> &gt;&gt; ~/.bashrc
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764095242744/3c708db4-d267-4043-aa11-d04d890904f9.png" alt="Preview of CUDA library path in WSL Ubuntu terminal" class="image--center mx-auto" width="1284" height="693" loading="lazy"></p>
<p>After adding those paths, you need to source the shell profile for the changes to take effect. You can do that by running the following command:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">source</span> ~/.bashrc
</code></pre>
<h2 id="heading-nvcc-version">nvcc Version</h2>
<p>NVCC stands for Nvidia CUDA Compiler. It is basically a compiler driver for the CUDA platform that allows developers to write parallel programs to run on Nvidia GPUs. As we have already installed the CUDA toolkit, we need to see whether the compiler is also properly activated. To check that, we need to verify the version.</p>
<p>Verify that CUDA is properly installed by checking the version:</p>
<pre><code class="lang-bash">nvcc --version
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764095277858/2d1ded0a-01ac-4f78-9f6c-ac499d623207.png" alt="Preview of nvcc version check in WSL Ubuntu terminal" class="image--center mx-auto" width="1839" height="946" loading="lazy"></p>
<p>If the output shows the correct CUDA version, then you have successfully installed CUDA Toolkit in your WSL2 Ubuntu environment.</p>
<h2 id="heading-cudnn-sdk">cuDNN SDK</h2>
<p>The cuDNN (CUDA Deep Neural Network) SDK is a <a target="_blank" href="https://developer.nvidia.com/cudnn">GPU accelerated library of primitives for deep neural networks</a>, developed by Nvidia. It provides highly optimized building blocks for common deep learning operations, significantly speeding up the training and inference processes of AI models on Nvidia GPUs.</p>
<p>Note: Even though TensorFlow GPU suggests a specific cuDNN version, it’s often compatible with multiple versions. Because of this, I recommend downloading the latest cuDNN version that is compatible with your installed CUDA version. You can find the cuDNN download page <a target="_blank" href="https://developer.nvidia.com/cudnn-downloads">here</a>.</p>
<p>Select the Operating System as Linux, Architecture as x86_64, Distribution as Ubuntu, Version as 24.04, Installer Type as deb (local), Configuration as FULL. After selecting those, it will give you the download commands. You have to apply them sequentially.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764095312370/1fca5959-f492-4160-8027-deec0674863b.png" alt="Preview of cuDNN download commands for Ubuntu 24.04" class="image--center mx-auto" width="1543" height="938" loading="lazy"></p>
<p>⚠️ Make sure to copy and paste the commands one by one in your WSL Ubuntu terminal to download and install the cuDNN SDK properly. If you face any issues related to CUDA dependency, then quickly go through the <a class="post-section-overview" href="#heading-install-cuda-dependencies">Install CUDA dependencies</a> section, where I have explained how to install the CUDA dependencies properly.</p>
<h2 id="heading-tensorflow-gpu">TensorFlow GPU</h2>
<p>Now, we are going to install TensorFlow GPU in our conda environment. Make sure that you have activated the conda environment where you want to install it. I’m going to install it in my previously created <strong>ml</strong> environment. To activate it, I’ll use the following command:</p>
<pre><code class="lang-bash">conda activate ml
</code></pre>
<p>⚠️ Make sure that you have activated the correct conda environment before installing TensorFlow GPU. You will see the environment name in the terminal prompt.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764095398777/0c7d8813-eb6c-4e2e-bad9-1fc7d344d7a2.png" alt="Preview of activating 'ml' conda environment in WSL Ubuntu terminal" class="image--center mx-auto" width="1227" height="692" loading="lazy"></p>
<p>I will install ipykernel and jupyter in this new environment.</p>
<pre><code class="lang-bash">conda install jupyter ipykernel -y
</code></pre>
<p>Now, to install TensorFlow GPU, I will simply use the following command:</p>
<pre><code class="lang-bash">pip install tensorflow[and-cuda]
</code></pre>
<p>It might take a couple of minutes depending on the internet speed you have. Just have patience and wait for it to finish the installation.</p>
<h3 id="heading-check-tensorflow-gpu">Check TensorFlow GPU</h3>
<p>After installing TensorFlow GPU, we need to verify that it is working properly with GPU support. Open a Python shell in your Ubuntu terminal and run the following commands:</p>
<pre><code class="lang-bash">python3 -c <span class="hljs-string">"import tensorflow as tf; print(tf.config.list_physical_devices('GPU'))"</span>
</code></pre>
<p>If the output shows a list of available GPU devices, then TensorFlow GPU is successfully installed and working properly.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764095453933/ccda58fc-9ae9-4185-9c78-6196c98d8b7c.png" alt="Preview of TensorFlow GPU check in WSL Ubuntu terminal" width="1903" height="1029" loading="lazy"></p>
<h2 id="heading-pytorch-gpu">PyTorch GPU</h2>
<p>Now, we’re going to install PyTorch GPU in our conda environment. Make sure that you have activated the conda environment where you want to install it. I’m going to install it in my previously created ml environment. To activate it, I will use the following command:</p>
<pre><code class="lang-bash">conda activate ml
</code></pre>
<p>Installing PyTorch GPU is very straightforward. You can use the official PyTorch installation command generator <a target="_blank" href="https://pytorch.org/get-started/locally/">here</a>.</p>
<p>Make sure to select PyTorch Build as the latest Stable one, Your OS as Linux, Package as Pip, Language as Python. For the Compute Platform, select the CUDA version that matches your installed CUDA Toolkit. For me, it is CUDA 12.3. But, if you can not find the exact one then choose the closest. As CUDA 12.3 is not available for me now, I am choosing CUDA 12.6.</p>
<p>After selecting those, it will give you the installation command. You have to apply it in your WSL Ubuntu terminal.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764095511862/6f631369-c8db-4681-9d1c-669ad88df69d.png" alt="Preview of PyTorch installation command generator" class="image--center mx-auto" width="1618" height="911" loading="lazy"></p>
<p>It might take a couple of minutes depending on the internet speed you have. Just have patience and wait for it to finish the installation.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764095532246/56232263-36ea-4043-9881-df162965c514.png" alt="Preview of PyTorch GPU installation in WSL Ubuntu terminal" class="image--center mx-auto" width="1280" height="689" loading="lazy"></p>
<h3 id="heading-check-pytorch-gpu">Check PyTorch GPU</h3>
<p>After installing PyTorch GPU, verify that it is working properly with GPU support. Open a Python shell in your Ubuntu terminal and run the following commands:</p>
<pre><code class="lang-bash">python3 - &lt;&lt; <span class="hljs-string">'EOF'</span>
import torch
<span class="hljs-built_in">print</span>(torch.cuda.is_available())
<span class="hljs-built_in">print</span>(torch.cuda.device_count())
<span class="hljs-built_in">print</span>(torch.cuda.current_device())
<span class="hljs-built_in">print</span>(torch.cuda.device(0))
<span class="hljs-built_in">print</span>(torch.cuda.get_device_name(0))
EOF
</code></pre>
<p>The output should look similar to the screenshot, showing:</p>
<ul>
<li><p><strong>True</strong>: GPU is available for PyTorch</p>
</li>
<li><p><strong>1</strong>: Number of detected CUDA devices</p>
</li>
<li><p><strong>0</strong>: Index of the current active CUDA device</p>
</li>
<li><p>A device object representation</p>
</li>
<li><p><strong>NVIDIA GeForce RTX 3060</strong> (or your GPU name)</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764095584921/69269152-7ea6-404b-b1ca-8534b51f2491.png" alt="Preview of PyTorch GPU check in WSL Ubuntu terminal" class="image--center mx-auto" width="1917" height="937" loading="lazy"></p>
<h3 id="heading-check-pytorch-amp-tensorflow-gpu-inside-jupyter-notebook">Check PyTorch &amp; TensorFlow GPU inside Jupyter Notebook</h3>
<p>Now that the environment is fully configured, we will verify GPU support directly inside Jupyter Notebook. This ensures both PyTorch and TensorFlow can successfully detect and use your GPU.</p>
<h4 id="heading-1-test-pytorch-gpu">1. Test PyTorch GPU</h4>
<p>Create a new Jupyter Notebook and run the following commands one by one:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> torch

print(torch.cuda.is_available())
print(torch.cuda.device_count())
print(torch.cuda.current_device())
print(torch.cuda.device(<span class="hljs-number">0</span>))
print(torch.cuda.get_device_name(<span class="hljs-number">0</span>))
</code></pre>
<p>If everything is configured correctly, you will see your GPU (for example <strong>NVIDIA GeForce RTX 3060</strong>) detected properly:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764095624229/f94c97a0-2e44-45ad-a2a8-52f40c922482.png" alt="Preview of PyTorch GPU check inside Jupyter Notebook" class="image--center mx-auto" width="1861" height="743" loading="lazy"></p>
<h4 id="heading-2-test-tensorflow-gpu">2. Test TensorFlow GPU</h4>
<p>Next, run the following code to check whether TensorFlow detects your GPU:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> tensorflow <span class="hljs-keyword">as</span> tf

print(tf.config.list_physical_devices(<span class="hljs-string">'GPU'</span>))
</code></pre>
<p>You can also check the number of GPUs detected:</p>
<pre><code class="lang-python">print(<span class="hljs-string">"Num GPUs Available:"</span>, len(tf.config.list_physical_devices(<span class="hljs-string">'GPU'</span>)))
</code></pre>
<p>Finally, run TensorFlow’s built-in GPU validation (warnings are normal):</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> tensorflow <span class="hljs-keyword">as</span> tf

<span class="hljs-keyword">assert</span> tf.test.is_gpu_available()
<span class="hljs-keyword">assert</span> tf.test.is_built_with_cuda()
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764095666216/f9017979-b5c9-4b86-9f60-d9aaa2fe8ac1.png" alt="TensorFlow GPU initialization and CUDA validation output" class="image--center mx-auto" width="1638" height="935" loading="lazy"></p>
<p>If TensorFlow logs show your GPU model (such as <strong>RTX 3060</strong>), then TensorFlow GPU is successfully installed and fully working inside Jupyter Notebook.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Thank you so much for reading all the way through. I hope you have been able to configure your Windows 11 computer properly for running almost any kind of Machine Learning-based experiments.</p>
<p>To get more content like this, you can follow me on <a target="_blank" href="https://www.linkedin.com/in/fahimfba/">LinkedIn</a> and <a target="_blank" href="https://x.com/Fahim_FBA">X</a>. You can also check <a target="_blank" href="https://www.fahimbinamin.com/">my website</a> and follow me on <a target="_blank" href="https://github.com/FahimFBA">GitHub</a> if you are into open source and development.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Set Up GitHub CLI on WSL2 ]]>
                </title>
                <description>
                    <![CDATA[ Recently, I set up WSL2 and Ubuntu on my Windows 11 to work on some open-source projects. Since I also maintain these projects, I installed GitHub CLI to ease my workflow. I successfully installed the GitHub CLI, but failed to authenticate it. The er... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/github-cli-wsl2-guide/</link>
                <guid isPermaLink="false">689e444cbfe79386885372b0</guid>
                
                    <category>
                        <![CDATA[ GitHub ]]>
                    </category>
                
                    <category>
                        <![CDATA[ WSL ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Linux ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ayu Adiati ]]>
                </dc:creator>
                <pubDate>Thu, 14 Aug 2025 20:17:16 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1755202477019/fbc68131-107a-40ae-9dae-c14224d0866a.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Recently, I set up WSL2 and Ubuntu on my Windows 11 to work on some open-source projects. Since I also maintain these projects, I installed <a target="_blank" href="https://cli.github.com/">GitHub CLI</a> to ease my workflow. I successfully installed the GitHub CLI, but failed to authenticate it.</p>
<p>The error message <code>failed to authenticate via web browser: Too many requests have been made in the same timeframe. (slow_down)</code> appeared on my terminal, while on the web browser, it indicated that the authentication was successful.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754718774837/0d1de969-a1e3-4f0a-a3ce-e3c4661ce0d0.png" alt="A message says &quot;Congratulations, you're all set,&quot; marking GitHub CLI authentication is successful " class="image--center mx-auto" width="457" height="334" loading="lazy"></p>
<p>I googled and found some workarounds that I tried, but only one worked like a charm!</p>
<p>After finally solving the tricky authentication issue for GitHub CLI on WSL2, I've put together this guide. It's a complete walkthrough for a solution that works, covering everything from a smooth installation to ongoing management.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-install-github-cli-on-wsl2">How to Install GitHub CLI on WSL2</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-authenticate-github-cli-on-wsl2-with-your-github-account">How to Authenticate GitHub CLI on WSL2 with Your GitHub Account</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-upgrade-github-cli-on-wsl2">How to Upgrade GitHub CLI on WSL2</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-uninstall-github-cli-on-wsl2">How to Uninstall GitHub CLI on WSL2</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-revoke-github-cli-access-on-github">How to Revoke GitHub CLI Access on GitHub</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-final-words">Final Words</a></p>
</li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before getting started, ensure that you have these installed on your Windows machine:</p>
<ul>
<li><p>WSL2</p>
</li>
<li><p>A Linux distro</p>
</li>
<li><p>Windows PowerShell</p>
</li>
<li><p><a target="_blank" href="https://learn.microsoft.com/en-us/windows/terminal/install">Windows Terminal</a> (optional)</p>
</li>
</ul>
<p>To follow the instructions in this article, you can use Windows PowerShell terminal as an administrator.</p>
<p>Alternatively, if you have Windows Terminal installed, you can use the Linux terminal by clicking the ‘down arrow’ icon at the top and selecting the distro.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754677301223/7e846117-3fd1-42a2-ab3e-029e94672aca.png" alt="Dropdown menu at Windows Terminal" class="image--center mx-auto" width="582" height="375" loading="lazy"></p>
<h2 id="heading-how-to-install-github-cli-on-wsl2">How to Install GitHub CLI on WSL2</h2>
<p>You can use the installation process described here if you use Ubuntu, Debian, or Raspberry Pi OS (apt) distros. For other distros other than those mentioned here, you can walk through the installation process that's available on the <a target="_blank" href="https://github.com/cli/cli/blob/trunk/docs/install_linux.md">GitHub CLI official docs</a>.</p>
<p>To install GitHub CLI in WSL2:</p>
<ol>
<li><p>Run this command:</p>
<pre><code class="lang-bash"> (<span class="hljs-built_in">type</span> -p wget &gt;/dev/null || (sudo apt update &amp;&amp; sudo apt install wget -y)) \
     &amp;&amp; sudo mkdir -p -m 755 /etc/apt/keyrings \
     &amp;&amp; out=$(mktemp) &amp;&amp; wget -nv -O<span class="hljs-variable">$out</span> https://cli.github.com/packages/githubcli-archive-keyring.gpg \
     &amp;&amp; cat <span class="hljs-variable">$out</span> | sudo tee /etc/apt/keyrings/githubcli-archive-keyring.gpg &gt; /dev/null \
     &amp;&amp; sudo chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg \
     &amp;&amp; sudo mkdir -p -m 755 /etc/apt/sources.list.d \
     &amp;&amp; <span class="hljs-built_in">echo</span> <span class="hljs-string">"deb [arch=<span class="hljs-subst">$(dpkg --print-architecture)</span> signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main"</span> | sudo tee /etc/apt/sources.list.d/github-cli.list &gt; /dev/null \
     &amp;&amp; sudo apt update \
     &amp;&amp; sudo apt install gh -y
</code></pre>
</li>
<li><p>Type your Linux password when you get prompted.</p>
</li>
<li><p>Ensure the GitHub CLI is installed by running <code>gh --version</code> command. If the installation is successful, you should see something like this in your terminal:</p>
<pre><code class="lang-bash"> gh version 2.76.2 (2025-07-30)
 https://github.com/cli/cli/releases/tag/v2.76.2
</code></pre>
</li>
</ol>
<h2 id="heading-how-to-authenticate-github-cli-on-wsl2-with-your-github-account">How to Authenticate GitHub CLI on WSL2 with Your GitHub Account</h2>
<p>Before you can use GitHub CLI, you must first authenticate it. You will get an <code>HTTP 401: Bad credentials (https://api.github.com/graphql)</code> error message if you run any GitHub CLI command without authenticating.</p>
<p>To authenticate GitHub CLI with your GitHub account:</p>
<ol>
<li><p>Run the <code>gh auth login</code> command in your terminal.</p>
</li>
<li><p>You will receive several prompts, and you need to choose the methods you prefer. Here’s what I selected in each prompt:</p>
<pre><code class="lang-plaintext"> ? Where do you use GitHub? GitHub.com
 ? What is your preferred protocol for Git operations on this host? HTTPS
 ? How would you like to authenticate GitHub CLI? Login with a web browser
</code></pre>
<p> After answering all prompts, you should get the message to copy a one-time code as shown below. You <strong>don’t need to copy the code</strong> at this point.</p>
<pre><code class="lang-bash"> ! First copy your one-time code: XXXX—XXXX
</code></pre>
</li>
<li><p>Press ‘Enter’. It automatically opens the "Device Activation" page on your browser.</p>
</li>
<li><p>Click the green ‘Continue’ button.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754848322666/2a4af9ab-c197-4ec9-802f-ad9b4f24375c.png" alt="GitHub Device Activation page on a browser" class="image--center mx-auto" width="486" height="384" loading="lazy"></p>
<p> GitHub should ask you to enter the code displayed on your terminal, as shown in the screenshot below. But here’s the trick! <strong>Don’t paste any code, and don’t close the browser</strong>. Let’s first get back to your terminal.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754722491767/d84534da-522f-4e82-84c2-a1bfc75940ef.png" alt="GitHub Device Activation page on a browser" class="image--center mx-auto" width="436" height="460" loading="lazy"></p>
<p> Now you might get this error message on your terminal:</p>
<pre><code class="lang-bash"> grep: /proc/sys/fs/binfmt_misc/WSLInterop: No such file or directory
 WSL Interopability is disabled. Please <span class="hljs-built_in">enable</span> it before using WSL.
 grep: /proc/sys/fs/binfmt_misc/WSLInterop: No such file or directory
 [error] WSL Interoperability is disabled. Please <span class="hljs-built_in">enable</span> it before using WSL.
</code></pre>
</li>
<li><p>Press <code>Ctrl + C</code> to stop the process if it's still running, or let it stop by itself. Once it's stopped, you should see this message:</p>
<pre><code class="lang-bash"> failed to authenticate via web browser: Too many requests have been made <span class="hljs-keyword">in</span> the same timeframe. (slow_down)
</code></pre>
</li>
<li><p>Run the <code>gh auth login</code> command again and repeat the process to select the methods of your choice. This time, when it asks you to press ‘Enter’, <strong>don’t press it</strong>.</p>
</li>
<li><p>Copy the latest code and return to the "Device Activation" page that you left open in your browser.</p>
</li>
<li><p>Paste the code that you copied and click the green ‘Continue’ button.</p>
</li>
<li><p>Click the green ‘Authorize github’ button after GitHub redirects you to the “Authorize GitHub CLI” page. You should now see the message “Congratulations, you're all set!”</p>
</li>
<li><p>Get back to your terminal and press ‘Enter’. Doing so triggers these actions:</p>
<ul>
<li><p>It automatically opens a new “Device Activation” page in your browser. You can safely ignore this.</p>
</li>
<li><p>In the terminal, you first see the error message as in step 4. Don’t do anything and wait for a little bit. Then, you get:</p>
<pre><code class="lang-bash">  ✓ Authentication complete.
  - gh config <span class="hljs-built_in">set</span> -h github.com git_protocol https
  ✓ Configured git protocol
  ! Authentication credentials saved <span class="hljs-keyword">in</span> plain text
  ✓ Logged <span class="hljs-keyword">in</span> as YOUR-GITHUB-USERNAME
  ! You were already logged <span class="hljs-keyword">in</span> to this account
</code></pre>
</li>
</ul>
</li>
</ol>
<p>And GitHub CLI is now successfully authenticated!</p>
<blockquote>
<p>Credit goes to <a target="_blank" href="https://github.com/cli/cli/discussions/6884#discussioncomment-10176332">username “ikeyan” on GitHub for their GitHub CLI authentication solution</a>!</p>
</blockquote>
<h2 id="heading-how-to-upgrade-github-cli-on-wsl2">How to Upgrade GitHub CLI on WSL2</h2>
<p>It’s always a good practice to regularly check for package and dependency updates, and upgrade to the newest version when it’s available — this includes GitHub CLI. To check for updates and upgrade the version of GitHub CLI:</p>
<ol>
<li><p>Run the <code>sudo apt update</code> command in your terminal. This command fetches the list of available updates.</p>
</li>
<li><p>Type your Linux password when you get prompted.</p>
</li>
<li><p>If you need to upgrade your GitHub CLI, run <code>sudo apt install gh</code>. This command installs the newest version of GitHub CLI.</p>
</li>
<li><p>Type your Linux password when you get prompted.</p>
</li>
</ol>
<p>Now your GitHub CLI has the newest version.</p>
<h2 id="heading-how-to-uninstall-github-cli-on-wsl2">How to Uninstall GitHub CLI on WSL2</h2>
<p>If one day you feel like you don’t need to use GitHub CLI anymore, you can uninstall it by following these steps:</p>
<ol>
<li><p>Run the <code>sudo apt remove gh</code> command in your terminal.</p>
</li>
<li><p>Type your Linux password when you get prompted.</p>
</li>
<li><p>Press ‘Y’ to continue the uninstall process.</p>
</li>
</ol>
<p>GitHub CLI is now uninstalled from your WSL environment.</p>
<h2 id="heading-how-to-revoke-github-cli-access-on-github">How to Revoke GitHub CLI Access on GitHub</h2>
<p>After uninstalling the GitHub CLI, you might think your account access is gone, but it's not. The authentication you granted is still active. If you don't plan on using the CLI again, it's a good practice to revoke this access.</p>
<p>Here's how to do it directly from your GitHub account:</p>
<ol>
<li><p>On your GitHub account, click your profile picture on the top right and click ‘Settings’.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754725091482/8fb8a0fd-8dbd-4342-9fe8-309a13d72c39.png" alt="Settings option on dropdown menu at GitHub" class="image--center mx-auto" width="283" height="471" loading="lazy"></p>
<ol start="2">
<li><p>On the left side bar, find ‘Integrations’ and click ‘Applications’.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754815240842/ca49d207-6ee2-476f-a53d-bde53b2d57dd.png" alt="Applications tab in the Integrations settings on GitHub" class="image--center mx-auto" width="425" height="158" loading="lazy"></p>
</li>
<li><p>Click the ‘Authorized OAuth Apps’ tab on top.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754815346304/a360f7dc-7024-44c3-8e19-15d94b35ce8e.png" alt="Authorized OAuth Apps tab on GitHub" class="image--center mx-auto" width="837" height="141" loading="lazy"></p>
</li>
<li><p>Find GitHub CLI and click the ‘three dots’ icon next to it.</p>
</li>
<li><p>Click ‘Revoke’.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754725454783/dd544380-482a-4385-97c1-4ebc35026658.png" alt="Revoke option on GitHub to revoke an authorized OAuth apps" class="image--center mx-auto" width="1369" height="164" loading="lazy"></p>
</li>
<li><p>Confirm it by clicking the ‘I understand, revoke access’ button.</p>
</li>
</ol>
</li>
</ol>
<p>Now, GitHub CLI doesn’t have access to your GitHub account.</p>
<hr>
<h2 id="heading-final-words">Final Words</h2>
<p>🖼️ Credit cover image: <a target="_blank" href="http://undraw.co">undraw.co</a></p>
<p>Thank you for reading! Last, you can find me on <a target="_blank" href="https://twitter.com/@AdiatiAyu">X</a> and <a target="_blank" href="https://www.linkedin.com/in/adiatiayu/">LinkedIn</a>. Let's connect! 😊</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Free Up and Automatically Manage Disk Space for WSL on Windows 10/11 ]]>
                </title>
                <description>
                    <![CDATA[ Windows Subsystem for Linux (WSL) lets you run a Linux environment directly on Windows. This is particularly useful for web development where you can develop and test applications in a Linux environme ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-free-up-and-automatically-manage-disk-space-for-wsl-on-windows-1011/</link>
                <guid isPermaLink="false">6893e671640b08f689368ee6</guid>
                
                    <category>
                        <![CDATA[ WSL ]]>
                    </category>
                
                    <category>
                        <![CDATA[ wsl2 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ disk management ]]>
                    </category>
                
                    <category>
                        <![CDATA[ disk ]]>
                    </category>
                
                    <category>
                        <![CDATA[ disk space ]]>
                    </category>
                
                    <category>
                        <![CDATA[ automation ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Powershell ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Windows ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Windows 10 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ windows 11 ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ brooklyn ]]>
                </dc:creator>
                <pubDate>Wed, 06 Aug 2025 23:34:09 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1754523230294/70893973-fddf-42a9-b41a-2a8f94a47e22.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Windows Subsystem for Linux (<a href="https://learn.microsoft.com/en-us/windows/wsl/install">WSL</a>) lets you run a Linux environment directly on Windows. This is particularly useful for web development where you can develop and test applications in a Linux environment without leaving Windows. You can even run <a href="https://contribute.freecodecamp.org/how-to-setup-wsl/">freeCodeCamp locally</a> with it!</p>
<p>But managing disk space can be a quite a challenge, as WSL uses virtual hard disks that do not automatically free up unused space.</p>
<p>This tutorial will guide you through the process of manually compacting your WSL virtual hard disks. We’ll automate this task using a PowerShell script, ensuring that your WSL environment remains efficient and clutter-free.</p>
<h2 id="heading-reclaim-your-space">Reclaim Your Space</h2>
<p>WSL uses a virtualization platform to install Linux distributions on your Windows system. Each distribution you add gets its own Virtual Hard Disk (VHD), which uses the ext4 file system (common in Linux). It’s saved on your Windows drive as an ext4.vhdx file.</p>
<p>Key issues here:</p>
<ul>
<li><p>Inefficient storage: by default, VHD files <strong>do not reclaim</strong> unused space. This means that when you delete a file in WSL, the associated disk space isn’t immediately freed up.</p>
</li>
<li><p>Disk space consumption: due to that inefficient storage, the <strong>VHD files can grow large</strong> thanks to that accumulated data, especially if you’re a WSL heavy user.</p>
</li>
<li><p>Need for maintenance: you may not know that you need to <strong>compact</strong> your VHD files in order to reclaim disk space.</p>
</li>
</ul>
<p>If you notice that your free disk space is shrinking even after deleting files and apps, WSL might be the reason. This tutorial will help you keep your WSL and Windows environment running smoothly.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a href="#heading-part-1-how-to-manually-compact-your-virtual-hard-disk">Part 1: How to Manually Compact Your Virtual Hard Disk</a></p>
<ul>
<li><p><a href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a href="#heading-step-1-verify-your-wsl-version-and-status">Step 1: Verify your WSL version and status</a></p>
</li>
<li><p><a href="#heading-step-2-list-all-installed-distributions-verbosely">Step 2: List all installed distributions verbosely</a></p>
</li>
<li><p><a href="#heading-step-3-locate-your-linux-virtual-hard-drive-vhdx-path">Step 3: Locate your linux Virtual Hard Drive (VHDX) path</a></p>
</li>
<li><p><a href="#heading-step-4-shut-down-all-wsl-instances">Step 4: Shut down all WSL instances</a></p>
</li>
<li><p><a href="#heading-step-5-compact-the-linux-virtual-hard-drive-using-diskpart">Step 5: Compact the Linux virtual hard drive using DiskPart</a></p>
</li>
<li><p><a href="#heading-step-6-restart-wsl-and-verify">Step 6: Restart WSL and verify</a></p>
</li>
</ul>
</li>
<li><p><a href="#heading-part-2-how-to-make-your-life-easier-with-automation">Part 2: How to Make Your Life Easier with Automation</a></p>
<ul>
<li><p><a href="#heading-prerequisites-1">Prerequisites</a></p>
</li>
<li><p><a href="#heading-step-1-find-out-installed-wsl2-distributions">Step 1: Find out installed WSL2 distributions</a></p>
</li>
<li><p><a href="#heading-step-2-select-a-distro-to-compact">Step 2: Select a distro to compact</a></p>
</li>
<li><p><a href="#heading-step-3-locate-the-ext4vhdx-file">Step 3: Locate the ext4.vhdx File</a></p>
</li>
<li><p><a href="#heading-step-4-the-confirmation-prompt">Step 4: The confirmation prompt</a></p>
</li>
<li><p><a href="#heading-step-5-shut-down-wsl-and-compact">Step 5: Shut Down WSL and compact</a></p>
</li>
<li><p><a href="#heading-step-6-run-a-diskpart-script">Step 6: Run a DiskPart script</a></p>
</li>
</ul>
</li>
</ul>
<h2 id="heading-part-1-how-to-manually-compact-your-virtual-hard-disk"><strong>Part 1: How to Manually Compact Your Virtual Hard Disk</strong></h2>
<p>Let's start by going through the process manually. This section will guide you through checking your WSL version and associated Linux distributions, finding VHD files, shutting down WSL, and compacting the virtual disk.</p>
<h3 id="heading-prerequisites"><strong>Prerequisites</strong></h3>
<ul>
<li><p>Windows 10 (20H1/2004+) or Windows 11 with WSL2 installed</p>
</li>
<li><p>The PowerShell or Command Prompt running as <strong>Administrator</strong> (from the Windows menu, right click the icon and choose run as Administrator).</p>
</li>
</ul>
<h3 id="heading-step-1-verify-your-wsl-version-and-status"><strong>Step 1: Verify your WSL version and status</strong></h3>
<p>First, make sure you’re running on WSL version 2 (commonly referred as WSL2). The first version is outdated and WSL2 provides significant improvements. Open PowerShell (as Admin) or Command Prompt (as Admin) and run:</p>
<pre><code class="language-powershell">wsl -v

wsl --status
</code></pre>
<p>These commands display the WSL client version and whether your default distro is using WSL 2. Here’s the output of the <code>wsl -v</code> command:</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754250376279/ef11af4b-ba5b-43f9-9532-db2634eed154.png" alt="Command prompt displaying WSL version 2.5.9.0, with corrupted or incomplete text following &quot;Kernel version:&quot;, &quot;WSLg version:&quot;, and other version labels." width="421" height="143" loading="lazy">

<p>And here’s the output of the <code>wsl --status</code> command.</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754250364365/6cea2d97-0796-4320-8f84-58d1b5e62c5e.png" alt="Command line text showing &quot;C:sers>wsl --status&quot; with the information &quot;Default Distribution: Ubuntu&quot; and &quot;Default Version: 2&quot;." width="243" height="71" loading="lazy">

<h3 id="heading-step-2-list-all-installed-distributions-verbosely"><strong>Step 2: List all installed distributions verbosely</strong></h3>
<p>To see a detailed list of your WSL distributions (including which version each uses), run:</p>
<pre><code class="language-powershell">wsl.exe --list --verbose
</code></pre>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754250281542/1826814a-5516-483e-b8ab-6477fd950e21.png" alt="Output of  the WSL --list --verbose command." width="302" height="67" loading="lazy">

<p>Above you can see the output of the WSL <code>--list --verbose</code> command.</p>
<p>Look for your distro name (for example, “<em>Ubuntu</em>”) and note its WSL version. If it shows “Version 2”, you can proceed with compaction.</p>
<h3 id="heading-step-3-locate-your-linux-virtual-hard-drive-vhdx-path"><strong>Step 3: Locate your linux Virtual Hard Drive (VHDX) path</strong></h3>
<p>Each WSL distro’s files live in a <a href="https://en.wikipedia.org/wiki/VHD_(file_format)">VHDX file</a> on your Windows drive. To find the path for any Linux distribution, use this PowerShell snippet:</p>
<pre><code class="language-powershell">(Get-ChildItem `

-Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Lxss `

| Where-Object { $_.GetValue("DistributionName") -eq 'YOUR_DISTRO_NAME' }

).GetValue("BasePath") + "\ext4.vhdx"
</code></pre>
<p>Where you replace <code>YOUR_DISTRO_NAME</code> with yours (Ubuntu, Debian, Kali-linux..). Here’s the output of the command shown above in PowerShell (the filepath has been anonymized):</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754251303855/ea3b3880-5804-4f50-97c8-327ffd017084.png" alt="A PowerShell command is displayed, used to locate the ext4.vhdx file for the Ubuntu distribution. The command retrieves the Windows Subsystem for Linux (WSL) base path for Ubuntu." width="616" height="74" loading="lazy">

<p>This command reads the registry key for your linux distribution, then appends “\ext4.vhdx” to build the full file path.</p>
<p>Make sure you copy the whole line. We will need it in later stages.</p>
<h3 id="heading-step-4-shut-down-all-wsl-instances"><strong>Step 4: Shut down all WSL instances</strong></h3>
<p>Before you can compact any virtual drive, make sure WSL is completely shut down. In PowerShell or Command Prompt (still as Administrator), run:</p>
<pre><code class="language-powershell">wsl.exe --shutdown
</code></pre>
<h3 id="heading-step-5-compact-the-linux-virtual-hard-drive-using-diskpart"><strong>Step 5: Compact the Linux virtual hard drive using DiskPart</strong></h3>
<p>You successfully gathered all the needed information (about your system, the available distros, and their VHDX filepath) to proceed with the main task. In this step, you actually proceed with the compaction.</p>
<ol>
<li>Launch DiskPart in the same elevated (<em>admin</em>) shell:</li>
</ol>
<pre><code class="language-powershell">diskpart
</code></pre>
<p>DiskPart will open in a new window. It's a Windows command-line tool for managing disk partitions. Be cautious when using it, as incorrect actions can cause serious data loss.</p>
<ol>
<li>In the DiskPart prompt, select the VHDX file you found earlier. Replace the path as displayed below with your actual path (the line you copied before):</li>
</ol>
<pre><code class="language-powershell">select vdisk file="C:\Users\username\AppData\path\to\ext4.vhdx"
</code></pre>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754251748072/91795798-0896-4fcc-994c-0ab311955bee.png" alt="Screenshot of a command prompt window showing Microsoft DiskPart version information. A command is entered to select a virtual disk file, and a message confirms successful selection." width="920" height="150" loading="lazy">

<p>The above is the output of the select vdisk command (some data has been anonymized).</p>
<ol>
<li>Attach the virtual drive in read-only mode:</li>
</ol>
<p>Compaction only needs to scan the empty blocks in the file, not write to the Linux filesystem inside. Read-only mode guarantees that DiskPart only inspect the blocks for zero‐trimming without any chance of damaging or altering your Linux filesystem.</p>
<pre><code class="language-powershell">attach vdisk readonly
</code></pre>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754251937734/a90af720-1511-42cc-bc37-63439d855907.png" alt="Command prompt showing the output for &quot;DISKPART> attach vdisk readonly&quot; with a successful attachment message." width="462" height="107" loading="lazy">

<p>You can see in the screenshot above that the virtual hard drive has been successfully attached.</p>
<ol>
<li>Compact the disk:</li>
</ol>
<p>This frees up the disk space by shrinking the physical size of the <code>.vhdx</code> file to match the <strong>actual used data</strong> inside.</p>
<pre><code class="language-powershell">compact vdisk
</code></pre>
<p>This operation might take a while. When you see the <code>“DiskPart successfully compacted the virtual disk file”</code> message, proceed with the next step. In the image below, the virtual hard drive has been successfully compacted.</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754252148605/51cc9739-775b-4a84-a526-7c2a6d2a9722.png" alt="Terminal output showing &quot;DISKPART> compact vdisk&quot; with &quot;100 percent completed,&quot; indicating successful compaction of the virtual disk file." width="450" height="96" loading="lazy">

<ol>
<li>Detach the virtual drive:</li>
</ol>
<pre><code class="language-powershell">detach vdisk
</code></pre>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754252460797/e29387d7-4f03-4ddb-80f7-f14a5051b0fe.png" alt="Command prompt showing &quot;DISKPART> detach vdisk&quot; and a confirmation message that DiskPart successfully detached the virtual disk file." width="446" height="72" loading="lazy">

<p>There you go – the virtual hard drive has been successfully detached.</p>
<p>This command releases any locks on the virtual drive and effectively dismounts it. If you don't use this command, the file remains "in use," preventing WSL (or you) from accessing it until you reboot or manually force it closed.</p>
<p>6. Exit DiskPart:</p>
<pre><code class="language-powershell">exit
</code></pre>
<h3 id="heading-step-6-restart-wsl-and-verify"><strong>Step 6: Restart WSL and verify</strong></h3>
<p>Back in PowerShell or Command Prompt, you can relaunch your distro:</p>
<pre><code class="language-powershell">wsl -d YOUR_DISTRO_NAME
</code></pre>
<p>You can even try the Unix <code>df -h</code> command in your WSL prompt to check your new available disk spaces.</p>
<p>Congrats, you just achieved a maintenance task that can free up lots of gigabytes of storage over time. Now, it’s time to automate.</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754321783829/4325a626-806e-47e7-9147-a76f4c91a93a.jpeg" alt="A minimalistic white rectangular button with a cable on a pink surface." style="display:block;margin:0 auto" width="640" height="360" loading="lazy">

<h2 id="heading-part-2-how-to-make-your-life-easier-with-automation"><strong>Part 2: How to Make Your Life Easier with Automation</strong></h2>
<p>Since it's often hard to remember exactly where your WSL distro is located and you probably won't use it very often, this PowerShell script will automate the entire process we covered in part 1. Here's a preview of the steps you'll follow:</p>
<ul>
<li><p>Detect installed WSL distributions.</p>
</li>
<li><p>Select one (and handle the cases there are more than one).</p>
</li>
<li><p>Locate the corresponding <code>ext4.vhdx</code> file.</p>
</li>
<li><p>Shut down WSL and use DiskPart to compact the virtual disk.</p>
</li>
</ul>
<h3 id="heading-prerequisites"><strong>Prerequisites</strong></h3>
<ul>
<li><p>Windows 10 (20H1/2004+) or Windows 11 with WSL 2 enabled.</p>
</li>
<li><p>PowerShell or Command Prompt (as Administrator).</p>
</li>
</ul>
<p>You’ll also need a code editor. The Windows notepad is enough for completing this task. You can also use an IDE (Integrated Development Environment) like VS Code or an ISE (Integrated Scripting Environment) like PowerShell ISE (included with Windows).</p>
<p>To test the script, download it from <a href="https://github.com/hyperphantasia/WSL-VHDX-Compact/blob/c5c2e346ab0dd1a8dbc6130f8d372af8022ddd60/wsl_compactor.ps1">GitHub</a>. Open an elevated PowerShell or Command Prompt and navigate to the script’s folder. With just the command below, you will be able to run it and free up some disk space:</p>
<pre><code class="language-powershell">powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\wsl_compactor.ps1
</code></pre>
<h3 id="heading-step-1-find-out-installed-wsl2-distributions"><strong>Step 1: Find out installed WSL2 distributions</strong></h3>
<p>One of the main challenges is to find the Linux distributions available on the host system. Let’s check the first block and see what’s it about:</p>
<pre><code class="language-powershell">$lxssKey = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Lxss'
\(distros = Get-ChildItem \)lxssKey | ForEach-Object {
    \(p = Get-ItemProperty \)_.PSPath
    [PSCustomObject]@{
        Name     = $p.DistributionName
        BasePath = $p.BasePath
    }
}
</code></pre>
<p>WSL records each distribution under this windows registry key:</p>
<p><code>HKCU:\Software\Microsoft\Windows\CurrentVersion\Lxss</code></p>
<p>Each subkey has two important values:</p>
<ul>
<li><p><strong>DistributionName</strong> (for example, Ubuntu)</p>
</li>
<li><p><strong>BasePath</strong> (This is where the distribution files are stored. It’s the directory that contains the <code>ext4.vhdx</code> file.)</p>
</li>
</ul>
<p>The script uses <code>Get-ChildItem</code> and <code>Get-ItemProperty</code> to enumerate these subkeys and build a list of available Linux distributions.</p>
<pre><code class="language-powershell">if ($distros.Count -eq 0) {
Throw-And-Exit "No WSL distros found in the registry."
}
</code></pre>
<p>If no distributions are found, the script terminates and prints this error message on the terminal: <code>"No WSL distros found in the registry.”</code></p>
<h3 id="heading-step-2-select-a-distro-to-compact"><strong>Step 2: Select a distro to compact</strong></h3>
<p>Here, the process has two steps:</p>
<ul>
<li>If multiple distros are found, it displays all the distros with a numbered menu and prompts you to choose one:</li>
</ul>
<pre><code class="language-powershell">if ($distros.Count -gt 1) {
    Write-Host "Multiple distros detected. Please choose one:`n"

    for (\(i = 0; \)i -lt \(distros.Count; \)i++) {
        Write-Host "[\((\)i+1)] \((\)distros[$i].Name)"
    }
    \(selected = \)distros[[int]$choice - 1]
}
</code></pre>
<p>The computed menu will look like this:</p>
<pre><code class="language-markdown">Multiple distros detected. Please choose one:

[1] Ubuntu 20.04

[2] Debian

[3] Alpine
</code></pre>
<ul>
<li>If only one distribution is found on the host system, the script selects it automatically:</li>
</ul>
<pre><code class="language-powershell">else {
\(selected = \)distros[0]
}
</code></pre>
<p>When setting up a distribution, whether chosen manually by the user or selected automatically, <strong>the important information is the path to each distribution's virtual hard disk</strong>. This path is saved in two main variables: <code>'distro'</code> (which identifies the specific distribution) and <code>'basePath'</code> (which shows where its virtual disk is located).</p>
<pre><code class="language-powershell">\(distro = \)selected.Name
\(basePath = \)selected.BasePath

Write-Host "`nSelected distro: $distro" -ForegroundColor DarkYellow
Write-Host "BasePath: $basePath"
</code></pre>
<p>The lines above display an output that looks like this:</p>
<pre><code class="language-markdown">Selected distro: Ubuntu (or any other distro)
BasePath: C:\Users\&lt;User_name&gt;\AppData\Local\Packages\…
</code></pre>
<p>Like for all other steps, it’s important to consider the case of something going wrong, by throwing an error and exiting the program:</p>
<pre><code class="language-powershell">if (-not (Test-Path $basePath)) {
Throw-And-Exit "BasePath '$basePath' does not exist on disk."
}
</code></pre>
<h3 id="heading-step-3-locate-the-ext4vhdx-file"><strong>Step 3: Locate the ext4.vhdx File</strong></h3>
<p>In the first step, we collected the information we need about the available distributions and where they are stored on the Windows system. By choosing an entry (either manually or automatically), we can find the correct file. Sometimes, the ext4 file is located between the base path and a <em>LocalState</em> folder. This script manages both situations. It builds the usual locations where the file can be found.</p>
<p>They look like this:</p>
<ul>
<li><p><code>$BasePath\ext4.vhdx</code></p>
</li>
<li><p><code>$BasePath\LocalState\ext4.vhdx</code></p>
</li>
</ul>
<p>This can translate into something like this on your system (option 1):</p>
<pre><code class="language-markdown">C:\Users\Alice\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu20.04onWindows_79rhkp1fndgsc\ext4.vhdx
</code></pre>
<p>or like this (option 2):</p>
<pre><code class="language-markdown">C:\Users\Alice\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu20.04onWindows_79rhkp1fndgsc\LocalState\ext4.vhdx
</code></pre>
<p>(You might find out that your WSL2 distro is located in some other directory than “Packages” – but don’t worry, your BasePath will match the correct folders).</p>
<p>The idea is to build the two possible path options:</p>
<pre><code class="language-powershell">$possible = @(
Join-Path $basePath 'ext4.vhdx'
Join-Path $basePath 'LocalState\ext4.vhdx'
)
</code></pre>
<p>And pick the first one that actually contains the file:</p>
<pre><code class="language-powershell">\(vhdx = \)possible | Where-Object { Test-Path $_ } | Select-Object -First 1
</code></pre>
<p>Again, we throw an error message if no suitable file is found:</p>
<pre><code class="language-powershell">if (-not $vhdx) {
Throw-And-Exit "No ext4.vhdx found under '$basePath'."
}
</code></pre>
<h3 id="heading-step-4-the-confirmation-prompt"><strong>Step 4: The confirmation prompt</strong></h3>
<p>Disk management tools require caution and you need to understand the potential consequences of your actions. A confirmation prompt is always a good safeguard to prevent accidental data loss or unwanted system changes.</p>
<p>Before proceeding, the script shows you:</p>
<ul>
<li><p>a Distro name</p>
</li>
<li><p>its BasePath</p>
</li>
<li><p>the VHDX file path</p>
</li>
</ul>
<pre><code class="language-powershell">Write-Host "`nAbout to compact this WSL distro:" -ForegroundColor Magenta
Write-Host " Distro : $distro"
Write-Host " BasePath : $basePath"
Write-Host " VHDX file: $vhdx`n"
</code></pre>
<p>It then prompts <strong>“Are you sure you want to proceed? (Y/N)”:</strong></p>
<pre><code class="language-powershell">Write-Host "Are you sure you want to proceed? (Y/N) " -ForegroundColor DarkCyan -NoNewline

# Then read the response
$answer = Read-Host
</code></pre>
<p>You’re then prompted to Type Y (case-insensitive) to continue or anything else to cancel.</p>
<pre><code class="language-powershell">if ($answer.ToUpper() -ne 'Y') {
    Write-Warning "Operation canceled"
    exit
}
</code></pre>
<p>For the two steps above, I had to use a trick to print the question in color but a simple option (without colors) could be:</p>
<pre><code class="language-powershell">if ((Read-Host 'Are you sure you want to proceed? (Y/N)').ToUpper() -ne 'Y') { 
    Write-Warning 'Operation canceled'
    exit 
}
</code></pre>
<h3 id="heading-step-5-shut-down-wsl-and-compact"><strong>Step 5: Shut down WSL and compact</strong></h3>
<p>Before proceeding to the DiskPart utility, it’s important to stop all running WSL instances. Pass the shutdown command directly in PowerShell.</p>
<pre><code class="language-powershell">Write-Host "Shutting down WSL…" -ForegroundColor Cyan
wsl.exe –shutdown
</code></pre>
<p>A common mistake is to forget to launch PowerShell or the Command Prompt with Administrator rights. You can prevent this case with a message:</p>
<pre><code class="language-powershell">if ($LASTEXITCODE -ne 0) {
     Throw-And-Exit "Failed to shut down WSL (exit code $LASTEXITCODE). Are you running as Administrator?"
}
</code></pre>
<h3 id="heading-step-6-run-a-diskpart-script"><strong>Step 6: Run a DiskPart script</strong></h3>
<h4 id="heading-building-the-script">Building the script:</h4>
<p>The process is the same as in the manual part, but this time, we ‘inject’ the ready-to-go DiskPart commands into the script.</p>
<pre><code class="language-powershell">$dpScript = @"
select vdisk file="$vhdx"
attach vdisk readonly
compact vdisk
detach vdisk
exit
"@
</code></pre>
<p>Before launching, there are two steps you need to take:</p>
<ol>
<li>The PowerShell script writes the lines above to a temporary file:</li>
</ol>
<pre><code class="language-powershell">$tempFile = [IO.Path]::GetTempFileName()
Set-Content -LiteralPath \(tempFile -Value \)dpScript -Encoding ASCII
</code></pre>
<p>This is the equivalent to the commands passed in the manual part:</p>
<p><code>select vdisk file="</code><a href="/home/C:/"><code>C:\</code></a><code>…\ext4.vhdx" # full path to the vdisk file</code></p>
<p><code>attach vdisk readonly</code></p>
<p><code>compact vdisk</code></p>
<p><code>detach vdisk</code></p>
<p><code>exit</code></p>
<ol>
<li>Compacting can take a while, especially if you’ve never de-cluttered your virtual drive before. It’s wise to show a warning before proceeding:</li>
</ol>
<pre><code class="language-powershell">Write-Host "Running DiskPart to compact the VHDX. Be patient, this might take a while..." -ForegroundColor Cyan
</code></pre>
<h4 id="heading-invoke-diskpart"><strong>Invoke DiskPart:</strong></h4>
<pre><code class="language-powershell"># Run DiskPart with the script saved to the temporary file and process each output line as it arrives
diskpart /s $tempFile | ForEach-Object {
    # Grab any "NN percent" type message from the line
    if ($_ -match '(\d+)\s+percent') {
        # Only print when the percentage actually changes
        Write-Host "\((\)Matches[1])% completed"
    }
    else {
        # Just echo all over line-types, verbatim
        Write-Host $_
    }
}
</code></pre>
<p>Several points to note here:</p>
<ul>
<li><p>It runs <code>diskpart /s $tempFile</code>: DiskPart reads and executes commands from the temporary file into the PowerShell loop for on-the-fly processing.</p>
</li>
<li><p>For a better user-experience: the snippet below does the trick of filtering out repeated status values by comparing <code>\(pct</code> with the sentinel <code>\)lastPct</code>, and only writing new lines when they differ.</p>
</li>
</ul>
<p>How?</p>
<p>Before entering the loop, we initialize:</p>
<pre><code class="language-powershell">$lastPct with -1
$lastPct = -1 # We initiate a sentinel value
</code></pre>
<p>We are having a guaranteed “first” value that no real percent (0–100) will equal. That way, as soon as you see the first 0 percent, 10 percent, or whatever, it differs from -1.</p>
<p>Then:</p>
<pre><code class="language-powershell">if ($_ -match '(\d+)\s+percent') {
    # Print only when the percentage changes
    Write-Host "\((\)Matches[1])% completed"
}
</code></pre>
<p>This guarantees that on the very first percentage update (say “0 percent” or “10 percent”), <code>\(pct –ne \)lastPct</code> will be <code>true</code>, so it emits the first line. Afterwards, <code>$lastPct</code> holds the last real percentage, and it only prints again when a new, different progress percentage comes in.</p>
<p>The output looks more clean:</p>
<pre><code class="language-markdown">10% completed
20% completed
…
</code></pre>
<p>Otherwise, it’ll flood the screen with dozens of identical “20 percent completed” (for example) updates.</p>
<p>Of course we handle the case of other values (non percent lines) normally:</p>
<pre><code class="language-powershell">else {
    # non-percent lines: print verbatim
    if ($_ -match '\S') {
        Write-Host $_
    }
}
</code></pre>
<p>Once the process is done, don’t forget to clean up the tempfile.</p>
<pre><code class="language-powershell">Remove-Item $tempFile -ErrorAction SilentlyContinue
</code></pre>
<p>By the end of the process, you should see something like this</p>
<pre><code class="language-markdown">Leaving DiskPart...
</code></pre>
<p>Okay, that’s it for the scripting! If you collected all the snippets so far, just save them with a <code>.ps1</code> file extension, or download the full example from this <a href="https://github.com/hyperphantasia/WSL-VHDX-Compact">GitHub repository</a>.</p>
<h3 id="heading-usage"><strong>Usage:</strong></h3>
<p>You now have a complete understanding of what's happening. Ready to get started? In Windows, open the Command Prompt or PowerShell <strong>as an administrator.</strong></p>
<ul>
<li><p>Navigate to the directory containing your <code>.ps1</code>&nbsp;script.</p>
</li>
<li><p>Execute the script with the following command, replacing <code>&lt;File_name_here&gt;</code> with your actual file name:</p>
</li>
</ul>
<pre><code class="language-powershell">powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\&lt;File_name_here&gt;.ps1
</code></pre>
<p>The <code>-NoProfile -ExecutionPolicy Bypass</code> parameters launch PowerShell in a clean, unrestricted environment that ignores user-specific settings and allows script execution without security restrictions. Don’t worry, in this case, it’s okay to do that.</p>
<p><em>Wait…wait…wait...</em></p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754315563256/a709192a-6626-4a12-b411-46c8591c5eb6.jpeg" alt="Screenshot of a command line interface showing the execution of a PowerShell script to compact a WSL (Windows Subsystem for Linux) distro. The script confirms the selected distro &quot;Ubuntu&quot; and proceeds to compact the VHDX file using DiskPart. Progress is shown in percentage increments, with final messages indicating successful completion of the compacting process." style="display:block;margin:0 auto" width="878" height="500" loading="lazy">

<p>Well bravo! You’ve just reclaimed all that unused space inside your WSL2 (almost) hands free!</p>
<p>Now, you can take it a step further by modifying this script to run completely automatically, without the confirmation prompt (step 4). You can also schedule it as a regular maintenance task using a task scheduler:</p>
<pre><code class="language-powershell">schtasks /create /tn "Schedule_name" /tr "powershell.exe -ExecutionPolicy Bypass -File C:\path\to\script.ps1" /sc monthly /d 15 /st 09:00
</code></pre>
<p>This is an example for a monthly execution where <code>/d 15</code> means 15th of each month and <code>/st 09:00</code> is a start time set at 9 am.</p>
<p>That's it! Remember, regular maintenance, whether you do it manually or automatically, is essential to prevent unnecessary disk space usage and ensure a smooth experience with WSL.</p>
<h3 id="heading-thanks-for-reading">Thanks for reading!</h3>
<p>You can find a list of my current projects on <a href="https://github.com/hyperphantasia?tab=repositories">GitHub</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use Linux on a Windows Machine – 5 Different Approaches ]]>
                </title>
                <description>
                    <![CDATA[ As a developer, you might need to run both Linux and Windows side by side. Luckily, there are a number of ways you can get the best of both worlds without getting different computers for each operating system.  In this article, we'll explore a few wa... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/5-ways-to-use-linux-on-a-windows-machine/</link>
                <guid isPermaLink="false">66adea1ec537123a64ede7f8</guid>
                
                    <category>
                        <![CDATA[ Linux ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Windows ]]>
                    </category>
                
                    <category>
                        <![CDATA[ WSL ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Zaira Hira ]]>
                </dc:creator>
                <pubDate>Fri, 09 Jun 2023 15:03:52 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/06/5-ways-to-use-Linux-on-a-Windows-machine.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>As a developer, you might need to run both Linux and Windows side by side. Luckily, there are a number of ways you can get the best of both worlds without getting different computers for each operating system. </p>
<p>In this article, we'll explore a few ways to use Linux on a Windows machine. Some of them are browser-based or cloud-based that do not need any installation prior to using them.</p>
<p>Here are the methods we'll be discussing:</p>
<ul>
<li>Dual boot</li>
<li>Windows Subsystem for Linux (WSL)</li>
<li>Virtual Machines (VM)</li>
<li>Browser-based solutions</li>
<li>Cloud-based solutions</li>
</ul>
<h2 id="heading-option-1-dual-boot-linux-windows">Option 1: "Dual-boot" Linux + Windows</h2>
<p>With dual boot, you can install Linux alongside Windows on your computer, allowing you to choose which operating system to use at startup. </p>
<p>This requires partitioning your hard drive and installing Linux on a separate partition. With this approach, you can only use one operating system at a time.</p>
<p>If this sounds like the way you want to go, <a target="_blank" href="https://www.freecodecamp.org/news/how-to-dual-boot-windows-10-and-ubuntu-linux-dual-booting-tutorial/">here is a useful tutorial</a> on setting up dual boot on Windows 10.</p>
<h2 id="heading-option-2-use-windows-subsystem-for-linux-wsl">Option 2: Use Windows Subsystem for Linux (WSL)</h2>
<p>Windows Subsystem for Linux provides a compatibility layer that lets you run Linux binary executables natively on Windows.</p>
<p>Using WSL has some advantages:</p>
<ul>
<li>The setup for WSL is simple and not time consuming.</li>
<li>It is lightweight compared to VMs where you have to allocate resources from the host machine.</li>
<li>You don't need to install any ISO or virtual disc image for Linux machines which tend to be heavy files.</li>
<li>You can use Windows and Linux side by side.</li>
</ul>
<p>If this sounds like the right option for you, <a target="_blank" href="https://www.freecodecamp.org/news/how-to-install-wsl2-windows-subsystem-for-linux-2-on-windows-10/">here is a detailed guide</a> on how to install and use WSL.</p>
<h2 id="heading-option-3-use-a-virtual-machine-vm">Option 3: Use a Virtual Machine (VM)</h2>
<p>A virtual machine (VM) is a software emulation of a physical computer system. It allows you to run multiple operating systems and applications on a single physical machine simultaneously. Here's a detailed explanation of VMs:</p>
<p>You can use virtualization software such as Oracle VirtualBox or VMware to create a virtual machine running Linux within your Windows environment. This allows you to run Linux as a guest operating system alongside Windows.</p>
<p>VM software provides options to allocate and manage hardware resources for each VM, including CPU cores, memory, disk space, and network bandwidth. You can adjust these allocations based on the requirements of the guest operating systems and applications.</p>
<p>Here are some of the options available for virtualization:</p>
<ul>
<li><a target="_blank" href="https://www.virtualbox.org/">Oracle virtual box</a></li>
<li><a target="_blank" href="https://multipass.run/">Multipass</a></li>
<li><a target="_blank" href="https://www.vmware.com/content/vmware/vmware-published-sites/us/products/workstation-player.html.html">VMware workstation player</a></li>
</ul>
<h2 id="heading-option-4-use-a-browser-based-solution">Option 4: Use a Browser-based Solution</h2>
<p>Browser based solutions are particularly useful for quick testing, learning, or accessing Linux environments from devices that don't have Linux installed.</p>
<p>You can either use online code editors or web based terminals to access Linux. Note that you usually don't have full administration privileges in these cases. </p>
<h3 id="heading-online-code-editors">Online code editors</h3>
<p>Online code editors offer editors with built-in Linux terminals. While their primary purpose is coding, you can also utilize the Linux terminal to execute commands and perform tasks.</p>
<p><a target="_blank" href="https://replit.com/">Replit</a> is an example of an online code editor, where you can write your code and access the Linux shell at the same time.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/replit.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Replit provides a code editor and a Linux shell.</em></p>
<h3 id="heading-web-based-linux-terminals">Web-based Linux terminals</h3>
<p>Online Linux terminals allow you to access a Linux command-line interface directly from your browser. These terminals provide a web-based interface to a Linux shell, enabling you to execute commands and work with Linux utilities. </p>
<p>One such example is <a target="_blank" href="https://jslinux.org/">JSLinux</a>. The screenshot below shows a ready to use Linux environment:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/jslinux.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Accessing Linux via JSLinux</em></p>
<h2 id="heading-option-5-use-a-cloud-based-solution">Option 5: Use a Cloud-based Solution</h2>
<p>Instead of running Linux directly on your Windows machine, you can consider using cloud-based Linux environments or virtual private servers (VPS) to access and work with Linux remotely. </p>
<p>Services like Amazon EC2, Microsoft Azure, or DigitalOcean provide Linux instances that you can connect to from your Windows computer. Note that some of these services offer free tiers, but they are not usually free in the long run.</p>
<h2 id="heading-how-to-choose-the-correct-method">How to Choose the Correct Method</h2>
<p>The choice is totally dependent on your use case. But there are some factors that may help you decide which option works the best for you. Let's discuss them:</p>
<ul>
<li>Access level/elevated privilege: If you require full administrative privileges, it is better to skip the browser-based solutions. WSL, dual booting, VMs, and cloud-based solutions provide you with full administrative control.</li>
<li>Cost: Cloud-based solutions offer services against a subscription fee. This cost varies depending on the choice of operating system, hardware specs of the machine, traffic, and so on. If you are on a tight budget, cloud-based solutions might not be the best.</li>
<li>Scalability: If you are just starting, but plan to do resource exhaustive development in the future, you can always scale up the physical specs of your machine. Some options that support upgrading are cloud-based solutions and VMs. You can add more processors or increase the RAM as per your needs.</li>
<li>Current system's hardware specs: If your current system has lower RAM and storage, running VMs can make the system heavy. It would be better to opt for cloud-based or browser based solutions.</li>
<li>Switching: If you don't plan to use Windows and Linux side by side, dual-boot can be a really good option. It offers a complete and focused Linux experience.</li>
</ul>
<h2 id="heading-my-setup">My Setup</h2>
<p>I am using Ubuntu VM installed through VMWare workstation player. It is doing a great job as I can frequently switch between two operating systems. It was also simple to setup and I can enjoy the admin privileges as well!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/my-set.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>I hope you found this article helpful. What’s your favorite thing you learned from this tutorial? I would love to connect with you on any of these <a target="_blank" href="https://zaira_.bio.link/">platforms</a>. 📧</p>
<p>See you in the next tutorial, happy coding 😁</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Setup a Windows Machine for Machine Learning/Deep Learning Using an Nvidia Graphics Card (CUDA) ]]>
                </title>
                <description>
                    <![CDATA[ If you are learning machine learning / deep learning, you may be using the free Google Colab. But you might wonder if the free version is adequate.  If you can afford a good Nvidia Graphics Card (with a decent amount of CUDA cores) then you can easil... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-setup-windows-machine-for-ml-dl-using-nvidia-graphics-card-cuda/</link>
                <guid isPermaLink="false">66b90301dd7c39d8be3aeb5d</guid>
                
                    <category>
                        <![CDATA[ Deep Learning ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Machine Learning ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Windows ]]>
                    </category>
                
                    <category>
                        <![CDATA[ WSL ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Md. Fahim Bin Amin ]]>
                </dc:creator>
                <pubDate>Tue, 30 May 2023 14:58:31 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/05/arseny-togulev-MECKPoKJYjM-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>If you are learning machine learning / deep learning, you may be using the free <a target="_blank" href="https://colab.research.google.com/">Google Colab</a>. But you might wonder if the free version is adequate. </p>
<p>If you can afford a good Nvidia Graphics Card (with a decent amount of CUDA cores) then you can easily use your graphics card for this type of intensive work. </p>
<p>A lot of developers use Linux for this. But, I do not like Linux as a desktop operating system (do not get offended, as it is my personal preference. And yes, Linux is the best for server-related stuff). </p>
<p>Also, if you own the latest Nvidia GPU, then you're probably already familiar with the hassle regarding the graphics driver and so on.</p>
<p>For all these reasons, I was thinking about trying something different: utilizing the new Windows 11 operating system to use the CUDA cores from my Graphics Card. </p>
<p>I followed a lot of videos but couldn't implement it after trying many times, unfortunately. There was some gap in the latest version of PyTorch with the Windows 11 kernel in CUDA. Still, after researching a lot, I have found out that WSL2 should work just fine.</p>
<p>After trying for more than a few days, I have successfully managed to set up everything necessary and can use my graphics card's CUDA cores in my Windows machine! An interesting thing is, in this process, you do not need to download or use Microsoft Visual Studio 2022 and download huge 30/35GB files just to install the recommended compilers and so on.</p>
<p>Because of this, I wrote a complete handbook on my GitHub (here's the repo: <a target="_blank" href="https://github.com/FahimFBA/CUDA-WSL2-Ubuntu">CUDA-WSL2-Ubuntu</a>, and here's the website: <a target="_blank" href="https://fahimfba.github.io/CUDA-WSL2-Ubuntu">fahimfba.github.io/CUDA-WSL2-Ubuntu</a>).</p>
<p>I am writing the same handbook here as well. So, here we go! 🎉</p>
<h2 id="heading-my-computer-specification">My Computer Specification</h2>
<p>For this guide, I have used my Desktop workstation. If you are also interested in the current specification that I used for this task, here you go:</p>
<ul>
<li>Processor: Ryzen 5 3500X 6 Core and 6 Threads</li>
<li>RAM: 32GB DDR4 3200MHz (16 GB + 8 GB + 8 GB)</li>
<li>GPU: Zotac Nvidia GeForce RTX 3050 8GB GDDR6</li>
<li>Motherboard: Gigabyte B450M Aorus Elite</li>
<li>Storage: Gigabyte 240GB SATA SSD</li>
<li>Monitor: MSI Optix G24 Gaming Curved 75Hz</li>
</ul>
<p>I will be using Windows 11 Pro (Version 22H2) and WSL2 (of course!).</p>
<h2 id="heading-step-1-make-sure-you-have-solid-internet-and-electricity">Step 1: Make Sure You Have Solid Internet and Electricity</h2>
<p>This whole process can take a lot of time. So make sure you're properly connected to the internet and have consistent electricity. For me, it took almost 7 hours in total. You will also need to download some pretty huge packages along the way. </p>
<p>Also, make sure that you have installed the latest Nvidia driver after downloading the official driver from <a target="_blank" href="https://www.nvidia.com/download/index.aspx">the official website of Nvidia</a>. Make sure that you have installed all the updates of your Windows 11.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/win_update.png" alt="Image" width="600" height="400" loading="lazy">
<em>windows update</em></p>
<h2 id="heading-step-2-download-latest-powershell">St<strong>ep 2: Download Latest PowerShell</strong></h2>
<p>I will be using the latest PowerShell. You can download that from the Microsoft store, but I will download it from the official website as the store might create some problems later. </p>
<p>Go to <a target="_blank" href="https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-windows">the official website</a>. This normally redirects you to the latest version of PowerShell available at that moment. For me, the latest version is 7.3 (24 May 2023). For you, it might be the updated version. Don't worry about that. Simply download the latest stable version.</p>
<ol>
<li>Click on the <strong>Download PowerShell</strong> button.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/1-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Download Powershell button</em></p>
<ol start="2">
<li>Find the latest PowerShell of <code>win-x64.msi</code>. Download that.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/2-3.png" alt="Image" width="600" height="400" loading="lazy">
<em>latest PowerShell msi file</em></p>
<ol start="3">
<li>The installation process is pretty straightforward. But I will be guiding you throughout the entire process. Double click on the downloaded file. Then click <code>Next</code>.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/3-2.png" alt="Image" width="600" height="400" loading="lazy">
<em>msi software</em></p>
<ol start="4">
<li>Keep everything as it is and click <code>Next</code>.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/4-3.png" alt="Image" width="600" height="400" loading="lazy">
<em>Next step</em></p>
<ol start="5">
<li>I still prefer to keep everything as it is and simply click <code>Next</code>.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/5-4.png" alt="Image" width="600" height="400" loading="lazy">
<em>Next step</em></p>
<ol start="6">
<li>I still prefer to keep everything as it is and simply click <code>Next</code>.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/6-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Next step</em></p>
<ol start="7">
<li>Click <code>Install</code>.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/7-2.png" alt="Image" width="600" height="400" loading="lazy">
<em>Install</em></p>
<ol start="8">
<li>Now click <code>Finish</code>.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/8-3.png" alt="Image" width="600" height="400" loading="lazy">
<em>Finish</em></p>
<h2 id="heading-step-3-check-your-windows-terminal">Step 3: Check Your Windows Terminal</h2>
<p>I really like the Windows Terminal, as I can simply switch to any other WSL OSes (Ubuntu, Kali, Git Bash, and so on) whenever I want. But before proceeding further, I have to make sure that my current Windows Terminal is the updated one.</p>
<ol>
<li>Open the <strong>Microsoft Store</strong> and search for <code>Windows Terminal</code>.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/9-2.png" alt="Image" width="600" height="400" loading="lazy">
<em>Windows Terminal on Microsoft Store</em></p>
<ol start="2">
<li><p>Click on <code>Update</code> if it needs an update.</p>
</li>
<li><p>Make sure that you are on the latest updated Windows Terminal already.</p>
</li>
<li><p>Now open the Windows Terminal, because we have to change some settings first. Click on <code>Open Settings</code>.</p>
</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/10-2.png" alt="Image" width="600" height="400" loading="lazy">
<em>Windows Terminal Settings Customization</em></p>
<ol start="5">
<li>If you do not see the <code>Open Settings</code> prompt, then simply click the drop-down arrow, and click on <code>Settings</code>.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/11-2.png" alt="Image" width="600" height="400" loading="lazy">
<em>Settings</em></p>
<ol start="6">
<li>From <code>Startup</code>, make sure that the <strong>Default profile</strong> is set on <code>PowerShell</code> (the new PowerShell we installed in Step 2). The <code>Default terminal application</code> should be set on <code>Windows Terminal</code>.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/12-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Default startup config</em></p>
<ol start="7">
<li>Then click <code>Save</code> and exit the terminal.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/13-2.png" alt="Image" width="600" height="400" loading="lazy">
<em>Save</em></p>
<h2 id="heading-step-4-hardware-virtualization">Step 4: Hardware Virtualization</h2>
<p>In order to use WSL, we have to make sure that our CPU virtualization is enabled. You can check the status through your task manager. If it is disabled, then make sure to enable the virtualization through BIOS. </p>
<p>You will find a lot of YouTube videos about this, but make sure that you are following the correct one that matches your motherboard brand and model.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/14-2.png" alt="Image" width="600" height="400" loading="lazy">
<em>Virtualization</em></p>
<h2 id="heading-step-5-install-wsl-and-ubuntu-lts">Step 5: Install WSL and Ubuntu LTS</h2>
<p>Now we need to install the WSL2 and Ubuntu LTS.</p>
<ol>
<li>Open the Windows Terminal as an <strong>Administrator</strong>.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/15-2.png" alt="Image" width="600" height="400" loading="lazy">
<em>Open terminal as an administrator</em></p>
<ol start="2">
<li>For installing <strong>WSL</strong>, use the command <code>wsl --install</code>.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/16-3.png" alt="Image" width="600" height="400" loading="lazy">
<em>VMP install</em></p>
<ol start="3">
<li>Then, it would automatically install the latest LTS version of Ubuntu.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/18-2.png" alt="Image" width="600" height="400" loading="lazy">
<em>Ubuntu install</em></p>
<ol start="4">
<li>After the tasks get finished, it will prompt you for rebooting your PC. Save other work and simply restart your computer.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/19-3.png" alt="Image" width="600" height="400" loading="lazy">
<em>Reboot PC</em></p>
<ol start="5">
<li>After restarting the PC, it would automatically open the terminal and ask you for the username and password for your Linux OS.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/20-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>After rebooting PC</em></p>
<ol start="6">
<li>Give the Username and Password. Make sure to use the same Password on Retype Password!</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/21-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>username and password</em></p>
<ol start="7">
<li>After a while, it will install the necessary components.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/22-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Complete Ubuntu</em></p>
<ol start="8">
<li>Now, make sure that <strong>WSL2</strong> becomes the default WSL in this terminal. Apply the command, <code>wsl --set-default-version 2</code>.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/23-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>WSL 2 default</em></p>
<ol start="9">
<li>If you want to check the WSL OSes status (how many OSes are available, how many of them are running or stopped), use the command, <code>wsl --list --verbose</code>.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/24-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>OSes status</em></p>
<p>Here, it is telling me that I have <strong>Ubuntu</strong> installed on my WSL version 2 and it is currently stopped.</p>
<ol start="10">
<li>However, after working on a WSL OS, if you want to shut down the OS, then you can use the command <code>wsl -t distro_name</code>. For me, it is Ubuntu, so I used <code>wsl -t Ubuntu</code>. <code>t</code> represents the <strong>termination</strong> command here.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/25-2.png" alt="Image" width="600" height="400" loading="lazy">
<em>Terminate command</em></p>
<ol start="11">
<li>If you have multiple OSes in WSL, and if you want to run any specific distribution, then use the command <code>wsl --distribution distribution_name</code>. For example, if I want to run Ubuntu specifically, the command would be <code>wsl --distribution Ubuntu</code>. If you only have one distribution, then you do not necessarily need to worry about this at all.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/26-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>run specific distro</em></p>
<ol start="12">
<li>You can simply use <code>exit</code> to exit a distro from the terminal. It might not necessarily shut down the distribution. You can specifically use the termination command for that. But some regularly used commands are here.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/27-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>regularly used command</em></p>
<ol start="13">
<li>After installing a distribution, you would also be able to see and go there by using the drop-down menu from the Windows Terminal.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/28-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>the drop-down menu for other distributions</em></p>
<h2 id="heading-step-6-configure-ubuntu-lts">Step 6: Configure Ubuntu LTS</h2>
<p>We need to update and install some apps now.</p>
<ol>
<li>Open Ubuntu by using any method inside the Windows Terminal. You can obviously use the dedicated <strong>Ubuntu App</strong>. But I always prefer the Terminal as I can use multiple different distributions and command line applications here altogether.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/29.png" alt="Image" width="600" height="400" loading="lazy">
<em>start Ubuntu</em></p>
<ol start="2">
<li>Update the system by using the command <code>sudo apt update</code>.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/30.png" alt="Image" width="600" height="400" loading="lazy">
<em>update</em></p>
<ol start="3">
<li><p>If you get errors in updating/upgrading saying it can't reach the server then change the nameserver with the command <code>echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf &gt; /dev/null</code>.</p>
</li>
<li><p>After updating, upgrade the system using <code>sudo apt upgrade</code>.</p>
</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/31.png" alt="Image" width="600" height="400" loading="lazy">
<em>Upgrade</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/32.png" alt="Image" width="600" height="400" loading="lazy">
<em>Upgrade system</em></p>
<p>You can clear the terminal by using the <code>clear</code> command.</p>
<ol start="5">
<li>CUDA works with C. So we need to install the gcc compiler first. Use the command <code>sudo apt install gcc --fix-missing</code>.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/33.png" alt="Image" width="600" height="400" loading="lazy">
<em>gcc</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/34.png" alt="Image" width="600" height="400" loading="lazy">
<em>gcc installing</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/35.png" alt="Image" width="600" height="400" loading="lazy">
<em>finishing installation</em></p>
<h2 id="heading-step-7-install-cuda">Step 7: Install CUDA</h2>
<p>Now it is time to install CUDA from the <a target="_blank" href="https://developer.nvidia.com/cuda-downloads">official website of Nvidia</a>.</p>
<p>Make sure to select the following:</p>
<ul>
<li><strong>Operating System</strong>: Linux <br></li>
<li><strong>Architecture</strong>: x86_64 <br></li>
<li><strong>Distribution</strong>: WSL-Ubuntu <br></li>
<li><strong>Version</strong>: 2.0 <br></li>
<li><strong>Installer Type</strong>: deb(local) <br> </li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/36.png" alt="Image" width="600" height="400" loading="lazy">
<em>Nvidia - CUDA</em></p>
<p>This will provide the necessary commands.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/37.png" alt="Image" width="600" height="400" loading="lazy">
<em>commands CUDA</em></p>
<p>Now your task is to apply each command serially in the WSL Ubuntu terminal. Make sure to use the first command twice. It normally resolves the problem of keyring later.</p>
<p>Also, keep in mind that these commands might get changed later. So always follow the official website. For this guideline, I will be using the exact command I used to set up the CUDA in my machine.</p>
<ol>
<li><code>wget https://developer.download.nvidia.com/compute/cuda/repos/wsl-ubuntu/x86_64/cuda-wsl-ubuntu.pin</code></li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/38.png" alt="Image" width="600" height="400" loading="lazy">
<em>1st command</em></p>
<p>I used the same command again after finishing the previous transactions.</p>
<ol start="2">
<li><code>wget https://developer.download.nvidia.com/compute/cuda/repos/wsl-ubuntu/x86_64/cuda-wsl-ubuntu.pin</code></li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/39.png" alt="Image" width="600" height="400" loading="lazy">
<em>1st command</em></p>
<ol start="3">
<li><code>sudo mv cuda-wsl-ubuntu.pin /etc/apt/preferences.d/cuda-repository-pin-600</code></li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/40.png" alt="Image" width="600" height="400" loading="lazy">
<em>2nd Command</em></p>
<ol start="4">
<li><code>wget https://developer.download.nvidia.com/compute/cuda/12.1.1/local_installers/cuda-repo-wsl-ubuntu-12-1-local_12.1.1-1_amd64.deb</code></li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/41.png" alt="Image" width="600" height="400" loading="lazy">
<em>3rd command</em></p>
<p>This normally takes a lot of time as it downloads a large file (above 2GB file size).</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/42.png" alt="Image" width="600" height="400" loading="lazy">
<em>large file</em></p>
<ol start="5">
<li><code>sudo dpkg -i cuda-repo-wsl-ubuntu-12-1-local_12.1.1-1_amd64.deb</code></li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/43.png" alt="Image" width="600" height="400" loading="lazy">
<em>4th command</em></p>
<ol start="6">
<li><code>sudo cp /var/cuda-repo-wsl-ubuntu-12-1-local/cuda-*-keyring.gpg /usr/share/keyrings/</code></li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/44.png" alt="Image" width="600" height="400" loading="lazy">
<em>5th command</em></p>
<ol start="7">
<li>Then update the system using <code>sudo apt-get update</code>.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/45.png" alt="Image" width="600" height="400" loading="lazy">
<em>update system</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/46.png" alt="Image" width="600" height="400" loading="lazy">
<em>updating</em></p>
<ol start="8">
<li><code>sudo apt-get -y install cuda</code></li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/47.png" alt="Image" width="600" height="400" loading="lazy">
<em>install CUDA</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/48.png" alt="Image" width="600" height="400" loading="lazy">
<em>finish CUDA installation</em></p>
<h2 id="heading-step-8-post-installation">Step 8: Post Installation</h2>
<p>The <a target="_blank" href="https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html">official CUDA installation guide from Nvidia</a> tells us to add <code>export PATH=/usr/local/cuda-12.1/bin${PATH:+:${PATH}}</code> to the <strong>PATH</strong> variable.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/49.png" alt="Image" width="600" height="400" loading="lazy">
<em>path</em></p>
<p>I have changed the CUDA version <code>cuda-12.1</code> according to my installed CUDA version. Make sure to do the same for your updated CUDA version.</p>
<p>Do the following to do that:</p>
<ol>
<li>Open Ubuntu in the Windows Terminal.</li>
<li>Go to the root directory using <code>cd ~</code>. Then open the <code>bashrc</code> in nano using <code>nano .bashrc</code></li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/50.png" alt="Image" width="600" height="400" loading="lazy">
<em>root</em></p>
<ol start="3">
<li>Go to the end of the file and copy-paste the path there. For me, the path is <code>export PATH=/usr/local/cuda-12.1/bin${PATH:+:${PATH}}</code>.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/51.png" alt="Image" width="600" height="400" loading="lazy">
<em>path</em></p>
<p>Then use <code>Ctrl</code> + <code>X</code> to close. Make sure to use <code>Y</code> to save in the same file.</p>
<ol start="4">
<li>To apply the changes, use <code>source ~/.bashrc</code>. You can check the path using <code>echo $PATH</code>.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/52.png" alt="Image" width="600" height="400" loading="lazy">
<em>path check</em></p>
<h2 id="heading-step-9-nvidia-cuda-toolkit">Step 9: Nvidia CUDA Toolkit</h2>
<p>Install the Nvidia Cuda Toolkit using <code>sudo apt install nvidia-cuda-toolkit</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/53.png" alt="Image" width="600" height="400" loading="lazy">
<em>toolkit 1</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/54.png" alt="Image" width="600" height="400" loading="lazy">
<em>toolkit 2</em></p>
<p>You can check the Driver and CUDA versions using <code>nvidia-smi</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/55.png" alt="Image" width="600" height="400" loading="lazy">
<em>smi</em></p>
<p>Also, make sure to check whether the Nvidia Cuda Compiler Driver has been installed or not by using <code>nvcc -V</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/56.png" alt="Image" width="600" height="400" loading="lazy">
<em>nvcc</em></p>
<h2 id="heading-step-9-confirm-that-python-is-installed">Step 9: Confirm that Python is Installed</h2>
<p>Now, make sure that you have Python 3 installed in your system. You can check the version using <code>python3 --version</code>. If that says that "python3 is not found" or something like that, then install Python.</p>
<p>Install <strong>PIP</strong> using <code>sudo apt-get install python3-pip</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/57.png" alt="Image" width="600" height="400" loading="lazy">
<em>pip install</em></p>
<h2 id="heading-step-10-install-pytorch">Step 10: Install PyTorch</h2>
<p>For installing PyTorch, go to <a target="_blank" href="https://pytorch.org/get-started/locally/">the official website of PyTorch</a>. Then make sure to select the relevant sections. After that, it will provide you with a command. You have to use the command in your Ubuntu terminal.</p>
<p>For me, the selections were:</p>
<ul>
<li>PyTorch Build: Stable (2.0.1) - Make sure to select the latest stable version always</li>
<li>Your OS: Linux</li>
<li>Package: Pip</li>
<li>Language: Python</li>
<li>Computer Platform: CUDA 11.8 - Make sure to select the latest available CUDA version</li>
</ul>
<p>After that, I got the command <code>pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/58.png" alt="Image" width="600" height="400" loading="lazy">
<em>PyTorch command</em></p>
<p>I simply used that exact command in my Ubuntu terminal.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/59.png" alt="Image" width="600" height="400" loading="lazy">
<em>PyTorch command</em></p>
<p>It also downloads a large file that can take a lot of time if you have a slower internet connection like I do!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/60.png" alt="Image" width="600" height="400" loading="lazy">
<em>PyTorch download</em></p>
<h2 id="heading-step-11-cuda-availability">Step 11: CUDA Availability</h2>
<p>You can directly check whether your CUDA has been installed or not by running two lines of Python code in the terminal.</p>
<ul>
<li>Run Python in the terminal using <code>python3</code>.</li>
<li>Import torch using <code>import torch</code>.</li>
<li>Check the CUDA availability using <code>torch.cuda.is_available()</code>.</li>
</ul>
<p>If it returns <code>True</code>, then you have successfully finished installing CUDA on your system!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/61.png" alt="Image" width="600" height="400" loading="lazy">
<em>cuda yes</em></p>
<h2 id="heading-step-12-nvidia-developer-settings">Step 12: Nvidia Developer Settings</h2>
<p>You have to enable the Nvidia Developer Settings for using CUDA via WSL. Simply follow this process:</p>
<ol>
<li>Open the <strong>Nvidia Control Panel</strong>.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/62.png" alt="Image" width="600" height="400" loading="lazy">
<em>Nvidia control panel</em></p>
<ol start="2">
<li>Click "Agree and Continue".</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/63.png" alt="Image" width="600" height="400" loading="lazy">
<em>agree</em></p>
<ol start="3">
<li>In the Nvidia Control Panel, Click Desktop &gt; Enable Developer Settings. If the "Enable Developer Settings" does not have any check mark, then click on that to enable that feature.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/64.png" alt="Image" width="600" height="400" loading="lazy">
<em>not check mark</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/65.png" alt="Image" width="600" height="400" loading="lazy">
<em>check mark</em></p>
<ol start="4">
<li>The <strong>Developer</strong> section will be visible. Click on <strong>Manage GPU Performance Counters</strong>.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/66.png" alt="Image" width="600" height="400" loading="lazy">
<em>GPU counters</em></p>
<ol start="5">
<li>Check the radio button on "Allow access to the GPU performance counters to all users".</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/67.png" alt="Image" width="600" height="400" loading="lazy">
<em>check</em></p>
<ol start="6">
<li>Click "Apply" and "Yes" to approve the changes permanently.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/68.png" alt="Image" width="600" height="400" loading="lazy">
<em>approve changes</em></p>
<ol start="7">
<li>At the end, it should look like this. </li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/69.png" alt="Image" width="600" height="400" loading="lazy">
<em>final</em></p>
<ol start="8">
<li>You can again check the CUDA availability like earlier.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/70.png" alt="Image" width="600" height="400" loading="lazy">
<em>cuda availability</em></p>
<h2 id="heading-step-12-install-jupyter-notebook">Step 12: Install Jupyter Notebook</h2>
<p>I normally prefer the Jupyter Notebook. You can install it in various ways, like <code>pip install notebook</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/71.png" alt="Image" width="600" height="400" loading="lazy">
<em>notebook 1</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/72.png" alt="Image" width="600" height="400" loading="lazy">
<em>notebook 2</em></p>
<p>But I prefer the command <code>pip install jupyter notebook</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/73.png" alt="Image" width="600" height="400" loading="lazy">
<em>jupyter notebook</em></p>
<p>To open a Jypyter Notebook, you can simply use <code>jupyter notebook</code> in the terminal.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/74.png" alt="Image" width="600" height="400" loading="lazy">
<em>notebook cli</em></p>
<p>The notebook will open instantly and you can use the given URL to open that in your web browser:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/75.png" alt="Image" width="600" height="400" loading="lazy">
<em>open the notebook in the browser</em></p>
<h2 id="heading-step-13-run-some-tests">Step 13: Run Some Tests</h2>
<p>I ran two codes to check the performance of my CUDA.</p>
<ol>
<li>Open a Python3 script in the notebook.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/76.png" alt="Image" width="600" height="400" loading="lazy">
<em>open script</em></p>
<ol start="2">
<li>I used the following code to check whether it is using my CPU or CUDA from my GPU:</li>
</ol>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> torch

<span class="hljs-keyword">if</span> torch.cuda.is_available():
    device = torch.device(<span class="hljs-string">"cuda"</span>)
<span class="hljs-keyword">else</span>:
    device = torch.device(<span class="hljs-string">"cpu"</span>)
print(<span class="hljs-string">"using"</span>, device, <span class="hljs-string">"device"</span>)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/77.png" alt="Image" width="600" height="400" loading="lazy">
<em>cuda</em></p>
<ol start="3">
<li>For the performance comparison between my CPU and GPU (CUDA), I used the following code:</li>
</ol>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> time

matrix_size = <span class="hljs-number">32</span>*<span class="hljs-number">512</span>

x = torch.randn(matrix_size, matrix_size)
y = torch.randn(matrix_size, matrix_size)

print(<span class="hljs-string">"************* CPU SPEED *******************"</span>)
start = time.time()
result = torch.matmul(x, y)
print(time.time() - start)
print(<span class="hljs-string">"verify device:"</span>, result.device)

x_gpu = x.to(device)
y_gpu = y.to(device)
torch.cuda.synchronize()

<span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(<span class="hljs-number">3</span>):
    print(<span class="hljs-string">"************* GPU SPEED *******************"</span>)
    start = time.time()
    result_gpu = torch.matmul(x_gpu, y_gpu)
    torch.cuda.synchronize()
    print(time.time() - start)
    print(<span class="hljs-string">"verify device:"</span>, result_gpu.device)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/78.png" alt="Image" width="600" height="400" loading="lazy">
<em>CPU vs GPU</em></p>
<p>I also made side by side comparisons between the <a target="_blank" href="https://colab.research.google.com/">Google Colab</a> and my computer. You can check them as well.</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Try</td><td>Google Colab</td><td>My Computer</td></tr>
</thead>
<tbody>
<tr>
<td>1</td><td><a target="_blank" href="https://github.com/FahimFBA/CUDA-WSL2-Ubuntu/blob/main/GoogleCollab1.ipynb">Google Colab</a></td><td><a target="_blank" href="https://github.com/FahimFBA/CUDA-WSL2-Ubuntu/blob/main/CUDA%20_TEST_Fahim1.ipynb">My PC</a></td></tr>
<tr>
<td>2</td><td><a target="_blank" href="https://github.com/FahimFBA/CUDA-WSL2-Ubuntu/blob/main/GoogleCollab2.ipynb">Google Colab</a></td><td><a target="_blank" href="https://github.com/FahimFBA/CUDA-WSL2-Ubuntu/blob/main/CUDA%20_TEST_Fahim2.ipynb">My PC</a></td></tr>
</tbody>
</table>
</div><p>The result already states that my PC is working better than the Google Colab.</p>
<h2 id="heading-step-14-remove-the-cuda-deb-file">Step 14: Remove the CUDA Deb File</h2>
<p>If you think that you do not need the CUDA deb file anymore, then you can remove that using the following command:</p>
<pre><code class="lang-bash">rm filename
</code></pre>
<p>For me it was this:</p>
<pre><code class="lang-bash">rm cuda-repo-wsl-ubuntu-12-1-local_12.1.1-1_amd64.deb
</code></pre>
<p>It does not remove the CUDA from your system. It just removes the deb file from your system.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/79.png" alt="Image" width="600" height="400" loading="lazy">
<em>remove deb</em></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>I hope that you have successfully installed CUDA on your Windows 11 system using WSL2. If you have any questions, feel free to reach out to me using <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>Also, make sure to follow me on <a target="_blank" href="https://github.com/FahimFBA">GitHub</a> and star (⭐) the <a target="_blank" href="https://github.com/FahimFBA/CUDA-WSL2-Ubuntu">repository</a>!</p>
<p>You can also <a target="_blank" href="https://www.youtube.com/@FahimAmin?sub_confirmation=1">subscribe to my YouTube channel</a> for more helpful video content.</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>
<p>Thank you for reading the entire article till now. Have a great day! 😊</p>
<p>Cover image: Photo by <a target="_blank" href="https://unsplash.com/@tetrakiss?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Arseny Togulev</a> on <a target="_blank" href="https://unsplash.com/photos/MECKPoKJYjM?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Run Linux Apps on Windows 10 and 11 Using WSL ]]>
                </title>
                <description>
                    <![CDATA[ By Yosra Emad I've been using Windows Subsystem for Linux (WSL) for my OS class for quite a while now. And I love how I can use Linux commands in Windows in a straightforward way without the added complexity of installing a virtual machine or dual bo... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-run-linux-apps-on-windows-10-11-using-wsl/</link>
                <guid isPermaLink="false">66d4617151f567b42d9f84dc</guid>
                
                    <category>
                        <![CDATA[ Linux ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Windows ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Windows 10 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ WSL ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 16 Dec 2021 17:33:23 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/12/photo_2021-12-16_19-57-32.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Yosra Emad</p>
<p>I've been using Windows Subsystem for Linux (WSL) for my OS class for quite a while now. And I love how I can use Linux commands in Windows in a straightforward way without the added complexity of installing a virtual machine or dual booting. </p>
<p>By the end of this article, you should be able to run Linux commands right from Windows like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Untitled.png" alt="Image" width="600" height="400" loading="lazy">
<em>example of linux commands on windows</em></p>
<h1 id="heading-prerequisites">Prerequisites</h1>
<p>To have WSL running effectively, I suggest you upgrade to Windows 11. WSL is also available on Windows 10, but it is way more efficient on Windows 11 based on my experience. </p>
<p>For Windows 10, you'll need to have build 21364 or higher.</p>
<p>This article will cover what you can do on both Windows 10 and 11</p>
<h1 id="heading-how-to-install-wsl">How to Install WSL</h1>
<p>The command to run WSL is straightforward:</p>
<pre><code class="lang-powershell">wsl -<span class="hljs-literal">-install</span>
</code></pre>
<p>This will download the Linux kernel, set WSL 2 as the default, and install Ubuntu as the default distribution.</p>
<p>Don't want ubuntu? Here is the command for you:</p>
<pre><code class="lang-powershell">wsl -<span class="hljs-literal">-install</span> <span class="hljs-literal">-d</span> &lt;distro name&gt;
</code></pre>
<p>These are the available distributions as of now:</p>
<ul>
<li>Ubuntu</li>
<li>OpenSUSE Leap 42</li>
<li>SUSE Linux Enterprise Server 12 (SLES)</li>
<li>Kali Linux</li>
<li>Debian GNU/Linux</li>
</ul>
<p>After this, you'll find an app called Ubuntu (or any other distro) in your start menu:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Untitled-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h1 id="heading-open-the-linux-terminal">Open the Linux Terminal</h1>
<p>Open the Ubuntu app that you just installed, and you'll be greeted with a Linux terminal! Try running some commands:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Untitled-2.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h1 id="heading-what-if-i-want-to-access-my-windows-files">What if I want to access my Windows files?</h1>
<p>If you go to your file explorer (winkey+E) you'll find a new Linux option on the left where all your Linux files exist. This is where when any files you create in the terminal will be located:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Untitled-3.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>But what if you want to access your regular files?</p>
<p>Luckily, you can do that easily. Just run the following command in your Linux terminal:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">cd</span> /mnt/
</code></pre>
<p>If you run <code>ls</code> here, you'll find your computer drives. This way you'll be able to <code>cd</code> your way into your files.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Untitled-4-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h1 id="heading-how-to-create-aliases-in-wsl2">How to Create Aliases in WSL2</h1>
<p>Do you ever have a long command to type and wish there were a shortcut for it? Then, aliases are your friends.</p>
<p>There are two ways to create aliases:</p>
<ul>
<li>per session</li>
<li>permanently</li>
</ul>
<h2 id="heading-how-to-create-per-session-aliases-in-wsl2">How to create per session aliases in WSL2</h2>
<p>To create an alias in your current session of Linux (the alias will be forgotten once you close the terminal), then you should run the following command:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">alias</span> &lt;<span class="hljs-built_in">alias</span> name&gt;=<span class="hljs-string">'&lt;command&gt;'</span>
</code></pre>
<p>for example:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">alias</span> runc=<span class="hljs-string">'gcc main.c -o main'</span>
</code></pre>
<h2 id="heading-how-to-create-permanent-aliases-in-wsl2">How to create permanent aliases in WSL2</h2>
<p>We'll edit a file called <code>.bash_aliases</code> to save our aliases.</p>
<p>Run the following commands:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">cd</span> ~
ls -a
</code></pre>
<p>Look through the list of files that are printed out and look for <code>.bash_aliases</code>.</p>
<p>If you can't find it, run the following command:</p>
<pre><code class="lang-bash">touch .bash_aliases
</code></pre>
<p>Now in order to edit the file, run this command:</p>
<pre><code class="lang-bash">vi .bash_aliases
</code></pre>
<p>You'll be greeted with a screen like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Untitled-5.png" alt="Image" width="600" height="400" loading="lazy"></p>
<ul>
<li>Press "i" to start typing, and add as many aliases as you want.</li>
</ul>
<p>For example:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">alias</span> runc=<span class="hljs-string">'gcc main.c -o main'</span>
<span class="hljs-built_in">alias</span> hello=<span class="hljs-string">'echo hello'</span>
</code></pre>
<ul>
<li>To exit the typing mode, press "ctrl + c".</li>
<li>To exit Vim and save the files type ":wq!" (I'm proud that I didn't have to google that.)</li>
</ul>
<p>Now you're ready! Restart Ubuntu and start typing any of the following aliases above and it should work perfectly:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Untitled-6.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h1 id="heading-how-to-run-gui-apps">How to Run GUI Apps</h1>
<p>Okay cool, now we know how to run command line apps from WSL2. But what if we want to run Linux GUI apps? The answer is simple – you just need to install the GUI app before running it. I'll use Firefox as an example.</p>
<p>To install Firefox:</p>
<pre><code class="lang-bash">sudo apt install firefox
</code></pre>
<p>To run Firefox:</p>
<pre><code class="lang-bash">firefox
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Screenshot--531-.png" alt="Untitled" width="600" height="400" loading="lazy"></p>
<p>If you already have Firefox on your Windows machine, you'll find that it isn't open. That's because you're now running Firefox for Linux not Windows.</p>
<p>You can even run Firefox for Linux right from the start menu if you use Windows 11. You'll find it under your distro's folder.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Untitled-7.png" alt="Untitled" width="600" height="400" loading="lazy"></p>
<h1 id="heading-conclusion">Conclusion</h1>
<p>This article covered how to run WSL 2 effectively. If you have any questions, feel free to contact me on any of my <a target="_blank" href="https://yosracodes.bio.link/">social media platforms</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Automating your Windows Subsystem Linux Setup ]]>
                </title>
                <description>
                    <![CDATA[ By Scott Spence I’m a Windows user and have been so for as long as I can remember. I have fiddled around with Linux as well but have stuck to Windows as I’ve found it to be a bit less neckbeardy for me. Both have their pros and cons. But ]]>
                </description>
                <link>https://www.freecodecamp.org/news/automating-your-windows-subsystem-linux-setup-df4c9a7b0e7b/</link>
                <guid isPermaLink="false">66d8521662a291dea89878f0</guid>
                
                    <category>
                        <![CDATA[ Node.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ terminal ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Windows 10 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ WSL ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 16 Jan 2018 18:07:26 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*03UuTGdsAF5PEgaI4BwYZg.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Scott Spence</p>
<p>I’m a Windows user and have been so for as long as I can remember. I have fiddled around with Linux as well but have stuck to Windows as I’ve found it to be a bit less <a target="_blank" href="http://theoatmeal.com/blog/fix_computer">neckbeardy</a> for me. Both have their pros and cons. But one of the biggest cons with Windows for me when I started learning web development was the lack of all my Linux command line tools.</p>
<p>That was until Windows Subsystem Linux (WSL) came along ?</p>
<p>I love it! You can have a Bash shell in Windows and run all your Node.js Apps through it too and with the Windows 10 Fall Creators Update, WSL is really easy to set up.</p>
<p>Quick backstory on why I’m posting this. I nuked my laptop the other day as I was having issues with Bash on Windows related partly to using <a target="_blank" href="https://github.com/Microsoft/WSL/issues/776">nvm</a> with WSL. I was getting frustrated with how my computer was performing. But I realise now that I overreacted.</p>
<p>After I brought my computer back up again, I had to set up my development environment again from scratch. Luckily for me, I keep all my settings and config information in a <a target="_blank" href="https://github.com/spences10/settings">GitHub repo</a> in the event of me getting a new computer or to recover from a catastrophic event (like a nuked computer).</p>
<p>In this article, I’d like to show you how I set up my Windows Subsystem Linux for my development environment.</p>
<p>This is my opinionated view on my specif setup and usage of WSL and this is my step by step guide for the next time I have to spin up a development environment from scratch on Windows.</p>
<p>So, after installing <a target="_blank" href="https://www.microsoft.com/store/productId/9NBLGGH4MSV6">WSL</a> from the Microsoft Store and adding your default user, the first thing is to update and upgrade everything.</p>
<pre><code>sudo apt updatesudo apt -y upgrade
</code></pre><p>If you’ve not used any Linux distributions before the <code>-y</code> in the upgrade statement is to default the answer to “Yes” for any prompts that are displayed in the terminal. You might not want to do this, as there may be some programs you don’t want to update but I do.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/OXOMF6dNg6mFcLndoTphMYRDL76E880tt09a" alt="Image" width="800" height="215" loading="lazy">
<em>Yes to all the things!</em></p>
<p>By adding the <code>-y</code> flag, you wont have these messages ?</p>
<p><strong>Build tools</strong></p>
<p>To compile and install native add-ons from npm you may also need to install build tools, I need this for Gatsby images which uses <code>sharp</code> which in turn uses <code>node-gyp</code>:</p>
<pre><code>sudo apt install -y build-essential
</code></pre><p><strong>Install node</strong></p>
<p>Installing Node.js via the instructions given on the nodejs.org site doesn’t set up the correct permissions for me. So when trying to <code>npm install</code> anything I get errors, I <a target="_blank" href="https://github.com/Microsoft/WSL/issues/776#issuecomment-266112578">found out</a> that using <code>n</code> helps:</p>
<p><strong>Install node with <code>n</code></strong></p>
<p>As it’s a fresh install then we can go ahead and use <a target="_blank" href="https://github.com/mklement0/n-install">n-install</a> with:</p>
<pre><code>curl -L https:<span class="hljs-comment">//git.io/n-install | bash</span>
</code></pre><p>This will install the latest stable version of node ?</p>
<p>Once the script is complete, restart bash with:</p>
<pre><code>. /home/my_user_name/.bashrc # displays <span class="hljs-built_in">this</span> <span class="hljs-keyword">for</span> you to copy paste
</code></pre><p>Check your node and npm versions:</p>
<pre><code>node -v &amp;&amp; npm -v
</code></pre><p><strong>Install fish ?</strong></p>
<p>Fish is now my go to shell purely for the auto complete/intellisense ? there’s also some nice themes you can get for it too.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/sT61-l2VWUosXNsabUdkBCH2ZJQm6COn6LEy" alt="Image" width="800" height="527" loading="lazy">
<em>fish awesomeness ?</em></p>
<pre><code>sudo apt -y install fishsudo apt -y upgrade &amp;&amp; sudo apt -y autoremove
</code></pre><p><strong>Install Oh My Fish | OMF</strong></p>
<p>Oh My Fish is like a package manager for Fish enabling the installation of packages and themes.</p>
<pre><code>curl -L https:<span class="hljs-comment">//get.oh-my.fish | fish</span>
</code></pre><p><strong>Install OMF theme</strong></p>
<pre><code>omf install clearance
</code></pre><p><strong>The start of the beginning</strong></p>
<p>Ok, so that is a basic setup for WSL. You’ll probably want to get Git set up now. I have been using SSH over HTTPS for a while now on WSL.</p>
<p><strong>Note:</strong> At the time of writing this, WSL Git integration with VSCode doesn’t work so I have added a Git install to my windows machine, you can omit this and go full Git via the terminal but I really like the VSCode Git integration.</p>
<p>To get SSH set up on your machine take a look at this <a target="_blank" href="https://github.com/spences10/cheat-sheets/blob/master/git.md#how-to-authenticate-with-github-using-ssh">handy SSH setup</a>. I say SSH instead of HTTPS because I had all sorts of issues with the Git credential manager and the keyring manager. In the end it was actually quicker to create an SSH key and authenticate with GitHub. The guide I linked walks you through it.</p>
<p><strong>Move your dotfiles</strong></p>
<p>If you have all your <a target="_blank" href="https://github.com/spences10/dotfiles">dotfiles</a> backed up in a GitHub repo then now is a good time to add them to your WSL folder, the last times I did this I manually set the permissions after moving each of the the files but have since discovered <code>[rsync](https://www.tecmint.com/rsync-local-remote-file-synchronization-commands/)</code> to move all the files.</p>
<pre><code>rsync -avzh /mnt/c/Users/dotfiles/ ~/
</code></pre><p>That will copy the contents of my <code>dotfiles</code> folder to the <code>~/</code> (home) directory in WSL, you can check them with:</p>
<pre><code>ls -la ~/
</code></pre><p><img src="https://cdn-media-1.freecodecamp.org/images/Uq3kAxUEXpizEGd-h7ajRZMLBBZVvlrg5t8B" alt="Image" width="581" height="305" loading="lazy"></p>
<p>I copied across my <code>.gitconfig</code>, <code>.gitignore</code> and <code>.npmrc</code> dotfiles pictured here and you can see that the permissions are not consistent with the <code>.bashrc</code> file.</p>
<p>Change the file permissions with <code>chmod</code> and to get the attributes of a similar file use <code>stat</code>:</p>
<pre><code>stat -c “%a %n” ~/.*
</code></pre><p>This will list out all everything that begins with a <code>.</code> here’s mine:</p>
<pre><code><span class="hljs-number">777</span> /home/scott/<span class="hljs-number">.755</span> /home/scott/.<span class="hljs-number">.600</span> /home/scott/.bash_history644 /home/scott/.bash_logout644 /home/scott/.bashrc777 /home/scott/.cache777 /home/scott/.config777 /home/scott/.gitconfig777 /home/scott/.gitignore777 /home/scott/.local777 /home/scott/.npm777 /home/scott/.npmrc644 /home/scott/.profile644 /home/scott/.sudo_as_admin_successful
</code></pre><p>I only want to change <code>.gitconfig</code>, <code>.gitignore</code> and <code>.npmrc</code> here so I’m going to do this:</p>
<pre><code>chmod <span class="hljs-number">644</span> .gitconfig .gitignore .npmrc
</code></pre><p>And now my files look like this. ?</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/JbMu-0tz5J581tQ3FwIjYADBvuWyqXC-xMof" alt="Image" width="572" height="386" loading="lazy"></p>
<p>Ok now were up and running with an updated Ubuntu install, node and fish terminal. Of course there’s still the case of installing all your global npm packages you want for development now.</p>
<p>Good luck!</p>
<h3 id="heading-thanks-for-reading">Thanks for reading</h3>
<p>If you thought this was interesting, leave a clap or two, subscribe for future updates or tweet me your thoughts.</p>
<p>If there is anything I have missed, or if you have a better way to do something then please let me know.</p>
<p>Get me on <a target="_blank" href="https://twitter.com/ScottDevTweets">Twitter</a> or <a target="_blank" href="https://github.com/spences10/ama">Ask Me Anything</a> on GitHub.</p>
<blockquote>
<p><strong>You can read other articles like this on <a target="_blank" href="https://thelocalhost.blog/">my blog</a>.</strong></p>
</blockquote>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
