<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Self Hosting on avni.sh</title>
    <link>http://www.avni.sh/posts/self-hosting/</link>
    <description>Recent content in Self Hosting on avni.sh</description>
    <image>
      <title>avni.sh</title>
      <url>http://www.avni.sh/cover.webp</url>
      <link>http://www.avni.sh/cover.webp</link>
    </image>
    <generator>Hugo</generator>
    <language>en</language>
    <lastBuildDate>Fri, 12 Jan 2024 00:00:00 +0000</lastBuildDate>
    <atom:link href="http://www.avni.sh/posts/self-hosting/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Self Hosting LLMs using Ollama</title>
      <link>http://www.avni.sh/posts/self-hosting/self-hosting-ollama/</link>
      <pubDate>Fri, 12 Jan 2024 00:00:00 +0000</pubDate>
      <guid>http://www.avni.sh/posts/self-hosting/self-hosting-ollama/</guid>
      <description>Hosting Large Language Models (LLMs) on your infrastructure and integrating them with your development environment</description>
      <content:encoded><![CDATA[<p>Ollama provides an interface to self-host and interact with
open-source LLMs (Large Language Models) using its binary
or container image. Managing LLMs using Ollama
is like managing <a href="/posts/computer-science/technologies/cloud-native/container-lifecycle" target="_blank">container lifecycle</a> using container engines like <code>docker</code> or <code>podman</code>.</p>
<ul>
<li>
<p>Ollama commands <code>pull</code> and <code>run</code> are used to download and execute
LLMs respectively, just like the ones used to manage containers
with <code>podman</code> or <code>docker</code>.</p>
</li>
<li>
<p>Tags like <code>13b-python</code> and <code>7b-code</code> are used to manage different
variations of an LLM.</p>
</li>
<li>
<p>A <code>Modelfile</code> (like <code>Dockerfile</code>) is created to build a custom
model using an existing LLM as its base. Additional
parameters like <code>TEMPLATE</code> and <code>PARAMETER</code> could be used to define
a prompt template or fine-tune model parameters respectively.</p>
</li>
</ul>
<h1 id="deploying-ollama-container-with-nvidia-gpu">Deploying Ollama container with NVIDIA GPU</h1>
<p>Deploying the Ollama container directly would allow it to
utilize CPU resources for its LLM workloads, but with the parallel
computation capabilities of a Graphics Processing Unit (GPU), we can
improve the inference performance of all models.</p>
<p>In this article I&rsquo;m using an <strong>NVIDIA GeForce RTX 3070 Ti</strong> GPU, if you
want to use a GPU from AMD/Intel or any other manufacturer then steps
like driver and container toolkit installation and GPU configuration
for the container engine will differ.</p>
<h2 id="gpu-passthrough-to-vm">GPU Passthrough to VM</h2>
<p>I am deploying the Ollama container on a Fedora 38 virtual machine
so the first step will be the GPU Passthrough from my hypervisor
(Proxmox) to the VM. You can skip this step if you are deploying
Ollama on a baremetal machine.</p>
<p>In the Proxmox&rsquo;s Web UI, we can go to the VM&rsquo;s <code>Hardware</code> section
and <code>Add</code> your <code>PCI  Device</code> i.e. your GPU.</p>
<p align="center"><img src="proxmox-hardware.png" alt="Proxmox VM's Hardware Section"></p>
<p align="center"><small>Proxmox VM's Hardware Section</small></p>
<p>Make sure to mark the <code>All Functions</code> checkbox.</p>
<p align="center"><img src="proxmox-gpu-passthrough.png" alt="GPU Passthrough to a Proxmox VM"></p>
<p align="center"><small>GPU Passthrough to a Proxmox VM</small></p>
<p>Once the VM is rebooted we can verify the GPU Passthrough using
the following command.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">lspci <span class="p">|</span> grep NVIDIA
</span></span></code></pre></td></tr></table>
</div>
</div><p>If the GPU name is present in the command&rsquo;s output (like below)
then the passthrough is successful and we can move to the next step.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">06:10.0 VGA compatible controller: NVIDIA Corporation GA104 [GeForce RTX 3070 Ti] (rev a1)
</span></span><span class="line"><span class="cl">06:10.1 Audio device: NVIDIA Corporation GA104 High Definition Audio Controller (rev a1)
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="cuda-toolkit-installation">CUDA Toolkit Installation</h2>
<p>To utilize the parallel computation capabilities of the CUDA cores
provided in NVIDIA GPUs we have to install the CUDA Toolkit.
You can follow <a href="https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html" target="_blank">NVIDIA&rsquo;s documentation</a> on the CUDA Toolkit
installation on Linux because the steps vary depending on the host&rsquo;s configuration.</p>
<p>Here are the steps for Fedora 38:</p>
<ol>
<li>Downloading CUDA Toolkit Repo RPM.</li>
</ol>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">wget https://developer.download.nvidia.com/compute/cuda/12.3.2/local_installers/cuda-repo-fedora37-12-3-local-12.3.2_545.23.08-1.x86_64.rpm
</span></span></code></pre></td></tr></table>
</div>
</div><ol start="2">
<li>Installing CUDA Toolkit Repo RPM.</li>
</ol>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo rpm -i cuda-repo-fedora37-12-3-local-12.3.2_545.23.08-1.x86_64.rpm
</span></span></code></pre></td></tr></table>
</div>
</div><ol start="3">
<li>Cleaning <code>dnf</code> Repository Metadata.</li>
</ol>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo dnf clean all
</span></span></code></pre></td></tr></table>
</div>
</div><ol start="4">
<li>Installing <code>cuda-toolkit</code> package.</li>
</ol>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo dnf -y install cuda-toolkit-12-3
</span></span></code></pre></td></tr></table>
</div>
</div><ol start="5">
<li>Installing <code>legacy</code> (proprietary) or <code>open</code> (open source)
kernel module for <code>nvidia-driver</code>.</li>
</ol>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo dnf -y module install nvidia-driver:latest-dkms
</span></span></code></pre></td></tr></table>
</div>
</div><p>or</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo dnf -y module install nvidia-driver:open-dkms
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="nvidia-container-toolkit-installation">NVIDIA Container Toolkit Installation</h2>
<p>With <code>nvidia-container-tookit</code>, we can use our NVIDIA GPU
in containerized applications. Here are the steps for installing
NVIDIA Container Toolkit on Fedora 38:</p>
<ol>
<li>Adding <code>nvidia-container-tookit</code> repository.</li>
</ol>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl -s -L https://nvidia.github.io/libnvidia-container/stable/rpm/nvidia-container-toolkit.repo <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>    <span class="p">|</span> sudo tee /etc/yum.repos.d/nvidia-container-toolkit.repo
</span></span></code></pre></td></tr></table>
</div>
</div><ol start="2">
<li>Installing the <code>nvidia-container-tookit</code> package.</li>
</ol>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo dnf install -y nvidia-container-toolkit
</span></span></code></pre></td></tr></table>
</div>
</div><ol start="3">
<li>Once the container toolkit is installed, we have to add its
runtime to our container engine.</li>
</ol>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo nvidia-ctk runtime configure --runtime<span class="o">=</span>docker
</span></span></code></pre></td></tr></table>
</div>
</div><ol start="4">
<li>Finally, we can start using our NVIDIA GPU with Docker
containers after restarting the <code>docker</code> Daemon.</li>
</ol>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo systemctl restart docker
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="deploying-ollama-as-a-docker-container">Deploying Ollama as a Docker Container</h2>
<ol>
<li>Create a directory on our host to store LLMs to avoid
re-downloading models after reprovisioning or updating the
container.</li>
</ol>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">mkdir -p ~/container-data/ollama
</span></span></code></pre></td></tr></table>
</div>
</div><ol start="2">
<li>The following <code>compose.yaml</code> file will deploy
the <code>ollama</code> container with our NVIDIA GPU.</li>
</ol>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">version</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;3.6&#39;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">services</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">ollama</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">container_name</span><span class="p">:</span><span class="w"> </span><span class="l">ollama</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">ollama/ollama:latest</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">volumes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">~/container-data/ollama:/root/.ollama</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">ports</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;11434:11434&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">restart</span><span class="p">:</span><span class="w"> </span><span class="l">unless-stopped</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">deploy</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">resources</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">reservations</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">devices</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span>- <span class="nt">driver</span><span class="p">:</span><span class="w"> </span><span class="l">nvidia</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">count</span><span class="p">:</span><span class="w"> </span><span class="l">all</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">capabilities</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="l">gpu]</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><p>If you want to provision the container without GPU
you have to remove the <code>deploy</code> section.</p>
<ol start="3">
<li>Deploy the <code>ollama</code> container using the following command.</li>
</ol>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">docker compose down <span class="o">&amp;&amp;</span> docker compose up -d
</span></span></code></pre></td></tr></table>
</div>
</div><p>If you want to deploy Ollama with a ChatGPT-Style Web UI
then follow the deployment steps for <a href="/posts/self-hosting/self-hosting-ollama/#ollama-web-ui">Ollama Web UI</a>.</p>
<h1 id="managing-llms-using-ollama">Managing LLMs using Ollama</h1>
<p>Once the container is provisioned we can start downloading and
executing models.</p>
<p>To attach the Ollama container with a terminal use the
following command</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">docker <span class="nb">exec</span> -it ollama /bin/bash
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="downloading-llms-using-the-pull-command">Downloading LLMs using the <code>pull</code> command</h2>
<p>To download a model use the <code>ollama pull</code> command with the name
of LLM and its tag (refer to the <a href="https://ollama.ai/library" target="_blank">Ollama Library</a>).</p>
<p>For example, to download the Code Llama model with 7 Billion
parameters we have to pull the <code>codellama:7b</code> model.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ollama pull codellama:7b
</span></span></code></pre></td></tr></table>
</div>
</div><p>The model size could range from 4 to 19 GB (or even more).
So choosing the right model tag is crucial to decrease downloading
time and resource utilization.</p>
<p>If we want to delete a downloaded model we&rsquo;ll use the <code>ollama rm</code>
command followed by the name of the model.</p>
<h2 id="executing-llms-using-the-run-command">Executing LLMs using the <code>run</code> command</h2>
<p>Before we prompt the model we have to run it
first using the <code>ollama run</code> command followed by the name of
the model.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ollama run codellama:7b
</span></span></code></pre></td></tr></table>
</div>
</div><p>This command will drop us directly into the model&rsquo;s
prompting window.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">&gt;&gt;&gt; Who are you?
</span></span><span class="line"><span class="cl">I am LLaMA, an AI assistant developed by Meta AI that 
</span></span><span class="line"><span class="cl">can understand and respond to human input in a conversational 
</span></span><span class="line"><span class="cl">manner. I am trained on a massive dataset of text from the 
</span></span><span class="line"><span class="cl">internet and can generate human-like responses to a wide range 
</span></span><span class="line"><span class="cl">of topics and questions. I can be used to create chatbots, 
</span></span><span class="line"><span class="cl">virtual assistants, and other applications that require natural 
</span></span><span class="line"><span class="cl">language understanding and generation capabilities.
</span></span></code></pre></td></tr></table>
</div>
</div><h1 id="prompting-llms-from-command-line">Prompting LLMs from Command Line</h1>
<p>Ollama exposes multiple REST API endpoints to manage and interact
with the models</p>
<ul>
<li><code>/api/tags</code>: To list all the local models.</li>
<li><code>/api/generate</code>: To generate a response from an LLM with the
prompt passed as input.</li>
<li><code>/api/chat</code>: To generate the next chat response from an LLM.
The prior chat history could be passed as input.</li>
</ul>
<p>We can perform these API requests using <code>curl</code> and format the
response using <code>jq</code>.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl -d <span class="s1">&#39;{
</span></span></span><span class="line"><span class="cl"><span class="s1">  &#34;model&#34;: &#34;codellama:7b&#34;,
</span></span></span><span class="line"><span class="cl"><span class="s1">  &#34;prompt&#34;: &#34;Write a quicksort program in Go&#34;,
</span></span></span><span class="line"><span class="cl"><span class="s1">  &#34;stream&#34;: false
</span></span></span><span class="line"><span class="cl"><span class="s1">}&#39;</span> http://localhost:11434/api/generate <span class="p">|</span> jq -r <span class="s2">&#34;.response&#34;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>By assigning the <code>stream</code> as <code>false</code> we will receive the complete
response as a single JSON object rather than a stream of multiple
objects.</p>
<h1 id="ollama-web-ui">Ollama Web UI</h1>
<p>With self-hosted applications, it always helps to have a web interface
for management and access from any device.
The Ollama Web UI provides an interface similar to ChatGPT to interact
with LLMs present in Ollama.</p>
<h2 id="deploying-ollama-web-ui">Deploying Ollama Web UI</h2>
<p>Similar to the <code>ollama</code> container deployment we will create a data
directory for <code>ollama-webui</code></p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">mkdir -p ~/container-data/ollama-webui
</span></span></code></pre></td></tr></table>
</div>
</div><p>Modify our existing <code>compose.yaml</code>.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">version</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;3.6&#39;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">services</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">ollama</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">container_name</span><span class="p">:</span><span class="w"> </span><span class="l">ollama</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">ollama/ollama:latest</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">volumes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">~/container-data/ollama:/root/.ollama</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">ports</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;11434:11434&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">restart</span><span class="p">:</span><span class="w"> </span><span class="l">unless-stopped</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">deploy</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">resources</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">reservations</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">devices</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span>- <span class="nt">driver</span><span class="p">:</span><span class="w"> </span><span class="l">nvidia</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">count</span><span class="p">:</span><span class="w"> </span><span class="l">all</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">capabilities</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="l">gpu]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">ollama-webui</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">container_name</span><span class="p">:</span><span class="w"> </span><span class="l">ollama-webui</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">ghcr.io/ollama-webui/ollama-webui:main</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">ports</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="s2">&#34;3030:8080&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">extra_hosts</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="l">host.docker.internal:host-gateway</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">volumes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="l">~/container-data/ollama-webui:/app/backend/data</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">restart</span><span class="p">:</span><span class="w"> </span><span class="l">always</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><p>Deploy both containers using <code>docker compose</code>.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">docker compose down <span class="o">&amp;&amp;</span> docker compose up -d
</span></span></code></pre></td></tr></table>
</div>
</div><p>If the <code>ollama</code> container is deployed on a different host then
we have to rebuild the <code>ollama-webui</code> container image by following
the instructions from <a href="https://github.com/ollama-webui/ollama-webui#using-ollama-on-a-different-server" target="_blank">here</a>.</p>
<h2 id="managing-llms-from-ollama-web-ui">Managing LLMs from Ollama Web UI</h2>
<p>Once the deployment is completed we can visit the web UI
at <a href="http://localhost:3030" target="_blank"><code>localhost:3030</code></a>.</p>
<p align="center"><img src="ollama-webui.png" alt="Ollama Web UI"></p>
<p align="center"><small>Ollama Web UI</small></p>
<p>Alongside prompting we can also use the Web UI to manage models.</p>
<p align="center"><img src="ollama-webui-models.png" alt="Managing models using Ollama Web UI"></p>
<p align="center"><small>Managing models using Ollama Web UI</small></p>
<h1 id="integrating-ollama-with-neovim">Integrating Ollama with Neovim</h1>
<p>If you are using Neovim (<a href="/posts/developer-tools/my-development-environment" target="_blank">like me</a>)
then you can integrate models in your development environment
using <a href="https://github.com/nomnivore/ollama.nvim" target="_blank"><code>ollama.nvim</code></a>.</p>
<p><code>ollama.nvim</code> supports the following features:</p>
<ul>
<li>Code generation from a text prompt</li>
<li>Generating an explanation for a code snippet</li>
<li>Code modification suggestions</li>
</ul>
<p align="center"><img src="ollama-nvim.gif" alt="Code explanation from Ollama using ollama.nvim"></p>
<p align="center"><small>Code explanation from Ollama using ollama.nvim</small></p>
<p>I am using LazyVim so I&rsquo;ve created <code>~/.config/nvim/lua/plugins/ollama.lua</code>
with the following content.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-lua" data-lang="lua"><span class="line"><span class="cl"><span class="kr">return</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">	<span class="s2">&#34;nomnivore/ollama.nvim&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">	<span class="n">dependencies</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">		<span class="s2">&#34;nvim-lua/plenary.nvim&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">	<span class="p">},</span>
</span></span><span class="line"><span class="cl">	<span class="c1">-- All the user commands added by the plugin</span>
</span></span><span class="line"><span class="cl">	<span class="n">cmd</span> <span class="o">=</span> <span class="p">{</span> <span class="s2">&#34;Ollama&#34;</span><span class="p">,</span> <span class="s2">&#34;OllamaModel&#34;</span><span class="p">,</span> <span class="s2">&#34;OllamaServe&#34;</span><span class="p">,</span> <span class="s2">&#34;OllamaServeStop&#34;</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl">	<span class="n">keys</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">		<span class="c1">-- Sample keybind for prompt menu.</span>
</span></span><span class="line"><span class="cl">		<span class="c1">-- Note that the &lt;c-u&gt; is important for selections</span>
</span></span><span class="line"><span class="cl">		<span class="c1">-- to work properly.</span>
</span></span><span class="line"><span class="cl">		<span class="p">{</span>
</span></span><span class="line"><span class="cl">			<span class="s2">&#34;&lt;leader&gt;oo&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">			<span class="s2">&#34;:&lt;c-u&gt;lua require(&#39;ollama&#39;).prompt()&lt;cr&gt;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">			<span class="n">desc</span> <span class="o">=</span> <span class="s2">&#34;ollama prompt&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">			<span class="n">mode</span> <span class="o">=</span> <span class="p">{</span> <span class="s2">&#34;n&#34;</span><span class="p">,</span> <span class="s2">&#34;v&#34;</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl">		<span class="p">},</span>
</span></span><span class="line"><span class="cl">		<span class="c1">-- Sample keybind for direct prompting.</span>
</span></span><span class="line"><span class="cl">		<span class="c1">-- Note that the &lt;c-u&gt; is important for selections</span>
</span></span><span class="line"><span class="cl">		<span class="c1">-- to work properly.</span>
</span></span><span class="line"><span class="cl">		<span class="p">{</span>
</span></span><span class="line"><span class="cl">			<span class="s2">&#34;&lt;leader&gt;oG&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">			<span class="s2">&#34;:&lt;c-u&gt;lua require(&#39;ollama&#39;).prompt(&#39;Generate_Code&#39;)&lt;cr&gt;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">			<span class="n">desc</span> <span class="o">=</span> <span class="s2">&#34;ollama Generate Code&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">			<span class="n">mode</span> <span class="o">=</span> <span class="p">{</span> <span class="s2">&#34;n&#34;</span><span class="p">,</span> <span class="s2">&#34;v&#34;</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl">		<span class="p">},</span>
</span></span><span class="line"><span class="cl">	<span class="p">},</span>
</span></span><span class="line"><span class="cl">	<span class="c1">---@type Ollama.Config</span>
</span></span><span class="line"><span class="cl">	<span class="n">opts</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">		<span class="n">model</span> <span class="o">=</span> <span class="s2">&#34;codellama:7b&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">		<span class="n">url</span> <span class="o">=</span> <span class="s2">&#34;http://127.0.0.1:11434&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">	<span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h1 id="integrating-ollama-with-vscode">Integrating Ollama with VSCode</h1>
<p>The <a href="https://marketplace.visualstudio.com/items?itemName=Continue.continue" target="_blank">Continue</a> VSCode
extension supports the integration of LLMs
as coding assistants. To use it with Ollama we have to
change the <strong>Proxy Server Url</strong> in its settings to the one
used by our Ollama container.</p>
<p align="center"><img src="continue-settings.png" alt="Continue Extension Settings"></p>
<p align="center"><small>Continue Extension Settings</small></p>
<p>Watch Ollama in action inside VSCode</p>
<p align="center"><img src="ollama-vscode.gif" alt="Optimizing code using Ollama in VSCode"></p>
<p align="center"><small>Optimizing code using Ollama in VSCode</small></p>
<hr>
<p>Thank you for taking the time to read this blog post! Have questions, feedback or want to discuss this topic? Feel free to reach out at <a href="mailto:blog@avni.sh"><a href="mailto:blog@avni.sh">blog@avni.sh</a></a>.</p>
<p>If you found this content valuable and would like to stay updated with my latest posts, consider subscribing to my <a href="https://www.avni.sh/index.xml" target="_blank">RSS Feed</a>.</p>
<h1 id="resources">Resources</h1>
<p><a href="https://ollama.ai/" target="_blank">Ollama</a><br>
<a href="https://hub.docker.com/r/ollama/ollama" target="_blank">Ollama Docker Image</a><br>
<a href="https://www.nvidia.com/en-in/geforce/graphics-cards/30-series/rtx-3070-3070ti/" target="_blank">NVIDIA GeForce RTX 3070 Ti</a><br>
<a href="https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html" target="_blank">NVIDIA CUDA Installation Guide for Linux</a><br>
<a href="https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/index.html" target="_blank">NVIDIA Container Toolkit</a><br>
<a href="https://ollama.ai/library" target="_blank">Ollama Library</a><br>
<a href="https://github.com/ollama-webui/ollama-webui" target="_blank">Ollama Web UI</a><br>
<a href="https://github.com/nomnivore/ollama.nvim" target="_blank">ollama.nvim</a><br>
<a href="https://marketplace.visualstudio.com/items?itemName=Continue.continue" target="_blank">Continue</a></p>
]]></content:encoded>
    </item>
    <item>
      <title>Building Your Own Homelab</title>
      <link>http://www.avni.sh/posts/self-hosting/building-your-own-homelab/</link>
      <pubDate>Mon, 27 Mar 2023 00:00:00 +0000</pubDate>
      <guid>http://www.avni.sh/posts/self-hosting/building-your-own-homelab/</guid>
      <description>A Guide to Selecting the Right Hardware for Self-Hosting Services</description>
      <content:encoded><![CDATA[<p>There is an app for everything and modern app stores have made it extremely convenient to install them on your device. However, some underlying issues need to be discussed</p>
<ul>
<li>
<p>Each application has a different set of terms and services. A small subset of users read it and a smaller subset of them will refuse to use the application if they disagree with it.</p>
</li>
<li>
<p>These applications are critical for your daily life but if you lose access to them, there might not be a proper support channel to regain access or retrieve data.</p>
</li>
</ul>
<p>If you lose access to your Google account you’ll also lose access to your emails, your photos (backed up on Google Photos), your YouTube account, and probably most of the services you signed in using Google.</p>
<ul>
<li>Many of them operate on a subscription-based model which means you don&rsquo;t own the product outright, you are just renting it as a service.</li>
</ul>
<p>The application provider can change their payment model to subscription-based, while also discontinuing your existing “lifetime” license. <a href="https://support.google.com/a/answer/2855120?hl=en" target="_blank">G Suite legacy free edition</a>, <a href="https://community.teamviewer.com/English/discussion/119369/has-anyone-who-bought-a-lifetime-license-for-earlier-version-5-gotten-free-update-to-v-1" target="_blank">TeamViewer</a></p>
<p>The service itself could be discontinued. <a href="https://killedby.tech/google/" target="_blank">Killed by Google</a></p>
<p>Content &ldquo;owned&rdquo; by you could be removed without your consent. <a href="https://www.pushsquare.com/news/2022/07/sony-removing-some-purchased-films-movies-from-users-accounts" target="_blank">Sony Removing Some Purchased Films, Movies from Users&rsquo; Accounts</a></p>
<p>Self-Hosted alternatives to some or all of these services will give you more control while also keeping your data private. There are multiple hardware options available across the budget that could be used to host services like media streaming, cloud storage, VPN server, etc. at your home.</p>
<h1 id="mini-pcs">Mini PCs</h1>
<p>Mini PCs provide maximum utility for homelab but in a smaller package with low power consumption and noise.</p>
<p>If you want to get started with self-hosting or deploy a secondary server for services running round-the-clock (like a password manager, DNS, router, etc.) then a mini PC would be a great option.</p>
<h2 id="raspberry-pi-and-alternatives">Raspberry Pi and Alternatives</h2>
<p align="center"><img src="raspberry-pi-and-alternatives.jpg" alt="Raspberry Pi and Alternatives"></p>
<p align="center"><small><i>Photo by <a href="https://unsplash.com/@harrisonbroadbent?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Harrison Broadbent</a> on <a href="https://unsplash.com/photos/1mu9gF8OhNk?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a></i></small></p>
<p>Raspberry Pi is a credit-card-sized mini PC that uses CPUs based on ARM architecture. Due to its modularity and open design, it is used for monitoring weather, robotics, and teaching basic computer science.</p>
<p>General-Purpose Input/Output (GPIO) pins on Raspberry Pi could be used for integrating it with different circuits or appliances to monitor/control them or extend their functionality.</p>
<p>It is a great candidate for self-hosting due to</p>
<ul>
<li>its smaller size</li>
<li>a large community of developers</li>
<li>minimal energy consumption</li>
<li>relatively affordable compared to other options</li>
</ul>
<p>At the time of writing the Raspberry Pis are unavailable in most countries or sold at a price significantly higher than their MSRP so you can explore its alternatives in this video from LinusTechTips: <a href="https://youtu.be/uJvCVw1yONQ" target="_blank">I Can Save You Money! – Raspberry Pi Alternatives</a></p>
<h2 id="intel-nuc-and-alternatives">Intel NUC and Alternatives</h2>
<p align="center"><img src="intel-nuc.jpg" alt="Intel NUC"></p>
<p align="center"><small><i>Photo by <a href="https://unsplash.com/@gabimedia?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Gabriel Vasiliu</a> on <a href="https://unsplash.com/photos/1cIirhlCMts?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a></i></small></p>
<p>Next Unit of Computing (NUC) kits (PC kits without memory and storage) from Intel provide a relatively powerful alternative to Raspberry Pi or similar mini PCs.</p>
<p>NUCs are available with four types of Intel x86 processors: Celeron, Core i3, Core i5, and Core i7. NUC Extreme could be configured with a Core i9 processor and a desktop GPU.</p>
<p>MiniPCs like Beelink&rsquo;s <a href="https://www.bee-link.net/products/pre-order-beelink-gtr6-6900hx-first-quad-8k-mini-pc" target="_blank">GTR</a>, <a href="https://www.bee-link.net/products/beelink-ser5-mini-pc-amd-ryzen-5-5500u-16g-ddr4-500gb-m-2-2280-nvme-ssd-mini-desktop-computer-4k-60hz-wifi-6-bt5-2-dual-hdmi-type-c-support-2-5-inch-hdd" target="_blank">SER</a>, and <a href="https://www.bee-link.net/products/beelink-sr55-5800h-mini-pc" target="_blank">SR</a> series provide an AMD alternative to NUC in similar form factors.</p>
<h2 id="limitations-of-using-mini-pcs-for-self-hosting">Limitations of Using Mini PCs for Self-Hosting</h2>
<p>While MiniPCs are a great starting point for self-hosting services, there are still some limitations that you have to keep in mind</p>
<ul>
<li>MiniPCs do provide options for expansion and upgrades but relatively less than a custom PC build or a server.</li>
<li>You might not be able to run multiple intensive workloads in parallel.</li>
<li>To scale your homelab running on MiniPC you have to create a cluster of mini PC nodes.</li>
</ul>
<h1 id="cloud-service-providers-csps">Cloud Service Providers (CSPs)</h1>
<p>You can host your services on VMs provided by Cloud Service Providers (CSPs) like Azure, Amazon Web Services (AWS), and Google Cloud Platform (GCP). They also provide a static IP for VMs which could be useful if you want your services publicly available.</p>
<h2 id="limitations-of-using-csps-for-self-hosting">Limitations of Using CSPs for Self-Hosting</h2>
<ul>
<li>You are dependent on your CSP for the availability of your services. A CSP outage could also mean a homelab outage.</li>
<li>Depending on your workload and your geographical location, hosting and running a VM round-the-clock might be expensive due to cloud costs.</li>
<li>Scaling your lab on the cloud could be expensive.</li>
</ul>
<h1 id="decommissioned-serversworkstations">Decommissioned Servers/Workstations</h1>
<p align="center"><img src="servers.jpg" alt="Servers"></p>
<p align="center"><small><i>Photo by <a href="https://unsplash.com/@tvick?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Taylor Vick</a> on <a href="https://unsplash.com/photos/M5tzZtFCOfs?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a></i></small></p>
<p>Datacenters and IT organizations often decommission servers and sell them on the secondary market. They might not perform well with the current enterprise workloads but their performance should be adequate for homelab.</p>
<p>Some enterprise features could help you in managing your homelab like</p>
<ul>
<li>10 Gigabit Ethernet: If you are running a media streaming service or a video editing file server then having 10GbE could significantly improve your workflow.</li>
<li>Intelligent Platform Management Interface (IPMI): A Motherboard with IPMI allows you to access your system’s firmware remotely. Using this you can diagnose firmware/hardware-related issues or install OS without connecting a display or peripherals.</li>
<li>Error Correction Code (ECC) memory: ECC memory unlike non-ECC memory automatically detects and corrects memory errors. It is a necessary feature for critical workloads as it prevents unexpected crashes and outages.</li>
<li>Ability to swap Power Supply Units (PSUs) and storage devices easily.</li>
</ul>
<h2 id="limitations-of-using-decommissioned-servers-for-self-hosting">Limitations of Using Decommissioned Servers for Self-Hosting</h2>
<ul>
<li>Scarce availability of replacements for components.</li>
<li>Datacenter servers are designed to provide maximum cooling with the tradeoff of the high noise level. This might not be ideal if you want to deploy it in your home.</li>
<li>The footprint of a server might be larger than an average PC.</li>
</ul>
<h1 id="custom-pc-build">Custom PC Build</h1>
<p align="center"><img src="pc.jpg" alt="Not my PC"></p>
<p align="center"><small><i>Not my PC. Photo by <a href="https://unsplash.com/ja/@amieldh?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Amiel D Hechanova</a> on <a href="https://unsplash.com/photos/XznGSZ9DtpQ?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a>
  </i></small></p>
<p>Custom PC builds provide maximum upgradability and customization and that’s why I decided to build one. I’ll go through my thought process for selecting each component, while it might not be the same for you, it can provide a direction for decision-making.</p>
<p>My planned use case for homelab:</p>
<ul>
<li>Hosting a Network Attached Storage (NAS) server</li>
<li>Deploying Kubernetes/Red Hat OpenShift Local cluster</li>
<li>Hosting a Virtual Private Network (VPN) server</li>
<li>Hosting a media streaming server</li>
<li>Windows VM for gaming</li>
<li>Trying different self-hosted applications</li>
</ul>
<p>Based on my use case I decided on the following specification:</p>
<ul>
<li>More than 8 cores and 16 threads for simultaneous execution of multiple VMs and containers. I decided that I&rsquo;ll allocate at least 4 threads to my Windows VM.</li>
<li>2TB of redundant storage i.e. two drives mirrored on NAS.</li>
<li>2.5 Gigabit networking on the motherboard as I’ll be accessing services remotely.</li>
<li>32GB memory would be adequate for VMs. I went with DDR4 because DDR5 exceeds my budget.</li>
<li>1TB NVMe SSD storage for the host OS/hypervisor to be installed on homelab.</li>
<li>PCIe bandwidth and PSU wattage to support Nvidia’s GeForce RTX 3070/RTX 4070 GPU with an expansion card like Network Interface Card (NIC) for a possible 10 Gigabit upgrade in the future.</li>
<li>2 X 2TB HDD for NAS server.</li>
</ul>
<p><a href="/posts/homelab/building-your-own-homelab/#my-pc-build-specification">Skip to My PC Build Specification &raquo;</a></p>
<h2 id="cpu">CPU</h2>
<p>You should make sure that your CPU has support for virtualization with enough cores and threads to host and deploy multiple services concurrently.</p>
<p>Depending on your goals you should also look for:</p>
<ul>
<li>Overclocking support</li>
<li>ECC Memory support</li>
<li>Integrated Graphics: If your CPU doesn’t have integrated graphics then you have to purchase a GPU to install or access the OS/hypervisor.</li>
</ul>
<p>I wanted a CPU with more than or equal to 8 cores with integrated graphics, the options in my budget were: <a href="https://www.amd.com/en/products/apu/amd-ryzen-7-7700" target="_blank">AMD Ryzen 7 7700</a> or <a href="https://www.intel.in/content/www/in/en/products/sku/230580/intel-core-i513500-processor-24m-cache-up-to-4-80-ghz/specifications.html" target="_blank">Intel Core i5-13500</a>. I didn&rsquo;t have any overclocking requirements, otherwise, I would&rsquo;ve gone with <a href="https://www.intel.in/content/www/in/en/products/sku/230493/intel-core-i513600k-processor-24m-cache-up-to-5-10-ghz/specifications.html" target="_blank">Intel Core i5-13600K</a>.</p>
<p>I went with the <strong>i5-13500</strong> as it has more cores and threads compared to Ryzen 7700.</p>
<h2 id="motherboard">Motherboard</h2>
<p>The choice of your CPU limits the choices of your motherboard. First, you&rsquo;ll have to select the motherboard chipset compatible with your CPU:</p>
<ul>
<li><a href="https://www.amd.com/en/chipsets/am5" target="_blank">AMD chipsets</a>: B650, B650E, X670, X670E</li>
<li><a href="https://ark.intel.com/content/www/us/en/ark/products/series/229717/intel-700-series-desktop-chipsets.html#@Desktop" target="_blank">Intel 700 series chipsets</a>: Z790, H770, B760, W790</li>
</ul>
<p>Motherboard features you might want to consider for your homelab:</p>
<ul>
<li>Upgradability path with future CPU releases</li>
<li>PCIe Bandwidth for expansion cards</li>
<li>2.5 Gigabit networking</li>
<li>SATA ports for storage expansion</li>
<li>IPMI support</li>
</ul>
<p>I planned on getting <a href="https://www.msi.com/Motherboard/PRO-B760M-A-WIFI-DDR4" target="_blank">MSI PRO B760M-A WIFI DDR4</a> but I got a better deal with <a href="https://www.msi.com/Motherboard/PRO-Z690-P-WIFI" target="_blank">MSI PRO Z690-P WIFI DDR4</a> so I went with that. It has 2.5 Gigabit networking and 6x SATA ports which provides me the option to add more drives in the future.</p>
<h2 id="cpu-cooler">CPU Cooler</h2>
<p>Most CPUs come with an air cooler. But if you are using a high-end CPU you might not be able to extract its complete performance using the default cooler.</p>
<p>Options are air cooling, custom water cooling, or an All-In-One (AIO) Liquid cooler. You can make your decision based on your CPU, cooling performance, noise level, and ease of installation.</p>
<p>I went with <a href="https://www.corsair.com/br/en/Categories/Products/Liquid-Cooling/RGB-Liquid-CPU-Coolers/p/CW-9060053-WW" target="_blank">Corsair H100 RGB 240mm Liquid CPU Cooler</a> due to its price and aesthetics.</p>
<h2 id="memory">Memory</h2>
<p>At the time of writing the price of DDR5 memory is significantly higher than its MSRP so I opted for DDR4.</p>
<p>I went with 2 x <a href="https://www.corsair.com/us/en/Categories/Products/Memory/VENGEANCE-LPX/p/CMK16GX4M1E3200C16" target="_blank">Corsair VENGEANCE LPX 16GB DDR4 DRAM Memory Kit</a> because its 3200MHz speed will be adequate for my workload.</p>
<h2 id="storage">Storage</h2>
<p>Network Attached Storage (NAS) server is a common self-hosted service. With a NAS server, you have your cloud storage without privacy concerns or subscriptions. That’s why selecting the right storage device is important.</p>
<p>Along with drives for NAS you&rsquo;ll need additional storage for the OS/Hypervisor running on your homelab.</p>
<h3 id="boot-drive">Boot Drive</h3>
<p>It&rsquo;s ideal to store the OS/Hypervisor in a faster drive compared to the drives used for NAS, like NVMe or SATA Solid-State Drive (SSD).</p>
<p>I&rsquo;m using <a href="https://www.kingston.com/en/ssd/nv2-nvme-pcie-ssd?capacity=1tb" target="_blank">Kingston NV2 PCIe 4.0 NVMe SSD </a> as the boot disk for the Proxmox hypervisor.</p>
<h3 id="nas-drives">NAS Drives</h3>
<p>Although you can use any Hard Disk Drive (HDD) for your NAS server you might want to consider NAS-rated hard drives because they provide advantages like</p>
<ul>
<li>Optimization for read-and-write operations</li>
<li>Relatively fewer vibrations compared to desktop hard drives</li>
<li>Rated for 24/7 operation</li>
</ul>
<p>If you are using two hard drives in mirrored mode then it is safer to source them from different vendors.</p>
<p>I opted for <a href="https://www.westerndigital.com/en-in/products/internal-drives/wd-blue-desktop-sata-hdd#WD5000AZLX" target="_blank">WD Blue PC Desktop Hard Drive 2TB</a> and <a href="https://www.seagate.com/in/en/products/hard-drives/barracuda-hard-drive/" target="_blank">Seagate BarraCuda Hard Drives 2TB</a> as storage drives. I&rsquo;ll be running them in mirrored mode using TrueNAS.</p>
<h2 id="power-supply-unit-psu">Power Supply Unit (PSU)</h2>
<p>Websites like <a href="https://outervision.com/power-supply-calculator" target="_blank">OuterVision Power Supply Calculator</a> could be used to calculate the power budget of your PC. It&rsquo;s ideal to select a power supply with higher wattage to ensure upgradability.</p>
<p>PSUs are rated as White, Bronze, Silver, Gold, Platinum, and Titanium in the increasing order of their efficiency. An efficient PSU will draw less power and run quieter. Hence, reducing your power bill.</p>
<p>I opted for <a href="https://www.corsair.com/us/en/Categories/Products/Power-Supply-Units/Power-Supply-Units-Advanced/RM-Series%E2%84%A2-80-PLUS-Gold-Power-Supplies/p/CP-9020196-NA" target="_blank">Corsair RM850 850 Watt 80 PLUS Gold Certified Fully Modular PSU</a> which provides 850W of wattage and that is enough to run my homelab while also providing an option to add an Nvidia GeForce RTX 3070/RTX 4070 in the future.</p>
<h2 id="pcie-expansion-cards">PCIe Expansion Cards</h2>
<p>If you are planning to use your homelab for video editing, animation, machine learning, gaming, or any similar workloads then adding a GPU can improve its performance significantly.</p>
<p>By adding a 10 Gigabit Network Interface Card (NIC) you can reduce the access time to your services.</p>
<h2 id="case">Case</h2>
<p>As long as all the components fit, any PC case could be used for homelab. You might want to consider its</p>
<ul>
<li>options for expansion</li>
<li>cooling</li>
<li>build quality</li>
<li>cable management</li>
</ul>
<p>I selected <a href="https://www.corsair.com/us/en/Categories/Products/Cases/Mid-Tower-ATX-Cases/4000D-Airflow-Tempered-Glass-Mid-Tower-ATX-Case/p/CC-9011200-WW" target="_blank">Corsair 4000D AIRFLOW Tempered Glass Mid-Tower ATX Case</a> due to its airflow and ease of building.</p>
<h2 id="limitations-of-using-custom-pc-build-for-self-hosting">Limitations of Using Custom PC Build for Self-Hosting</h2>
<ul>
<li>While it is easy to build PCs by following guides and tutorials on the internet. It might still be very difficult for novice builders. Retailers do provide an option to assemble the components, sometimes at no extra cost.</li>
<li>Current prices of some components are significantly higher than their MSRPs, even double in some cases.</li>
<li>The upfront cost is higher compared to other options.</li>
</ul>
<h1 id="my-pc-build-specification">My PC Build Specification</h1>
<table>
  <thead>
      <tr>
          <th>Component</th>
          <th>Product</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>CPU</td>
          <td><a href="https://www.intel.in/content/www/in/en/products/sku/230580/intel-core-i513500-processor-24m-cache-up-to-4-80-ghz/specifications.html" target="_blank">Intel Core i5-13500</a></td>
      </tr>
      <tr>
          <td>Motherboard</td>
          <td><a href="https://www.msi.com/Motherboard/PRO-Z690-P-WIFI" target="_blank">MSI PRO Z690-P WIFI DDR4</a></td>
      </tr>
      <tr>
          <td>CPU Cooler</td>
          <td><a href="https://www.corsair.com/br/en/Categories/Products/Liquid-Cooling/RGB-Liquid-CPU-Coolers/p/CW-9060053-WW" target="_blank">Corsair H100 RGB 240mm Liquid CPU Cooler</a></td>
      </tr>
      <tr>
          <td>Memory</td>
          <td>2 X <a href="https://www.corsair.com/us/en/Categories/Products/Memory/VENGEANCE-LPX/p/CMK16GX4M1E3200C16" target="_blank">Corsair VENGEANCE LPX 16GB DDR4 DRAM Memory Kit</a></td>
      </tr>
      <tr>
          <td>SSD</td>
          <td><a href="https://www.kingston.com/en/ssd/nv2-nvme-pcie-ssd?capacity=1tb" target="_blank">Kingston NV2 PCIe 4.0 NVMe SSD </a></td>
      </tr>
      <tr>
          <td>HDD 1</td>
          <td><a href="https://www.westerndigital.com/en-in/products/internal-drives/wd-blue-desktop-sata-hdd#WD5000AZLX" target="_blank">WD Blue PC Desktop Hard Drive 2TB</a></td>
      </tr>
      <tr>
          <td>HDD 2</td>
          <td><a href="https://www.seagate.com/in/en/products/hard-drives/barracuda-hard-drive/" target="_blank">Seagate BarraCuda Hard Drives 2TB</a></td>
      </tr>
      <tr>
          <td>PSU</td>
          <td><a href="https://www.corsair.com/us/en/Categories/Products/Power-Supply-Units/Power-Supply-Units-Advanced/RM-Series%E2%84%A2-80-PLUS-Gold-Power-Supplies/p/CP-9020196-NA" target="_blank">Corsair RM850 850 Watt 80 PLUS Gold Certified Fully Modular PSU</a></td>
      </tr>
      <tr>
          <td>Case</td>
          <td><a href="https://www.corsair.com/us/en/Categories/Products/Cases/Mid-Tower-ATX-Cases/4000D-Airflow-Tempered-Glass-Mid-Tower-ATX-Case/p/CC-9011200-WW" target="_blank">Corsair 4000D AIRFLOW Tempered Glass Mid-Tower ATX Case</a></td>
      </tr>
  </tbody>
</table>
<p align="center"><img src="pc_front.jpg" alt="PC - Front"></p>
<p align="center"><img src="pc_side.jpg" alt="PC - Side"></p>
<p align="center"><small><i>The Result</i></small></p>
<h1 id="challenges-of-self-hosting">Challenges of Self-Hosting</h1>
<ul>
<li>Deploying and managing a homelab could be difficult for people who don&rsquo;t work with computers. But it is possible with patience and research.</li>
<li>Managing some services like an email server is difficult, especially when they integrate with other services.</li>
<li>You have to manage and debug issues yourself. You&rsquo;ll learn a lot, which might help you in your professional career.</li>
<li>You have to provide technical support to everyone else using your services.</li>
<li>You might lose out on some features or their quality provided by proprietary services. Like AI face recognition provided with Google Photos.</li>
<li>You are responsible for the security of your data. Make sure that all of the services, OS, and hypervisors are up to date.</li>
<li>For some applications, you might not have full autonomy to switch to a self-hosted alternative. For example, if your friends and family use WhatsApp then you can’t simply switch to a self-hosted alternative and expect others to do the same.</li>
</ul>
<hr>
<p>Thank you for taking the time to read this blog post! Have questions, feedback or want to discuss this topic? Feel free to reach out at <a href="mailto:blog@avni.sh"><a href="mailto:blog@avni.sh">blog@avni.sh</a></a>.</p>
<p>If you found this content valuable and would like to stay updated with my latest posts, consider subscribing to my <a href="https://www.avni.sh/index.xml" target="_blank">RSS Feed</a>.</p>
<h1 id="resources-to-learn-about-homelab-and-self-hosting">Resources to Learn About Homelab and Self-Hosting</h1>
<h2 id="blogs">Blogs</h2>
<p><a href="https://pimylifeup.com/" target="_blank">PiMyLifeUp</a><br>
<a href="https://blog.patshead.com/" target="_blank">Pat&rsquo;s Blog</a><br>
<a href="https://noted.lol/" target="_blank">noted.lol</a><br>
<a href="https://www.homelabrat.com/" target="_blank">homelabrat</a></p>
<h2 id="repositories">Repositories</h2>
<p><a href="https://github.com/awesome-selfhosted/awesome-selfhosted" target="_blank">awesome-selfhosted</a><br>
<a href="https://github.com/tteck/Proxmox" target="_blank">tteck/Proxmox</a><br>
<a href="https://github.com/topics/homelab" target="_blank">topics/homelab</a></p>
<h2 id="subreddits">Subreddits</h2>
<p><a href="https://old.reddit.com/r/selfhosted/" target="_blank">r/selfhosted</a><br>
<a href="https://old.reddit.com/r/homelab/" target="_blank">r/homelab</a><br>
<a href="https://old.reddit.com/r/homeautomation/" target="_blank">r/homeautomation</a></p>
<h2 id="youtube-channels">Youtube Channels</h2>
<p><a href="https://www.youtube.com/@NetworkChuck" target="_blank">NetworkChuck</a><br>
<a href="https://www.youtube.com/@TechnoTim" target="_blank">TechnoTim</a><br>
<a href="https://www.youtube.com/@RaidOwl" target="_blank">RaidOwl</a><br>
<a href="https://www.youtube.com/@HardwareHaven" target="_blank">Hardware Haven</a><br>
<a href="https://www.youtube.com/@WolfgangsChannel" target="_blank">Wolfgang&rsquo;s Channel</a><br>
<a href="https://www.youtube.com/@LearnLinuxTV" target="_blank">Learn Linux TV</a><br>
<a href="https://www.youtube.com/@LAWRENCESYSTEMS" target="_blank">Lawrence Systems</a><br>
<a href="https://www.youtube.com/@AwesomeOpenSource" target="_blank">AwesomeOpenSource</a></p>
<h1 id="resources">Resources</h1>
<p><a href="https://support.google.com/a/answer/2855120?hl=en" target="_blank">G Suite legacy free edition</a><br>
<a href="https://community.teamviewer.com/English/discussion/119369/has-anyone-who-bought-a-lifetime-license-for-earlier-version-5-gotten-free-update-to-v-1" target="_blank">Has anyone who bought a lifetime license for earlier version (5) gotten free update to v.1?</a>
<a href="https://killedby.tech/google/" target="_blank">Killed by Google</a><br>
<a href="https://www.pushsquare.com/news/2022/07/sony-removing-some-purchased-films-movies-from-users-accounts" target="_blank">Sony Removing Some Purchased Films, Movies from Users&rsquo; Accounts</a><br>
<a href="https://www.raspberrypi.org/help/what-%20is-a-raspberry-pi/" target="_blank">What is a Raspberry Pi?</a><br>
<a href="https://www.raspberrypi.com/software/" target="_blank">Raspberry Pi OS</a><br>
<a href="https://youtu.be/uJvCVw1yONQ" target="_blank">I Can Save You Money! – Raspberry Pi Alternatives</a><br>
<a href="https://www.intel.in/content/www/in/en/products/details/nuc.html" target="_blank">Intel NUC Mini PCs</a><br>
<a href="https://www.amd.com/en/products/embedded-minipc-solutions" target="_blank">Mini PCs – Powered by AMD Ryzen™ Embedded Processors</a><br>
<a href="https://www.bee-link.net/products/pre-order-beelink-gtr6-6900hx-first-quad-8k-mini-pc" target="_blank">GTR</a><br>
<a href="https://www.bee-link.net/products/beelink-ser5-mini-pc-amd-ryzen-5-5500u-16g-ddr4-500gb-m-2-2280-nvme-ssd-mini-desktop-computer-4k-60hz-wifi-6-bt5-2-dual-hdmi-type-c-support-2-5-inch-hdd" target="_blank">SER</a><br>
<a href="https://www.bee-link.net/products/beelink-sr55-5800h-mini-pc" target="_blank">SR</a><br>
<a href="https://blog.synology.com/xmas-wishlist-why-choose-nas-drives-over-desktop-drives-for-your-nas" target="_blank">Why choose NAS drives over desktop drives for your NAS?</a><br>
<a href="https://www.pcworld.com/article/394951/pc-power-supply-ratings-80-plus-platinum-vs-gold-vs-bronze-vs-white-explained.html" target="_blank">Power supply ratings explained: 80 Plus Platinum vs. Gold vs. Bronze vs. White</a><br>
<a href="https://outervision.com/power-supply-calculator" target="_blank">OuterVision® Power Supply Calculator</a><br>
<a href="https://www.howtogeek.com/719270/how-to-choose-a-pc-case-5-features-to-consider/" target="_blank">How to Choose a PC Case: 5 Features to Consider</a><br>
<a href="https://old.reddit.com/r/selfhosted/comments/t8gqir/why_you_really_dont_want_to_selfhost_your_own/" target="_blank">Why you really DON&rsquo;T want to self-host your own e-mail server</a><br>
<a href="https://thehackernews.com/2023/03/lastpass-hack-engineers-failure-to.html" target="_blank">LastPass Hack: Engineer&rsquo;s Failure to Update Plex Software Led to Massive Data Breach</a></p>
]]></content:encoded>
    </item>
  </channel>
</rss>
